diff options
2263 files changed, 218361 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000000..f0db6e6f5b --- /dev/null +++ b/.cvsignore @@ -0,0 +1,10 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* + +configparms + +sun4 i386 i386-gnuelf hp300-netbsd hp300 + +ieeetest hppa-sysdeps regex diff --git a/=__ify b/=__ify new file mode 100755 index 0000000000..017d909a1a --- /dev/null +++ b/=__ify @@ -0,0 +1,12 @@ +for func in $*; do + for file in `find sysdeps -name "${func}.c"`; + do + script=/tmp/foo$$; + ( echo "%s/${func}/__&/g"; + echo x )>$script ; + ex $file <$script ; + newfile=`echo $file | sed "s/${func}/__&/"`; + mv $file $newfile; + echo $newfile; + done +done diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000000..f43f045752 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,11886 @@ +Fri Feb 17 12:16:27 1995 Roland McGrath <roland@duality.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/Makefile (errlist.c, errnos.h): Do cvs commit + if there is a CVS directory. + * sysdeps/sparc/Makefile (divrem output): Likewise. + * sysdeps/alpha/Makefile (divrem output): Likewise. + + * Makerules (rule to install lib%.a from $(install-lib)): Fix + patsubst to elide ranlib for $(non-lib.a). + + * stdio/tst-printf.c: Enable FP tests. Add some new tests from rfg. + +Thu Feb 16 04:06:06 1995 Roland McGrath <roland@duality.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mig-reply.c: Add weak aliases to non-__ names. + * mach/mig-dealloc.c: Add weak alias mig_deallocate. + +Wed Feb 15 13:34:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd/signal.h (HURD_MSGPORT_RPC): Take new arg + DEALLOC_REFPORT; deallocate the refport after use only if it + evaluates to nonzero. + * sysdeps/mach/hurd/kill.c: Pass DEALLOC_REFPORT arg of one. + * hurd/hurdkill.c: Pass DEALLOC_REFPORT arg of zero. + + * hurd/hurdsig.c (abort_rpcs): Take new arg int *STATE_CHANGE; set + *STATE_CHANGE to indicate whether or not we changed *STATE and it + should be committed to the thread. + (abort_all_rpcs): Take new arg LIVE; if nonzero and abort_rpcs changes + state for a thread, do thread_set_state on that thread. Don't use + SS->intr_port for collecting reply ports, it is not safe to + clobber that when suspending; instead, alloca a temporary array. + (_hurd_internal_post_signal): Pass LIVE flag to abort_all_rpcs: + zero when dying, one when suspending. Pass new arg to abort_rpcs. + + * sysdeps/mach/hurd/stdio_init.c: Don't lock the file descriptor; + HURD_FD_PORT_USE will. Don't use critical sections around + HURD_FD_PORT_USE invocations. + + * sysdeps/mach/hurd/stdio_init.c: Don't make pipes/FIFOs unbuffered. + * sysdeps/posix/stdio_init.c: Likewise. + +Tue Feb 14 03:01:12 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd/fd.h (_hurd_fd_get): Don't do critical section + locking; don't leave the descriptor locked on return. + (HURD_FD_PORT_USE): Don't expect _hurd_fd_get to return the fd locked. + Use a critical section around locking the descriptor. + Check for an empty descriptor and return EBADF. + * sysdeps/mach/hurd/dup2.c: Likewise. + * sysdeps/mach/hurd/fcntl.c: Likewise. + Use HURD_FD_PORT_USE macro for RPCs. + * sysdeps/mach/hurd/sysd-stdio.c: Don't lock the descriptor before + using HURD_FD_PORT_USE. + * sysdeps/mach/hurd/defs.c (init_stdio): Don't expect _hurd_fd_get + to lock the descriptor. + * sysdeps/mach/hurd/stdio_init.c: Use critical sections while + locking the descriptor. + * sysdeps/mach/hurd/fdopen.c: Likewise. + * hurd/fd-close.c: Likewise. + Don't expect the descriptor to be locked on entry. + Check for empty descriptor and return EBADF. + + Factor ctty RPC code for SIGTTIN/SIGTTOU generation out into + new functions _hurd_ctty_input and _hurd_ctty_output, each + called with (io_t port, io_t ctty, error_t (*rpc) (io_t)). + * hurd/ctty-input.c: New file. + * hurd/ctty-output.c: New file. + * hurd/Makefile (dtable): Add ctty-input and ctty-output. + * hurd/fd-read.c: Use _hurd_ctty_input. + * hurd/fd-write.c: Use _hurd_ctty_output. + * sysdeps/mach/hurd/ioctl.c: Likewise. + * hurd/hurd/fd.h (_hurd_ctty_input, _hurd_ctty_output): Declare them. + +Mon Feb 13 11:36:12 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/vfscanf.c (%e, %f, %g): Use strtod, __strtold, or __strtof + as appropriate to the type. + + * sysdeps/ieee754/huge_val.h (__huge_val_t): New macro to avoid + repeating the union. + (HUGE_VAL, __huge_val): Use it. + [__USE_GNU] (HUGE_VALf, HUGE_VALl): New macros, along with + analogous macros to HUGE_VAL's: __huge_val[fl]_t, __HUGE_VAL[fl]_bytes. + * stdlib/strtold.c (FLOAT_HUGE_VAL): Define this to HUGE_VALl. + (STRTOF): Set to __strtold; define strtold as weak alias. + * stdlib/strtof.c (FLOAT_HUGE_VAL): Define this to HUGE_VALf. + (STRTOF): Set to __strtof; define strtof as weak alias. + + * sysdeps/ieee754/ieee754.h (union ieee754_float): New type. + (IEEE754_FLOAT_BIAS): New macro. + + * sysdeps/ieee754/mpn2ldbl.c: Fix typos. + + * stdlib/testmb.c: Add tests from rfg for using normal chars as + multibyte chars. + + * hurd/hurdmalloc.c (malloc_init): Add self reference to avoid not + only the `defined but not used' warning, but also to avoid GCC + optimizing out the entire function (!). + + * stdlib/wctomb.c: Include ctype.h. + + * Makerules (install-lib-non.a): Don't include $(non-lib.a). + + * hurd/hurdmalloc.c: Include string.h; #define bcopy using memcpy. + +Sat Feb 11 04:05:29 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/printf_fp.c: Include "fpioconst.h". + (_tens_p): Table moved to fpioconst.c, renamed to _fpioconst_pow10. + (__printf_fp): All references changed. + Don't bother computing THOUSANDS_SEP if GROUPING is empty. + (group_number): Use memmove instead of memcpy, since operands overlap. + * stdio/fpioconst.c: New file, tables broken out of stdio/printf_fp.c. + * stdio/fpioconst.h: New file, header declaring the table data. + * stdio/Makefile (aux): Add fpioconst. + (distribute): Add fpioconst.h. + * stdlib/strtod.c: Complete rewrite from drepper. + * stdlib/strtof.c: New file. + * stdlib/strtold.c: New file. + * stdlib/Makefile (routines): Add strtof, strtold. + * stdio/Makefile (routines): Add mpn2flt, mpn2dbl, mpn2ldbl. + * sysdeps/stub/mpn2flt.c: New file. + * sysdeps/stub/mpn2dbl.c: New file. + * sysdeps/stub/mpn2ldbl.c: New file. + * sysdeps/ieee754/mpn2flt.c: New file. + * sysdeps/ieee754/mpn2dbl.c: New file. + * sysdeps/ieee754/mpn2ldbl.c: New file. + + * Makerules (install-lib.a): Don't filter out $(non-lib.a). + ($(install-lib.a) in $(libdir) rule): Elide ranlib command when $@ + appears in $(non-lib.a). + +Fri Feb 10 17:20:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdlib/wctomb.c: A normal ASCII character translates to itself. + * stdlib/mbtowc.c: Likewise. + +Thu Feb 9 03:55:55 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * setjmp/setjmp.h (longjmp, _longjmp, __longjmp, siglongjmp): + Remove `const' from prototypes. + * sysdeps/m68k/__longjmp.c: Likewise. + * setjmp/longjmp.c: Likewise. + * sysdeps/i386/__longjmp.c: Likewise. + + * sysdeps/posix/tempname.c: Increment *IDX at beginning of loop, + so when we return a name, it is incremented past the value that + produces that same name. + + * stdio/fgets.c (fgets): Change `size_t' to `int' in prototype. Sigh. + * stdio/stdio.h (fgets): Likewise. + + * stdio/vfprintf.c (printf_unknown): Print ' for INFO->group flag. + + * hurd/fd-write.c: Don't clobber ERR with the msg_sig_post call + when it's EBACKGROUND; we need to notice that it is EBACKGROUND + and retry the RPC. + * hurd/fd-read.c: Likewise. + +Wed Feb 8 05:01:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/sysdep.h (FATAL_PREPARE_INCLUDE): New macro, set to + <mach/mig_support.h>. + * assert/assert-perr.c [FATAL_PREPARE_INCLUDE]: Include it. + * assert/assert.c: Likewise. + * sysdeps/posix/libc_fatal.c: Likewise. + +Tue Feb 7 12:17:58 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/stdio.h [__STRICT_ANSI__] (stdin, stdout, stderr): Define + as macros, to satisfy ANSI pedants. + + * stdio/internals.c (flushbuf): When there is no new data after + priming the stream, return without writing out the buffer. + * stdio/Makefile (tests): Add bug7. + * stdio/bug7.c: New file. + + * io/sys/stat.h (S_IFIFO, S_IFLNK, S_IFSOCK, S_ISFIFO, S_ISLNK, + S_ISSOCK): Define only if the corresponding underlying __S_IF* macro + is defined. + + * stdio/getdelim.c: Decrement COPY after getting a char from __fillbf. + + * stdio/Makefile (tests): Add errnobug. + * stdio/errnobug.c: New file. + + * mach/mig_strncpy.c: Include string.h. + + * sysdeps/mach/sysdep.h: Don't #include <mach/mig_support.h>. Its + inlines cause trouble for files defining global register + variables. + + * stdio/vfprintf.c: Use _strerror_internal for %m. + + * sysdeps/ieee754/dbl2mpn.c: Fixes from drepper for 64-bit limbs. + + * stdio/printf.h (struct printf_info): New member `group', for %' flag. + * stdio/printf-prs.c (parse_printf_format): Grok %' flag and set flag. + * stdio/vfprintf.c (group_number): New function. + (vfprintf): Support %' flag for integer formats, by calling + group_number after formatting the number in WORK. + * stdio/printf_fp.c (guess_grouping, group_number): New functions. + (__printf_fp): Implement `group' flag using them. + + * Makefile (include sysd-dirs): Protect with ifndef avoid-generated. + (parent-clean): Remove sysd-rules, not sysdirs. + (distclean): Pass avoid-generated=yes to submake. + (distclean-1): Remove $(sysdep-$(distclean-1)). + + * Makerules (objects, objs): Depend on $(extra-objs) too. + (include sysd-Makefile): Protect with ifndef avoid-generated. + + * Makeconfig (+defines, +gnu-stabs, gnu-as): Variables removed. + (CPPFLAGS): Use $(defines) in place of $(+defines). + Replace -D_LIBC with -include $(..)libc-symbols.h. + + * stdio/freopen.c: Set seen bit before calling fclose. + +Mon Feb 6 18:34:40 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/setpriority.c: Keep track of numbers of + successes and each kind of failure. Return EPERM or EACCES only + if every task failed that way. + + * sysdeps/mach/hurd/getpriority.c: Handle out of band buffers + correctly. + + * sysdeps/mach/hurd/ptrace.c (PTRACE_ATTACH, PTRACE_DETACH): Stop + or resume the process after frobbing. + + * hurd/hurdsig.c: Use spin lock operations on sigstate locks + throughout. + (_hurd_thread_sigstate): Don't lock the sigstate lock. + (_hurd_internal_post_signal): New subfunction `mark_pending'; replace + repeated sequences with calls to it. Don't expect the sigstate + lock to be held on entry; lock it just before examining sigaction. + In handler case, check SS->critical_section after calling + abort_rpcs; if set, mark the signal pending and resume the thread. + * hurd/hurd/signal.h (_hurd_self_sigstate_unlocked): Function removed. + (_hurd_self_sigstate): Don't lock the sigstate lock. + (HURD_EINTR_RPC): Call _hurd_self_sigstate instead of + _hurd_self_sigstate_unlocked. + * hurd/msgportdemux.c: Don't expect _hurd_self_sigstate to lock + the sigstate lock. + * hurd/hurdexec.c: Use spin lock operations on sigstate lock. + Don't expect _hurd_self_sigstate to lock it. Fix critical section + locking. + * hurd/hurd-raise.c: Likewise. + * sysdeps/mach/hurd/sigsuspend.c: Likewise. + * sysdeps/mach/hurd/sigpending.c: Likewise. + * sysdeps/mach/hurd/sigaltstack.c: Likewise. + * sysdeps/mach/hurd/sigaction.c: Likewise. + * sysdeps/mach/hurd/sigprocmask.c: Likewise. + * hurd/fd-write.c: Likewise. + * hurd/fd-read.c: Likewise. + * sysdeps/mach/hurd/ioctl.c: Likewise. + * sysdeps/mach/hurd/fork.c: Likewise. + * sysdeps/mach/hurd/i386/sigreturn.c: Likewise. + * sysdeps/mach/hurd/mips/sigreturn.c: Likewise. + * sysdeps/mach/hurd/alpha/sigreturn.c: Likewise. + * hurd/hurdmsg.c (get_int): Likewise. + + * stdio/vfprintf.c: Include stddef.h. Fix typos in libio code. + + * stdio/vfprintf.c (__pad): Function renamed to __printf_pad, made + global. + (PAD): Caller changed. + * stdio/printf_fp.c (__pad): Function removed. + (PAD): Use __printf_pad instead. + +Sun Feb 5 17:59:53 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + Merged new FP printer by Ulrich Drepper. + * stdio/printf_fp.c: Rewrite by drepper. + * stdio/Makefile (routines): Add ldbl2mpn. + * sysdeps/ieee754/ieee754.h (union ieee754_double): Add `ieee_nan' + member. + (union ieee854_long_double): New type, from drepper. + (IEEE754_DOUBLE_BIAS, IEEE854_LONG_DOUBLE_BIAS): New macros. + * sysdeps/ieee754/ldbl2mpn.c: New file, by drepper. + * sysdeps/stub/ldbl2mpn.c: New file. + * math/Makefile (routines): Add isinfl and isnanl. + * sysdeps/ieee754/isinfl.c: New file. + * sysdeps/stub/isinfl.c: New file. + * sysdeps/ieee754/isnanl.c: New file. + * sysdeps/stub/isnanl.c: New file. + + * malloc/malloc.c (__malloc_extra_blocks): New variable. + (malloc): When getting more core, get __malloc_extra_blocks extra; + put the new block at the end of the free list and let the next loop + iteration use the initial portion of it. + * malloc/free.c (_free_internal): Account for twice + __malloc_extra_blocks in deciding if we have so much extra memory + we should return it to the system. + * malloc/malloc.h (__malloc_extra_blocks): Declare it. + * posix/glob.c (prefix_array, glob_pattern_p): Remove gratuitous + const in parameter decl. + + * sysdeps/unix/mips/sysdep.h (ENTRY): Add `.ent' directive. + +Fri Feb 3 18:15:52 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * munch.awk (EXTERNS): Print decls using __P instead of EXFUN. + + * sysdeps/mips/setjmp_aux.c: Use ENV[0].__jmpbuf[0]. + * sysdeps/mips/bsd-_setjmp.S: Use `li' insn instead of `move'. + * sysdeps/mips/bsd-setjmp.S: Likewise. + * sysdeps/mips/__longjmp.c: Remove obsolete __NORETURN keyword. + * sysdeps/mach/hurd/mips/trampoline.c (_hurd_setup_sighandler): + Use `long int' for sigcode. Use explicit register numbers instead + of names. + (_hurdsig_rcv_interrupted_p): Use _hurdsig_catch_fault. + * sysdeps/mach/hurd/mips/exc2signal.c: Use `long int' for sigcode. + +Thu Feb 2 20:06:45 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdmalloc.c: Remove bogus bcopy decl. + + * mach/mig_strncpy.c: Add missing `const' in prototype. Rewritten + using __stpncpy. + + * io/ftw.c (ftw, ftw_dir): Treat ENOENT from stat like EACCES. + + * stdio/vfprintf.c: Set PREC to zero for %. without following + digit. + +Tue Jan 31 13:49:57 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * mach/mig_strncpy.c: Include mach.h instead of string.h. Use + vm_size_t instead of size_t for arg and return types. + + * mach/mach_init.c: Don't declare __mig_init; mach/mig_support.h + already does. + +Mon Jan 30 00:33:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * set-hooks.h (RUN_HOOK): Dereference PTR properly. + + * configure.in (friendly stddef.h check): Write override defn for + `stddef.h' Make variable. + (AC_LINK_FILES): Use `echo ...` to avoid " " appearing nonempty. + + * configure.in (host_os=sysv4*|solaris2*): Set elf=yes. + + * Rules ($(objpfx)dummy.o): Write an empty function, not just an + empty file. + + * sysdeps/sparc/Makefile (sysdep-realclean): New variable. + +Sat Jan 28 03:38:56 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makefile (distribute): Remove gnu-stabs.h; add libc-symbols.h. + + * sysdeps/mach/sysdep.h [ASSEMBLER]: Protect include of + mach/machine/syscall_sw.h with this. + +Fri Jan 27 18:33:20 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd/signal.h: Include <hurd/msg.h>, and <spin-lock.h> + instead of <lock-intern.h>. + (struct hurd_sigstate): Member `lock' changed to a `spin_lock_t'. + (_hurd_critical_section_lock): Use spin lock operators. + Don't hold the sigstate lock, unlock it after setting the flag. + (_hurd_critical_section_unlock): Take the sigstate lock + to clear the flag; while holding it, check pending signals. After + unlocking, sig_post ourselves if there were pending signals. + + * hurd/catch-exc.c (_S_catch_exception_raise): Don't take the + sigstate lock. If it is locked, clear SS->critical_section and + SS->context, and unlock it. + + * sysdeps/mach/sysdep.h (EXT, LEXT): New macros. + + * set-init.c (__libc_init) [HAVE_ELF]: Run _init and atexit (_fini). + * munch-tmpl.c: Likewise. + + * mach/Makefile (routines): Don't filter out syscall_% from + $(mach-syscalls). + +Fri Jan 27 17:53:49 1995 Jim Meyering (meyering@comco.com) + + * posix/fnmatch.c: Declare errno if it's not defined. + That's simpler than testing #if !defined(__GNU_LIBRARY__) + && !defined(STDC_HEADERS). + +Fri Jan 27 15:40:29 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * csu/Makefile: New file. + * csu/initfini.c: New file. + * Makefile (+other_dirs): Add csu. + (+init): Variable renamed to libc-init. All references changed. + (aux): Remove start. + (install-lib): Variable removed. + (crt0.o, Mcrt1.o crt1.o): Targets removed. + + * mach/Machrules (static deps of RPC_*.o): Add $(..)libc-symbols.h + and $(objpfx)config.h. + (static deps of RPC alias *.o): Removed. + + * sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h [ASSEMBLER]: + Protect macros with this. + * sysdeps/unix/bsd/osf1/alpha/sysdep.h: Likewise. + * sysdeps/unix/bsd/sequent/i386/sysdep.h: Likewise. + * sysdeps/unix/bsd/vax/sysdep.h: Likewise. + * sysdeps/unix/bsd/sun/m68k/sysdep.h: Likewise. + * sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h: Likewise. + * sysdeps/unix/mips/sysdep.h: Likewise. + +Thu Jan 26 00:02:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makerules (compile.[Sc]): Match gcc in $(CC) better. + (BUILD_CFLAGS): Instead of $(config-defines), use -include config.h. + + * hurd/intr-rpc.awk: Emit weak alias. + + * sysdeps/unix/bsd/sun/sunos4/wait4.c: Call getpgrp instead of + __getpgrp. + + * sysdeps/unix/bsd/hp/m68k/sysdep.h [ASSEMBLER]: Protect macros with + this. + * sysdeps/unix/i386/sysdep.h: Likewise. + * sysdeps/unix/sparc/sysdep.h: Likewise. + + * io/ftw.c: Avoid `ret' as variable name. + * posix/glob.c: Likewise. + + * ctype/ctype.h (_ISalpha): Define as its own bit. + * locale/C-ctype_ct.c (__ctype_b_C): Set _ISalpha bit in all letters. + + * stdlib/exit.c [HAVE_GNU_LD]: Protect #include "set-hooks.h" and + DEFINE_HOOK with this. + +Wed Jan 25 00:45:56 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdinit.c: Use DECLARE_HOOK instead of `extern DEFINE_HOOK'. + * mach/spin-solid.c (spin_lock_solid): Define as weak alias to __name. + * mach/shortcut.awk: Emit weak alias. + * mach/spin-lock.c: Add weak aliases for all spin-lock.h functions. + * mach/mach_init.c (mach_init, vm_page_size): Defin weak aliases for + __ names. + * mach/Makefile (lock): Remove spin-syms. + (routines): Remove __ names, vm_page_size, msgserver_t. + ($(mach-syscalls) rule): Generate files without __, add weak alias. + Remove symbol alias file rule. + ($(mach-shortcuts) rule): Likewise. + [!mach-shortcuts] (user-interfaces): Filter out mach/mach4 too. + * mach/Machrules (if-calls.c): Variable and rule removed. + (interface-headers): Don't add $($(if)-calls). + (transform-user-stub): Define to add weak alias. + * set-hooks.h: Use new libc-symbols.h set access macros. + * time/Makefile (routines): Remove __ names. + (aux): Variable removed. + * hurd/Makefile: Likewise. + * sysdeps/unix/start.c (environ): Define as weak alias for __environ. + (data_start): Define as weak alias for __data_start. + * sysdeps/mach/hurd/start.c: Likewise. + * sysdeps/unix/sparc/start.c: Likewise. + * sysdeps/unix/make_errlist.c: Emit weak aliases for sys_nerr and + sys_errlist. + * sysdeps/mach/hurd/errlist.awk: Likewise. + * sysdeps/unix/bsd/osf1/alpha/start.S (environ): Define as weak + alias for __environ. + * sysdeps/unix/bsd/ultrix4/mips/start.S: Likewise. + * sysdeps/stub/setdomain.c: Use new stub_warning macro. + * sysdeps/stub/getdomain.c: Likewise. + * sysdeps/stub/vhangup.c: Likewise. + * sysdeps/stub/swapon.c: Likewise. + * sysdeps/stub/sendmsg.c: Likewise. + * sysdeps/stub/recvmsg.c: Likewise. + * sysdeps/stub/acct.c: Likewise. + * sysdeps/stub/isinf.c: Likewise. Add weak alias isinf for __isinf. + * sysdeps/mach/hurd/_exit.c: Remove obsolete __NORETURN keyword. + * sysdeps/posix/libc_fatal.c: Likewise. + * sysdeps/i386/abort.c: Likewise. + * sysdeps/i386/__longjmp.c: Likewise. + * sysdeps/generic/make_siglist.c: Emit defn always for + _sys_siglist. Emit weak alias to sys_siglist. + * sysdeps/generic/atan.c: Remove obsolete __CONSTVALUE keyword. + * sysdeps/ieee754/log10.c: Likewise. + * time/difftime.c: Likewise. + * stdlib/random.c (srand): Define as weak alias for __srandom. + * stdlib/exit.c: Remove obsolete __NORETURN keyword. Use set-hooks + macros for __libc_atexit. + * stdlib/Makefile (routines): Remove __random, srand. + * stdio/gets.c: Use new link_warning macro instead of old + warn_references. + * stdio/Makefile (routines): Remove __ names. + (aux): Remove syms-stdio. + * socket/Makefile (routines): Added e on getpeernam and getsocknam. + * setjmp/longjmp.c: Remove obsolete __NORETURN keyword. + * setjmp/Makefile (routines): Remove _longjmp, siglongjmp. + * setjmp/setjmp.h: Replace __NORETURN keyword with __attribute__ uses. + * stdio/stdio.h: Likewise. + * misc/Makefile (routines): Remove __ names. + (aux): Remove data_start. + * sysdeps/mach/hurd/defs.c: Don't include gnu-stabs.h. + * sysdeps/mach/hurd/brk.c: Likewise. + * hurd/hurdid.c: Likewise. + * hurd/hurdpid.c: Likewise. + * hurd/openport.c: Likewise. + * hurd/hurdsock.c: Likewise. + * hurd/hurdsig.c: Likewise. + * hurd/hurdrlimit.c: Likewise. + * hurd/hurdmalloc.c: Likewise. + * hurd/dtable.c: Likewise. + * hurd/setauth.c: Likewise. + * misc/progname.c: Likewise. + * misc/init-misc.c: Likewise. + * sysdeps/generic/vfork.c: Likewise. + * sysdeps/unix/bsd/init-posix.c: Likewise. + * math/math.h: Replace __CONSTVALUE keyword with __attribute__ uses. + * time/time.h: Likewise. + * math/Makefile (routines): Remove __ names. + * io/Makefile: Likewise. + * termios/Makefile: Likewise. + * resource/Makefile: Likewise. + * signal/Makefile: Likewise. + * dirent/Makefile: Likewise. + * assert/assert.h: Replace __NORETURN keyword with __attribute__ + uses. Functions return void and macros deal with this. + * assert/assert-perr.c: Remove obsolete __NORETURN keyword. + Return void. Don't include gnu-stabs.h. + * assert/assert.c: Likewise. + * posix/Makefile (routines): Remove __ names, setpgrp. Add + getpgid. + (aux): Remove environ. + * stdlib/stdlib.h (abort, exit): Replace __NORETURN keyword with + __attribute__ use. + * posix/unistd.h (_exit): Likewise. + (__getpgrp, __setpgrp): Declarations removed. + (__getpgid, getpid): Declare these. + + * configure.in (host_os=gnuelf|linuxelf): Set elf=yes. Do AC_SUBST + for gnu_ld, gnu_as, elf, and weak. Call AC_LINK_FILEES on + $libc_link_{sources,dests}. + * sysdeps/unix/configure.in: Remove __ from file names. Don't + create files, just add to libc_link_{dests,sources}. + + * config.make.in (gnu-as, gnu-ld, elf, weak-symbols): New variables. + + * config.h.in: Add #undefs used by sysdeps configures. + + * sysdeps/unix/sysv/sysv4/Makefile (sysdep_routines): Removed + __setpgid, __getpgid. + * sysdeps/unix/sysv/sco3.2.4/setpgid.c: Included file was renamed + from setpgrp.c. + * sysdeps/unix/sysv/sco3.2.4/getpgid.c: Included file was renamed + from __getpgrp.c. + * sysdeps/unix/bsd/getpgrp.c: File removed. + * sysdeps/generic/getpgrp.c: Moved from sysdeps/stub/getpgrp.c. + Call __getpgid with zero. + * sysdeps/stub/setpgid.c: Renamed __setpgrp to __setpgid, added + weak aliases setpgid and setpgrp. + * sysdeps/unix/sysv/irix4/setpgid.S: Likewise. + * sysdeps/unix/common/setpgid.S: Likewise. + * sysdeps/mach/hurd/setpgid.c: Likewise. + * sysdeps/unix/sysv/sysv4/setpgid.c: Likewise. + Use subcall 5 to __pgrpsys. + * sysdeps/stub/getpgid.c: Renamed __getpgrp to __getpgid, added + weak alias getpgid. + * sysdeps/mach/hurd/getpgid.c: Likewise. + * sysdeps/unix/sysv/irix4/getpgid.S: Likewise. + * sysdeps/unix/common/getpgid.S: Likewise. + * sysdeps/unix/sysv/sysv4/getpgid.c: Likewise. + Use subcall 4 to __pgrpsys. + * sysdeps/stub/__getpgrp.c: Renamed to getpgid.c. + * sysdeps/unix/sysv/sysv4/__getpgrp.c: Renamed to getpgid.c. + * sysdeps/unix/sysv/sco3.2.4/__getpgrp.c: Renamed to getpgid.c. + * sysdeps/unix/sysv/irix4/__getpgrp.S: Renamed to getpgid.S. + * sysdeps/unix/common/__getpgrp.S: Renamed to getpgid.S. + * sysdeps/mach/hurd/__getpgrp.c: Renamed to getpgid.c. + * sysdeps/stub/setpgrp.c: Renamed to setpgid.c. + * sysdeps/unix/sysv/sysv4/setpgrp.c: Renamed to setpgid.c. + * sysdeps/unix/sysv/sco3.2.4/setpgrp.c: Renamed to setpgid.c. + * sysdeps/unix/sysv/irix4/setpgrp.S: Renamed to setpgid.S. + * sysdeps/unix/common/setpgrp.S: Renamed to setpgid.S. + * sysdeps/mach/hurd/setpgrp.c: Renamed to setpgid.c. + + * sysdeps/unix/bsd/hp/m68k/getdents.S: Included file was renamed + from __getdents.S. + + * sysdeps/posix/defs.c: Don't include gnu-stabs.h. + * sysdeps/stub/sigpending.c: Use new libc-symbols.h macro for stub + warning. + * sysdeps/stub/fexecve.c: Likewise. + * sysdeps/stub/fchdir.c: Likewise. + * sysdeps/stub/fchflags.c: Likewise. + * sysdeps/stub/chflags.c: Likewise. + + * sysdeps/m68k/__longjmp.c: Remove __NORETURN; it's obsolete. + * sysdeps/generic/abort.c: Likewise. + * sysdeps/ieee754/ldexp.c: Remove __CONSTVALUE; it's obsolete. + + * hurd/hurdioctl.c: Include hurd/ioctl.h. + (_hurd_ioctl_handler_lists): Define this set. + (_hurd_lookup_ioctl_handler): New function. + * hurd/hurd/fd.h: ioctl handler stuff moved to hurd/ioctl.h. + * hurd/hurd/ioctl.h: New file, broken out of hurd/fd.h. + (_hurd_lookup_ioctl_handler): Declare it. + (ioctl_handler_t): New typedef. Use it throughout. + * sysdeps/mach/hurd/ioctl.c: Include hurd/ioctl.h. + (_hurd_ioctl_handler_lists): Don't define. + (__ioctl): Call _hurd_lookup_ioctl_handler. + + * stdlib/strtol.c (maxquad): Make this const. + [__GNUC__ == 2 && __GNUC_MINOR__ < 7]: Only use maxquad in this case. + + * posix/glob/configure.in: Put AC_AIX and AC_MINIX early, before + any compile tests. + + * sysdeps/mach/hurd/setitimer.c (timer_thread): Call + __msg_sig_post_request, not __sig_post_request. + + * misc/getusersh.c: Renamed to getusershell.c. + * sysdeps/stub/sethostnam.c: Renamed to sethostname.c. + * sysdeps/unix/inet/sethostnam.S: Renamed to sethostname.S. + * sysdeps/unix/sysv/sysv4/sethostnam.c: Renamed to sethostname.c. + * sysdeps/mach/hurd/sethostnam.c: Renamed to sethostname.c. + +Tue Jan 24 00:14:30 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/stub/settod.c: Renamed to settimeofday.c. + * sysdeps/unix/bsd/settod.S: Renamed to settimeofday.c. + * sysdeps/unix/sysv/settod.c: Renamed to settimeofday.c. + * sysdeps/mach/hurd/settod.c: Renamed to settimeofday.c. + * sysdeps/stub/setitmr.c: Renamed to setitimer.c. + * sysdeps/unix/common/setitmr.S: Renamed to setitimer.S. + * sysdeps/mach/hurd/setitmr.c: Renamed to setitimer.c. + * sysdeps/posix/fpathcon.c: Renamed to fpathconf.c. + * sysdeps/stub/fpathcon.c: Renamed to fpathconf.c. + * sysdeps/unix/sysv/irix4/fpathcon.c: Renamed to fpathconf.c. + * sysdeps/stub/getprio.c: Renamed to getpriority.c. + * sysdeps/unix/sysv/irix4/getprio.c: Renamed to getpriority.c. + * sysdeps/unix/common/getprio.S: Renamed to getpriority.S. + * sysdeps/mach/hurd/getprio.c: Renamed to getpriority.c. + * sysdeps/stub/setprio.c: Renamed to setpriority.c. + * sysdeps/unix/sysv/irix4/setprio.c: Renamed to setpriority.c. + * sysdeps/unix/common/setprio.S: Renamed to setpriority.S. + * sysdeps/mach/hurd/setprio.c: Renamed to setpriority.c. + * sysdeps/stub/getpeernam.c: Renamed to getpeername.c. + * sysdeps/unix/inet/getpeernam.S: Renamed to getpeername.S. + * sysdeps/unix/sysv/linux/getpeernam.S: Renamed to getpeername.S. + * sysdeps/mach/hurd/getpeernam.c: Renamed to getpeername.c. + * sysdeps/stub/getsocknam.c: Renamed to getsockname.c. + * sysdeps/unix/inet/getsocknam.S: Renamed to getsockname.S. + * sysdeps/unix/sysv/linux/getsocknam.S: Renamed to getsockname.S. + * sysdeps/mach/hurd/getsocknam.c: Renamed to getsockname.c. + * sysdeps/stub/sigaltstk.c: Renamed to sigaltstack.c. + * sysdeps/unix/bsd/bsd4.4/sigaltstk.S: Renamed to sigaltstack.S. + * sysdeps/unix/sysv/sysv4/sigaltstk.S: Renamed to sigaltstack.S. + * sysdeps/mach/hurd/sigaltstk.c: Renamed to sigaltstack.c. + + * sysdeps/mach/hurd/i386/sigreturn.c: Call __msg_sig_post instead + of __sig_post. + * sysdeps/mach/hurd/sigsuspend.c: Likewise. + * sysdeps/mach/hurd/kill.c: Likewise. + * sysdeps/mach/hurd/sigprocmask.c: Likewise. + + * misc/sys/cdefs.h (__NORETURN, __CONSTVALUE): Macros removed. + [!__GNUC__ || __GNUC__<2] (__attribute__): Define to empty. + + * sysdeps/stub/remove.c: New file. + * sysdeps/posix/remove.c: New file. + +Mon Jan 23 03:26:09 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * time/mktime.c [weak_alias] (timelocal): Define as weak alias for + mktime. + * mach/mig_strncpy.c (mig_strncpy): Define as weak alias for + __mig_strncpy. + * mach/msg-destroy.c: Renamed from __msg_dest.c. + (mach_msg_destroy): Define as weak alias for __mach_msg_destroy. + * mach/setup-thread.c (mach_setup_thread): Define as weak alias. + * time/tzset.c (tzname, daylight, timezone): Define as weak + aliases for __ names. + * hurd/hurdkill.c (hurd_sig_post): Define as weak alias. + * hurd/hurdlookup.c: Add weak aliases for non-__ names. + * Makefile (+init): Test $(gnu-ld)=yes, not for $(+gnu-stabs) + being defined. + +Sun Jan 22 15:19:51 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * string/Makefile (routines): Remove __ names, index, rindex, and + bcmp. + * sysdeps/alpha/strchr.c [weak_alias] (index): Define as weak + alias for strchr. + * sysdeps/generic/strchr.c: Likewise. + * sysdeps/generic/strrchr.c [weak_alias] (rindex): Define as weak + alias for strrchr. + * sysdeps/generic/memcmp.c [weak_alias] (bcmp): Define as weak + alias for memcmp. + + * malloc/free.c (cfree): Define this function, with weak_alias if + available, otherwise a C function. + * malloc/Makefile (gmalloc-routines): Remove cfree. + +Sat Jan 21 08:08:58 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/fseek.c: Do move bufp by O when that puts it exactly at + get_limit. This has the effect of no-op'ing properly for zero. + + * configure.in: Add AC_CONFIG_HEADER(config.h). + (--with-elf, --with-weak-symbols): Grok these and define HAVE_*. + * config.h.in: New file. + + * setjmp/longjmp.c: Add weak aliases _longjmp, siglongjmp. + All code converted to use weak symbols, defined in the files which + define the real code (with the __ names, the non-__ names are weak). + All old symbol alias files removed. + Many files renamed to remove __ prefix since there is now just + the one file for both the __ and non-__ name for each function. + * libc-symbols.h: New file. + * set-hooks.h: Use libc-symbols.h macros for accessing symbol + sets. + * gnu-stabs.h: Prepend #error this file is obsolete. + * sysdeps/ieee754/ldexp.c: Add weak aliases scalb and __scalb. + * sysdeps/stub/__access.c: Renamed to access.c; added weak alias + access. + * sysdeps/unix/common/__access.S: Likewise. + * sysdeps/mach/hurd/__access.c: Likewise. + * sysdeps/stub/__adjtime.c: Renamed to adjtime.c; added weak alias + adjtime. + * sysdeps/unix/common/__adjtime.S: Likewise. + * sysdeps/mach/__adjtime.c: Likewise. + * sysdeps/mach/hurd/__adjtime.c: Likewise. + * sysdeps/stub/__brk.c: Renamed to brk.c; added weak alias brk. + * sysdeps/unix/bsd/sun/m68k/__brk.S: Likewise. + * sysdeps/unix/bsd/vax/__brk.S: Likewise. + * sysdeps/unix/bsd/hp/m68k/__brk.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__brk.S: Likewise. + * sysdeps/unix/i386/__brk.S: Likewise. + * sysdeps/unix/sparc/__brk.S: Likewise. + * sysdeps/unix/mips/__brk.S: Likewise. + * sysdeps/mach/hurd/__brk.c: Likewise. + * sysdeps/standalone/__brk.c: Likewise. + * sysdeps/stub/__chdir.c: Renamed to chdir.c; added weak alias chdir. + * sysdeps/unix/__chdir.S: Likewise. + * sysdeps/mach/hurd/__chdir.c: Likewise. + * sysdeps/stub/__chmod.c: Renamed to chmod.c; added weak alias chmod. + * sysdeps/unix/__chmod.S: Likewise. + * sysdeps/mach/hurd/__chmod.c: Likewise. + * sysdeps/stub/__chown.c: Renamed to chown.c; added weak alias chown. + * sysdeps/unix/__chown.S: Likewise. + * sysdeps/mach/hurd/__chown.c: Likewise. + * sysdeps/stub/__close.c: Renamed to close.c; added weak alias close. + * sysdeps/unix/__close.S: Likewise. + * sysdeps/mach/hurd/__close.c: Likewise. + * sysdeps/standalone/__close.c: Likewise. + * sysdeps/generic/__copysign.c: Renamed to copysign.c; added weak + alias copysign. + * sysdeps/ieee754/__copysign.c: Likewise. + * sysdeps/alpha/__copysign.c: Likewise. + * sysdeps/ieee754/__drem.c: Renamed to drem.c; added weak alias drem. + * sysdeps/m68k/fpu/__drem.c: Likewise. + * sysdeps/stub/__drem.c: Likewise. + * sysdeps/posix/__dup.c: Renamed to dup.c; added weak alias dup. + * sysdeps/stub/__dup.c: Likewise. + * sysdeps/unix/__dup.S: Likewise. + * sysdeps/posix/__dup2.c: Renamed to dup2.c; added weak alias dup2. + * sysdeps/stub/__dup2.c: Likewise. + * sysdeps/unix/sysv/sysv4/__dup2.c: Likewise. + * sysdeps/unix/sysv/irix4/__dup2.c: Likewise. + * sysdeps/unix/common/__dup2.S: Likewise. + * sysdeps/mach/hurd/__dup2.c: Likewise. + * sysdeps/stub/__execve.c: Renamed to execve.c; added weak alias + execve. + * sysdeps/unix/__execve.S: Likewise. + * sysdeps/mach/hurd/__execve.c: Likewise. + * sysdeps/generic/__expm1.c: Renamed to expm1.c; added weak alias + expm1. + * sysdeps/m68k/fpu/__expm1.c: Likewise. + * sysdeps/stub/__fchmod.c: Renamed to fchmod.c; added weak alias + fchmod. + * sysdeps/unix/common/__fchmod.S: Likewise. + * sysdeps/mach/hurd/__fchmod.c: Likewise. + * sysdeps/stub/__fchown.c: Renamed to fchown.c; added weak alias + fchown. + * sysdeps/unix/common/__fchown.S: Likewise. + * sysdeps/mach/hurd/__fchown.c: Likewise. + * sysdeps/stub/__fcntl.c: Renamed to fcntl.c; added weak alias fcntl. + * sysdeps/unix/__fcntl.S: Likewise. + * sysdeps/mach/hurd/__fcntl.c: Likewise. + * math/__finite.c: Renamed to finite.c; added weak alias finite. + * sysdeps/posix/__flock.c: Renamed to flock.c; added weak alias flock. + * sysdeps/stub/__flock.c: Likewise. + * sysdeps/unix/bsd/__flock.S: Likewise. + * sysdeps/mach/hurd/__flock.c: Likewise. + * hurd/__fopenport.c: Renamed to fopenport.c; added weak alias + fopenport. + * sysdeps/stub/__fork.c: Renamed to fork.c; added weak alias fork. + * sysdeps/unix/__fork.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__fork.S: Likewise. + * sysdeps/unix/i386/__fork.S: Likewise. + * sysdeps/unix/sparc/__fork.S: Likewise. + * sysdeps/unix/mips/__fork.S: Likewise. + * sysdeps/mach/hurd/__fork.c: Likewise. + * sysdeps/posix/__fpathcon.c: Renamed to fpathcon.c; added weak + alias fpathconf. + * sysdeps/stub/__fpathcon.c: Likewise. + * sysdeps/unix/sysv/irix4/__fpathcon.c: Likewise. + * sysdeps/stub/__fstat.c: Renamed to fstat.c; added weak alias fstat. + * sysdeps/unix/__fstat.S: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__fstat.S: Likewise. + * sysdeps/mach/hurd/__fstat.c: Likewise. + * stdio/__getdelim.c: Renamed to getdelim.c; added weak alias + getdelim. + * sysdeps/stub/__getdents.c: Renamed to getdents.c; added weak + alias getdents. + * sysdeps/unix/__getdents.c: Likewise. + * sysdeps/unix/bsd/sun/__getdents.S: Likewise. + * sysdeps/unix/bsd/hp/m68k/__getdents.S: Likewise. + * sysdeps/unix/bsd/ultrix4/__getdents.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__getdents.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__getdents.S: Likewise. + * sysdeps/unix/sysv/__getdents.c: Likewise. + * sysdeps/mach/hurd/__getdents.c: Likewise. + * hurd/__getdport.c: Renamed to getdport.c; added weak alias getdport. + * sysdeps/posix/__getdtsz.c: Renamed to getdtsz.c; added weak + alias getdtablesize. + * sysdeps/stub/__getdtsz.c: Likewise. + * sysdeps/unix/bsd/__getdtsz.S: Likewise. + * sysdeps/unix/sysv/sysv4/__getdtsz.c: Likewise. + * sysdeps/mach/hurd/__getdtsz.c: Likewise. + * sysdeps/stub/__getegid.c: Renamed to getegid.c; added weak alias + getegid. + * sysdeps/unix/__getegid.S: Likewise. + * sysdeps/mach/hurd/__getegid.c: Likewise. + * sysdeps/stub/__geteuid.c: Renamed to geteuid.c; added weak alias + geteuid. + * sysdeps/unix/__geteuid.S: Likewise. + * sysdeps/mach/hurd/__geteuid.c: Likewise. + * sysdeps/stub/__getgid.c: Renamed to getgid.c; added weak alias + getgid. + * sysdeps/unix/__getgid.S: Likewise. + * sysdeps/mach/hurd/__getgid.c: Likewise. + * sysdeps/stub/__getgrps.c: Renamed to getgroups.c; added weak + alias getgroups. + * sysdeps/unix/bsd/sequent/i386/__getgrps.S: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__getgrps.c: Likewise. + * sysdeps/unix/sysv/irix4/__getgrps.c: Likewise. + * sysdeps/unix/common/__getgrps.S: Likewise. + * sysdeps/mach/hurd/__getgrps.c: Likewise. + * sysdeps/stub/__gethstnm.c: Renamed to gethostname.c; added weak + alias gethostname. + * sysdeps/unix/inet/__gethstnm.S: Likewise. + * sysdeps/unix/sysv/__gethstnm.c: Likewise. + * sysdeps/unix/sysv/sysv4/__gethstnm.c: Likewise. + * sysdeps/mach/hurd/__gethstnm.c: Likewise. + * sysdeps/stub/__getitmr.c: Renamed to getitimer.c; added weak + alias getitimer. + * sysdeps/unix/common/__getitmr.S: Likewise. + * sysdeps/mach/hurd/__getitmr.c: Likewise. + * stdio/__getline.c: Renamed to getline.c; added weak alias getline. + * sysdeps/posix/__getpgsz.c: Renamed to getpagesize.c; added weak + alias getpagesize. + * sysdeps/stub/__getpgsz.c: Likewise. + * sysdeps/unix/__getpgsz.c: Likewise. + * sysdeps/unix/bsd/__getpgsz.S: Likewise. + * sysdeps/unix/sysv/sysv4/__getpgsz.c: Likewise. + * sysdeps/mach/__getpgsz.c: Likewise. + * sysdeps/stub/__getpid.c: Renamed to getpid.c; added weak alias + getpid. + * sysdeps/unix/__getpid.S: Likewise. + * sysdeps/mach/hurd/__getpid.c: Likewise. + * sysdeps/stub/__getppid.c: Renamed to getppid.c; added weak alias + getppid. + * sysdeps/unix/__getppid.S: Likewise. + * sysdeps/mach/hurd/__getppid.c: Likewise. + * sysdeps/posix/__gettod.c: Renamed to gettimeofday.c; added weak + alias gettimeofday. + * sysdeps/stub/__gettod.c: Likewise. + * sysdeps/unix/sysv/irix4/__gettod.c: Likewise. + * sysdeps/unix/common/__gettod.S: Likewise. + * sysdeps/mach/__gettod.c: Likewise. + * sysdeps/stub/__getuid.c: Renamed to getuid.c; added weak alias + getuid. + * sysdeps/unix/__getuid.S: Likewise. + * sysdeps/mach/hurd/__getuid.c: Likewise. + * sysdeps/generic/__infnan.c: Renamed to infnan.c; added weak + alias infnan. + * sysdeps/ieee754/__infnan.c: Likewise. + * sysdeps/vax/__infnan.c: Likewise. + * sysdeps/stub/__ioctl.c: Renamed to ioctl.c; added weak alias ioctl. + * sysdeps/unix/__ioctl.S: Likewise. + * sysdeps/mach/hurd/__ioctl.c: Likewise. + * sysdeps/posix/__isatty.c: Renamed to isatty.c; added weak alias + isatty. + * sysdeps/stub/__isatty.c: Likewise. + * sysdeps/unix/bsd/__isatty.c: Likewise. + * sysdeps/mach/hurd/__isatty.c: Likewise. + * sysdeps/ieee754/__isinf.c: Renamed to isinf.c; added weak alias + isinf. + * sysdeps/m68k/fpu/__isinf.c: Likewise. + * sysdeps/stub/__isinf.c: Likewise. + * sysdeps/generic/__isnan.c: Renamed to isnan.c; added weak alias + isnan. + * sysdeps/ieee754/__isnan.c: Likewise. + * sysdeps/m68k/fpu/__isnan.c: Likewise. + * sysdeps/stub/__kill.c: Renamed to kill.c; added weak alias kill. + * sysdeps/unix/__kill.S: Likewise. + * sysdeps/mach/hurd/__kill.c: Likewise. + * sysdeps/stub/__link.c: Renamed to link.c; added weak alias link. + * sysdeps/unix/__link.S: Likewise. + * sysdeps/mach/hurd/__link.c: Likewise. + * sysdeps/ieee754/__logb.c: Renamed to logb.c; added weak alias logb. + * sysdeps/m68k/fpu/__logb.c: Likewise. + * sysdeps/stub/__logb.c: Likewise. + * sysdeps/stub/__lseek.c: Renamed to lseek.c; added weak alias lseek. + * sysdeps/unix/__lseek.S: Likewise. + * sysdeps/mach/hurd/__lseek.c: Likewise. + * sysdeps/generic/__lstat.c: Renamed to lstat.c; added weak alias + lstat. + * sysdeps/stub/__lstat.c: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__lstat.S: Likewise. + * sysdeps/unix/common/__lstat.S: Likewise. + * sysdeps/mach/hurd/__lstat.c: Likewise. + * sysdeps/generic/__memccpy.c: Renamed to memccpy.c; added weak + alias memccpy. + * sysdeps/vax/__memccpy.c: Likewise. + * sysdeps/stub/__mkdir.c: Renamed to mkdir.c; added weak alias mkdir. + * sysdeps/unix/sysv/__mkdir.c: Likewise. + * sysdeps/unix/common/__mkdir.S: Likewise. + * sysdeps/mach/hurd/__mkdir.c: Likewise. + * sysdeps/stub/__mknod.c: Renamed to mknod.c; added weak alias mknod. + * sysdeps/unix/__mknod.S: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__mknod.S: Likewise. + * sysdeps/mach/hurd/__mknod.c: Likewise. + * mach/__msg.c: Renamed to msg.c; added weak alias mach_msg. + * mach/__msgserver.c: Renamed to msgserver.c; added weak alias + mach_msg_server. + * sysdeps/stub/__open.c: Renamed to open.c; added weak alias open. + * sysdeps/unix/__open.S: Likewise. + * sysdeps/mach/hurd/__open.c: Likewise. + * sysdeps/standalone/__open.c: Likewise. + * sysdeps/stub/__pathconf.c: Renamed to pathconf.c; added weak + alias pathconf. + * sysdeps/unix/sysv/sco3.2.4/__pathconf.S: Likewise. + * sysdeps/unix/sysv/irix4/__pathconf.c: Likewise. + * hurd/__pid2task.c: Renamed to pid2task.c; added weak alias pid2task. + * sysdeps/stub/__pipe.c: Renamed to pipe.c; added weak alias pipe. + * sysdeps/unix/bsd/vax/__pipe.S: Likewise. + * sysdeps/unix/bsd/m68k/__pipe.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__pipe.S: Likewise. + * sysdeps/unix/i386/__pipe.S: Likewise. + * sysdeps/unix/sparc/__pipe.S: Likewise. + * sysdeps/unix/mips/__pipe.S: Likewise. + * sysdeps/mach/hurd/__pipe.c: Likewise. + * stdlib/__random.c: Renamed to random.c; added weak alias random. + * sysdeps/stub/__read.c: Renamed to read.c; added weak alias read. + * sysdeps/unix/__read.S: Likewise. + * sysdeps/mach/hurd/__read.c: Likewise. + * sysdeps/standalone/__read.c: Likewise. + * sysdeps/stub/__readlink.c: Renamed to readlink.c; added weak + alias readlink. + * sysdeps/unix/common/__readlink.S: Likewise. + * sysdeps/mach/hurd/__readlink.c: Likewise. + * sysdeps/generic/__rint.c: Renamed to rint.c; added weak alias rint. + * sysdeps/m68k/fpu/__rint.c: Likewise. + * sysdeps/stub/__rmdir.c: Renamed to rmdir.c; added weak alias rmdir. + * sysdeps/unix/sysv/__rmdir.c: Likewise. + * sysdeps/unix/common/__rmdir.S: Likewise. + * sysdeps/mach/hurd/__rmdir.c: Likewise. + * sysdeps/generic/__sbrk.c: Renamed to sbrk.c; added weak alias sbrk. + * sysdeps/stub/__sbrk.c: Likewise. + * sysdeps/mach/hurd/__sbrk.c: Likewise. + * math/__scalb.c: Renamed to scalb.c; added weak alias scalb. + * sysdeps/stub/__select.c: Renamed to select.c; added weak alias + select. + * sysdeps/unix/common/__select.S: Likewise. + * sysdeps/mach/hurd/__select.c: Likewise. + * hurd/__setauth.c: Renamed to setauth.c; added weak alias setauth. + * sysdeps/stub/__setgid.c: Renamed to setgid.c; added weak alias + setgid. + * sysdeps/unix/__setgid.S: Likewise. + * sysdeps/unix/bsd/__setgid.c: Likewise. + * sysdeps/mach/hurd/__setgid.c: Likewise. + * sysdeps/stub/__setitmr.c: Renamed to setitmr.c; added weak alias + setitmr + * sysdeps/unix/common/__setitmr.S: Likewise. + * sysdeps/mach/hurd/__setitmr.c: Likewise. + * sysdeps/stub/__setpgrp.c: Renamed to setpgrp.c; added weak alias + setpgrp + * sysdeps/unix/sysv/sysv4/__setpgrp.c: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__setpgrp.c: Likewise. + * sysdeps/unix/sysv/irix4/__setpgrp.S: Likewise. + * sysdeps/unix/common/__setpgrp.S: Likewise. + * sysdeps/mach/hurd/__setpgrp.c: Likewise. + * sysdeps/stub/__setregid.c: Renamed to setregid.c; added weak + alias setregid. + * sysdeps/unix/common/__setregid.S: Likewise. + * sysdeps/mach/hurd/__setregid.c: Likewise. + * sysdeps/stub/__setreuid.c: Renamed to setreuid.c; added weak + alias setreuid. + * sysdeps/unix/common/__setreuid.S: Likewise. + * sysdeps/mach/hurd/__setreuid.c: Likewise. + * sysdeps/stub/__setsid.c: Renamed to setsid.c; added weak alias + setsid. + * sysdeps/unix/bsd/__setsid.c: Likewise. + * sysdeps/unix/bsd/sun/sunos4/__setsid.S: Likewise. + * sysdeps/unix/bsd/ultrix4/__setsid.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__setsid.S: Likewise. + * sysdeps/unix/sysv/linux/__setsid.S: Likewise. + * sysdeps/unix/sysv/sysv4/__setsid.c: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__setsid.c: Likewise. + * sysdeps/mach/hurd/__setsid.c: Likewise. + * sysdeps/stub/__settod.c: Renamed to settod.c; added weak alias + settimeofday. + * sysdeps/unix/bsd/__settod.S: Likewise. + * sysdeps/unix/sysv/__settod.c: Likewise. + * sysdeps/mach/hurd/__settod.c: Likewise. + * sysdeps/stub/__setuid.c: Renamed to setuid.c; added weak alias + setuid. + * sysdeps/unix/__setuid.S: Likewise. + * sysdeps/unix/bsd/__setuid.c: Likewise. + * sysdeps/mach/hurd/__setuid.c: Likewise. + * sysdeps/posix/__sigblock.c: Renamed to sigblock.c; added weak + alias sigblock. + * sysdeps/stub/__sigblock.c: Likewise. + * sysdeps/unix/bsd/__sigblock.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__sigblock.c: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigblock.S: Likewise. + * sysdeps/posix/__sigpause.c: Renamed to sigpause.c; added weak + alias sigpause. + * sysdeps/stub/__sigpause.c: Likewise. + * sysdeps/unix/bsd/__sigpause.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigpause.S: Likewise. + * sysdeps/stub/__sigproc.c: Renamed to sigprocmask.c; added weak + alias sigprocmask. + * sysdeps/unix/bsd/__sigproc.c: Likewise. + * sysdeps/unix/sysv/sysv4/__sigproc.S: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__sigproc.S: Likewise. + * sysdeps/mach/hurd/__sigproc.c: Likewise. + * sysdeps/stub/__sigret.c: Renamed to sigreturn.c; added weak + alias sigreturn. + * sysdeps/unix/bsd/sun/__sigret.S: Likewise. + * sysdeps/unix/sysv/i386/__sigret.S: Likewise. + * sysdeps/unix/sysv/irix4/__sigret.S: Likewise. + * sysdeps/unix/i386/__sigret.S: Likewise. + * sysdeps/unix/mips/__sigret.S: Likewise. + * sysdeps/mach/hurd/i386/__sigret.c: Likewise. + * sysdeps/mach/hurd/alpha/__sigret.c: Likewise. + * sysdeps/mach/hurd/mips/__sigret.c: Likewise. + * sysdeps/posix/__sigvec.c: Renamed to sigvec.c; added weak alias + sigvec. + * sysdeps/stub/__sigvec.c: Likewise. + * sysdeps/unix/bsd/__sigvec.S: Likewise. + * sysdeps/unix/bsd/sun/__sigvec.S: Likewise. + * sysdeps/unix/bsd/sequent/i386/__sigvec.S: Likewise. + * sysdeps/unix/bsd/ultrix4/mips/__sigvec.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__sigvec.c: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigvec.S: Likewise. + * sysdeps/stub/__stat.c: Renamed to stat.c; added weak alias stat. + * sysdeps/unix/__stat.S: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__stat.S: Likewise. + * sysdeps/mach/hurd/__stat.c: Likewise. + * sysdeps/generic/__stpncpy.c: Renamed to stpncpy.c; added weak + alias stpncpy. + * sysdeps/stub/__symlink.c: Renamed to symlink.c; added weak alias + symlink. + * sysdeps/unix/common/__symlink.S: Likewise. + * sysdeps/mach/hurd/__symlink.c: Likewise. + * sysdeps/posix/__sysconf.c: Renamed to sysconf.c; added weak + alias sysconf. + * sysdeps/stub/__sysconf.c: Likewise. + * sysdeps/unix/bsd/ultrix4/__sysconf.c: Likewise. + * sysdeps/unix/sysv/sysv4/__sysconf.c: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__sysconf.S: Likewise. + * sysdeps/unix/sysv/irix4/__sysconf.c: Likewise. + * hurd/__task2pid.c: Renamed to task2pid.c; added weak alias task2pid. + * sysdeps/stub/__times.c: Renamed to times.c; added weak alias times. + * sysdeps/unix/bsd/__times.c: Likewise. + * sysdeps/unix/sysv/__times.S: Likewise. + * time/__tzset.c: Renamed to tzset.c; added weak alias tzset. + * sysdeps/stub/__umask.c: Renamed to umask.c; added weak alias umask. + * sysdeps/unix/__umask.S: Likewise. + * sysdeps/mach/hurd/__umask.c: Likewise. + * sysdeps/stub/__unlink.c: Renamed to unlink.c; added weak alias + unlink. + * sysdeps/unix/__unlink.S: Likewise. + * sysdeps/mach/hurd/__unlink.c: Likewise. + * sysdeps/stub/__utimes.c: Renamed to utimes.c; added weak alias + utimes. + * sysdeps/unix/bsd/__utimes.S: Likewise. + * sysdeps/unix/sysv/sysv4/solaris2/__utimes.S: Likewise. + * sysdeps/mach/hurd/__utimes.c: Likewise. + * sysdeps/generic/__vfork.c: Renamed to vfork.c; added weak alias + vfork. + * sysdeps/unix/bsd/sun/m68k/__vfork.S: Likewise. + * sysdeps/unix/bsd/vax/__vfork.S: Likewise. + * sysdeps/unix/bsd/i386/__vfork.S: Likewise. + * sysdeps/unix/bsd/hp/m68k/__vfork.S: Likewise. + * sysdeps/unix/bsd/ultrix4/mips/__vfork.S: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__vfork.S: Likewise. + * sysdeps/unix/sparc/__vfork.S: Likewise. + * stdio/__vfscanf.c: Renamed to vfscanf.c; added weak alias vfscanf. + * stdio/__vsscanf.c: Renamed to vsscanf.c; added weak alias vsscanf. + * sysdeps/posix/__wait.c: Renamed to wait.c; added weak alias wait. + * sysdeps/stub/__wait.c: Likewise. + * sysdeps/unix/bsd/sony/newsos4/__wait.c: Likewise. + * sysdeps/unix/bsd/sun/sunos4/__wait.c: Likewise. + * sysdeps/unix/bsd/sun/sunos3/m68k/__wait.S: Likewise. + * sysdeps/unix/bsd/vax/__wait.S: Likewise. + * sysdeps/unix/bsd/m68k/__wait.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__wait.c: Likewise. + * sysdeps/unix/sysv/i386/linux/__wait.S: Likewise. + * sysdeps/unix/sysv/irix4/__wait.S: Likewise. + * sysdeps/unix/i386/__wait.S: Likewise. + * sysdeps/unix/mips/__wait.S: Likewise. + * sysdeps/posix/__wait3.c: Renamed to wait3.c; added weak alias wait3. + * sysdeps/stub/__wait3.c: Likewise. + * sysdeps/unix/bsd/sony/newsos4/__wait3.c: Likewise. + * sysdeps/unix/bsd/sun/sunos4/__wait3.c: Likewise. + * sysdeps/unix/bsd/vax/__wait3.S: Likewise. + * sysdeps/unix/bsd/i386/__wait3.S: Likewise. + * sysdeps/unix/bsd/hp/m68k/__wait3.S: Likewise. + * sysdeps/unix/bsd/ultrix4/__wait3.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__wait3.c: Likewise. + * sysdeps/unix/sysv/irix4/__wait3.S: Likewise. + * sysdeps/stub/__wait4.c: Renamed to wait4.c; added weak alias wait4. + * sysdeps/unix/bsd/sony/newsos4/__wait4.c: Likewise. + * sysdeps/unix/bsd/sun/sunos4/__wait4.c: Likewise. + * sysdeps/unix/bsd/bsd4.4/__wait4.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__wait4.S: Likewise. + * sysdeps/unix/sysv/linux/__wait4.S: Likewise. + * sysdeps/mach/hurd/__wait4.c: Likewise. + * sysdeps/stub/__waitpid.c: Renamed to waitpid.c; added weak alias + waitpid. + * sysdeps/unix/bsd/sun/sunos4/__waitpid.c: Likewise. + * sysdeps/unix/bsd/ultrix4/__waitpid.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__waitpid.c: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__waitpid.c: Likewise. + * sysdeps/unix/sysv/linux/__waitpid.S: Likewise. + * sysdeps/unix/sysv/sysv4/__waitpid.c: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__waitpid.S: Likewise. + * sysdeps/unix/sysv/irix4/__waitpid.c: Likewise. + * sysdeps/stub/__write.c: Renamed to write.c; added weak alias write. + * sysdeps/unix/__write.S: Likewise. + * sysdeps/mach/hurd/__write.c: Likewise. + * sysdeps/standalone/__write.c: Likewise. + * sysdeps/stub/__tcgetatr.c: Renamed to tcgetattr.c; added weak + alias tcgetattr. + * sysdeps/unix/bsd/__tcgetatr.c: Likewise. + * sysdeps/unix/bsd/sun/sunos4/__tcgetatr.c: Likewise. + * sysdeps/unix/bsd/bsd4.4/__tcgetatr.c: Likewise. + * sysdeps/unix/sysv/__tcgetatr.c: Likewise. + * sysdeps/stub/__sigact.c: Renamed to sigaction.c; added weak + alias sigaction. + * sysdeps/unix/bsd/__sigact.c: Likewise. + * sysdeps/unix/sysv/__sigact.c: Likewise. + * sysdeps/unix/sysv/sysv4/__sigact.c: Likewise. + * sysdeps/unix/sysv/sco3.2.4/__sigact.S: Likewise. + * sysdeps/mach/hurd/__sigact.c: Likewise. + * sysdeps/posix/__sigstmsk.c: Renamed to sigsetmask.c; added weak + alias sigsetmask. + * sysdeps/stub/__sigstmsk.c: Likewise. + * sysdeps/unix/bsd/__sigstmsk.S: Likewise. + * sysdeps/unix/bsd/bsd4.4/__sigstmsk.c: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigstmsk.S: Likewise. + * sysdeps/stub/__getrusag.c: Renamed to getrusage.c; added weak + alias getrusage. + * sysdeps/unix/sysv/irix4/__getrusag.c: Likewise. + * sysdeps/unix/common/__getrusag.S: Likewise. + * hurd/task2pid.c: File removed. + * hurd/setauth.c: File removed. + * hurd/pid2task.c: File removed. + * hurd/hurdsyms.c: File removed. + * hurd/getdport.c: File removed. + * hurd/fopenport.c: File removed. + * mach/thread-sym.c: File removed. + * mach/spin-syms.c: File removed. + * mach/msgserver_t.c: File removed. + * mach/msgserver.c: File removed. + * mach/msg.c: File removed. + * mach/mig_syms.c: File removed. + * malloc/mcheck-init.c: File removed. + * malloc/cfree.c: File removed. + * io/flock.c: File removed. + * io/write.c: File removed. + * io/unlink.c: File removed. + * io/umask.c: File removed. + * io/symlink.c: File removed. + * io/rmdir.c: File removed. + * io/readlink.c: File removed. + * io/read.c: File removed. + * io/pipe.c: File removed. + * io/open.c: File removed. + * io/mkdir.c: File removed. + * io/lstat.c: File removed. + * io/lseek.c: File removed. + * io/link.c: File removed. + * io/isatty.c: File removed. + * io/stat.c: File removed. + * io/fstat.c: File removed. + * io/fchown.c: File removed. + * io/fchmod.c: File removed. + * io/dup2.c: File removed. + * io/dup.c: File removed. + * io/close.c: File removed. + * io/fcntl.c: File removed. + * io/chmod.c: File removed. + * io/chdir.c: File removed. + * io/access.c: File removed. + * io/chown.c: File removed. + * time/tzset.c: File removed. + * time/timelocal.c: File removed. + * time/syms-time.c: File removed. + * time/settod.c: File removed. + * time/setitmr.c: File removed. + * time/gettod.c: File removed. + * time/getitmr.c: File removed. + * time/adjtime.c: File removed. + * termios/tcgetattr.c: File removed. + * string/stpncpy.c: File removed. + * string/rindex.c: File removed. + * string/memccpy.c: File removed. + * string/index.c: File removed. + * string/bcmp.c: File removed. + * stdlib/srand.c: File removed. + * stdlib/random.c: File removed. + * stdio/vsscanf.c: File removed. + * stdio/vfscanf.c: File removed. + * stdio/syms-stdio.c: File removed. + * stdio/remove.c: File removed. + * stdio/getline.c: File removed. + * stdio/getdelim.c: File removed. + * signal/ssignal.c: File removed. + * signal/sigvec.c: File removed. + * signal/sigsetmask.c: File removed. + * signal/sigret.c: File removed. + * signal/sigproc.c: File removed. + * signal/sigpause.c: File removed. + * signal/sigblock.c: File removed. + * signal/sigaction.c: File removed. + * signal/kill.c: File removed. + * signal/gsignal.c: File removed. + * setjmp/siglongjmp.c: File removed. + * setjmp/_longjmp.c: File removed. + * resource/getrusage.c: File removed. + * posix/waitpid.c: File removed. + * posix/wait4.c: File removed. + * posix/wait3.c: File removed. + * posix/wait.c: File removed. + * posix/times.c: File removed. + * posix/sysconf.c: File removed. + * posix/setuid.c: File removed. + * posix/setsid.c: File removed. + * posix/setpgrp.c: File removed. + * posix/setpgid.c: File removed. + * posix/setgid.c: File removed. + * posix/pathconf.c: File removed. + * posix/getuid.c: File removed. + * posix/getppid.c: File removed. + * posix/getpid.c: File removed. + * posix/getgrps.c: File removed. + * posix/getgid.c: File removed. + * posix/geteuid.c: File removed. + * posix/getegid.c: File removed. + * posix/fpathcon.c: File removed. + * posix/fork.c: File removed. + * posix/execve.c: File removed. + * posix/environ.c: File removed. + * misc/utimes.c: File removed. + * misc/setreuid.c: File removed. + * misc/setregid.c: File removed. + * misc/select.c: File removed. + * misc/sbrk.c: File removed. + * misc/mknod.c: File removed. + * misc/ioctl.c: File removed. + * misc/getpgsz.c: File removed. + * misc/gethstnm.c: File removed. + * misc/getdtsz.c: File removed. + * misc/data_start.c: File removed. + * misc/brk.c: File removed. + * math/scalb.c: File removed. + * math/rint.c: File removed. + * math/logb.c: File removed. + * math/isnan.c: File removed. + * math/isinf.c: File removed. + * math/infnan.c: File removed. + * math/finite.c: File removed. + * math/expm1.c: File removed. + * math/drem.c: File removed. + * math/copysign.c: File removed. + * math/__scalb.c: File removed. + * dirent/getdents.c: File removed. + +Fri Jan 20 16:11:06 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/generic/morecore.c (__default_morecore): Use + __malloc_ptrdiff_t; don't cast arg to int. + + * resolv/getnetnamadr.c: Include "conf/portability.h". + +Thu Jan 19 02:20:04 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdlib/strtol.c: Include errno.h. + [QUAD] (ULONG_MAX): Define to a static variable initialized to + ULONG_LONG_MAX. This is to work around a GCC bug in using the + constant in arithmetic. + + * posix/unistd.h (daemon): Declare it. + + * malloc/mcheck-init.c: Remove GNU ld hacks. + (__malloc_initialize_hook): Initialize this hook to turn_on_mcheck. + * malloc/malloc.c (__malloc_initialize_hook): New hook variable. + (initialize): Call the hook if set. + * malloc/malloc.h: Use __malloc_{size,ptrdiff}_t in prototypes. + (__malloc_initialize_hook): Declare new hook variable. + +Wed Jan 18 01:43:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdsig.c: Prepend `msg_' to server RPC names. + * hurd/hurdpid.c: Likewise. + * hurd/hurdauth.c: Likewise. + +Tue Jan 17 03:16:47 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__select.c: If some replies are EINTR, succeed + if any are successful. + + * hurd/hurdmsg.c: Prepend `msg_' to all RPC names. + (_S_msg_get_exec_flags, _S_msg_set_exec_flags, + _S_msg_set_some_exec_flags, _S_msg_clear_some_exec_flags): New + functions. + (_S_io_select_done, _S_dir_changed, _S_file_changed): Stubs removed. + + * hurd/hurdkill.c: __sig_post renamed to __msg_sig_post. + * hurd/hurd-raise.c: Likewise. + * hurd/hurdsig.c (post_reply): Prepend `msg_' to RPC names. + + * sysdeps/mach/hurd/ptrace.c: New file. + + * sysdeps/mach/hurd/__select.c: Revamped to use new io_select + interface, which has normal EINTR semantics. Instead of waiting + for io_select_done notification messages, send io_select messages + with short reply timeout and then wait for io_select_reply + messages. + + * hurd/hurdexec.c (_hurd_exec): Pass (_hurd_exec_flags & + EXEC_INHERITED) to file_exec. + + * hurd/hurdsig.c (post_reply): Take new arg UNTRACED; if nonzero, + use sig_post_untraced_reply. All callers changed. + (abort_thread, abort_rpcs): Take same new arg and pass it through. + All callers changed. + (_hurd_internal_post_signal): Take new arg UNTRACED. + If zero and process is traced, stop with SIGNO as stop signal. If + nonzero, resume process before delivering signal (unless + ACT==stop). Expand local fn sigwakeup into block at end taken iff + SIGNO!=0. + (signal_allowed): New function, broken out of _S_sig_post. + (_S_sig_post): Call it. Pass UNTRACED arg of false to + _hurd_internal_post_signal. + (_S_sig_post_untraced): New function. Just like _S_sig_post, but + pass true for UNTRACED. + * hurd/hurd/signal.h (_hurd_internal_post_signal): Take new arg + UNTRACED. + * hurd/catch-exc.c (_S_catch_exception_raise): Pass UNTRACED arg + to _hurd_internal_post_signal (value zero). + +Mon Jan 16 16:40:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdinit.c (_hurd_exec_flags): New variable. + (_hurd_init): Initialize it from FLAGS arg. + (_hurd_proc_init): If EXEC_TRACED is set in _hurd_exec_flags, + raise a SIGTRAP signal (with a sigcode of zero). + * hurd/hurd.h (_hurd_exec_flags): Declare it. + + * Version 1.09.5. + +Mon Jan 16 16:16:55 1995 Richard Stallman <rms@mole.gnu.ai.mit.edu> + + * malloc/malloc.c (malloc): Fix 1-off in previous change. + +Mon Jan 16 15:49:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob/Makefile.in: Remove config.h and config.log. + +Sun Jan 15 06:56:47 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob/configure.in: Add AC_CONST check. + + * conf/portability.h: #undef sun. + * resolv/res_query.c: Updated from BIND-4.9.3-BETA17. + * resolv/getnetnamadr.c: Likewise. + + * socket/Makefile (headers): Add sockaddrcom.h. + * inet/netinet/in.h: Include <sockaddrcom.h>. + (struct sockaddr_in): Use the __SOCKADDR_COMMON macro. + * socket/sys/un.h (struct sockaddr_in): Likewise. + * socket/sys/socket.h (struct sockaddr): Likewise. + * sysdeps/unix/bsd/bsd4.4/sockaddrcom.h: New file. + * sysdeps/generic/sockaddrcom.h: New file. + + * sysdeps/unix/sysv/sysv4/ftruncate.c: New file. + * sysdeps/unix/common/fcntlbits.h [__USE_SVID] (F_ALLOCSP, + F_FREESP): New macros. + * sysdeps/posix/truncate.c: New file. + + * malloc/malloc.c (malloc): Fix typos in RMS's change. + + * malloc/Makefile (dist-routines): Add malloc-find. + * malloc/malloc.h (malloc_find_object_address): Declare it. + * malloc/malloc-find.c: New file. + + * malloc/malloc.h (__malloc_ptrdiff_t): New macro, defined a la + __malloc_size_t. + (malloc_info): Use that type for member `busy.info.size'. + + * stdlib/strtol.c: Change uses of `long' keyword throughout to use + `LONG' macro. + [! QUAD] (LONG): Define as long. + [QUAD] (LONG): Define as long long. + [QUAD] (LONG_MIN, LONG_MAX, ULONG_MAX): Redefine to long long + versions. + [QUAD] (strtoul, strtol): Define to strtouq, strtoq. + * stdlib/Makefile (routines): Add strtoq and strtouq. + * stdlib/strtoq.c, stdlib/strtouq.c: New files. + * stdlib/stdlib.h [__GNUC__ && __USE_BSD] (strtoq, strtouq): + Declare them. + + * stdio/vfprintf.c: If there was a precision specified, ignore the + 0 flag and always pad with spaces. + + * stdio/vfprintf.c: Don't use strchr to skip text until next %. + Use a loop and also stop on first !isascii char. + +Wed Jan 11 00:07:10 1995 Richard Stallman <rms@mole.gnu.ai.mit.edu> + + * malloc/malloc.h (malloc_info): Change usage of .busy.info.size. + + * malloc/malloc.c (malloc): For a multi-block object, store a + negative number into the busy.info.size of all but the first block. + +Tue Jan 10 13:45:20 1995 Brendan Kehoe <brendan@zen.org> + + * sysdeps/unix/bsd/ultrix4/mips/start.S: Use s0, s1, and s2 + instead of t0, t1, and t2. + +Tue Jan 10 05:53:50 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * malloc/memalign.c (__memalign_hook): New variable. + (memalign): Call it if set. + * malloc/malloc.h (__memalign_hook): Declare new variable. + +Wed Dec 28 03:27:21 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * conf/portability.h: Include string.h and stdlib.h. + * inet/netdb.h (NETDB_INTERNAL, NETDB_SUCCESS): New macros. + * resolv/resolv.h, resolv/arpa/nameser.h, resolv/gethnamaddr.c, + resolv/getnetbyname.c, resolv/getnetent.c, resolv/herror.c, + resolv/res_mkquery.c, resolv/res_send.c, resolv/res_comp.c, + resolv/res_debug.c, resolv/res_init.c: Updated from BIND 4.9.3-BETA14. + + * sysdeps/m68k/fpu/__math.h (__m81_inline): New macro. Replace + all uses of `extern __inline' with `__m81_inline'. + + * sysdeps/unix/bsd/hp/m68k/__vfork.S: Use subl, not decl. + * sysdeps/unix/__fork.S: Swap args in subl. + + * posix/sys/types.h [__USE_MISC] (ushort, uint): New typedefs, for + compatibility. + +Tue Dec 20 13:33:20 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__setpgrp.c (__setpgrp): Use __swtch_pri instead + of swtch. + * sysdeps/mach/hurd/__setsid.c (__setsid): Likewise. + * mach/spin-solid.c (__spin_lock_solid): Likewise. + +Thu Dec 15 12:01:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * inet/rcmd.c (iruserok): Use alloca instead of fixed-size buffer + for PBUF. + (__ivaliduser): Use getline instead of fgets with fixed-size buffer. + + * sysdeps/mach/hurd/Makefile (subdirs): Don't elide inet. + +Wed Dec 14 18:20:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/alpha/bsd-setjmp.S: Reverse register and immediate args + in `bis' insn; immediate must be second. + + * sysdeps/unix/__fork.S: Use subl instead of decl. + * sysdeps/unix/i386/__fork.S: New file. + + * sysdeps/mach/hurd/alpha/trampoline.c (_hurd_setup_sighandler): + Remove A macro; just use `asm volatile' with proper quotes in each + line. + * sysdeps/mach/alpha/sysdep.h (CALL_WITH_SP): Put parens around + jmp target register. + + * time/africa, time/asia, time/australasia, time/emkdir.c, + time/europe, time/ialloc.c, time/northamerica, time/private.h, + time/scheck.c, time/yearistype, time/zdump.c, time/zic.c: New code + and data from ADO 94h distribution. + + * sysdeps/sparc/setjmp.S: Use sethi and or to put address of + __sigjmp_save in %g1 and jmp there. jmp cannot contain a complete + absolute pointer. Put second store in jmp delay slot. + +Tue Dec 13 15:47:52 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/sparc/bsd-_setjmp.S: Use sethi and or to put address of + __sigsetjmp in %g1 and jmp there. jmp cannot contain a complete + absolute pointer. + * sysdeps/sparc/bsd-setjmp.S: Likewise. + + * configure.in: Use ; before } in { ... } exprs. + +Mon Dec 12 01:41:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.09.3. + + * sysdeps/mach/hurd/alpha/trampoline.c: Use `long int' for sigcode + values. Use _hurdsig_catch_fault. Pass address of __sigreturn in + $27, SCP value in $25. In trampoline code, use those regs. + + * sysdeps/mach/hurd/alpha/__sigret.c: Use asms instead of global + register vars to restore FP regs. Fix typo in REI invocation. + +Sun Dec 11 14:10:11 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd/fd.h (hurd_register_ioctl_handler, + _HURD_HANDLE_IOCTLS): Third arg to handler is a void *, not a + __gnuc_va_list. + + * stdio/memstream.c (enlarge_buffer): Always add one char into + NEED for the char we are writing or the NUL terminator. + + * stdio/memstream.c (enlarge_buffer): If realloc fails, just set + error flag and preserve old buffer state. + + * stdio/fwrite.c: In fill_buffer case, check for zero buffer space + after fflush and write one char normally. + +Sat Dec 10 00:02:21 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__fork.c: Use natural_t in place of int. + + * sysdeps/alpha/macros.m4: Use C comments instead of ! comments. + + * sysdeps/mach/hurd/mmap.c: Cast -1 to long int before casting to + caddr_t. + + * sysdeps/mach/alpha/syscall.S: Include + <mach/machine/alpha_instruction.h> to define op_chmk. + + * sysdeps/mach/hurd/__mknod.c: Include <string.h>. + * sysdeps/mach/hurd/setegid.c: Likewise. + * sysdeps/mach/hurd/seteuid.c: Likewise. + * sysdeps/mach/hurd/__setregid.c: Likewise. + * sysdeps/mach/hurd/__setreuid.c: Likewise. + * sysdeps/mach/hurd/__ioctl.c: Likewise. + + * sysdeps/mach/hurd/recvfrom.c: Include <string.h>. Use + mach_msg_type_number_t in place of unsigned int. + * sysdeps/mach/hurd/recv.c: Likewise. + * sysdeps/mach/hurd/getsockopt.c: Likewise. + * sysdeps/mach/hurd/getsocknam.c: Likewise. + * sysdeps/mach/hurd/getpeernam.c: Likewise. + * sysdeps/mach/hurd/accept.c: Likewise. + * sysdeps/mach/hurd/__gethstnm.c: Likewise. + +Fri Dec 9 00:01:21 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__readlink.c: Use mach_msg_type_number_t in + place of unsigned int. + * sysdeps/mach/hurd/__fork.c: Likewise. + + * sysdeps/mach/hurd/__setgid.c: Include <string.h>. + * sysdeps/mach/hurd/__setuid.c: Likewise. + * sysdeps/mach/hurd/__getgrps.c: Likewise. + * hurd/getuids.c: Likewise. + * sysdeps/mach/hurd/__getdents.c: Likewise. + + * sysdeps/mach/hurd/dirstream.h (DIR): Use unsigned long int for + `__allocation' and `__size' members. + + * sysdeps/mach/hurd/alpha/exc2signal.c: Use `long int' for sigcode + values. + * sysdeps/mach/hurd/i386/exc2signal.c: Likewise. + + * mach/devstream.c (input): Use mach_msg_type_number_t for NREAD. + + * sysdeps/mach/hurd/__setitmr.c (preempt_sigalrm): Use `long int' + for SIGCODE; take SIGERROR arg. + + * sysdeps/alpha/divrem.m4: Include <sysdep.h> instead of + <regdef.h>. Use C comments instead of ! comments. + + * sysdeps/alpha/memchr.c: Remove extra shift and OR of CHARMASK. + * sysdeps/alpha/strchr.c: Likewise. + + * sysdeps/mach/hurd/sysd-stdio.c: Use mach_msg_type_number_t in + place of unsigned int. + + * sysdeps/posix/tempname.c (__stdio_gen_tempname): Cast FD to long + int before casting to pointer. + + * stdio/printf_fp.c: Include <string.h>. + + * sysdeps/alpha/setjmp_aux.c: Use ENV[0].__jmpbuf[0]. + + * sysdeps/mach/alpha/sysdep.h (ENTRY): New macro. + + * hurd/hurdioctl.c (fioctl): Pass a mach_msg_type_number_t* to + __io_readable. + + * hurd/hurd-raise.c: Use `long int' for sigcode values. + + * hurd/hurdfault.c: Use `long int' for sigcode values. + * hurd/hurdfault.h: Likewise. + + * hurd/hurd/signal.h (struct hurd_signal_preempt): Handler takes + new SIGERROR arg. + * hurd/preempt-sig.c: Likewise. + * hurd/hurdsig.c (_hurd_internal_post_signal): Pass SIGERROR to + PREEMPT. + + * hurd/hurdlookup.c: Use mach_msg_type_number_t and natural_t in + place of unsigned int and int. + + * hurd/hurd/id.h: Use mach_msg_type_number_t in place of unsigned int. + + * hurd/catch-exc.c: Use `long int' for sigcode values. + * sysdeps/mach/hurd/i386/trampoline.c: Likewise. + * hurd/preempt-sig.c: Likewise. + + * configure.in (machine): Don't recognize r[34]00. + Convert mips64* to mips/mips64/& and mips* to mips/&. + * sysdeps/mips/mipsel/bytesex.h: New file. + * sysdeps/mips/r4000: Directory renamed to sysdeps/mips/mips64. + + * sysdeps/mach/alpha/sysdep.h (START_MACHDEP): Add missing + backslashes. + (CALL_WITH_SP): Cast FN to long int. + + * sysdeps/mach/alpha/thread_state.h (struct machine_thread_all_state): + New member `exc'. + + * hurd/fd-read.c: Include <string.h>. Use mach_msg_type_number_t + in place of mach_msg_type_size_t. + + * hurd/hurdfault.c: Use natural_t instead of int. + + * hurd/hurd/signal.h: Use `long int' for sigcode values. + * hurd/hurdsig.c: Use mach_msg_type_number_t and natural_t in + place of unsigned int and int. Use `long int' for sigcode values. + + * hurd/vpprintf.c (pwrite): Cast &N to mach_msg_type_number_t *. + + * hurd/__fopenport.c: Include <string.h>. Use + mach_msg_type_number_t in place of unsigned int. + + * hurd/hurdauth.c: Include <string.h>. + * hurd/hurdsock.c: Likewise. + + * sysdeps/mach/alpha/machine-lock.h: Remove ".set noreorder" et + al; GCC already emits them. Fix register constraints in asms. + Set RTN in C, not asm. + + * hurd/hurdprio.c: Use mach_msg_type_number_t in place of unsigned + int. + +Thu Dec 8 04:00:11 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/alpha/__sigret.c: Remove ".set noreorder" et + al; GCC already emits them. + * sysdeps/mach/hurd/alpha/trampoline.c: Likewise. + + * sysdeps/mach/thread_state.h: Use mach_msg_type_number_t and + natural_t in place of unsigned int and int. + + * sysdeps/mach/sysdep.h (ENTRY): Don't #error if undefined. + + * sysdeps/mach/syscall.h: New file. + + * sysdeps/mach/Makefile: Remove debugging printout. + + * sysdeps/mach/hurd/configure.in: Converted to an autoconf script + from sysdeps/mach/hurd/configure, to work better with autoconf + version 2. + * sysdeps/mach/configure.in: Likewise, from sysdeps/mach/configure. + + * hurd/hurdmsg.c: Use mach_msg_type_number_t in place of unsigned + int. + + * sysdeps/mach/alpha/sysdep.h: Rename variable `sp' to avoid + conflict with #define in <mach/alpha/asm.h>. + + * sysdeps/mach/hurd/alpha/__sigret.c: Remove unused variable. + + * sysdeps/mach/hurd/__ioctl.c: Pass arg to + __mig_dealloc_reply_port. + + * configure.in: Converted to Autoconf version 2. + * sysdeps/generic/configure.in: Likewise. + * sysdeps/unix/common/configure.in: Likewise. + * sysdeps/unix/configure.in: New file, converted to a + part-autoconf script from sysdeps/unix/configure, to work better + with autoconf version 2. + * aclocal.m4: Converted to Autoconf version 2. + (AC_CHECK_SYMBOL): New macro. + * config.make.in: New file. + * config-name.in: New file. + * Makefile (distribute): Rename install.sh to install-sh. + Add config.make.in, config-name.in, Makefile.in. + (distclean-1): Remove config-name.h and config.cache. + * Makefile.in: New file. + * Makeconfig (+gnu-stabs, gnu-as): Match -DHAVE_GNU_{AS,LD}=1 too. + +Wed Dec 7 14:05:12 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/mips/cacheflush.c: New file. + * sysdeps/mach/mips/Makefile: New file. + * sysdeps/mach/mips/Dist: New file. + + * hurd/hurdmalloc.c (vm_allocate, vm_page_size): #define these to + __ names at top. + + * posix/glob/Makefile.in (realclean): Remove config.status. + + * posix/glob/Makefile.in (DEFS): New variable, set from @DEFS@. + (CPPFLAGS): Remove @DEFS@ from here. + (.c.o): Use $(DEFS). + + * setjmp/siglongjmp.c: First arg is const. + +Tue Dec 6 19:04:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob/Makefile.in (CPPFLAGS): Include @DEFS@. + +Mon Dec 5 12:05:10 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob/configure.in: Add AC_PROG_CC. + + * sysdeps/mach/hurd/alpha/longjmp-ts.c: Use ENV[0].__jmpbuf[0]. + * sysdeps/mach/hurd/mips/longjmp-ts.c: Likewise. + * sysdeps/mach/hurd/i386/longjmp-ts.c: Likewise. + + * Version 1.09.2. + + * sysdeps/mach/hurd/__select.c: Don't make TO const. + +Sun Dec 4 12:06:36 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/configure (config_vars): Add missing backslash + before a $. + + Revamp the `setjmp' interface to be cleaner: only one type + `jmp_buf'/`sigjmp_buf', and only one `longjmp' function (with + aliases `_longjmp', `siglongjmp'). Internal setjmp interface is + now __sigsetjmp, which takes SAVEMASK flag and optionally saves + the signal mask. Add extern entry points `setjmp' and `_setjmp' + for BSD compatiblity; they tail-call __sigsetjmp. + * setjmp/setjmp.h: Include <sigset.h> for __sigset_t, not + <signal.h> + (jmp_buf): Define unconditionally with old `sigjmp_buf' defn. + (__sigjmp_save): Declare to return int. + (__setjmp): Remove declaration; this function no longer exists. + (__sigsetjmp): Declare it; this is the new internal function. + (setjmp): Define to call __sigsetjmp, second arg depending on + __FAVOR_BSD. + [__OPTIMIZE__] (longjmp): Remove #define. + [__USE_BSD] (_longjmp): Declare it, another name for `longjmp'. + [__USE_BSD] (_setjmp): Define macro to do __sigsetjmp (ENV, 0). + [__FAVOR_BSD]: Remove all these defns. + [__USE_POSIX] (sigjmp_buf): Define as another name for `jmp_buf'. + [__USE_POSIX] (sigsetjmp): Define to call __sigsetjmp. + * setjmp/sigjmp.c (__sigjmp_save): Return an int, always zero, not + void. + * setjmp/Makefile (routines): Remove _setjmp, add bsd-setjmp and + bsd-_setjmp. + * setjmp/longjmp.c: Define as a real funciton, which restores + signal mask and calls __longjmp. + * setjmp/siglongjmp.c: Make this an alias to longjmp. + * setjmp/_longjmp.c: Alias to longjmp, not siglongjmp. + * sysdeps/stub/setjmp.c: Implement __sigsetjmp instead of + __setjmp; call __sigjmp_save. + * sysdeps/sparc/setjmp.S: Likewise. + * sysdeps/m68k/setjmp.c: Likewise. + * sysdeps/i386/setjmp.c: Likewise. + * sysdeps/vax/setjmp.c: Likewise. + * sysdeps/mips/setjmp.S: Implement __sigsetjmp instead of + __setjmp; call __sigsetjmp_aux instead of __setjmp_aux. Pass SP + and FP as 3rd and 4th args, not 2nd and 3rd. + * sysdeps/alpha/setjmp.S: Likewise. + * sysdeps/mips/setjmp_aux.c: Implement __sigsetjmp_aux instead of + __setjmp_aux; call __sigjmp_save. + * sysdeps/alpha/setjmp_aux.c: Likewise. + * sysdeps/mips/bsd-setjmp.S, sysdeps/mips/bsd-_setjmp.S: New files. + * sysdeps/alpha/bsd-setjmp.S, sysdeps/alpha/bsd-_setjmp.S: New files. + * sysdeps/vax/bsd-setjmp.S, sysdeps/vax/bsd-_setjmp.S: New files. + * sysdeps/sparc/bsd-setjmp.S, sysdeps/sparc/bsd-_setjmp.S: New files. + * sysdeps/i386/bsd-setjmp.S, sysdeps/i386/bsd-_setjmp.S: New files. + * sysdeps/m68k/bsd-setjmp.S, sysdeps/m68k/bsd-_setjmp.S: New files. + * sysdeps/stub/bsd-setjmp.c, sysdeps/stub/bsd-_setjmp.c: New files. + * setjmp/_setjmp.c: File removed. + * sysdeps/alpha/__longjmp.c: Take arg of type __jmp_buf, not + jmp_buf. + * sysdeps/vax/__longjmp.c: Likewise. + * sysdeps/stub/__longjmp.c: Likewise. + * sysdeps/i386/__longjmp.c: Likewise. + * sysdeps/m68k/__longjmp.c: Likewise. + +Sat Dec 3 09:00:17 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/alpha/__sigret.c: Set up frame for `rei' to + restore on user stack, aligned to an 8-word boundary and with a PS + value that restores user's stack alignment. + +Fri Dec 2 19:31:24 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/readdir.c: Search one char more than D_NAMLEN(DP) + for the null terminator. Always set D->d_namlen, using + D_NAMLEN(DP) if no null is found. + + * sysdeps/unix/sysv/sco3.2.4/__sigact.S: Fix typo `.global' to + `.globl'. Silly me, I used a vowel in a Unix program. + +Mon Nov 28 16:11:39 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * io/fts.c (ALIGN, ALIGNBYTES): New macros, defined if not already + defined. + +Tue Nov 22 06:39:49 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/bsd/osf1/dirstream.h: File removed. + + * sysdeps/stub/sigcontext.h (struct sigcontext): Use `__sigset_t' + instead of `sigset_t' for `sc_mask'. + * sysdeps/mach/hurd/i386/sigcontext.h: Likewise. + * sysdeps/mach/hurd/alpha/sigcontext.h: Likewise. + * sysdeps/mach/hurd/mips/sigcontext.h: Likewise. + * sysdeps/unix/bsd/ultrix4/mips/sigcontext.h: Likewise. + * sysdeps/unix/bsd/sun/m68k/sigcontext.h: Likewise. + * sysdeps/unix/bsd/sun/sparc/sigcontext.h: Likewise. + + * hurd/hurdsig.c (_hurd_internal_post_signal: case handle): Call + abort_thread always, first thing after thread_suspend. + +Mon Nov 21 13:18:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__fcntl.c: Don't make this whole function a + critical section. + + * sysdeps/generic/strpbrk.c: Don't call strchr; do it by hand for + efficiency. + +Wed Nov 16 12:47:22 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/bsd/m68k/sysdep.S [__motorola__]: Swap operands in + cmp.l. + + * hurd/msgportdemux.c (_hurd_msgport_receive): Call + _hurd_self_sigstate to get sigstate cached before running any + signal thread code. + + * sysdeps/mach/hurd/__fork.c: Pass _hurd_msgport_thread to + __thread_get_state, not _hurd_sigthread. Don't do + __thread_get_state on THREAD_SELF--the kernel does not allow it. + + * hurd/hurdsig.c (_hurd_internal_post_signal): In stopping orphan + test, take sigmask of SIGNO, don't & its value with a mask. In + blocked signal test, be careful not to pass SIGNO=0 to __sigismember. + +Tue Nov 15 01:39:36 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makerules (stub-$(subdir)): Save absolute name of + $(..)sysdeps/stub before cd'ing, transform gleaned file names to + refer to saved name. + + * sysdeps/mach/hurd/socketpair.c: Include <fcntl.h>. + + * time/test_time.args: Add CST as a test case. + + * sysdeps/mach/hurd/socketpair.c: Rewritten (copying __pipe.c). + + * sysdeps/unix/bsd/dirstream.h [__USE_BSD] (dirfd): New macro. + + * posix/unistd.h: Declare fchdir. + + * io/fts.c (MAXPATHLEN): Define if not defined. + + * io/fts.c, io/fts.h: New files, from 4.4 BSD code by Keith Bostic. + * io/Makefile (routines): Add fts. + (headers): Add fts.h. + + Mostly ported the Hurd to the DEC Alpha. + * sysdeps/mach/alpha/machine-sp.h: New file. + * sysdeps/mach/alpha/thread_state.h: New file. + * sysdeps/mach/alpha/sysdep.h: New file. + * sysdeps/mach/alpha/machine-lock.h: New file. + * sysdeps/mach/hurd/alpha/sigcontext.h: New file. + * sysdeps/mach/hurd/alpha/longjmp-ts.c: New file. + * sysdeps/mach/hurd/alpha/trampoline.c: New file. + * sysdeps/mach/hurd/alpha/exc2signal.c: New file. + * sysdeps/mach/hurd/alpha/__sigret.c: New file. + + * sysdeps/mach/hurd/Makefile (errlist.c, errnos.h): Make the + output unwritable. + * sysdeps/alpha/Makefile (divrem rule): Make the output + unwritable, use mv -f. + * sysdeps/sparc/Makefile (divrem rule): Likewise. + + * configure.in (sysnames): Put another loop on $mach inside $base + loop but outside $vendor loop. This should catch .../cpu/vendor. + +Mon Nov 14 22:52:03 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/start.c: Add missing #endif. + +Sun Nov 13 05:04:18 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__select.c: At end of receiving loop, clear TO + instead of TIMEOUT. + + * malloc/mcheck-init.c (turn_on_mcheck): Add gratuitous self + reference to silence compiler warning. + (_hurd_preinit_hook): Add the function to this set too. + + * time/__tzset.c (__tzset): Give tz_rules coherent default when TZ + value is short or malformed. + + * mach/devstream.c: Echo input after reading it. + + * Make-dist (generated): Mutate to add .S and .s variations for .c + files. + +Fri Nov 11 11:43:26 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/i386/__sigret.c (__sigreturn): Don't actually + abort here; at least let the user continue with bogus FP; that's + better than a random crash until it's fixed. + +Thu Nov 10 04:56:28 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/bsd/sun/sunos4/sys/mman.h (msync): Use __caddr_t + instead of caddr_t in decl. + + * sysdeps/mach/start.c (START_ARGS): Define to void if undefined. + [START_MACHDEP]: Reference this if defined. + [START_MACHDEP] (_start): #define to _start0. + (_start): Take args START_ARGS. + * sysdeps/mach/hurd/start.c: Likewise. + +Wed Nov 9 08:02:59 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/Makefile (sig): Remove longjmp-ctx (it is never called). + + * sysdeps/mach/hurd/__fork.c: Do thread_get_state on parent's + threads to modify and thread_set_state new child threads. + +Mon Nov 7 00:38:45 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob/configure.in: Converted to Autoconf v2. + * posix/glob.c: Test HAVE_DIRENT_H, HAVE_SYS_DIR_H, HAVE_NDIR_H + instead of DIRENT, SYSDIR, NDIR. + * posix/glob/Makefile.in (CC): New variable, set from @CC@. + (CPPFLAGS): Set from @CPPFLAGS@, not @DEFS@. + + * sysdeps/unix/__fork.S: Use decrement and AND instead of test and + branch. + * sysdeps/unix/sparc/__fork.S: Likewise. + * sysdeps/unix/sparc/__vfork.S: Likewise. + * sysdeps/unix/bsd/sun/m68k/__vfork.S: Likewise. + * sysdeps/unix/bsd/hp/m68k/__vfork.S: Likewise. + * sysdeps/unix/i386/__fork.S: File removed. + +Sun Nov 6 19:26:28 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.09. + +Fri Nov 4 16:52:05 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.14. + + * manual/Makefile (stamp-summary): Depend on $(chapters-incl) too. + +Thu Nov 3 18:33:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/generic/sigset.h (__sigemptyset): Cast to __sigset_t. + (__sigfillset): Likewise. Use ~(__sigset_t)0 in place of -1. + (__SIGSETFN): Don't try to be clever. Test bounds of SIG with < + and >. + + * sysdeps/mach/hurd/__fork.c: Unlock signal state earlier, just + after unlocking _hurd_ports locks. + + * sysdeps/unix/bsd/osf1/direct.h: File removed. + * sysdeps/unix/bsd/direct.h (struct direct): Use `unsigned int' + instead of `unsigned long int' for `d_fileno' member. + + * Makerules (common-mostlyclean): Remove $(tests:=.out) too. + + * assert/assert-perr.c (__assert_perror_fail): Add missing comma. + + * sysdeps/unix/ioctls-tmpl.c [__osf__ && __alpha__] (FIOPIPESTAT, + SIOCSRREQR, SIOCSRREQW, SRVC_REQUEST): #undef these. + +Wed Nov 2 23:00:19 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/setegid.c: Pass poly and count args for + other_handles in correct order in call to auth_makeauth. + * sysdeps/mach/hurd/__setregid.c: Likewise. + * sysdeps/mach/hurd/__setreuid.c: Likewise. + + * Makerules (compile.S): Add -DASSEMBLER. + * sysdeps/mach/sysdep.h [ASSEMBLER]: Don't include + <mach/mig_support.h> if this is defined. + +Wed Nov 2 22:39:55 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/seteuid.c: Pass poly and count args for + other_handles in correct order in call to auth_makeauth. + +Wed Nov 2 15:03:51 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/internals.c (fillbuf): Make sure returned char doesn't get + sign extended. + +Tue Nov 1 01:25:28 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/common/Implies: File removed. + * sysdeps/unix/bsd/Implies: Add unix/inet. + + * assert/assert-perror.c: Renamed to assert-perr.c. + * assert/Makefile (routines): Rename assert-perror to assert-perr. + + * Version 1.08.13. + + * mach/Makefile (generated): Add __%.c for $(mach-shortcuts) too. + + * dirent/Makefile (tests): Add tst-seekdir. + * dirent/tst-seekdir.c (main): New file. + * sysdeps/unix/bsd/seekdir.c: New file. + * sysdeps/unix/bsd/telldir.c: New file. + * sysdeps/unix/bsd/dirstream.h (DIR): New member `__pos'. + * sysdeps/unix/bsd/readdir.c: Update DIRP->__pos in getdirentries + call. + * sysdeps/unix/opendir.c: Use calloc in place of malloc, to zero + fill new DIRs. + + * sysdeps/standalone/i386/force_cpu386/force_cpu386.ld: Renamed to + target.ld. + * sysdeps/standalone/i386/force_cpu386/Makefile: Install it from + that name (still into $(libdir)/force_cpu386.ld). + + * mach/Makefile (headers, user-interfaces, server-interfaces): + Don't add default_pager stuff. + +Mon Oct 31 07:00:40 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/bsd/sun/sunos4/termbits.h (TCSASOFT): Macro + removed. + + * malloc/malloc.h: Change #ifdef __STDC__ to #if defined + (__STDC__) && __STDC__. + +Fri Oct 28 00:09:24 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/sysdep.h: Include <mach/mig_support.h> for decls. + (FATAL_PREPARE): Pass arg to __mig_dealloc_reply_port. + + * assert/Makefile (routines): Add assert-perror. + + * Makerules (stubs): cd into $(objdir) and use local file names, + making the cmd shorter. + + * sysdeps/mach/hurd/getprio.c (getonepriority): Call + proc_getprocinfo with proc port. + + * sysdeps/mach/hurd/errnos.awk: Grok "@comment errno %d" in + errno.texi, instead of assigning sequentially. + * sysdeps/mach/hurd/errlist.awk: Likewise. + + * stdio/fwrite.c: Reset BUFFER_SPACE after fflush in fill_buffer + case. + + * sysdeps/generic/sigset.h (__SIGSETFN): When losing, punt to + `raise (-1)'. Old method looped. + + * hurd/hurd/resource.h: Include <hurd/process.h>. + +Thu Oct 27 15:00:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/standalone/standalone.h: Fixed typo. + +Wed Oct 26 00:21:16 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/i386/vfork.S: New file. + + * sysdeps/generic/strchr.c: Increment CP properly in check for 5th + char of quadword hit. + + * sysdeps/mach/hurd/getprio.c (getonepriority): Always set ONERR. + +Tue Oct 25 03:53:26 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd/resource.h: Include <errno.h>. + + * stdio/ftell.c: If STREAM->__pushed_back, calculate from + pushback_bufp instead of bufp. + + * Makefile (format-me): New canned sequence; runs makeinfo + --no-headers. + (INSTALL): Use it. + (NOTES): New file rule. + + * manual/intro.texi (Feature Test Macros): Node moved off to + creature.texi. + * manual/creature.texi: New file, broken out of intro.texi. + + * manual/Makefile (indices): New variable; include ky. + (realclean): Use $(indices) to remove all index and sorted index + files. + + * sysdeps/mach/hurd/fcntlbits.h (O_ASYNC, O_FSYNC, O_SYNC): + Protect with [__USE_BSD]. + +Mon Oct 24 00:16:59 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/bsd/utime.c: Initialize tv_usec fields. + Use __gettimeofday instead of time. + + * sunrpc/pmap_rmt.c: Include <sys/param.h> before <net/if.h>. + Undef _POSIX_SOURCE before that. + * sunrpc/pm_getport.c: Likewise. + * sunrpc/pm_getmaps.c: Likewise. + * sunrpc/get_myaddr.c: Likewise. + + * misc/sys/cdefs.h: Undef __P first. + + * Version 1.08.12. + + * sysdeps/mach/hurd/getprio.c: Rewritten. + * sysdeps/mach/hurd/setprio.c: New file. + * hurd/hurdprio.c: New file. + * hurd/Makefile (routines): Add hurdprio. + * hurd/hurd/resource.h (_hurd_priority_which_map): Declare it. + (NICE_TO_MACH_PRIORITY, MACH_PRIORITY_TO_NICE): New macros. + +Sun Oct 23 19:39:18 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makerules (sources): Fix typo in last change. + +Fri Oct 21 13:15:39 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/generic/termbits.h (ECHOKE): Remove gratuitous leading + space before #define. + + * Makerules (sources): Filter out $(elided-routines). + + * sysdeps/sparc/divrem.m4 (entry point): For OP=rem, set SIGN from + dividend only, ignoring divisor. + (Lgot_result): Test SIGN here for OP=rem too (as originally). + +Wed Oct 19 02:40:02 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdsig.c: Use assert_perror. + + * assert/assert-perror.c (__assert_perror_fail): New file. + * assert/assert.h (assert_perror): New macro. + + * Version 1.08.11. + + * hurd/hurdsig.c (abort_rpcs): Actually return a port instead of + boolean, as the type says. + + * hurd/hurdsig.c (abort_all_rpcs): If waiting for reply from + interrupted RPC returns error, print debugging msg with error + test, don't assert. + +Mon Oct 17 00:06:03 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdlib/strtol.c: Deansideclized. + * sysdeps/generic/strcspn.c: Deansideclized. + * sysdeps/generic/putenv.c: Deansideclized, added portability + cruft. + +Fri Oct 14 14:00:11 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/sysv/sysv4/solaris2/utsnamelen.h: + Moved to sysdeps/unix/sysv/sysv4. + +Thu Oct 13 22:06:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/common/glue-ctype.c [HAVE__LOCP]: Move this defn to + first. Include sys/types.h. + + * sysdeps/unix/bsd/readdir.c: Include direct.h. + + * socket/sys/socket.h (__SOCKADDR_ARG): Always use non-GCC defn, + for now. + * posix/sys/wait.h (__WAIT_STATUS): Likewise. + +Tue Oct 11 00:42:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.10. + +Mon Oct 10 00:33:47 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * malloc/malloc.h [_MALLOC_INTERNAL] (CHAR_BIT): Don't define if + already defined. + + * stdio/__vfscanf.c: Grok %q modifier like %ll. + + * mach/__msgserver.c: Increase default MAX_SIZE to two pages. + + * misc/init-misc.c: Cast string constant to non-const type. + + * sysdeps/i386/ffs.c: Use %1 again instead of listing TMP as an + input with constraint "1". This avoids a warning that TMP may be + used before set. + +Sun Oct 9 22:41:20 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdsig.c (abort_all_rpcs): Declare SS. + +Sun Oct 09 01:19:38 1994 Jim Meyering (meyering@comco.com) + + * posix/fnmatch.c: Remove CONFIG_BROKETS conditional. + +Fri Oct 7 15:28:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/__vfscanf.c: Properly grok %a modifier. + + * hurd/hurdsig.c (abort_rpcs): Return the reply port or null, + instead of boolean. + (abort_all_rpcs): Record the returns from abort_rpcs and wait for + a message on each reply port. Don't bother locking _hurd_siglock. + +Thu Oct 6 18:57:44 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurd.h (_hurd_socket_server): Take new arg DEAD; explain + its use in comment. + * hurd/hurdsock.c (_hurd_socket_server): Take new arg DEAD; if + nonzero, clear any old cached port and always do a fresh lookup. + * sysdeps/mach/hurd/socket.c: Pass new arg to _hurd_socket_server, + cope with dead server on socket_create. + * sysdeps/mach/hurd/__pipe.c: Likewise. + +Mon Oct 3 02:09:43 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/generic/utsnamelen.h (_UTSNAME_LENGTH): Increase to + 1024. + +Sun Oct 2 18:35:16 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/glob.h (__P): Change arg name to `protos', for congruence + with 4.4 BSD. + * posix/fnmatch.h (__P): Likewise. + +Sat Oct 1 04:25:35 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * misc/Makefile (routines): Add daemon. + +Fri Sep 30 16:49:09 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * misc/daemon.c: New file, incorporated from BSD 4.4-Lite. + + * sysdeps/mach/hurd/__setsid.c: Call _hurd_setcttyid with + MACH_PORT_NULL after proc_setsid. + + * hurd/hurdioctl.c (_hurd_setcttyid): Don't do mod_refs if port is + null. + + Always use fds' `port' cell for the generic port. + For ctty fds, use the `ctty' cell for the ctty-special port. + * hurd/dtable.c (get_dtable_port): Use port, never ctty. + (fork_child_dtable): Reset D->ctty instead of D->port. + (ctty_new_pgrp): Likewise. + * sysdeps/mach/hurd/__ioctl.c: Use ctty port for RPC if set and + !NOCTTY. + * hurd/port2fd.c (_hurd_port2fd): Install normal port in D->port + cell, and ctty-special port in the D->ctty cell, not the reverse. + * hurd/hurdioctl.c (tiocsctty): Don't assume MACH_PORT_NULL is + zero. + * hurd/hurdexec.c (_hurd_exec): Always pass fds' normal port, + never its ctty port. + * hurd/fd-write.c (_hurd_fd_write): Use ctty port for RPC if set + and !NOCTTY. + * hurd/fd-read.c (_hurd_fd_read): Use ctty port for RPC if set. + +Thu Sep 29 18:28:01 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * mach/mig_syms.c (mig_put_reply_port): Add symbol alias to __ + name. + +Thu Sep 29 12:23:07 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h (ENTRY): Use + poundfnc instead of \#function, to satisfy gcc-2.6.0 and higher. + (cat, poundfnc): Define macros to pull it off. + + * sysdeps/unix/sysv/sysd-stdio.c: Include + sysdeps/generic/sysd-stdio.h, + not looking in sysdeps/posix. + +Thu Sep 29 05:38:14 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/common/configure.in (ctype check): In test prog, + just reference $ctype; we don't care what type it is. + + * sysdeps/unix/bsd/bsd4.4/direct.h: New file. + (HAVE_D_TYPE): Define this macro. + * dirent/dirent.h (struct dirent): New member `d_type'; shorten + `d_namlen' to a byte. + * sysdeps/unix/bsd/readdir.c [! HAVE_D_TYPE]: Shuffle d_namlen and + clear d_type. + +Wed Sep 28 17:23:26 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * posix/sys/utsname.h [__USE_SVID] (SYS_NMLN): New macro. + + * dirent/scandir.c: Free storage on error from readdir. + +Mon Sep 26 00:55:34 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.9. + + * MakeTAGS (all-dist): Prepend the appropriate sysdep dir names. + + * hurd/hurdsig.c (_hurd_internal_post_signal: sigwakeup): Create a + send right. + +Sat Sep 24 13:44:51 1994 Jim Meyering (meyering@comco.com) + + * sysdeps/generic/memcmp.c [CMP_LT_OR_GT]: New macro. + (memcmp): Use it in place of each of ten 5-line #ifdef blocks. + +Fri Sep 23 16:55:54 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/sigsuspend.c: Include <hurd/msg.h>. + + * sysdeps/mach/hurd/sigsuspend.c: Add missing & in __mach_msg + call. + +Thu Sep 15 14:22:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/standalone/i386/force_cpu386/Dist: New file. + * sysdeps/standalone/m68k/m68020/mvme136/Dist: New file. + * sysdeps/standalone/i960/Dist: New file. + * sysdeps/standalone/m68k/m68020/Dist: New file. + * sysdeps/standalone/i386/force_cpu386/force_cpu386.ld: New file. + * sysdeps/standalone/m68k/m68020/mvme136/mvme136.ld: New file. + * sysdeps/standalone/i960/i960ca.h: New file. + * sysdeps/standalone/m68k/m68020/m68020.h: New file. + + * sysdeps/unix/common/configure.in: Use AC_COMPILE_CHECK instead + of AC_HAVE_FUNCS. + + * sysdeps/generic/make_siglist.c (sys_siglist): Define as macro to + my_siglist. + + * sysdeps/mach/i386/thread_state.h: Include from mach/machine, not + mach/i386. + * sysdeps/mach/hurd/i386/sigcontext.h: Likewise. + + * mach/mach/mig_support.h (__mig_put_reply_port): Declare. + (__mig_dealloc_reply_port): Take arg. + * sysdeps/mach/hurd/mig-reply.c (__mig_put_reply_port): New + function. + (__mig_dealloc_reply_port): Take arg, ignore it. + +Wed Sep 14 18:16:07 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/Makefile (libc-name): Set to crt. + [!subdir]: Install libc-ldscript as libc.a. + * sysdeps/mach/hurd/Dist: Add libc-ldscript. + +Tue Sep 13 19:57:09 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/sync.c: Don't be synchronous: pass WAIT=0 to + file_syncfs. + + * Makerules (libc-name): New variable. + (install, libc installation rule): Use $(libc-name) in place of `c'. + +Sun Sep 11 23:28:20 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__readlink.c: Only decrement LEN to remove the + null terminator when LEN is already large enough to include it. + + * hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Add break + after FS_RETRY_MAGICAL case. + +Fri Sep 9 04:03:59 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * stdio/vfprintf.c: Grok q modifier like ll. + + * Make-dist (sysdep-Subdir-files, subdirs): Set these early on, + before doing distinfo. + [parent] (+distinfo): Set inhibit_interface_rules=t in sub-make. + +Thu Sep 8 17:18:14 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/generic/morecore.c (__default_morecore) [! __STDC__]: + Declare arg as `int' instead of `ptrdiff_t'. + +Tue Sep 6 19:06:00 1994 Roland McGrath <roland@geech.gnu.ai.mit.edu> + + * posix/glob.c (prefix_array, glob): Avoid const on initialized + variables. Some compiler generates bad code. + +Mon Sep 5 13:24:26 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * malloc/Makefile (malloc/%: ../sysdeps/generic/%): New rule, to get + morecore.c. + + * malloc/malloc.h (size_t, ptrdiff_t): Never define these as macros. + (__malloc_size_t): Define this instead. + Change all uses of size_t to __malloc_size_t. + * malloc/valloc.c: Replace all uses of size_t with __malloc_size_t. + * malloc/memalign.c: Likewise. + * malloc/mcheck.c: Likewise. + * malloc/mtrace.c: Likewise. + * malloc/malloc.c: Likewise. + * malloc/free.c: Likewise. + * malloc/realloc.c: Likewise. + * malloc/calloc.c: Likewise. + + * MakeTAGS (TAGS): Define first so as to be default goal. + (sysdep_dirs): Set this by running find, if it is not already set. + (all-dirs): Include that value. + (all-dist): Filter output of cat, not args to it. + * Makerules (TAGS): Depend on distinfo, not distfile. + + * resolv/getnetnamadr.c (getnetbyname): Arg is always const, + regardless of [sun]. + +Sun Sep 4 00:04:55 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.8. + + * Makerules (distinfo-vars): Double $s in final emitted sources defn. + + * inet/Makefile (headers): Add netdb.h. + * resolv/Makefile (headers): Remove netdb.h. + * resolv/netdb.h: Moved to inet. + * inet/netdb.h: Incorporated from BSD 4.4-Lite. + Add back h_errno declaration. + + * hurd/Makefile (faultexc.c): Change this to a pattern rule to + build both faultexc.[ch]. + (hurdfault.o): Depend on faultexc.h and faultexc.c to get them built. + + * sysdeps/mach/hurd/i386/trampoline.c + (_hurdsig_rcv_interrupted_p): Make PC volatile. + (_hurd_setup_sighandler): Cast SS->context to int before comparing to + _hurdsig_fault_sigcode. + + * sysdeps/mach/thread_state.h (MACHINE_THREAD_STATE_SET_{SP,PC}): + Cast args to unsigned long int. + + * sysdeps/mach/hurd/i386/trampoline.c: Use _hurdsig_catch_fault. + + * Make-dist (subdirs): Use sed to remove comments from Subdirs files. + * MakeTAGS (subdirs): Likewise. + + * sysdeps/mach/i386/thread_state.h: Include + <mach/i386/thread_status.h> first thing. + + * hurd/Makefile (sig): Add faultexc. + ($(objpfx)faultexc.c): New target. + (generated): Append faultexc.c. + + * hurd/Makefile (sig): Add hurdfault; remove init-fault. + (distribute): Add hurdfault.h. + * hurd/hurdfault.h: New file. + * hurd/hurdfault.c: New file. + * hurd/hurdsig.c (interrupted_reply_port_location): Use + _hurdsig_catch_fault and _hurdsig_end_catch_fault. + (_hurdsig_getenv): Likewise. + * sysdeps/mach/hurd/i386/trampoline.c: Likewise. + + * hurd/catch-exc.c: Return EPERM if TASK is not right. + + * hurd/hurdsig.c (_hurd_sigthread_fault_env): Variable moved to + hurdfault.c. + (_hurdsig_fault_init): Function moved to hurdfault.c. + +Sat Sep 3 12:22:53 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/thread_state.h (MACHINE_THREAD_STATE_SET_PC, + MACHINE_THREAD_STATE_SET_SP): New macros. + * mach/setup-thread.c: Use MACHINE_THREAD_STATE_SET_PC. + * sysdeps/mach/hurd/__fork.c: Likewise. + + * string/test-ffs.c (main: try): Actually call ffs in the test. + +Fri Sep 2 21:20:17 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/__sigret.c: Restore FPU state. Code from + kkojima. + + * sysdeps/mach/hurd/__mknod.c: Fixed copying of the translator + name into buffer with major and minor numbers, and setting of LEN. + + * sysdeps/unix/configure (unix_syscall): In sed cmd, do = first to + avoid clobbering produced assignments. + +Thu Sep 1 03:25:17 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.7. + + * sysdeps/mach/hurd/connect.c (connect): Fix accidental renaming + of sun_path to sun_file_name. + + * bare/Makefile (routines, elided-routines): Set these both to + $(bare-routines). + (distribute): Don't set this. + + * Makerules (distinfo-vars): Fix cmd to echo `sources' defn. + + * sysdeps/unix/configure: Handle dirs other than common. Check + for [gs]etdomainname. + * misc/Makefile (routines): Add getdomain, setdomain. + * sysdeps/unix/bsd/bsd4.4/setdomain.S: New file. + * sysdeps/unix/bsd/bsd4.4/getdomain.S: New file. + * sysdeps/stub/setdomain.c: New file. + * sysdeps/stub/getdomain.c: New file. + +Wed Aug 31 01:15:26 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdsig.c (_hurd_internal_post_signal: sigwakeup): Take no + args; use parent SS variable. Changed all calls. + + * hurd/hurd/signal.h (struct hurd_sigstate): Make `suspended' a + port; remove `arrived'. + * sysdeps/mach/hurd/sigsuspend.c (sigsuspend): Rewritten to set + SS->suspended port and wait for msg on it. Check for and deliver + pending signals properly. + * hurd/hurdsig.c (_hurd_internal_post_signal: sigwakeup): If + SS->suspended is set, send an empty message on it and clear it. + + * math/test-math.c (print_trig_stuff): New function, tests many + math functions. + (main): Call it at end. + + * string/Makefile (tests): Added test-ffs. + * string/test-ffs.c: New file. + +Tue Aug 30 20:33:49 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * misc/fstab.c (error): Return void. + (fstabscan): Return int. + + * sysdeps/i386/ffs.c: Use & modifier in constraint for CNT. + + * misc/fstab.c (EFTYPE): If not defined by errno.h, define this to + EINVAL. + (fstabscan): Return void. + +Tue Aug 30 11:00:01 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__access.c (__access): Use a send right, + not a send-once right, in the new auth protocol. + * hurd/__setauth.c (_hurd_setauth): Likewise. + * hurd/hurdsig.c (reauth_proc): Likewise. + * hurd/dtable.c (reauth_dtable): Likewise. + * hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Likewise. + +Tue Aug 30 03:59:38 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * socket/sys/socket.h (__SOCKADDR_ARG) [GCC>=2.6]: Use a typedef + with the transparent_union attribute. + + * sysdeps/mach/hurd/__access.c: Use new authentication protocol: + for each port, create a fresh receive right and pass send-once + rights in the auth calls, then destroy the port. + + * sysdeps/mach/mips/syscall.S: New file. + + * stdio/Makefile (mpn-headers, mpn-sysdep): Change asm.h to + asm-syntax.h. + + * misc/Makefile (headers): Added fstab.h. + (routines): Added fstab. + * misc/fstab.c: New file. + * misc/fstab.h: New file. + + * hurd/Makefile (routines): Changed hurdpath to hurdlookup. + * hurd/hurdpath.c: Renamed to hurd/hurdlookup.c. + * hurd/hurdlookup.c: Globally replace `pathtrans' with `lookup' and + `path' with `file_name'. + (__hurd_file_name_split): Don't bother skipping leading slashes. + * hurd/hurd.h: Rename likewise in decls. + * hurd/fchroot.c: Globally replace `pathtrans' with `lookup' and + `path' with `file_name'. + * hurd/hurdsig.c: Likewise. + * hurd/hurdsock.c: Likewise. + * hurd/hurdsyms.c: Likewise. + * hurd/invoke-trans.c: Likewise. + * sysdeps/mach/hurd/__access.c: Likewise. + * sysdeps/mach/hurd/__chmod.c: Likewise. + * sysdeps/mach/hurd/__chown.c: Likewise. + * sysdeps/mach/hurd/__execve.c: Likewise. + * sysdeps/mach/hurd/__link.c: Likewise. + * sysdeps/mach/hurd/__lstat.c: Likewise. + * sysdeps/mach/hurd/__mkdir.c: Likewise. + * sysdeps/mach/hurd/__mknod.c: Likewise. + * sysdeps/mach/hurd/__open.c: Likewise. + * sysdeps/mach/hurd/__rmdir.c: Likewise. + * sysdeps/mach/hurd/__readlink.c: Likewise. + * sysdeps/mach/hurd/__stat.c: Likewise. + * sysdeps/mach/hurd/__symlink.c: Likewise. + * sysdeps/mach/hurd/__unlink.c: Likewise. + * sysdeps/mach/hurd/__utimes.c: Likewise. + * sysdeps/mach/hurd/bind.c: Likewise. + * sysdeps/mach/hurd/chflags.c: Likewise. + * sysdeps/mach/hurd/connect.c: Likewise. + * sysdeps/mach/hurd/fchdir.c: Likewise. + * sysdeps/mach/hurd/opendir.c: Likewise. + * sysdeps/mach/hurd/sysd-stdio.c: Likewise. + * sysdeps/mach/hurd/truncate.c: Likewise. + * sysdeps/mach/hurd/rename.c: Likewise. + * sysdeps/mach/hurd/getcwd.c: Likewise. + * sysdeps/mach/hurd/chroot.c: Likewise. + * sysdeps/mach/hurd/__chdir.c: Likewise. + + * hurd/__setauth.c (_hurd_setauth): Use new authentication + protocol: for each port, create a fresh receive right and pass + send-once rights in the auth calls, then destroy the port. + * hurd/hurdsig.c (reauth_proc): Likewise. + * hurd/dtable.c (reauth_dtable): Likewise. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): Don't handle + FS_RETRY_NONE (it's gone). Use new authentication protocol: + create a fresh receive right and pass send-once rights in the auth + calls, then destroy the port. + +Mon Aug 29 13:17:39 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__symlink.c (__symlink): Use new + file_set_translator protocol. + * sysdeps/mach/hurd/bind.c (bind): Likewise. + * sysdeps/mach/hurd/__mknod.c (__mknod): Likewise. + + * sysdeps/mach/hurd/__pipe.c (__pipe): Use PF_LOCAL instead + of AF_FILE. + +Fri Aug 26 01:21:09 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Makefile ($(objpfx)sysd-dirs): Use sed to remove # comments from + Subdirs files. + + Support for miscellaneous standalone boards (no OS), contributed + by Joel Sherrill (jsherril@redstone-emh2.army.mil), On-Line + Applications Research Corporation. + * sysdeps/standalone: New directory. + * sysdeps/standalone/standalone.h: New file. + * sysdeps/standalone/stdio_lim.h: New file. + * sysdeps/stub/strtsupp.c: New file. + * sysdeps/standalone/filedesc.h: New file. + * sysdeps/posix/{setenv,putenv}.c: Moved to sysdeps/generic. + * sysdeps/unix/getenv.c: Moved to sysdeps/generic. + * sysdeps/unix/morecore.c: Moved to sysdeps/generic. + * sysdeps/posix/sysd-stdio.c: Moved to sysdeps/generic. + * sysdeps/stub/errnos.h: Add ENFILE and EMFILE. + * sysdeps/stub/errlist.c (_sys_errlist): Likewise. + * sysdeps/stub/console.c: New file. + * sysdeps/standalone/__open.c: New file. + * sysdeps/standalone/__read.c: New file. + * sysdeps/standalone/__write.c: New file. + * sysdeps/standalone/__close.c: New file. + * sysdeps/stub/brdinit.c: New file. + * sysdeps/unix/__sbrk.c: Moved to sysdeps/generic. + * sysdeps/standalone/__brk.c: New file. + * sysdeps/standalone/Subdirs: New file + * bare/Makefile: New file (and new directory). + * sysdeps/i960/ffs.c: New file. + * sysdeps/i960/Implies: New file. + * configure.in (os=none): base_os=standalone + +Thu Aug 25 23:56:32 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/stub/__sigret.c: Arg is not const. + * signal/sigret.c: Likewise. + +Tue Aug 23 14:43:19 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * socket/sys/socket.h (PF_FILE, AF_FILE): Removed (use LOCAL instead). + (PF_XTP, PF_COIP, PF_CNT, PF_RTIP, PF_IPX, PF_SIP, PF_PIP): New + macros. + (PF_MAX): Increased to 26. + (pseudo_AF_XTP, AF_COIP, AF_CNT, pseudo_AF_RTIP, AF_IPX, AF_SIP, + pseudo_AF_PIP): New macros. + (MSG_EOR, MSG_TRUNC, MSG_CTRUNC, MSG_WAITALL, MSG_DONTWAIT, + SO_REUSEPORT): New enum constants. + + * hurd/hurdsig.c (_hurd_internal_post_signal): If not preempted, + set ACT before checking for SIGCONT. When continuing and + ACT==handle, don't resume SS->thread; record that it is suspended + and in handler-setup code, don't suspend it again. + + * sysdeps/mach/hurd/sys/param.h: Include <errno.h> (BSD does). + + * sysdeps/mach/hurd/__fork.c: When unchaining old sigstates, check + for SS being head of chain. + +Mon Aug 22 00:29:02 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * time/{asia,australasia,europe,northamerica}: New data from ADO. + + * hurd/hurdsig.c (abort_rpcs): After destroying MSGING_PORT, + change the return value register in STATE to EINTR. + * sysdeps/mach/mips/thread_state.h (SYSRETURN): New macro. + * sysdeps/mach/i386/thread_state.h (SYSRETURN): New macro. + + * hurd/hurdsig.c (default_sigaction): New function. + (_hurd_thread_sigstate): Use it to initialize SS->actions. + Initialize rest of new sigstate by hand, don't just bzero it. + + * hurd/hurdsig.c (_hurd_internal_post_signal): Initialize + THREAD_STATE.set to zero. + + * posix/execl.c: Use ARG instead of PATH in va_start. + + * sysdeps/mach/hurd/__fork.c: In child fork, unchain stale + structures from _hurd_sigstates first, and only free them after + other processing is complete. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): For malformed number + in magic "fd/N", return ENOENT instead of treating it as bogus + magic. + + * sysdeps/mach/hurd/__chdir.c: After __path_lookup on arg, use + __hurd_path_lookup of empty file name on resultant port to check + that it's a directory. + * sysdeps/mach/hurd/chroot.c: Likewise. + * sysdeps/mach/hurd/fchdir.c: Use __hurd_path_lookup of empty file + name on FD port to check that it's a directory and acquire a + reference at the same time. + * hurd/fchroot.c: Likewise. + + * hurd/hurdpid.c (init_pids): Add gratuitous self reference to + silence compiler. + + * hurd/hurdpath.c: Include <hurd/term.h> for cttyid opening rpc. + (__hurd_path_lookup_retry): Fixed typo. + + * sysdeps/mach/hurd/i386/__sigret.c: Push state onto the user's + stack, switch to it, pop and return. + + Major rewrite of Hurd signal delivery. + * hurd/hurd/signal.h (struct hurd_sigstate): New member `context'. + * sysdeps/mach/hurd/i386/trampoline.c: Include "thread_state.h" + instead of <mach/thread_status.h>. + (struct mach_msg_trap_args): New type. + (trampoline): Function removed. + (_hurd_setup_sighandler): Take struct hurd_sigstate * arg instead + of FLAGS and SIGALTSTACK args; take new flag arg RPC_WAIT; use + struct machine_thread_all_state * for STATE arg. New declared + labels `trampoline', `rpc_wait_trampoline' mark asm code at end of + function (after return). Add another struct sigcontext * to + STACKFRAME after the first one, for the arg to __sigreturn. If + SS->context is set, fill registers in SCP from that instead of + STATE, and reset SS->INTR_PORT from it. Use memcpy to copy from + STATE into SCP; the structures are congruent. If RPC_WAIT is set, + set up to use rpc_wait_trampoline and frob args to mach_msg_trap + syscall in progress so that it will retry the receive operation + (but not resend!). + {rpc_wait_trampoline, trampoline}: New trampoline code. + (_hurd_rcv_interrupted_p): New function. + * sysdeps/mach/hurd/mips/trampoline.c: Likewise. + * hurd/hurdsig.c (write_corefile): Take new arg SIGERROR. Use + _hurdsig_getenv instead of getenv. Use dir_mkfile to create an + unlinked node for the core file; then use dir_link to name it, + only if core_dump_task succeeded. + (post_reply): New function. + (abort_thread): New function. + (interrupted_reply_port_location): New function. + (interrupted_reply_port): Function removed (replaced by above). + (abort_all_rpcs): Take struct machine_thread_all_state * for STATE. + (abort_rpcs): Likewise. + Return int, nonzero iff interrupt_operation RPC was done. Take + args for reply port and its port type; call abort_thread instead + of doing thread_abort and thread_get_state. Call + _hurdsig_rcv_interrupted_p instead of _hurd_thread_state_msging_p. + Use __interrupt_operation mig stub instead of manual packing. If + we destroy the msging port, and it is the thread's mig reply port, + clear its reply port slot. Fix inverted SA_RESTART test. + (_hurd_internal_post_signal): Take new arg SIGERROR. + Remove `cont' from ACT enum; SIGCONT processing is independent of + handling. Removed local function `check_pending'; add `reply'. + Use mask macro STOPSIGS instead of alternation to check for stop + signals. Process SIGCONT and do continuation before examining the + handler. Use SS->pending_data instead of SS->sigcodes. When + dying, don't lock _hurd_siglock around __proc_dostop call. When + dying, reply immediately after stopping user threads. When + handling, notice return from abort_rpcs and pass it to + _hurd_setup_sighandler; also pass SS instead of its components. + Set SCP->sc_error from SIGERROR; clear SS->intr_port after saving + it in SCP->sc_intr_port. For pending checks, use macro PENDING + and goto pending if returns true. + (_S_sig_post): Eliminate unnecessary variable WIN; pass SIGERROR + value of zero to _hurd_internal_post_signal. + (_hurdsig_getenv): New function. + * sysdeps/mach/hurd/i386/__sigret.c (sp): New global register + variable. + (__sigreturn): Arg is not const. + After restoring SCP->sc_mask, check for pending signals (newly + unblocked); if any, set SS->context to SCP, clear SS->intr_port, + and send sig_post to the signal thread to deliver the pending + signals. Point SP directly at &SCP->sc_gs and used popa;iret to + restore. (This does not actually work; iret is unhelpful.) + * sysdeps/mach/hurd/mips/__sigret.c (__sigreturn): Arg is not + const. After restoring SCP->sc_mask, check for pending signals + (newly unblocked); if any, set SS->context to SCP, clear + SS->intr_port, and send sig_post to the signal thread to deliver + the pending signals. Don't write $1 value into the user stack. + Instead, write it into the word just past SCP->sc_pc; then point + $1 at SCP->sc_pc and use `op_sigreturn' pseudo-instruction to + restore the PC and $1 from that. + +Fri Aug 19 15:39:54 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * configure.in (machine): Grok i586 -> i386/i586. + * sysdeps/i386/pentium: Directory renamed to sysdeps/i386/i586. + + * hurd/hurd.h (_hurd_pids_changed_stamp, _hurd_pids_changed_sync): + New variables. + * hurd/hurdpid.c (_S_proc_newids): Last thing, increment + _hurd_pids_changed_stamp and broadcast on _hurd_pids_changed_sync. + * sysdeps/mach/hurd/__setpgrp.c: After proc_setpgrp succeeds and + PID is ourself, wait on _hurd_pids_changed_sync until + _hurd_pids_changed_stamp increases from the value before the RPC. + * sysdeps/mach/hurd/__setsid.c: After proc_setsid succeeds, wait + on _hurd_pids_changed_sync until _hurd_pids_changed_stamp + increases from the value before the RPC. + + * posix/sys/wait.h [GCC>=2.6] (__WAIT_STATUS): Define this with + typedef as a union with the new (GCC 2.6.1) `transparent_union' + attribute. + + * stdio/printf_fp.c (MPNSIZE): New macro, computed from DBL_MAX_EXP. + (MPN_VAR): Use that for size of bignums. + + * sysdeps/mach/hurd/__kill.c: For pgrp, ignore ESRCH error from + kill_pid of individual pids, unless from all of them. + * hurd/hurdkill.c (_hurd_sig_post): Likewise. + +Fri Aug 19 00:54:50 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * configure.in (INSTALL): Quote this shell goop from m4. + + * sysdeps/stub/start.c (errno, __environ): Define these variables. + + * sysdeps/stub/errnos.h (ENOMEM, EACCES): New macros. + * sysdeps/stub/errlist.c (_sys_errlist): Add strings for all + macros defined in stub/errnos.h. + (_sys_nerr): Use value computed from sizeof (_sys_errlist). + +Wed Aug 17 15:32:39 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/hurdmsg.c (_S_io_select_done): Take poly arg for notify + port arg. + + * mach/mach_init.h (vm_page_size): Remove macro defn. + + * hurd/Makefile (distribute): Added STATUS. + + * sysdeps/mach/thread_state.h: Include <string.h> and + <mach/mach_interface.h>. + + * sysdeps/mach/hurd/__select.c: Pass port-type arg to io_select. + + * sysdeps/mach/hurd/__fork.c: Include "hurdmalloc.h", so we use + the right `free'. + + * sysdeps/mach/hurd/__select.c (SELECT_DONE_MSGID): Correct value + to 23020. + (__select): Don't set PORT until just before sending io_select calls. + Pass proper send-size for io_select_done reply message. Clear the + reply port slot in io_select_done reply message header. + + * sysdeps/mach/hurd/__kill.c: Rename parameter to ARG_SIG, make + SIG a local variable initialized to that (this to work around a + GCC bug). + Initialize PIDS and NPIDS properly for proc_getpgrppids call. + + * signal/signal.h (__sigreturn, sigreturn): Arg is not const. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): For REAUTH or NORMAL + with empty retryname, treat like NONE (which is now obsolete) + after reauthentication. For magic "tty", use new + termctty_open_terminal RPC on cttyid port. + +Tue Aug 16 01:58:21 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/__kill.c (kill_pid): Make non-inline. Treat + null msgport like EPERM return from sig_post. + * hurd/hurdkill.c (_hurd_sig_post): Treat null msgport like EPERM. + + * sysdeps/mach/thread_state.h (machine_get_state, + machine_get_basic_state): Initialize count arg before calling + thread_get_state. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): Initialize ERR to zero. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): Grok magic "tty". + + * hurd/hurd/signal.h (struct hurd_sigstate): Replace `sigcodes' with + `pending_data'. + (_hurd_raise_signal, _hurd_setup_sighandler): Update prototypes. + (_hurd_thread_state_msging_p): Don't declare. + (_hurdsig_rcv_interrupted_p): Declare this instead. + (HURD_EINTR_RPC): Invert sense of restart test. + + * hurd/hurdrlimit.c (_hurd_rlimits): Add braces to initializer. + + * hurd/catch-exc.c: Unlock _hurd_siglock when done with it. Use + __spin_lock_locked on `held' member instead of __mutex_lock_locked. + + * sysdeps/mach/thread_state.h: New file. + * sysdeps/mach/i386/thread_state.h: Don't #include + <mach/thread_status.h>. Add #include_next <thread_state.h> at end. + * sysdeps/mach/mips/thread_state.h: Likewise. + + * sysdeps/mach/hurd/i386/sigcontext.h (struct sigcontext): Lay out + corresponding to i386_thread_state and i386_float_state. + * sysdeps/mach/hurd/mips/sigcontext.h (sc_mips_thread_state, + sc_mips_exc_state, sc_mips_float_state): New macros, marking + members that correspond to thread_state.h structs. + +Mon Aug 15 17:21:20 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Rules [cross-compiling=yes] (tests): Depend on the binaries, not + the output files. + + * Makerules: Replace uses of HOST_CC with BUILD_CC and + native-CFLAGS with BUILD_CFLAGS. + + * sysdeps/unix/Makefile (mk-local_lim, make-ioctls): Replace uses + of CC with BUILD_CC and native-CFLAGS with BUILD_CFLAGS. + * sysdeps/unix/sysv/sysv4/solaris2/Makefile: Replace uses of + HOST_CC with BUILD_CC and native-CFLAGS with BUILD_CFLAGS. + * sysdeps/posix/Makefile: Likewise. + + * Makeconfig (+cc_version): Variable and associated code removed. + (HOST_CC): Use BUILD_CC instead; all uses changed. + (cross-compiling): Set to no if not the case. + + * sysdeps/m68k/fpu/__math.h: Replace all uses of __const with + __CONSTVALUE. + + * Makerules (distinfo-vars): Remove $@.new first thing. Write + elided-routines instead of sysdep_routines. After writing + variables, append to sources from $(elided-routines). + * sysdeps/vax/Makefile (elided-routines): New variable (append to + it). + (aux, routines): Don't set these. + (sysdep_routines): Append things here instead. + * sysdeps/generic/Makefile (elided-routines): New variable (append + to it). + (aux): Don't set this. + * sysdeps/generic/Makefile (routines): Don't set this. + (sysdep_routines): Append exp__E and log__L here instead. + + * time/test_time.c (main): Set TBUF.tm_isdst to -1 before calling + mktime. + + * stdlib/stdlib.h (atof, atoi, atol, random, srandom, setstate, + initstate, mblen): Never define as macros. + [__OPTIMZE__ && __GNUC__ >= 2]: Define those functions as extern + inlines. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): For magic "fd/%u", + lose on random chars after number; for / after number, retry + remainder properly. + + * hurd/hurdpath.c (pathtrans_error): New function; filters errors + from dir_pathtrans: EOPNOTSUPP and MIG_BAD_ID become ENOTDIR. + (__hurd_path_lookup, __hurd_path_lookup_retry): Call it. + +Thu Aug 11 11:59:33 1994 Noel Cragg (noel@churchy.gnu.ai.mit.edu) + + * time/mktime.c (_mktime_internal): Add code to normalize value of + TM_ISDST to -1, 0, or 1 so code doesn't loop forever. + +Thu Aug 11 02:26:37 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * resolv/Makefile (subdir): Set to resolv, not res. + + * sysdeps/mach/hurd/sysd-stdio.c (fd_fail): Pass ERR to + _hurd_raise_signal. + + * sysdeps/mach/i386/thread_state.h (struct machine_thread_all_state): + Add new member `fpu'. + +Wed Aug 10 23:39:49 1994 Karl Heuer <kwzh@hal.gnu.ai.mit.edu> + + * malloc/mcheck.c (mcheck): Remove obsolete extern declaration. + + * malloc/mcheck.c (flood): Add an arg. + (freehook, mallochook, reallochook): Use different flood bytes to + distinguish freed space from uninitialized allocated space. + + * malloc/mtrace.c (mtrace): Guard against being called twice. + (muntrace): New function, to turn off tracing. + * malloc/malloc.h: Declare it. + +Wed Aug 10 02:47:24 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/sigcontext.h (struct sigcontext): Renamed + member `sc_err' to `sc_error'. + + * hurd/hurd-raise.c: Take new arg SIGERROR. Set + SS->pending_data[SIGNO] from SIGCODE and SIGERROR instead of + setting SS->sigcodes[SIGNO]. + + * Makeconfig (+includes): Use text manipulation to avoid + conditional for $(..). Append $(last-includes). + * sysdeps/mach/hurd/Makefile (last-includes): Append + -I.../libthreads to this. + (includes): Not to this. + + * hurd/hurd/fd.h (_hurd_fd_error): Pass ERR to _hurd_raise_signal. + + * stdlib/stdlib.h [__OPTIMIZE__] (cfree, rand, srand, random, + srandom, initstate, setstate): Macros removed. + + * malloc/mcheck.c (reallochook): Fixed typo. + (mabort) [! __GNU_LIBRARY__]: Use fprintf and abort instead of + __libc_fatal. + + * hurd/Makefile (sig): Remove msging-p; that function will go in + trampoline.c. + * sysdeps/stub/msging-p.c: File removed. + * sysdeps/mach/hurd/mips/msging-p.c: File removed. + * sysdeps/mach/hurd/i386/msging-p.c: File removed. + +Tue Aug 9 19:20:29 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * hurd/catch-exc.c: Get error code from _hurd_exception2signal and + pass it to _hurd_internal_post_signal. Search for SS manually + rather than using _hurd_thread_sigstate, to avoid locks. + + * sysdeps/mach/hurd/mips/msging-p.c: Fetch port argument from + register $8 (t0) instead of stack. Change type of STATE arg to + `struct machine_thread_all_state *'. + + * inet/inet_netof.c: Incorporated from BSD 4.4-Lite. + * inet/inet_net.c: Incorporated from BSD 4.4-Lite. + +Tue Aug 9 18:28:40 1994 Karl Heuer <kwzh@hal.gnu.ai.mit.edu> + + * malloc/mtrace.c (tr_mallochook, tr_reallochook): Don't assume + %lx format matches size_t arg. + * malloc/mtrace.c: Enable file- and line-number tracing. + * malloc/mtrace.awk: Postprocess that trace information. + + * malloc/mcheck.c (flood): New function. + (freehook, mallochook, reallochook): Initialize new space and + freed space to non-zero garbage, to help find code that makes + unwarranted assumptions. + +Mon Aug 8 01:20:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/exc2signal.c (_hurd_exception2signal): Take + new arg `int *error'; set it. + * sysdeps/mach/hurd/i386/exc2signal.c: Likewise. + * sysdeps/stub/exc2signal.c: Likewise. + * hurd/hurd/signal.h (_hurd_exception2signal): Take new arg + `int *error'. + (_hurd_internal_post_signal): Take new arg `int error'. + + * res: Directory renamed to resolv. + * sysdeps/unix/inet/Subdirs: Change res to resolv. + + * Version 1.08.6. + + * sysdeps/sparc/divrem.m4 (DEVELOP_QUOTIENT_BITS): Use ** instead of + ^ for exponentiation. Pinard says it is more portable. + + * sysdeps/mach/hurd/mips/sigcontext.h (struct sigcontext): Added + member `sc_err'. + * sysdeps/mach/hurd/i386/sigcontext.h (struct sigcontext): Move + sc_err to front machine-independent section; change its comment. + + * sysdeps/stub/thread_state.h (struct machine_thread_all_state): New + type. + * sysdeps/mach/i386/thread_state.h: Likewise. + * sysdeps/mach/mips/thread_state.h: Likewise. + + * sysdeps/mach/i386/Implies: File removed; it was superfluous. + + * sysdeps/sparc/divrem.m4 (Lgot_result): Add more quotes in ifelse. + + * configure.in (fpu_dirs): Fixed typo. + +Sun Aug 7 01:13:04 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * inet/inet_lnaof.c: Incorporated from BSD 4.4-Lite. + * inet/inet_mkadr.c: Incorporated from BSD 4.4-Lite. + * inet/inet_addr.c: Incorporated from BSD 4.4-Lite. + * res/Makefile (headers): Use only arpa/nameser.h, not arpa/*.h. + * res/arpa/inet.h: Moved to inet/arpa/inet.h. + * inet/arpa/inet.h: Incorporated from BSD 4.4-Lite. + + * misc/init-misc.c: New file. + * misc/Makefile (aux): Added init-misc. + + * Makeconfig (localtime-file): Use $(sysconfdir) instead of + $(etcdir). + + * Makerules (install-bin-nosubdir): Use $(install-bin) instead of + $(install). + (install-sbin-nosubdir): New target. + (install-no-libc.a-nosubdir): Depend on that. + + * configure.in ($nfp check): Iterate through $mach and use all + fpu/ dirs that exist. + +Wed Aug 3 02:46:03 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/sigcontext.h: Rearranged structure so + machine-dependent portion is laid out like `struct mips_thread_state; + struct mips_exc_state; struct mips_float_state;'. + + * Version 1.08.5. + + * sysdeps/mach/hurd/mips/__sigret.c: Compare *reply_port to + MACH_PORT_NULL, not implicit zero. + (restore_gpr): Use N-1 as subscript into sc_gpr (sc_gpr[0] => $1). + Before general regs, restore from sc_mdlo and sc_mdhi. Don't + treat sp, fp specially; use restore_gpr for them too. For final + return, store user $1 value beyond top of user stack ahead of + time; then use $1 to hold the user PC, and restore it from the + stack in the delay slot. + +Tue Aug 2 21:03:51 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/trampoline.c (_hurd_setup_sighandler): + Copy TS to SCP all at once. + * sysdeps/mach/hurd/mips/sigcontext.h (struct sigcontext): sc_gpr + has 31 elts; sc_gpr, sc_pc, sc_mdlo, sc_mdhi are arranged in that + order to mimic struct mips_thread_state. + + * Make-dist (all-headers): Instead of removing rpcsvc/%, use + $(wildcard) to remove all headers that don't exist at top level, + but preserve top-level $(headers). + + * Make-dist (sysdep_dirs): Avoid directories called RCS. + (%/configure): Pass -f to mv. + + * sysdeps/mips/setjmp.S [__sgi__]: Use `fp' instead of `$fp'. + +Mon Aug 1 20:12:23 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/mach/hurd/mips/sigcontext.h (struct sigcontext): Add + members sc_mdlo, sc_mdhi. + * sysdeps/mach/hurd/mips/trampoline.c (_hurd_setup_sighandler): + Save mdlo and mdhi. + +Sun Jul 31 14:21:16 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * time/mktime.c: Remove errant comment end sequence. + + * termios/sys/ttydefaults.h: Incorporated from BSD 4.4-Lite. + * sysdeps/vax/DEFS.h: Incorporated from BSD 4.4-Lite. + * sysdeps/unix/bsd/sys/reboot.h: Incorporated from BSD 4.4-Lite. + * sysdeps/unix/bsd/bsd4.4/errnos.h: Updated from 4.4-Lite sys/errno.h. + [__USE_BSD] (EAUTH, ENEEDAUTH, ELAST): New macros. + * sysdeps/ieee754/support.c: Incorporated from BSD 4.4-Lite. + * sysdeps/ieee754/cbrt.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/trig.h: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/tanh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/tan.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/sinh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/sincos.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/pow.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/mathimpl.h: Incorporated from BSD 4.4-Lite. + Add back __izing #define's, except for exp__E and log__L, which + have been renamed with __s in 4.4-Lite. + * sysdeps/generic/log__L.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/log1p.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/log.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/fmod.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/exp__E.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/exp.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/cosh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/atanh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/atan2.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/asinh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/asincos.c: Incorporated from BSD 4.4-Lite. + * misc/getusersh.c: Incorporated from BSD 4.4-Lite. + (initshells): Reapply fix of 16 Nov 1992. + * sysdeps/generic/acosh.c: Incorporated from BSD 4.4-Lite. + * sysdeps/generic/__expm1.c: Incorporated from BSD 4.4-Lite. + * misc/ttyslot.c: Incorporated from BSD 4.4-Lite. + * misc/ttyent.h: Incorporated from BSD 4.4-Lite. + * misc/syslog.c: Incorporated from BSD 4.4-Lite. + * misc/paths.h: Incorporated from BSD 4.4-Lite. + * misc/getttyent.c: Incorporated from BSD 4.4-Lite. + * misc/sys/syslog.h: Incorporated from BSD 4.4-Lite. + Don't include <machine/ansi>; define _BSD_VA_LIST_ to __gnuc_va_list. + * inet/rexec.c: Incorporated from BSD 4.4-Lite. + * inet/rcmd.c: Incorporated from BSD 4.4-Lite. + (rcmd): Reapply select max fd fix of 3 Jun 1994. + * inet/pathnames.h: File removed. + * inet/inet_ntoa.c: Incorporated from BSD 4.4-Lite. + * inet/getsrvbypt.c: Incorporated from BSD 4.4-Lite. + * inet/getsrvbynm.c: Incorporated from BSD 4.4-Lite. + * inet/getservent.c: Incorporated from BSD 4.4-Lite. + * inet/getprtname.c: Incorporated from BSD 4.4-Lite. + * inet/getprtent.c: Incorporated from BSD 4.4-Lite. + * inet/getproto.c: Incorporated from BSD 4.4-Lite. + * inet/protocols/timed.h: Incorporated from BSD 4.4-Lite. + * inet/protocols/talkd.h: Incorporated from BSD 4.4-Lite. + * inet/protocols/rwhod.h: Incorporated from BSD 4.4-Lite. + * inet/protocols/routed.h: Incorporated from BSD 4.4-Lite. + * inet/arpa/tftp.h: Incorporated from BSD 4.4-Lite. + * inet/arpa/telnet.h: Incorporated from BSD 4.4-Lite. + * inet/arpa/ftp.h: Incorporated from BSD 4.4-Lite. + +Fri Jul 29 01:50:37 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * Version 1.08.4. + + * res/Makefile (routines): Add missing backslash. + + * sysdeps/mach/hurd/mips/__sigret.c: Rename variable AT (which is + the register's name) to SCPREG. Fix some SCP references in + register loads to use SCPREG instead. Load SCPREG->sc_pc into $24 + and jump to it, restoring $at in the delay slot. This still + leaves $24 clobbered. + + * sysdeps/mach/hurd/mips/sigcontext.h: Use `unsigned int' + consistently for port names. + + * sysdeps/mach/hurd/mips/trampoline.c: Don't set up args on the + stack; pass them in registers. + + * Makefile (%/configure, sysd-dirs, munch-init.c): Pass -f to mv. + + * misc/sys/cdefs.h (__NORETURN, __CONSTVALUE): Use the + __attribute__ defn for GCC>=2.7, not >=2.6. Use the keyword defn + only for GCC<2.5. Use __volatile__ and __const__ instead of + noreturn and const for namespace safety. + + * sysdeps/mach/hurd/__readlink.c: If BUF is null, return the size + of buffer required. + +Thu Jul 28 17:17:11 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * res/netdb.h: Declare h_errno. + + * res: New directory, for all code incoporated from BIND. + * inet/arpa/inet.h, inet/arpa/resolv.h: Moved to res/arpa. + * inet/sys/bitypes.h: Moved to res/sys. + * inet/gethstnamad.c: Renamed to res/gethnamaddr.c. + * inet/getnetbyad.c: Renamed to res/getnetbyaddr.c. + * inet/getnetbynm.c: Renamed to res/getnetbyname.c. + * inet/res_mkqry.c: Renamed to res/res_mkquery.c. + * inet/Makefile (headers): Removed netdb.h, resolv.h, and + sys/bitypes.h. + (routines): Removed res_comp res_debug res_init res_mkqry res_query + res_send gethstnmad sethostent. + (aux, distribute): Variables removed. + * res/getnetnamadr.c, res/nsap_addr.c: New files. + * All .c and .h in res/ updated from BIND-4.9.3-BETA9. + * res/Makefile: New file. + * sysdeps/unix/inet/Subdirs: Added res. + + * Makerules: Replace all uses of `.dep' suffix with `.d' suffix. + (+make-deps): Replace `.dtm' suffix with `.T' suffix. + +Wed Jul 27 06:13:30 1994 Noel Cragg (noel@churchy.gnu.ai.mit.edu) + + * time/mktime.c: Add code to support tm_isdst flag in struct tm. + Fixed bug with handling of DST sections. + +Mon Jul 25 17:17:28 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/sparc/divrem.m4 (Lgot_result) [S=true]: Only test SIGN + and negate for [OP=div]. + + * socket/sys/socket.h (__SOCKADDR_ARG): New macro; for GCC 2.6 and + later, a funky union similar to __WAIT_STATUS in <sys/wait.h>. + (bind, getsockname, connect, getpeername, sendto, recvfrom, + accept): Use __SOCKADDR_ARG in place of `struct sockaddr *' in + declarations. + + * posix/glob/configure.bat: New file. + * posix/Makefile (glob.tar): Add glob/configure.bat. + + * sysdeps/unix/opendir.c: Fail with ENOENT when passed "". + Check STATBUF and fail with ENOTDIR if it's not a directory. + +Mon Jul 25 15:44:18 1994 Noel Cragg (noel@churchy.gnu.ai.mit.edu) + + * time/mktime.c: Fix range-checking bug in NORMALIZE macro. + +Fri Jul 22 02:42:44 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * sysdeps/unix/readdir.c: Search for NUL character to limit + d_namlen. Some systems return very bogus values. + + * sysdeps/unix/sysv/sysv4/i386/sysdep.h (PSEUDO): Remove ret at end. + + * mach/Makefile (mach-shortcuts): Filter out device_writev_request. + + * limits.h (_LIBC_LIMITS_H_): Don't define if already defined. + [__GNUC__ < 2]: Only protect this section from multiple inclusion. + + * sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): + Declare SIGSP volatile. + + * hurd/hurdinit.c (_hurd_setproc): Fixed arg in + _hurd_pgrp_changed_hook decl. + + * hurd/hurd/signal.h (_hurd_self_sigstate_unlocked): New function. + (HURD_EINTR_RPC): Use it instead of _hurd_self_sigstate followed by + __mutex_unlock; this thread might already hold the lock. + +Wed Jul 20 18:53:54 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * hurd/fd-read.c (_hurd_fd_read): Test for EBACKGROUND in + do loop was reversed. + + * hurd/hurdpath.c (__hurd_path_lookup): Skip over initial slashes + before calling __dir_pathtrans. + +Tue Jul 19 15:28:39 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/Makefile (user-interfaces): Add mach/mach4. + (mach-shortcuts): Match all syscall_% again; the missing ones are in + mach4.defs. + + * mach/Machrules (%.ir): Match SimpleRoutine as well as Routine + comments. + + * sysdeps/mach/hurd/Makefile ($(hurd)/errlist.c): Use -f flag to mv. + +Sat Jul 16 00:42:30 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules [install]: Rewrite this rule to use install-bin. + [install-sbin]: New rule parallel to that one, installs in $(sbindir). + + * time/Makefile (install-sbin): Set this instead of install. + * sunrpc/Makefile (install-others): Use $(sysconfdir)/rpc instead + of $(etcdir)/rpc. + (install-bin): Set this instead of install; set it to just rpocgen. + (install-sbin): Put rpcinfo and portmap here instead. + ($(sysconfdir)/rpc): Rule renamed from $(etcdir)/rpc. + (defines): Rename it in _PATH_RPC defn here too. + + * posix/Makefile (install-bin): Set this instead of install. + + * Makeconfig (datadir): Default to $(prefix)/share, not $(prefix)/lib. + (sbindir): New variable. + (sysconfdir): Variable renamed from etcdir. + + * sysdeps/unix/bsd/sun/signum.h: New file; no SIGINFO, SIGLOST is 29. + + * sysdeps/unix/sysv/sco3.2.4/uname.S: New file from Scott Bartram. + + * sysdeps/unix/sysv/sco3.2.4/__getgrps.c: Include alloca.h. + + * configure.in (INSTALL): If it is $srcdir/install.sh after + AC_PROG_INSTALL, reset it to '$(..)./install.sh'. + + * sysdeps/mach/hurd/__ioctl.c (io2mach_type): Move macro defn before + first use. + (__ioctl): Fix swapped args to __sigismember; remove unused variable. + + * sysdeps/mach/hurd/send.c: Fix portsPoly arg to __socket_send. + * sysdeps/mach/hurd/sendto.c: Likewise. + + * sysdeps/mach/hurd/recv.c: Pass &BUFP, not BUFP. + * sysdeps/mach/hurd/recvfrom.c: Likewise. + + * sysdeps/mach/hurd/connect.c: Include <hurd/ifsock.h>. + + * sysdeps/mips/dec/bytesex.h: New file. + * sysdeps/mips/p40/bytesex.h: New file. + +Fri Jul 15 23:12:06 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/sys/types.h (u_quad, quad): Renamed to &_t. + * posix/gnu/types.h [__GNUC__] (__u_quad_t, __quad_t, __qaddr_t): + New typedefs, using long long int and derivatives. + [! __GNUC__] (__u_quad, __quad): Renamed to &_t. + (__fsid_t): Make this always be __u_quad_t. + + * time/sys/time.h (struct timespec): New type. + (TIMEVAL_TO_TIMEPSEC, TIMESPEC_TO_TIMEVAL): New macros. + +Thu Jul 14 15:43:39 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/sysinfo.S: New file. + * sysdeps/unix/sysv/sysv4/Dist: Add sysinfo.S. + * sysdeps/unix/sysv/sysv4/Makefile: Add sysinfo to sysdep_routines + if we're inside misc. + * sysdeps/unix/sysv/sysv4/sethostnam.c: New file. + * sysdeps/unix/sysv/sysv4/__gethstnm.c: New file. + + * sysdeps/unix/sysv/sysv4/solaris2/fsync.S: New file. + +Tue Jul 12 00:57:08 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/Makefile (mach-shortcuts): Only match known Mach + subsystems: vm, task, mach_port, and thread. + +Mon Jul 11 20:18:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/intr-rpc.defs, hurd/intr-rpc.awk: New files. + * hurd/Makefile (user-MIGFLAGS): Add -imacros intr-rpc.defs. + (transform-user-stub): New canned sequence. + (transform-user-stub-output): New variable. + Make the .ustamp files depend on intr-rpc.awk. + + * mach/Machrules (%.ir): Cull the RPC names from the preceding + comment rather than the definition, so we don't see any userprefix. + (transform-user-stub-output): New variable. + (%.ustamp: %.defs): Invoke $(transform-user-stub) inside for loop. + Use $(transform-user-stub-output) in place of `tmp' in arg to + move-if-change. + + * mach/Makefile [! mach-shortcuts] (user-interfaces): Also filter + out device/device_request. + +Mon Jul 11 17:50:14 1994 Brendan Kehoe (brendan@mole.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sysv4/Makefile: Put the sys-sig.S stuff in + here, rather than in .../sysv4/solaris2/sparc/Makefile. + * sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile: Removed the + sys-sig.S part. + +Sun Jul 10 19:04:24 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/bind.c: Call __hurd_invoke_translator. + + * hurd/hurd.h (__hurd_invoke_translator, hurd_invoke_translator): + Declare them. + * hurd/Makefile (routines): Add invoke-trans. + * hurd/invoke-trans.c (__hurd_invoke_translator): New file. + * hurd/hurdsyms.c (hurd_invoke_translator): New alias. + + * hurd/hurdpath.c (__hurd_path_lookup_retry): New function. + * hurd/hurdsyms.c (hurd_path_lookup_retry: New alias. + * hurd/hurd.h (__hurd_path_lookup_retry, hurd_path_lookup_retry): + Declare them. + + * hurd/hurd/fd.h (_hurd_fd_error_signal): Return SIGLOST for + MIG_SERVER_DIED. + + * time/strftime.c: Make %j value 1-origin instead of 0-origin. + +Sat Jul 9 02:31:23 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * gnu-stabs.h (__SYMBOL_PREFIX): New macro, based on NO_UNDERSCORES. + Use it in all macros instead of explicit leading underscores. + Removed all [! __STDC__] definitions. + + * sysdeps/mach/hurd/mips/trampoline.c: New file. + * sysdeps/mach/hurd/mips/sigcontext.h: New file. + * sysdeps/mach/hurd/mips/longjmp-ts.c: New file. + * sysdeps/mach/hurd/mips/msging-p.c: New file. + * sysdeps/mach/hurd/mips/longjmp-ctx.c: New file. + * sysdeps/mach/hurd/mips/init-fault.c: New file. + * hurd/mach/hurd/mips/__sigret.c: New file. + * sysdeps/mach/hurd/mips/exc2signal.c: New file. + * sysdeps/mach/mips/thread_state.h: New file. + * sysdeps/mach/mips/machine-sp.h: New file. + * sysdeps/mach/mips/machine-lock.h: New file. + * sysdeps/mach/mips/sysdep.h: New file. + + * mach/Makefile (mach-syscalls.mk): Snarf 3rd arg from kernel_trap. + ($(mach-syscalls:%=__%.S): Emit kernel_trap instead of SYSCALL_TRAP. + * mach/syscalls.awk: Print nargs-$1 = $3 for each line. + * sysdeps/mach/sysdep.h: Include <mach/machine/syscall_sw.h>. + * sysdeps/mach/i386/sysdep.h (ENTRY, SYSCALL_TRAP): Macros removed. + + * sysdeps/mach/i386/machine-lock.h: Use __volatile in place of + volatile to work with -traditional. + +Fri Jul 8 21:06:43 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdsig.c (_hurd_internal_post_signal): For stop signals, + clear pending SIGCONT no matter what action we choose. + Add new value `cont' to ACT enum; use it for default SIGCONT action. + (_hurd_internal_post_signal: sigwakeup): New local inline. + +Fri Jul 8 20:26:49 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile (sysdep-CFLAGS): Set + this to include the -mhard-quad-float option. + + * sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S: New file. + * sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile: New file. + * sysdeps/unix/sysv/sysv4/solaris2/sparc/Dist: New file. + +Fri Jul 8 13:54:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdpath.c (__hurd_path_lookup): Don't treat leading / + specially for FS_RETRY_NORMAL. Handle FS_RETRY_MAGICAL; leading / + here means use crdir. In that case, deallocate *RESULT if nonnull. + + * sysdeps/unix/sysv/sysv4/i386/sysdep.h: Don't define _ERRNO_H if + already defined. + + * posix/gnu/types.h (__ino_t): Make this unsigned int instead of + unsigned long int (matters for Alpha). + + * Makeconfig (+gccopt): Variable removed. + (+cflags): Don't use it. + (CPPFLAGS): Append $(sysdep-CPPFLAGS). + (CFLAGS): Append $(sysdep-CFLAGS). + + * sysdeps/mach/hurd/__ioctl.c: In MSGID calculation, skip blocks + of 100 for request commands >= 100, to allow for the reply msgids. + +Thu Jul 7 19:07:00 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/bsd/osf1/dirstream.h (DIR): Make __allocation + member be int, not size_t (which is a long). + +Thu Jul 7 15:21:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/__fopenport.c (readio, writeio, seekio, closeio): New + functions. + (funcsio): New const variable. + (__fopenport): Make the new stream use that for its io functions, and + the default room functions, and set its seen flag. + +Tue Jul 5 11:32:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurd/signal.h (struct hurd_sigstate): Removed `intr_restart'. + (HURD_EINTR_RPC): Uncommented. Declare label + `__do_call' so it has block instead of function scope. Don't use + SS->intr_restart; instead SS->intr_port being reset to + MACH_PORT_NULL tells us to restart the call. + + * sysdeps/mach/hurd/__ioctl.c: Enable use of HURD_EINTR_RPC. + Do ctty magic and check for EBACKGROUND to generate SIGTTOU. + + * mach/devstream.c (dealloc_ref): New function. + (mach_open_devstream): Add a user reference to DEV, and set + STREAM's close fn to dealloc_ref, which will release the reference. + + * hurd/fd-read.c (_hurd_fd_read): Enabled and rewrote SIGTTIN code. + * hurd/fd-write.c (_hurd_fd_write): Enabled and rewrote SIGTTOU code. + + * hurd/hurdsyms.c: Add an alias hurd_sig_post -> _hurd_sig_post. + * hurd/hurdkill.c (_hurd_sig_post): Renamed back from hurd_sig_post. + * hurd/hurd.h: Declare _hurd_sig_post. + + * hurd/hurdsig.c (_S_sig_post): Add SIGTTIN and SIGTTOU cases, + handled like SIGINT et al. + + * mach/devstream.c: Turn back on NL->CRNL translation. + + * stdio/xbug.c (main): Return instead of running off the end. + +Mon Jul 4 16:57:13 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.08.3. + +Sat Jul 2 00:15:37 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__ioctl.c: Account for three type fields in + message buffer size. + + * sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): + Catch faults accessing user stack and return NULL. + * hurd/hurdsig.c (_hurd_internal_post_signal): When it does, die + with SIGILL and dump core. + + * hurd/hurdsig.c (_hurd_internal_post_signal): Use + _hurd_msgport_thread instead of __mach_thread_self () to avoid the + system call. (Signals will now lose if _hurd_msgport_thread gets + clobbered.) + (abort_rpcs): Always do thread_abort and thread_get_state. + + * misc/getpass.c: Fix typo resulting in newline not being removed. + + * termios/sys/ttydefaults.h [TTYDEFCHARS] (ttydefchars): Cast + _POSIX_VDISABLE to cc_t to avoid gcc warning. + +Fri Jul 1 14:07:40 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/Makefile (user-interfaces): Add hurd/ifsock. + + * socket/sys/socket.h (AF_LOCAL): New macro. + + * sysdeps/mach/hurd/__kill.c: Fix SIGKILL loop condition. + +Fri Jul 1 13:36:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/hurdkill.c (hurd_sig_post): New var PIDSBUF; initialize + PIDS and NPIDS correctly; only free PIDS if the MiG stub + changed it. + +Thu Jun 30 18:47:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/hurdsock.c (_hurd_socket_server): Zero up to and *including* + new[DOMAIN]. + +Thu Jun 30 08:12:28 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdsig.c (abort_all_rpcs): Just iterate over _hurd_sigstates. + + * hurd/dtable.c (fork_child_dtable): Skip empty descriptor slots. + + * sysdeps/mach/hurd/__ioctl.c: Fix MSG.data size calculation. + +Wed Jun 29 19:06:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/bind.c: For AF_LOCAL, create a new node in the + filesystem, put the ifsock translator on it, and fetch the + address port. + * sysdeps/mach/hurd/connect.c: For AF_LOCAL, look up the socket + file and fetch the address port using the ifsock protocol. + +Tue Jun 28 16:03:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/Makefile (routines): Add ports-get, ports-set, and hurdmsg. + (aux): Remove msgstub. + * hurd/hurdports.c (get): Just call _hurd_ports_get. + (set): Just call _hurd_ports_set. + (getcttyid, setcttyid): New functions. + * hurd/ports-get.c (_hurd_ports_get): New file, new function. + * hurd/ports-set.c (_hurd_ports_set): New file, new function. + * hurd/hurd.h: Declare _hurd_ports_get and _hurd_ports_set. + Declare getcttyid and setcttyid. + * hurd/__setauth.c (__setauth): Just call _hurd_setauth. + (_hurd_setauth): New function, code moved from __setauth. + * hurd/hurdinit.c (_hurd_setproc): New function. + * hurd/hurdioctl.c (_hurd_setcttyid): New function. + + * locale/C-ctype_ct.c (__ctype_tolower_C, __ctype_toupper_C): Use + integer constants instead of character constants for octal values + so they will not be sign extended. + + * sysdeps/mach/hurd/__setitmr.c (fork_itimer): New function, on + _hurd_fork_child_hook. + + * sysdeps/stub/sysd-stdio.c (__stdio_reopen): Fix typo in arg type. + * sysdeps/stub/__ioctl.c: Fix type of REQUEST arg. + * sysdeps/stub/syscall.c: Include ansidecl.h. + * sysdeps/stub/_exit.c: Add __NORETURN to defn. + + * sysdeps/unix/sysv/sysv4/sigset.h (_EXTERN_INLINE): Define to + `extern __inline', not empty. + + * sysdeps/mach/hurd/ttyname.c: Don't bother searching /dev. + +Sat Jun 25 15:41:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__fork.c: Moved proc_task2pid call to just + before proc_child. It is a waste to do it earlier. + +Sat Jun 25 13:17:39 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__fork.c: Move proc_task2pid call to after + _hurd_ports are unlocked. Call proc_child nearly last thing. + Ignore errors from thread_resume. + +Fri Jun 24 20:21:11 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/getcwd.c: Remove empty `#define'. + +Fri Jun 24 17:57:36 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__fork.c: Call proc_task2pid immediately after + task_create. Add comment explaining why thread_resume must be the + last thing we do to the child. + +Fri Jun 24 01:41:41 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdinit.c (_hurd_proc_init): Call __proc_set_arg_locations + in place of __proc_setprocargs (it was renamed). + + * hurd/hurd.h: Rename _hurd_sig_post to hurd_sig_post. + * hurd/hurdkill.c: Likewise. + + * hurd/port2fd.c (_hurd_port2fd): Call __term_open_ctty instead of + __term_become_ctty, and don't pass the message port. + * hurd/hurdioctl.c (rectty_dtable): Likewise. + * hurd/dtable.c (fork_child_dtable, ctty_new_pgrp): Likewise. + + * sysdeps/mach/hurd/__fork.c: Use __proc_{get,set}_arg_locations + to propagate argv and envp locations to the child. + + * stdio/freopen.c (freopen): If STREAM->__seen is clear, pass + __stdio_close to __stdio_reopen. + + * misc/Makefile (install-lib): Add libg.a. + ($(objpfx)libg.a): New rule; use make-dummy-lib. + (lib): Depend on $(objpfx)libg.a + +Thu Jun 23 01:14:36 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * termios/termios.h (CCEQ): New macro. + + * sysdeps/unix/sysv/irix4/__getgrps.c: Add missing __ to fn name. + + Don't compile in absolute file names for localtime and posixrules + files if they were specified relative to $(zonedir). + * time/Makefile (installed-localtime-file, + installed-posixrules-file): Set these instead of + {localtime,posixrules}-file to the absolute file names. + ($(localtime-file), $(posixrules-file)): Change targets to + $(installed-localtime-file) and $(installed-posixrules-file). + +Wed Jun 22 15:52:26 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/Makefile (sig): Add hurdkill. + +Sat Jun 18 12:57:54 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/_itoa.h (_itoa): Change type of VALUE to unsigned long long. + * stdio/_itoa.c (_itoa): Likewise. + +Thu Jun 16 01:10:41 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/dirstream.h (DIR): Replace `__filepos' member + with `__entry_ptr' and `__entry_data'. Remove `__block_size' member. + Replace `__offset' member with `__ptr', a char *; no need to include + <gnu/types.h>. + * sysdeps/mach/hurd/readdir.c: Use those, new dir_readdir protocol. + * sysdeps/mach/hurd/opendir.c: Initialize new members. + Don't do io_stat to set __blocksize. + * sysdeps/mach/hurd/telldir.c: Rewritten; return DIRP->__entry_ptr. + * sysdeps/mach/hurd/seekdir.c: Rewritten; just set DIRP->__entry_ptr + from arg, and zero DIRP->__size so a new block will be read. + + * sysdeps/mach/hurd/getcwd.c: Use new dir_readdir protocol. + + * hurd/msgstub.c: Add stubs for dir_changed, file_changed. + + * hurd/hurdsock.c (_hurd_socket_server): Removed unused label. + + * sysdeps/mach/hurd/__getdents.c: Use new dir_readdir protocol. + + * sysdeps/mach/hurd/__access.c: Open the file with 0 flags and + then use file_check_access to discover what we are allowed. + +Tue Jun 14 14:10:03 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/mips/setjmp.S: Refer to `$fp', not `fp'. + +Tue Jun 14 00:50:54 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__pipe.c: Set FDS[1], not FDS[2]. + +Mon Jun 13 06:48:48 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sparc/sigtramp.c (trampoline): Use a + comment instead of a pointless insn to reference %0 in final asm. + + * hurd/hurdsock.c (_hurd_socket_server): If realloc fails, don't + fail; just don't cache the port. + Look up the server node only if it is not in the cache. + Translate errno only if path_lookup fails. + (init): New function, on _hurd_preinit_hook. + + * sysdeps/mach/hurd/__symlink.c: Complement _hurd_umask before ANDing. + +Sat Jun 11 12:52:28 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__fork.c: Can't insert dead name rights into + child. + +Sat Jun 11 05:19:47 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/i386/longjmp-ts.c: Set TS->uesp instead of + TS->esp. Set TS->eip. + + * gnu-stabs.h (bss_set_element): New macro. + * hurd/dtable.c: Use bss_set_element instead of data_set_element + to put _hurd_dtable_lock in the _hurd_fork_locks set. + +Fri Jun 10 02:04:51 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__fork.c: Don't apply MACH_PORT_TYPE to result + from __mach_port_names. Unlock SS->lock before return. + Check for KERN_NAME_EXISTS from mach_port_allocate_name when + creating a receive right and possibly ignore it. + + * sysdeps/unix/sysv/sco3.2.4/Dist: Add sco_getgrp.S. + + * crypt/speeds.c: Include signal.h and stdio.h first thing. + [! SIGVTALRM]: Define NO_ITIMER. + + * sysdeps/unix/sysv/isc3/direct.h: New file. + + * hurd/hurdinline.c: Include lock-intern.h before #define + _EXTERN_INLINE. + + * sysdeps/mach/hurd/__fork.c (_hurd_fork_locks): Don't be const. + (__fork): Set SS from _hurd_self_sigstate so it is never null. + New local flag PORTS_LOCKED records when we have spin_locked all + the _hurd_ports cells; unlock them if necessary on error. + + * hurd/hurdsig.c (_hurd_siglock): Don't initialize it. + (_hurdsig_init): Initialize _hurd_siglock at runtime. + +Wed Jun 8 12:22:27 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * hurd/hurdid.c (_hurd_check_ids): Zero P->nuids and P->ngids after + deallocating P->uids and P->ngids. + + * hurd/hurdioctl.c (_hurd_ioctl_handler_lists): Make defn initialized. + + * sysdeps/mach/hurd/__ioctl.c: Only try to unpack if IOC_OUT is set. + + * hurd/Makefile (routines): Replace $(inlines) with hurdinline. + (inlines): Variable and rule removed. + (generate-inlines): Variable removed. + * hurd/hurdinline.c: New file. + +Tue Jun 7 01:58:20 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makerules: Add -f to all mv commands missing it. + + * hurd/Makefile (generate-inline): New canned sequence. + (inline-%.c): Use it. + + * time/asia, time/europe, time/northamerica: New versions from ADO. + +Mon Jun 6 21:36:04 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * hurd/hurdid.c (init_id): New function. + + * Makerules (+make-deps): Put first s cmd before $(sed-remove-objpfx). + (sed-remove-objpfx): Replace occurrences at beginning of line too. + +Sun Jun 5 14:34:12 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 1.08.1. + + * sysdeps/mach/hurd/ioctls.h (_IOR, _IOW): Swap IOC_IN and IOC_OUT. + + * sysdeps/mach/hurd/__ioctl.c: Only pack input for ioctls that + take input. Compute expected reply size for ioctls that take + output and check it properly. + +Sat Jun 4 00:35:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/ioctls.h (union __ioctl): Type removed. + (enum __ioctl_datum): Name this enum. + (_IOC_INOUT, _IOC_GROUP, _IOC_COMMAND, _IOC_TYPE): New macros. + (_IOT_TYPE[012], _IOT_COUNT[012]): New macros. + * sysdeps/mach/hurd/__ioctl.c: Use those macros instead of the union. + + * sysdeps/mach/hurd/__fork.c: Major rewrite. Copy all ports + present in the task, not just library-maintained ones. Handle + sigstate and signal thread setup explicitly here. + * hurd/hurdsig.c (hurdsig_fork, hurdsig_fork_child): Functions + removed. + + * hurd/hurdpid.c (init_pids): Don't put this on _hurd_fork_child_hook. + + * sysdeps/mach/hurd/__isatty.c: New file. + + * hurd/hurdsock.c (_hurd_socket_server): Pass NP to __path_lookup, + not NAME (most of which is uninitialized). + + * hurd/hurdsig.c (_hurdsig_init): Don't check for _hurd_msgport + being non-null; always initialize it. + +Fri Jun 3 21:57:14 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * hurd/hurdrlimit.c (init_rlimit): Restore __mutex_init call. + (_hurd_rlimit_lock): Set initializer to random value; run-time + initialization is always required. + + * inet/rcmd.c (rcmd): Compute max fd + 1 for select instead of + hardcoding 32. + +Wed Jun 1 10:52:41 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/hurdrlimit.c (_hurd_rlimits, _hurd_rlimit_lock): Provide + initializers so that the file is included in the link properly. + (init_rlimit): Omit call to __mutex_init. + +Tue May 31 18:15:33 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * hurd/hurdmalloc.c (more_memory): Do spin_lock_init on H->lock. + (malloc_init): New function; put it on _hurd_preinit_hook. + + * sysdeps/mach/hurd/defs.c (init_stdio): If stream already + allocated, don't allocate a new one. Don't crash if _hurd_alloc_fd + returns null if __newstream does. + + * sysdeps/mach/hurd/__brk.c (init_brk): If _hurd_brk is nonzero, + leave it as it is. Set PAGEND from _hurd_brk instead of &_end. + +Mon May 30 18:37:47 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdrlimit.c (init_rlimit): Put this on _hurd_preinit_hook + instead of _hurd_subinit. + + * sysdeps/mach/hurd/mig-reply.c (mig_fork_child): Function removed. + * hurd/dtable.c (fork_parent_dtable): Function removed. + + * sysdeps/generic/resourcebits.h: Rename RLIM_NLIMITS to + RLIMIT_NLIMITS, add alias for old name. + + * sysdeps/mach/hurd/Makefile (hurd-objpfx): New variable. + (before-compile): Use that instead of $(common-objpfx). + + * sysdeps/mach/Makefile [! objpfx] (mach-objpfx): Add trailing slash. + +Fri May 27 01:34:56 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdsig.c (_hurdsig_init): Always initialize _hurd_sigthread. + + * hurd/dtable.c: Use data_set_element instead of text_set_element + for _hurd_fork_locks. + * hurd/hurdsig.c: Likewise. + + * hurd/hurd.h (_hurd_set_data_limit): Declaration removed. + + * hurd/dtable.c (_hurd_dtable_rlimit): Variable removed. + (init_dtable): Don't set it. + + * hurd/Makefile (headers): Add hurd/resource.h. + (routines): Add hurdrlimit. + * hurd/hurd/resource.h: New file. + * hurd/hurdrlimit.c: New file. + * sysdeps/mach/hurd/getrlimit.c: Rewritten to just fetch + _hurd_rlimits. + * sysdeps/mach/hurd/setrlimit.c: Rewritten to just set _hurd_rlimits. + * sysdeps/mach/hurd/__brk.c (_hurd_data_limit): Variable removed. + (_hurd_set_brk): Use _hurd_rlimits[RLIMIT_DATA]. + (_hurd_set_data_limit): Function removed. + * hurd/alloc-fd.c (_hurd_dtable_rlimit): Variable removed. + (_hurd_alloc_fd): Use _hurd_rlimits[RLIMIT_OFILE] instead. + + * sysdeps/generic/resourcebits.h: Add RLIMIT_NOFILE as an alias + for RLIMIT_OFILE. + + * sysdeps/mach/hurd/mig-reply.c (__mig_init): Argument is stack + on which to set the per-thread reply port variable. + + * sysdeps/mach/hurd/__brk.c (init_brk): Set _hurd_data_end to + DATA_SIZE bytes past the beginning of data space, rather than to + DATA_SIZE absolutely. If vm_map fails, set it to PAGEND. + + * sysdeps/mach/hurd/start.c (_start): Run _hurd_preinit_hook right + after __mach_init. + + * stdio/freopen.c (freopen): Rewritten using __stdio_reopen to + preserve the old cookie value when possible. + * sysdeps/posix/sysd-stdio.c (__stdio_reopen): New function. + * sysdeps/stub/sysd-stdio.c (__stdio_reopen): New function. + * sysdeps/mach/hurd/sysd-stdio.c (__stdio_reopen): New function. + + * stdio/freopen.c (freopen): Close the stream if MODE is invalid. + + * hurd/hurdsig.c (_hurd_core_limit): Define variable. + + * socket/sys/socket.h (PF_LOCAL): Define in preference to PF_FILE. + +Thu May 26 12:09:51 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/alloc-fd.c (_hurd_alloc_fd): Don't return EINVAL when + FIRST_FD is greater than _hurd_dtablesize and less than + _hurd_dtable_rlimit. If we want to grow _hurd_dtable, but + _hurd_dtablesize is as big as _hurd_dtable_rlimit, then return + EMFILE. When growing _hurd_dtable, actually do something if + _hurd_dtablesize is zero. + + * hurd/hurdmalloc.c (malloc_fork_prepare, malloc_fork_parent, + malloc_fork_child): Declare as static so they don't conflict with + the user's version of this file. + +Wed May 25 20:55:16 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__brk.c: Include <cthreads.h> instead of + <mutex.h>. + + * hurd/hurdmalloc.c, hurd/hurdmalloc.h: New files (temporary hack). + * hurd/Makefile (routines): Append hurdmalloc. + (distribute): Append hurdmalloc.h. + * hurd/alloc-fd.c: Include "hurdmalloc.h" (temporary hack). + * hurd/dtable.c: Likewise. + * hurd/hurdinit.c: Likewise. + * hurd/hurdsig.c: Likewise. + * hurd/hurdsock.c: Likewise. + * hurd/new-fd.c: Likewise. + * sysdeps/mach/hurd/start.c: Likewise. + + * sysdeps/mach/hurd/start.c (start1): Use malloc and a for loop + instead of calloc. + * hurd/hurdsig.c (_hurd_thread_sigstate): Use malloc and memset + instead of calloc. + + * sysdeps/mach/hurd/__brk.c (init_brk): Reference self to avoid + compiler warning. Add init_brk to _hurd_preinit_hook instead of + __libc_subinit. + + * sysdeps/mach/hurd/start.c (_hurd_preinit_hook): New variable. + (start1): Run _hurd_preinit_hook before threadvar setup. + +Tue May 24 17:42:34 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/dtable.c (init_dtable): Initialize _hurd_dtablesize to + _hurd_init_dtablesize. Initialize _hurd_dtable_rlimit as + _hurd_dtablesize used to be set, but don't let it be zero. + (_hurd_dtable_rlimit): New variable. + +Tue May 24 12:57:19 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/sleep.c (sleep): Timeout arg to mach_msg is + in milliseconds, not microseconds; compute it accordingly. + + * sysdeps/mach/hurd/__select.c (__select): Deleted variables + DTABLE and DTABLE_ULINK. Use new vars _hurd_dtablesize and + _hurd_dtable instead of old _hurd_dtable structure. Use new + locking protocol on _hurd_dtable. + +Tue May 24 01:55:24 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__setitmr.c: Don't include mutex.h. + + * sysdeps/mach/hurd/defs.c (init_stdio): Reference self. + + * sysdeps/unix/sysv/sysv4/i386/sysdep.h: Include + sysdeps/unix/sysv/i386/sysdep.h, not sysdeps/unix/i386/sysdep.h + +Mon May 23 19:05:44 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/Makefile (mib_hacks, defines): Variables removed. + + * mach/devstream.c (mach_open_devstream): Set STREAM's seek and + fileno io functions to null. + + * hurd/hurdexec.c (_hurd_exec): Fixed adding of dtable ports to + PLEASE_DEALLOC array. + + * sysdeps/mach/hurd/defs.c (init_stdio): Unlock the descriptors + after fetching them. If a standard descriptor is not allocated, + allocate the structure and store its pointer in the stream anyway. + + * stdio/gets.c: Only return null on P==S if feof (STREAM). + + * stdio/vfprintf.c: Make %Z a type modifier, not a format spec. + + * sysdeps/mach/hurd/fdopen.c: Return NULL rather than -1 for error. + +Mon May 23 14:24:50 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__close.c (__close): Use new _hurd_fd_get + protocol. + * sysdeps/mach/hurd/__dup2.c (__dup2): Likewise. Use + _hurd_dtablesize and _hurd_dtable instead of old _hurd_dtable + structure. + + * sysdeps/mach/hurd/sysd-stdio.c (__stdio_seek): Use + HURD_FD_PORT_USE, not HURD_FD_USE. + * sysdeps/mach/hurd/stdio_init.c (__stdio_init_stream): Variable + is D, not FD. + + * hurd/alloc-fd.c (_hurd_alloc_fd): Arg FIRST_FD is not actually + const. + * hurd/hurdsig.c (_hurd_internal_post_signal [case SIGINFO]): If + we are not the process group leader, ignore the signal. + (_S_sig_post [case SIGURG]): Declaration of D was out of place. + + * sysdeps/mach/hurd/fdopen.c: Include <hurd/io.h> for + io_get_openmodes prototype. + +Sat May 21 16:03:23 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * assert/assert.c (__assert_fail): Put program name first in msg. + + * hurd/Makefile (dtable): Removed setdtsz. + + * hurd/hurdexec.c: Use _hurd_dtable and _hurd_dtablesize instead of + old _hurd_dtable structure. + * hurd/hurdsig.c: Likewise. + * hurd/alloc-fd.c: Likewise. + * hurd/hurdioctl.c (rectty_dtable): Likewise. + + * Version 1.08 released. + + * mach/mach_error_string.c: Renamed to errstring.c. + * mach/Makefile (routines): Renamed mach_error_string to errstring. + * mach/err_mach_ipc.sub: Renamed to err_mach.sub. + * mach/err_bootstrap.sub: Renamed to err_boot.sub. + + * sysdeps/generic/sigset.h (__SIGSETFN): Take new arg CONST; use it + for CONST qualifier on SET arg to generated function. + Changed uses to pass it; sigismember passes __const, others empty. + + * sysdeps/mach/hurd/sysd-stdio.c: Rewritten to use `struct hurd_fd *'s + for cookies. + * sysdeps/mach/hurd/fdopen.c: Rewritten accordinly. + * sysdeps/mach/hurd/defs.c (init_stdio): Rewritten accordingly. + Add it to the _hurd_fd_subinit hook instead of the __libc_subinit + hook. + * sysdeps/mach/hurd/stdio_init.c: New file. + * hurd/dtable.c (_hurd_fd_subinit): New hook variable. + (init_dtable): Run the _hurd_fd_subinit hook. + + * hurd/hurd/fd.h (struct hurd_dtable): Type removed. + (_hurd_dtable_users, _hurd_dtable_rlimit): Variables removed. + (_hurd_dtable): Make this a struct hurd_fd **. + (_hurd_dtablesize): New variable. + (struct hurd_fd_user): Type removed. + (_hurd_dtable_get, _hurd_dtable_free, _hurd_dtable_fd): Functions + removed. + (_hurd_fd_get): Rewritten. Take just one arg, and look it up in + _hurd_dtable; return a struct hurd_fd *. + (HURD_FD_USE): Rewritten to use new _hurd_fd_get interface. + * hurd/dtable.c (_hurd_dtable_users, _hurd_dtable_rlimit): + Variables removed. + (_hurd_dtable): Make this a struct hurd_fd **. + (_hurd_dtablesize): New variable. + (init_dtable, fork_parent_dtable, fork_child_dtable, + ctty_new_pgrp, reauth_dtable): Use new simpler _hurd_dtable format. + * sysdeps/mach/hurd/__getdtsz.c: Use _hurd_dtablesize. + * sysdeps/mach/hurd/__fcntl.c: Use new _hurd_fd_get protocol. + + * hurd/dtable.c (get_dtable_port): Return the ctty port if set. + + * hurd/hurd/fd.h (_hurd_fd_error_signal): New function, broken out + of _hurd_fd_error. + (_hurd_fd_error): Call it. + + * hurd/Makefile (dtable): Add fd-close. + * hurd/fd-close.c: New file. + * hurd/hurd/fd.h: Declare _hurd_fd_close. + + * sysdeps/mach/hurd/__close.c: Call _hurd_fd_close. + + * signal/Makefile (routines): Add sigsetops. + * signal/sigsetops.c: New file. + + * sysdeps/unix/sysv/sysv4/sigset.h (_EXTERN_INLINE): New macro. + Use it for all the inline functions. + + * signal/signal.h: Move #include <signum.h> inside #ifdef _SIGNAL_H. + + * sysdeps/generic/sigset.h: Protect types with #ifndef + _SIGSET_H_types. Protect rest with #if !defined (_SIGSET_H_fns) + && defined (_SIGNAL_H). + (__SIGSETFN): Add extern declaration of NAME inside function. + + * sysdeps/unix/ioctls-tmpl.c: Add missing #endif. + * sysdeps/unix/Makefile (make-ioctls-CFLAGS): Remember -D. + +Fri May 20 20:42:33 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (sys/termios.h): Variable removed. + (ioctl-includes): New variable. + (make-ioctls-CFLAGS): Compute value generally from $(ioctl-includes). + ($(common-objpfx)ioctls): Depend on $(ioctl-includes), instead of + $(sys/termios.h). + + * sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S: New file. + * sysdeps/unix/sysv/sco3.2.4/Makefile (sysdep_routines): Add + sco_getgrp. + * sysdeps/unix/sysv/sco3.2.4/__getgrps.c: New file. + + * sysdeps/generic/sigset.h (__sigismember, __sigaddset, __sigdelset): + Rewritten as extern inline functions; check for bogus signal number. + + * configure.in (names): Put $implied before $* in new $sysnames + list remaining to be processed; this ensures unix/common precedes + unix/sysv4 for sysv4. + +Thu May 19 18:35:02 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/defs.c (init_stdio): Make stdin and stdout + line buffered and stderr unbuffered. + +Thu May 19 16:14:36 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/getcwd.c: Remember to call io_stat on cwdir. + + * sysdeps/generic/configure.in: Use changequote around if expr + to avoid [] elision. + +Thu May 19 13:53:59 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * hurd/hurdsock.c (_hurd_socket_server): Return EPFNOSUPPORT + rather than EPROTONOSUPPORT because it's the entire protocol + family that isn't present, not just one protocol. + + * sysdeps/mach/hurd/__access.c (__access): Don't deallocate + CRDIR or CWDIR; that's taken care of by the _hurd_port_get + and _hurd_port_free system. + +Thu May 19 04:14:57 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/libc_fatal.c: Include <errno.h>. + + * sysdeps/unix/sysv/sysv4/__sigact.c: Include <stddef.h> for NULL. + + * sysdeps/mach/hurd/__access.c: Fix swapped poly and count args in + __auth_makeauth call. + + * sysdeps/mach/hurd/ioctls.h (_IOC, _IOT): Rewritten using bitwise + operations, so the result is always technically a constant (the + old method of using a union constructor expression was not good + enough for initializers). + + * hurd/hurdsock.c (_hurd_socket_server): If path_lookup returns + ENOENT, we return EPROTONOSUPPORT. + + * hurd/Makefile (dtable): Add hurdioctl. + * hurd/dtable.c (rectty_dtable, tiocsctty, tiocnotty): Functions + moved: + * hurd/hurdioctl.c: New file. + (fioctl, fioclex): New functions. + * sysdeps/mach/hurd/__ioctl.c (_hurd_ioctl_handler_lists): Don't + define it, just declare it. + + * sysdeps/mach/hurd/getcwd.c: Use MACH_PORT_RIGHT_SEND, not + MACH_PORT_TYPE_SEND, in mach_port_mod_refs call. + + * sysdeps/mach/hurd/__getpgrp.c: Don't lock _hurd_pid_lock. + + * sysdeps/unix/common/glue-ctype.c: Don't include <ctype.h>. + Instead, add explicit extern declaration of TABLE in main. + +Wed May 18 17:54:00 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/Makefile (asm-CPPFLAGS): Append $(m68k-syntax-flag). + + * Version 1.07.6. + + * sunrpc/Makefile (+gccwarn): Set to -w. + + * sysdeps/unix/Makefile (ifeq testing sys/param.h): Use patsubst + instead of dir to remove directory name from .../sys/param.h but + preserve "sys/". + + * inet/sys/bitypes.h: Replaced with just #include <sys/types.h>. + + * posix/sys/utsname.h (_UTSNAME_NODENAME_LENGTH): If undefined, + define to _UTSNAME_LENGTH. + (struct utsname): Use _UTSNAME_NODENAME_LENGTH for `nodename' member. + * sysdeps/unix/bsd/sun/sunos4/utsnamelen.h (_UTSNAME_NODENAME_LENGTH): + Define it. + + * resource/sys/resource.h (enum __rlimit_resource): Removed. + Just include <resourcebits.h> instead. + * resource/Makefile (headers): Add resourcebits.h. + * sysdeps/generic/resourcebits.h: New file. + * sysdeps/unix/bsd/sun/sunos4/resourcebits.h: New file. + + * stdio/test-popen.c (main): Use popen to read the file back, too. + + * sysdeps/unix/sysv/sysv4/i386/sysdep.h: New file. + + * sysdeps/unix/sysv/sysv4/i386/sys-sig.S: Fixed typo: movel->movl. + +Tue May 17 12:46:31 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * mach/mach/mach_traps.h (__mach_reply_port, __mach_thread_self, + __mach_task_self, __mach_host_self): New declarations of __ + versions of syscall traps. + (swtch, __swtch, swtch_pri, __swtch_pri, thread_switch, + __thread_switch, evc_wait, __evc_wait): New prototypes. + * mach/Makefile (headers): Added mach/mach_traps.h so that the + GNU version is installed instead of the Mach version. + +Mon May 16 15:34:12 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/sys/param.h: New file. + + * mach/lock-intern.h (__mutex_lock, __mutex_unlock): Real definitions. + (__mutex_lock_solid, __mutex_unlock_solid, __mutex_init): Declare + them. + * mach/mutex-solid.c: New file. + * mach/Makefile (lock): Add mutex-solid. + (lock-headers): Remove mutex.h. + * mach/mutex.h: File removed. + * hurd/hurd/id.h: Include <cthreads.h> instead of <mutex.h>. + * hurd/hurd/signal.h: Likewise. + * hurd/hurdsig.c: Likewise. + * hurd/hurdsock.c: Likewise. + * hurd/dtable.c: Likewise. + * hurd/__setauth.c: Likewise. + * sysdeps/mach/hurd/Makefile (includes): Also append + -I$(hurd-srcdir)/libthreads. + + * sysdeps/posix/system.c [WAITPID_CANNOT_BLOCK_SIGCHLD]: Don't + block SIGCHLD. + * sysdeps/unix/sysv/sco3.2.4/system.c + (WAITPID_CANNOT_BLOCK_SIGCHLD): Define this macro. + + * sysdeps/posix/sigintr.c (siginterrupt) [! SA_RESTART]: Always + fail with ENOSYS. + + * sysdeps/posix/__sigvec.c [! SA_ONSTACK]: Fail with ENOSYS if + SV_ONSTACK is set in VEC->sv_flags. + [SA_RESTART]: Protect SV_INTERRUPT check with this. + + * sysdeps/mach/sysdep.h (FATAL_PREPARE): New macro. + * sysdeps/posix/libc_fatal.c: Include <sysdep.h>. + [FATAL_PREPARE]: Invoke the macro. + * assert/assert.c: Likewise. + + * sysdeps/generic/memmem.c: Start BEGIN at HAYSTACK, not partway + into it. Loop until BEGIN passes the location in HAYSTACK with + NEEDLE_LEN bytes remaining to the end. + Compare first byte manually before calling memcmp. + + * sysdeps/unix/sysv/sco3.2.4/__sigact.S: Fix typo. + + * posix/sys/types.h [__USE_BSD] (int32_t, int16_t, int8_t, + u_int32_t, u_int16_t, u_int8_t): New typedefs. + + * assert/assert.c (__assert_program_name): New variable. + (__assert_fail): Print that in the msg too. + [HAVE_GNU_LD] (set_progname): New function to set it up at startup. + +Thu May 12 01:10:52 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/__setauth.c: Do critical section locking. + * hurd/hurdexec.c: Likewise. + * hurd/hurdauth.c (_S_del_auth): Likewise. + * hurd/getuids.c: Likewise. + * hurd/dtable.c: Likewise. + * hurd/alloc-fd.c: Likewise. + * hurd/hurd/port.h: Likewise. + * hurd/hurd/fd.h: Likewise. + * hurd/setuids.c: Likewise. + * hurd/intern-fd.c: Likewise. + * hurd/hurdsock.c (_hurd_socket_server): Likewise. + * sysdeps/mach/hurd/setrlimit.c: Likewise. + * sysdeps/mach/hurd/setgroups.c: Likewise. + * sysdeps/mach/hurd/seteuid.c: Likewise. + * sysdeps/mach/hurd/setegid.c: Likewise. + * sysdeps/mach/hurd/getrlimit.c: Likewise. + * sysdeps/mach/hurd/__setuid.c: Likewise. + * sysdeps/mach/hurd/__setreuid.c: Likewise. + * sysdeps/mach/hurd/__setregid.c: Likewise. + * sysdeps/mach/hurd/__setitmr.c: Likewise. + * sysdeps/mach/hurd/__setgid.c: Likewise. + * sysdeps/mach/hurd/__select.c: Likewise. + * sysdeps/mach/hurd/__sbrk.c: Likewise. + * sysdeps/mach/hurd/__getuid.c: Likewise. + * sysdeps/mach/hurd/__getpgrp.c: Likewise. + * sysdeps/mach/hurd/__getitmr.c: Likewise. + * sysdeps/mach/hurd/__getgrps.c: Likewise. + * sysdeps/mach/hurd/__getgid.c: Likewise. + * sysdeps/mach/hurd/__geteuid.c: Likewise. + * sysdeps/mach/hurd/__getegid.c: Likewise. + * sysdeps/mach/hurd/__getdtsz.c: Likewise. + * sysdeps/mach/hurd/__fork.c: Likewise. + * sysdeps/mach/hurd/__fcntl.c: Likewise. + * sysdeps/mach/hurd/__dup2.c: Likewise. + * sysdeps/mach/hurd/__close.c: Likewise. + * sysdeps/mach/hurd/__brk.c: Likewise. + * sysdeps/mach/hurd/__access.c: Likewise. + + * sysdeps/mach/hurd/reboot.c (reboot): Use the host priv port to + prove authority. + + * sysdeps/mach/hurd/__readlink.c: Don't request O_READ access. + + * sysdeps/mach/hurd/__ioctl.c: Don't expect result data unless + return code is zero. Translate MIG_BAD_ID or EOPNOTSUPP to ENOTTY. + + * mach/devstream.c (output): Use device_write instead of + device_write_inband. + +Wed May 11 18:49:31 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/hurdinit.c (_hurd_init): Finsih loop of _hurd_port_init on + _hurd_ports elts before doing _hurd_proc_init or + __task_set_special_port. + + * hurd/hurd/signal.h (struct hurd_sigstate): Add new + `critical_section' member. Remove #if 0'd out vfork crap. + (_hurd_critical_section_lock, _hurd_critical_section_unlock): New + functions. + (HURD_CRITICAL_BEGIN, HURD_CRITICAL_END): New macros. + + * io/Makefile (headers): Add poll.h and sys/poll.h. + (routines): Add poll. + * sysdeps/unix/bsd/sun/sunos4/poll.S: New file. + * sysdeps/unix/sysv/poll.S: New file. + * sysdeps/unix/bsd/poll.c: New file. + * sysdeps/stub/poll.c: New file. + * io/poll.h, io/sys/poll.h: New files. + + * misc/bsd-compat.c (setjmp): New function. + + * sysdeps/unix/Makefile (sysdep_headers): Remove sys/param.h. + * misc/Makefile (headers): Add it here instead. + + * io/test-utime.c (main): New file. + * io/Makefile (tests): New variable. + +Wed May 11 13:44:33 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * hurd/hurd/threadvar.h (__hurd_errno_location): Remove + __volatile keyword. `volatile int errno' is not the same + as `int errno'; user programs often mention the latter. + * errno.h: Remove __volatile keyword; same reason. + +Tue May 10 17:21:41 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/zdump.c: New code from ADO. + + * time/difftime.c (difftime): Use hairy rounding algorithm from + eggert@twinsun.com when sizeof (time_t) >= sizeof (double). + + * Makerules (native-CFLAGS): Remove -I$(sysincludedir). RMS says + people with bogons in /usr/local/include deserve to lose. + + * stdio/printf_fp.c (__printf_fp): If IS_NEG gets set, negate + FPNUM before testing it for %g format choice. + + * sysdeps/unix/sysv/irix4/fcntlbits.h: New file. + * sysdeps/unix/sysv/irix4/Dist: New file. + * sysdeps/unix/sysv/irix4/readv.c: New file. + * sysdeps/unix/sysv/irix4/writev.c: New file. + * sysdeps/unix/sysv/irix4/__dup2.c: New file. + + * sunrpc/xdr_float.c (xdr_float): Change [mc68000 || sparc] to [! + vax]. + + * sysdeps/mips/setjmp.S: Remove spurious $. + + * sysdeps/generic/ftime.c: Include <errno.h>. + + * sysdeps/unix/mips/sysdep.S: Add .set noreorder. + +Tue May 10 16:27:13 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/generic/termbits.h (NCCS): Doc fix. + +Mon May 9 18:07:44 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/uname.c (uname): System uname information + has moved from init to proc. + + * sysdeps/mach/usleep.c (usleep): Return correct value. Destroy + RECV when we're done with it. + +Thu May 5 17:03:56 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__lstat.c: Use O_NOLINK instead of O_NOTRANS. + +Thu May 5 04:20:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/spin-lock.h (spin_lock_init): Define. + + * sysdeps/mach/hurd/sigsuspend.c: New local variable NEWMASK, set + it to *SET if SET is not null, before taking SS->lock; don't + dereference SET while holding the lock. Restore SS->blocked to + OLDMASK before unlocking and returning. + + * hurd/hurdsig.c (hurdsig_fork_child): Return zero. + + * sysdeps/mach/hurd/__fork.c (_hurd_fork_parent_hook, + _hurd_fork_prepare_hook)): Define variables (symbol sets). + (__fork): Run _hurd_fork_prepare_hook and _hurd_fork_parent_hook. + + * sysdeps/mach/hurd/sigsuspend.c: Don't test SS->pending; instead + wait until SS->suspended is cleared. + * hurd/hurdsig.c (_hurd_internal_post_signal): Clear SS->suspended + before signalling on SS->arrived. + + * mach/Makefile (headers): Added mach/default_pager_helper.defs. + + * sysdeps/sparc/Dist: Added alloca.S. + +Wed May 4 14:02:29 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/hurdexec.c (_hurd_exec): Unlock _hurd_dtable_lock when + all through. + + * sysdeps/mach/hurd/__setitmr.c: Changed _hurd_itimer_lock + to be a spin_lock; changed mutex_lock and mutex_unlock + accordingly throughout. + * sysdeps/mach/hurd/__getitmr.c: Corresponding changes from + mutex calls to spin lock calls here too. + + * sysdeps/mach/hurd/__setitmr.c (setitimer_locked): Fixed syntax + of declaration of PREEMPT. + (setitimer_locked): Declare variables ERR and ELAPSED. + (setitimer_locked): Fix some references to REMAINING that + were using it as an itimerval instead of a timeval. + (setitimer_locked): Deleted unused label STILLBORN. + +Wed May 4 00:17:32 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/__getitmr.c: Fix arg name __WHICH to WHICH. + + * sysdeps/unix/bsd/alarm.c: Round tv_usec with arithmetic rather + than a test. + + * hurd/Makefile (user-interfaces): Add hurd/msg_request. + + * sysdeps/stub/__setitmr.c: Fix arg name __WHICH to WHICH. + + * Makeconfig (cross-compiling): Define if $(HOST_CC) and $(CC) differ. + * time/Makefile (install-others): Omit defn ifdef cross-compiling. + +Tue May 3 23:12:48 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/Makefile (lock-headers): Add spin-lock.h. + + * misc/Makefile (routines): Add madvise. + + * malloc/Makefile (non-lib.a): Define. + * misc/Makefile (non-lib.a): Define. + * Makerules (install-lib.a): Filter out $(non-lib.a). + (install-lib-non.a): Append $(non-lib.a). + + * mach/Makefile (mach-headers): Rename sys/version.h to + mach/version.h. + + * hurd/Makefile (headers): Added hurd/threadvar.h. + + * Version 1.07.5. + + * hurd/port2fd.c (_hurd_port2fd): Use logic copied from + _hurd_port_locked_set to install PORT in D->port, but leave it locked. + + * sunrpc/Makefile (generated): Don't add $(objpfx). + + * sysdeps/stub/machine-lock.h: New file. + * sysdeps/stub/machine-sp.h: New file. + +Tue May 3 22:31:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/usleep.c (usleep): Specify MACH_RCV_MSG so that + mach_msg actually waits. + +Tue May 3 19:24:48 1994 Karl Heuer (kwzh@hal.gnu.ai.mit.edu) + + * malloc/malloc.h (enum mcheck_status): Delete trailing + comma in enum list; some compilers don't like it. + +Tue May 3 15:18:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__symlink.c (__symlink): Pass port type arg to + __file_set_translator. + +Mon May 2 17:56:47 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * hurd/Makefile (generated): Add $(inlines) .c files. + + * sysdeps/mach/hurd/__mknod.c: Pass port type arg to + __file_set_translator. + +Sun May 1 16:03:13 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/mig_syms.c: Add de-__ing aliases for mig_init, + mig_get_reply_port, and mig_dealloc_reply_port. + + * sysdeps/mach/hurd/errnos.awk: Handle copying errors from + mach/mig_errors.h and device/device_types.h. Omit E*_SUCCESS. + Omit MACH_MSG_MASK and other special bit macros. + + * sysdeps/mach/hurd/i386/sigcontext.h (struct sigcontext): Added + sc_reply_port member. + * hurd/hurdsig.c (fetch_reply_port): New function. + (_hurd_internal_post_signal): When setting up to run handler, set + SCP->sc_reply_port to the receiving thread's value for + _HURD_THREADVAR_MIG_REPLY. + * sysdeps/mach/hurd/i386/__sigret.c: Destroy the MiG reply port + used by the signal handler, and restore from SCP->sc_reply_port. + * hurd/hurd/threadvar.h (__hurd_threadvar_location_from_sp): New + function; guts from __hurd_threadvar_location. + (__hurd_threadvar_location): Call that. + + * hurd/hurdsig.c (check_pending): New function, broken out of: + (_hurd_internal_post_signal): Call that for pending signal check. + If SIGNO is zero, call check_pending on each thread's sigstate. + + * sysdeps/mach/hurd/start.c (start1): Use calloc to get + zero-filled space for __hurd_threadvar_stack_offset when + __hurd_threadvar_stack_mask is zero. + +Thu Apr 28 21:29:47 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Merged gmp-1.99.3+ mpn code from tege for printf_fp. + * stdio/printf_fp.c: Include "longlong.h"; gmp-impl.h no longer does. + + * Makerules (+depfiles): Filter $(extra-objs) to get only .o files. + +Wed Apr 27 00:20:41 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (depend-$(subdir)): Put output in tmp file and use mv -f. + Always use $(+depfiles), since sources is no longer exported. + +Tue Apr 26 20:05:55 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/bsd4.4/tcdrain.c: Don't include <termios.h> to + avoid <sys/ioctl.h> conflicts. + * sysdeps/unix/bsd/bsd4.4/tcsetattr.c: Undefine ECHO, MDMBUF, + TOSTOP, FLUSHO, PENDIN, and NOFLSH after including <termios.h> and + before including <sys/ioctl.h>. + * sysdeps/unix/bsd/bsd4.4/__tcgetatr.c: Likewise. + +Tue Apr 26 14:42:43 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/sleep.c (sleep): Specify MACH_RCV_MSG or else + mach_msg won't do anything but return immediately. + (sleep): Compute return value correctly. + +Tue Apr 26 04:49:56 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/i386/setjmp.c: Put global register decls first thing. + * sysdeps/i386/__longjmp.c: Likewise. + +Fri Apr 22 18:10:36 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/irix4/__wait3.S: New file. + * sysdeps/unix/sysv/irix4/time.S: New file. + * sysdeps/unix/sysv/irix4/__waitpid.c: New file. + +Thu Apr 21 16:54:11 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/malloc.c (initialize, morecore): When allocating the + _heapinfo block itself, account for it in the statistics. + +Tue Apr 19 20:17:06 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/pipestream.c: New file. + + * malloc/malloc.c (morecore): Only zero the new part of NEWINFO, + not the part we will copy _heapinfo into. + + * sysdeps/unix/bsd/signum.h (SIGLOST): Define. + (_NSIG): Increase to 33. + +Mon Apr 18 16:56:11 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (config.status): Use $configure_args instead of + $ac_configure_args. + (after AC_PREPARE): Call AC_LANG_C. + + * time/Makefile (routines): Add sys/timeb.h. + (routines): Add ftime. + * time/sys/timeb.h: New file. + * sysdeps/unix/bsd/ftime.c: New file. + * sysdeps/generic/ftime.c: New file. + + * sysdeps/posix/getenv.c (getenv): Return NULL if __environ is null. + + * malloc/malloc.h [_MALLOC_INTERNAL] [HAVE_UNISTD_H]: Include + unistd.h. + + * malloc/Makefile (gmalloc-routines): Put valloc first. + +Wed Apr 13 14:03:02 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__symlink.c (__symlink): Set the target of the + link to FROM, not TO. + + * sysdeps/mach/hurd/__readlink.c (__readlink): Copy just the + target into the user's buffer, not the entire translator spec. + +Tue Apr 12 00:13:19 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * hurd/fd-write.c (_hurd_fd_write): Set noctty for now rather + than depending on what happens to be on the stack. + + * sysdeps/mach/hurd/readdir.c (readdir): Notice when hitting + end-of-file and return NULL. + +Mon Apr 11 17:36:59 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/start.c (start1): Bother to set __environ. + + * sysdeps/mach/hurd/__ioctl.c (__ioctl): Comment out use of + HURD_EINTR_RPC until signals work. + +Mon Apr 11 14:16:40 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/__ioctl.c (__ioctl): Call __mig_get_reply_port + rather than __mig_reply_port (which doesn't exist). + + * sysdeps/mach/hurd/__mknod.c: Added temporary declarations + of major and minor. + + * (This change occurred on April 4, 1994) mach/setup-thread.c + (__mach_setup_thread): The March 31 change had an error; the stack + needs to be allocated with ANYWHERE cleared. + + * (This change occurred on April 8, 1994) hurd/hurdexec.c + (_hurd_exec): The arguments to exec_exec had the length and + type parameters transposed. In addition, fetch the correct + procserver port for the new task. + + * (This change occurred on April 8, 1994) + sysdeps/mach/hurd/__wait.c (__wait4): Deal properly with a null + USAGE argument. + + * (This change occurred on April 8, 1994) + sysdeps/mach/hurd/_exit.c (_exit): Changed commented-out call to + __proc_exit into a correct call to __proc_mark_exit. + +Fri Apr 8 14:58:24 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * string/strsignal.c (strsignal): Store of NUL into unknown_signal + was off by one. + +Tue Apr 5 21:26:25 1994 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/__sigact.c (__sigaction): Declare member + `oact' in lower case, to match its use in the rest of the function. + +Tue Apr 5 03:07:04 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (install-lib.a rule): Run ranlib on the target. + + * Makerules (library member rule): Tighten up pattern rule to + match only libc.a, not other libraries. + +Mon Apr 4 21:49:57 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * set-hooks.h: New file. + * Makefile (distribute): Add it. + * set-init.c: Include it and use its macro DEFINE_HOOK_RUNNER. + + * Makerules (sysd-Makefile): Put `sysd-Makefile-done=t' in output. + (sysd-rules): Don't include it unless sysd-Makefile-done is defined. + +Mon Apr 4 18:33:54 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * mach/setup-thread.c (__mach_setup_thread): Oops; the vm_allocate + call should have ANYWHERE cleared so that the change of the 31st + has any effect at all. + +Thu Mar 31 13:46:13 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * mach/setup-thread.c (__mach_setup_thread): Create a red zone + beneath the stack; also, work around a bug in cthreads by + forcing the stack into high memory. FIXME--this routine + depends on the direction of stack growth; that should be fixed. + +Mon Mar 28 12:55:51 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) + + * Rules (make-dummy-lib): Use `$(AR)' instead of literal `ar'. + + * configure.in (arg parsing): Don't take --os-release or --os-version. + (switches): Variable removed; don't write it into config.status. + (config.status): Write release and version values directly. + + * sysdeps/unix/common/configure.in: Use changequote around if expr + to avoid [] elision. + +Sat Mar 26 18:36:27 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) + + * malloc/mcheck.c [! _MALLOC_INTERNAL]: #include <stdio.h> + +Fri Mar 25 02:17:55 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) + + * malloc/mcheck.c (mprobe): New function. + (abortfunc): Take enum mcheck_status arg. + (checkhdr): Return an enum mcheck_status, and pass it to abortfunc. + (mabort): New function. + (mcheck): Use mabort as default abortfunc. + * malloc/malloc.h (enum mcheck_status): New type. + (mprobe): Declare new function. + (mcheck): ABORTFUNC takes an `enum mcheck_status' arg. + + * posix/unistd.h [__USE_GNU] (TEMP_FAILURE_RETRY): New macro. + + * stdio/stdio.h [__USE_GNU && !_LIBC] (cookie_io_functions_t): + Define instead of __io_functions (and make that a typedef for + this); omit __ from member names. + +Thu Mar 24 14:59:23 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/sigaction.h: New file. + + * sysdeps/unix/sysv/sco3.2.4/__sigact.S: Put address of + __sigreturn in %ecx before doing syscall trap. + + * sysdeps/stub/setegid.c: Fix arg type to __gid_t (was int). + +Wed Mar 23 17:33:09 1994 Roland McGrath (roland@mole.gnu.ai.mit.edu) + + * Makefile (headers): Remove $(stdarg.h). + * Makeconfig (stdarg.h): Variable removed. + * configure.in: Remove check for __gnuc_va_list in stdarg.h. + It is not safe to replace the compiler's stdarg.h with our own. + +Tue Mar 22 12:46:08 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Rules (dist): Rule removed. + * Makefile (dist): Likewise. + * Makerules (dist, distinfo): New rules. + (TAGS): Depend on distfile, pass -f distfile to submake. + + * math/Makefile: Remove if-ed out old bsdmath copying rules. + + * Makerules (sources, headers, sysdep_routines): Don't export these. + * Rules (others, tests): Likewise. + + * io/lockf.c: Include fcntl.h and errno.h. + +Mon Mar 21 20:27:32 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sony/newsos4/fchdir.S: New file. + * sysdeps/unix/bsd/sony/newsos4/{__wait4.c,__wait3.c,__wait.c, + sys_wait4.S,Makefile,Dist}: New files. + + * sysdeps/unix/Makefile (syscall.h): De-SYS_ify `kerncall_basenum'. + + * sysdeps/unix/bsd/m68k/sysdep.S [! __motorola__]: Rename label 0 + to `store'; a user reports gas 1.38 bombs on numbered labels. + + * sysdeps/posix/Makefile (mk-stdiolim): Use $(HOST_CC). + + * Rules (distribute, dont_distribute, generated): Don't export them. + (dist): Pass those vars down to sub-make on cmd line. + * Makefile (distribute, generated): Don't export them. + (dist): Pass distribute and generated values to sub-make on cmd line. + + * Makerules (install-lib-nosubdir): Insert $(libprefix) appropriately. + +Fri Mar 18 01:02:52 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h (DO_CALL): Use a6 in + place of fp. A user reports gas 1.38 doesn't grok fp. + +Tue Mar 8 18:35:02 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (common-clean): Prepend $(objpfx) to $(generated). + * Makefile (parent-clean): Prepend $(common-objpfx) to + $(common-generated). + * Makefile (generated): Don't prepend $(objpfx). + * Rules (generated): Likewise. + * sysdeps/unix/common/Makefile (generated): Likewise. + * sysdeps/unix/sysv/Makefile (generated): Likewise. + * sysdeps/unix/Makefile (common-generated): Don't prepend + $(common-objpfx). + * sysdeps/posix/Makefile (common-generated): Likewise. + * sysdeps/generic/Makefile (common-generated): Likewise. + (generated): Don't prepend $(objpfx). + + * sysdeps/generic/Makefile (common-generated): Set this instead of + generated for bytesex.h and det_endian. + + * sysdeps/stub/fexecve.c: New file. + * posix/Makefile (routines): Add fexecve. + * posix/unistd.h [__USE_GNU]: Declare fexecve. + + * sysdeps/unix/common/configure.in: Protect siglist and ctype + checks with if [ ! "$inhibit_glue" ]. + * sysdeps/generic/configure.in: Likewise for psignal check. + * sysdeps/unix/common/Makefile: Protect body with ifndef inhibit-glue. + +Mon Mar 7 17:46:46 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/osf1/alpha/__sigblock.S: New file from brendan. + +Fri Mar 4 01:56:26 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (native-compile, common-objdir-compile): Use + $(HOST_CC) in place of $(CC). + + * malloc/cfree.c: Move #undef cfree inside #ifdef _LIBC. + + * misc/sys/ioctl.h (struct ttysize): If TIOCGSIZE != TIOCGWINSZ, + use two int elts instead of four shorts. + +Thu Mar 3 17:35:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/realloc.c (realloc): When shrinking a block by splitting + and then freeing one, bump the _chunks_used counter. + + * sysdeps/unix/sysv/sysv4/i386/__mknod.S: New file. + +Tue Mar 1 11:42:41 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/__waitpid.S: Get first argument from + stack at 8(%esp), not 4(%esp). + + * sysdeps/unix/sysv/isc2.2/rename.S: Get unix/common, not unix/bsd. + +Thu Feb 24 14:40:43 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * io/lockf.c: New file. + * io/Makefile (routines): Add lockf. + * io/fcntl.h [__USE_MISC] (F_ULOCK, F_LOCK, F_TLOCK, F_TEST): New + macros. + [__USE_MISC] (lockf): Declare it. + * posix/unistd.h: Copy those new macros and declaration. + + * time/backward, time/etcetera, time/zic.c: New code and data from ADO. + * Makeconfig (posixrules): Default to America/New_York. + + * sysdeps/unix/mips/sysdep.S: Store -1 in v0 in the delay slot after + the return, rather than before (leaving the delay slot unfilled and + without a nop!). + + * sysdeps/unix/sysv/irix4: New directory; mips-sgi-irix4 port + courtesy Tom Quinn. + + * sysdeps/unix/sysv/sysv4/direct.h: Moved to unix/common; it is right + for irix4 as well as sysv4. + * sysdeps/unix/bsd/ultrix4/__wait.S: Moved to unix/mips. + (noerror): Store register v1 in location pointed to by first arg (if + not NULL). + * sysdeps/unix/bsd/ultrix4/__sigret.S: Moved to unix/mips. + + * sysdeps/unix/bsd/bsd4.4/{mmap,munmap,mprotect,msync,madvise}.S: + Moved to sysdeps/unix/mman (new directory). + * sysdeps/unix/bsd/bsd4.4/Implies: New file; imply unix/mman. + * sysdeps/unix/bsd/sunos4/Implies: Likewise. + * sysdeps/unix/bsd/ultrix4/Implies: Likewise. + * sysdeps/unix/bsd/osf1/Implies: Likewise. + * sysdeps/unix/bsd/sun/sunos4/munmap.S, + sysdeps/unix/bsd/sun/sunos4/mprotect.S, + sysdeps/unix/bsd/sun/sunos4/madvise.S, + sysdeps/unix/bsd/ultrix4/mmap.S, + sysdeps/unix/bsd/ultrix4/munmap.S, + sysdeps/unix/bsd/ultrix4/mprotect.S, + sysdeps/unix/bsd/osf1/mmap.S, + sysdeps/unix/bsd/osf1/munmap.S, + sysdeps/unix/bsd/osf1/mprotect.S: Files removed. + + * sysdeps/unix/sysv/sysv4/fcntlbits.h: Moved to sysdeps/unix/common. + + * stdio/printf_fp.c: Add many assertions to make sure no mpn size + variable is ever zero. + + * Makerules (native-CFLAGS): Add -I$(sysincludedir). + + * Makerules (depend-$(subdir)) [omit-deps]: Use $(+depfiles) value + instead of shell hackery. + +Wed Feb 23 00:09:08 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/sparc/alloca.S [! NO_UNDERSCORES]: Call it ___builtin_alloca. + +Tue Feb 22 18:47:10 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sunos4/sys/mman.h: Use __off_t in mmap + prototype. + + * time/setitmr.c: Swap args OLD and NEW. + * time/sys/time.h (setitimer): Likewise. + * sysdeps/stub/__setitmr.c: Likewise. + +Mon Feb 21 20:47:55 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/sparc/Makefile [gnulib] (routines): Add alloca. + * sysdeps/sparc/alloca.S: New file; support for SunOS libc's + `__builtin_alloca' function (never needed with GCC). + + * sysdeps/unix/sysv/sysv4/__sigact.c (trampoline): Cast handler to + three-arg type. + +Sun Feb 20 00:46:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sunos4/mmap.c: Add missing semicolon. + + * sysdeps/unix/sparc/start.c [! NO_SHLIB]: Include <sys/types.h> + before <sys/mman.h>. + + * sysdeps/unix/bsd/ultrix4/mips/{sysdep.h,sysdep.S,__pipe.S, + __fork.S,__brk.S}: Moved to sysdeps/unix/mips (new directory). + + * sysdeps/unix/bsd/ultrix4/mips/__sigret.S: Use SYS_sigreturn + instead of literal 103; #define to 103 if not already defined. + +Sat Feb 19 17:39:13 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sysv4/i386/Dist: New file; list sys-sig.S. + +Fri Feb 18 18:07:34 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/configure.in: New file; check for psignal. + + * sysdeps/unix/common/glue-ctype.c: Check for table named _ctype, + before checking for _ctype_. + * sysdeps/unix/common/configure.in: Check for _ctype. + + * sysdeps/unix/Makefile (syscall.h): Look for sys.s before syscall.h. + * sysdeps/unix/configure (unix_syscall_h): Likewise. + + * configure.in (os = irix4*): Set base_os=unix/sysv. + + * sunrpc/rpc/auth.h (u_int32): Always define, no #ifdefs. + * sunrpc/xdr_float.c: Change [mc68000 || sparc] to [! vax]. + +Thu Feb 17 18:42:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.07.4. + + * sysdeps/unix/bsd/sun/sunos4/Dist: Add sys_mmap.S. + + * Makerules (sysdep_dir): Remove defn. + * Makeconfig (sysdep_dir): Define it here instead. + +Wed Feb 16 16:54:00 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sysv4/__sigact.c: New file. + * sysdeps/unix/sysv/sysv4/i386/Makefile: New file. + * sysdeps/unix/sysv/sysv4/i386/sys-sig.S: New file. + + * time/sys/time.h (timerisset, timercmp, timerclear): New macros. + + * misc/Makefile (headers): Add sys/mman.h. + (routines): Add mmap, munmap, mprotect, msync. + * sysdeps/unix/bsd/sun/sunos4/sys_mmap.S: New file. + * sysdeps/unix/bsd/sun/sunos4/mmap.c: New file. + * sysdeps/unix/bsd/sun/sunos4/Makefile [$(subdir) == misc] + (sysdep_routines): Add sys_mmap. + * sysdeps/unix/bsd/bsd4.4/mprotect.S: New file. + * sysdeps/unix/bsd/bsd4.4/munmap.S: New file. + * sysdeps/unix/bsd/bsd4.4/msync.S: New file. + * sysdeps/unix/bsd/bsd4.4/mmap.S: New file. + * sysdeps/unix/bsd/bsd4.4/madvise.S: New file. + * sysdeps/unix/bsd/sun/sunos4/mprotect.S: New file. + * sysdeps/unix/bsd/sun/sunos4/munmap.S: New file. + * sysdeps/unix/bsd/sun/sunos4/msync.S: New file. + * sysdeps/unix/bsd/sun/sunos4/madvise.S: New file. + * sysdeps/unix/bsd/ultrix4/sys/mman.h: New file. + * sysdeps/unix/bsd/ultrix4/mmap.S: New file. + * sysdeps/unix/bsd/ultrix4/munmap.S: New file. + * sysdeps/unix/bsd/ultrix4/mprotect.S: New file. + * sysdeps/stub/mprotect.c: New file. + * sysdeps/stub/munmap.c: New file. + * sysdeps/stub/msync.c: New file. + * sysdeps/stub/mmap.c: New file. + * sysdeps/stub/madvise.c: New file. + * sysdeps/generic/sys/mman.h: New file. + * sysdeps/unix/bsd/sun/sunos4/sys/mman.h: New file. + * sysdeps/unix/bsd/osf1/msync.S: New file. + * sysdeps/unix/bsd/osf1/mmap.S: New file. + * sysdeps/unix/bsd/osf1/munmap.S: New file. + * sysdeps/unix/bsd/osf1/mprotect.S: New file. + * sysdeps/unix/bsd/osf1/sys/mman.h: New file. + +Tue Feb 15 16:47:45 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/unistd.h: Declare truncate, ftruncate. + + * misc/Makefile (headers): Add syslog.h. + * misc/syslog.h: New file; just includes <sys/syslog.h>. + + * posix/unistd.h: Change duplicate seteuid decl to setegid. + + * io/Makefile (headers): Add sys/fcntl.h. + * io/sys/fcntl.h: New file; just includes <fcntl.h>. + +Mon Feb 14 10:36:57 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (library pattern rule): Depend on + $(objpfx)stamp-$(subdir) and have empty commands. + ($(objpfx)stamp-$(subdir)): Move dep on $(objects) and ar cmds here. + (common-mostlyclean): Remove $(objpfx)stamp-$(subdir). + + * Makerules (+depfiles): Filter out deps for modules in $(omit-deps). + + * sunrpc/Makefile (omit-deps): Define new variable. + + * Makerules ($(libc.a)(__.SYMDEF)): Depend on $(+libobjs), not + lib-noranlib. + * Makefile ($(libc.a)(__.SYMDEF)): Depend on subdir_lib. + + * Makerules (+depfiles): Include deps for $(extra-objs). + + * sunrpc/rpcsvc/klm_prot.x: Move program definition to end. + + * sunrpc/Makefile (lib): Depend on $(objpfx)librpcsvc.a. + + * time/zic.c: Set CP to NAME before dereferencing. + + * sunrpc/Makefile ($(objpfx)x%.c): Target fixed from $(objpfx)x%.c. + ($(objpfx)rpcsvc/%.h): Target renamed from $(includedir)rpcsvc/%.h. + Make each x%.o file depend on the corresponding rpcsvc/%.h file. + (headers): Add rpcsvc/%.h. + (install-others): Remove generated rpcsvc headers. + (generated): Define to include generated rpcsvc headers and sources. + + * sysdeps/m68k/fpu/acos.c: Add __CONSTVALUE to defn. + * sysdeps/m68k/fpu/ldexp.c: Likewise. + * sysdeps/m68k/fpu/pow.c: Likewise. + * sysdeps/m68k/fpu/fmod.c: Likewise. + * sysdeps/m68k/fpu/atan2.c: Likewise. + * sysdeps/m68k/fpu/__drem.c: Likewise. + * sysdeps/m68k/fpu/__isinf.c: Likewise. + * sysdeps/generic/hypot.c: Likewise. + * sysdeps/m68k/fpu/__logb.c: Likewise. + + * sysdeps/unix/bsd/m68k/sysdep.S: Swap operands in cmpl. + +Sun Feb 13 19:49:24 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/Makefile (compile-command.S): Remove definition + that did kludgey # hackery. + * sysdeps/unix/bsd/hp/m68k/sysdep.h (PSEUDO): Add missing close paren. + (POUND): Define (no arg) to just `#' (a single pound sign). + (PSEUDO, DO_CALL): Use `POUND foo' in place of `POUND(foo)'. + * sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h: Likewise. + * sysdeps/unix/bsd/sun/m68k/sysdep.h: Likewise. + * sysdeps/unix/bsd/sun/m68k/__brk.S: Use #0, not POUND(0). + * sysdeps/unix/bsd/hp/m68k/__brk.S: Use #__end instead of POUND(__end). + +Fri Feb 11 00:29:45 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (Makefile): Set objdir instead of ARCH in submake cmd. + + * time/mktime.c: Define __P if undefined. + + * assert/assert.h (__ASSERT_FUNCTION): Check __GNUC_MINOR__<6 if + defined(__cplusplus). + +Thu Feb 10 00:52:31 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/__sigact.c: Use __sigismember and + __sigemptyset on sa_mask instead of assuming it's an int. + + * sysdeps/unix/sysv/sysv4/sigset.h (__sigismember): Declare arg + SET to be a pointer to const. + + * sysdeps/posix/__sigpause.c: Convert MASK to a sigset_t with a loop. + + * sysdeps/posix/__sigblock.c: When sigset_t==mask, take address of + SET or OSET, cast to int *, and dereference. + * sysdeps/posix/__sigstmsk.c: Likewise. + * sysdeps/posix/__sigvec.c: Likewise. + + Add the -lrpcsvc library of XDR routines for standard SunRPC protocols. + * sunrpc/Makefile (install-lib): Define to include librpcsvc.a. + (rpcsvc-objs): New variable. + (extra-objs): Add $(rpcsvc-objs). + ($(objpfxlibrpcsvc.a): New target. + ($(objpfx)x%.o): New rule to rpcgen XDR routines. + +Wed Feb 9 11:59:33 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/zic.c (mkdirs): Reapply fix to avoid writing into passed ptr. + + * sunrpc/Makefile (distribute): Add etc.rpc. + ($(includedir)/bootparam_prot.h): Change target to + $(includedir)/rpcsvc/bootparam_prot.h and dep to + $(includedir)/rpcsvc/bootparam.h. + (install-others): Change reference. + + * sunrpc/rpc_util.h: Comment out bogus decl of sprintf. + + * Makerules ($(libc.a)(__.SYMDEF)): Depend on lib-noranlib instead + of $(+libobjs); this way makes the parent do subdir_lib. + + * sysdeps/unix/sysv/sysv4/sigset.h: Protect types with #ifndef + _SIGSET_H_types. Protect rest with #if !defined (_SIGSET_H_fns) + && defined (_SIGNAL_H). + +Tue Feb 8 19:00:42 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.07.3. + + * sysdeps/unix/sysv/sysv4/sigset.h: Fix typos (omitted __s). + +Mon Feb 7 14:31:00 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules ($(libc.a)): Depend on $(libc.a)(__.SYMDEF); no commands. + ($(+libobjs)): Remove static pattern rule. + (ar-it): Target removed. + Replace with pattern rule to catch %(*.o) for all $(objects). + ($(libc.a)(__.SYMDEF)): New target. + (lib-noranlib, $(libdir)/lib$(libprefix)c.a): Don't depend on ar-it. + + * sysdeps/unix/sparc/sysdep.h (PSEUDO): Add nop after jmp; the + next insn is most likely a retl, which causes interesting behavior. + + * stdio/vfprintf.c: Pass WORKEND+1 to _itoa, not WORKEND. + Subtract one from result of _itoa when setting W. + + * time/{africa,asia,australasia,backward,europe,leapseconds, + northamerica,southamerica,zic.c}: New code and data from ADO. + +Sun Feb 6 13:55:27 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sunrpc: New directory; code from Sun's RPCSRC-4.0. + * sysdeps/unix/inet/Subdirs: Add sunrpc. + * inet/netdb.h: #include <rpc/netdb.h> at end. + + * Make-dist ($(tardir).tar): Use -v when extracting from dist.tar + and pipe output to doschk. + + * Makeconfig (etcdir): New variable. + (localtime-file): Use that in default value. + + * Makerules (depend-$(subdir)): Include dep files for all .o files + listed in $(extra-objs). + + * posix/sys/types.h (NFDBITS): #define to __NFDBITS. + + * inet/netinet/in.h (INADDR_LOOPBACK): Don't define if already + defined; avoids changing source which defines it before including this. + (struct sockaddr_in): Rename `__pad' member to `sin_zero'; some + code wants to bzero the area just for paranoia. + + Make cleaning targets only remove common (not specific to one + subdir) generated files if run from the parent directory. + * Makefile (parent-clean): Remove $(common-generated) also. + * sysdeps/unix/Makefile (local_lim.h, sys/param.h, errnos.h, + ioctls.h, syscall.h): Append to $(common-generated), not $(generated). + * sysdeps/posix/Makefile (stdio_lim.h): Likewise. + + * signal/signal.h: Declare psignal here. + * stdio/stdio.h: Not here. + + * stdio/stdio.h [__OPTIMIZE__] (vprintf, vfscanf, vscanf, + vsscanf): Define as extern inline functions instead of macros. + + * configure.in (names): Check existence of implied dirs and warn + for absentees. + +Sat Feb 5 13:38:26 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.07.2. + + * resource/sys/resource.h (RUSAGE_SELF, RUSAGE_CHILDREN): #define + to self for things that test #ifdef. + + * sysdeps/unix/common/Dist: Remove bsd_getgrp.S. + + * sysdeps/unix/Makefile: Don't include param.h.dep ifdef no_deps. + + * Makerules (vpath %.h): Use $(common-objpfx) in place of $(objpfx). + + * sysdeps/unix/bsd/i386/__vfork.S: Decrement R1 and AND it with R0 + to avoid the test and branch. + + * sysdeps/unix/bsd/getprio.S, sysdeps/unix/bsd/setprio.S, + sysdeps/unix/bsd/__setreuid.S, sysdeps/unix/bsd/__setregid.S: Moved to + sysdeps/unix/common. + + * sysdeps/unix/reboot.S: New file. + + * sysdeps/unix/sysv/sysv4/solaris2/signum.h: New file. + * sysdeps/unix/sysv/sysv4/signum.h: New file. + * sysdeps/unix/sysv/sysv4/sigset.h: New file. + * sysdeps/unix/sysv/sysv4/sigaction.h (struct sigaction): Swap + positions of sa_flags and sa_mask members (sa_flags is first now). + (SA_NOCLDWAIT): Renamed from SA_NOSCLDWAIT. + + * sysdeps/unix/bsd/init-posix.c (_posix_start_time): Initialize it. + + * Makerules (open-check-inhibit-asm): Use : for empty commands in case. + + * time/leapseconds: New version from ADO, adds 1994 leap second. + +Thu Feb 3 02:15:30 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/ulimit.c: Define ulimit instead of __ulimit. + +Wed Feb 2 16:56:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/sigsuspend.S: Moved to unix/sysv/sysv4. + Replaced with #include of that file. + + * sysdeps/unix/sysv/sysv4/solaris2/sigaltstack.S: Moved to + sysdeps/unix/sysv/sysv4/sigaltstk.S. + + * sysdeps/unix/sysv/sysv4/i386/__lstat.S: Syscall lxstat, not xlstat. + * sysdeps/unix/sysv/sysv4/i386/__fstat.S: Syscall fxstat, not xfstat. + +Tue Feb 1 18:22:21 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/_itoa.c, stdio/_itoa.h: New files. + * stdio/Makefile (routines): Add _itoa. + (distribute): Add _itoa.h. + * stdio/vfprintf.c: Use _itoa instead of doing it by hand. + + * sysdeps/unix/sparc/vfork.S: Add nop after jmp. Bad delay slot, + no pipeline. + * sysdeps/unix/bsd/ultrix4/mips/vfork.S: Likewise. + +Mon Jan 31 19:33:04 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * assert/assert.c (__assert_fail): Take 4th arg FUNCTION; if it is + not null, print it in the message. Also declare __NORETURN. + * assert/assert.h (__assert_fail): Update decl; also add __NORETURN. + (__ASSERT_FUNCTION): #define to be __PRETTY_FUNCTION__ for GCC>=2.4. + (assert): Pass __ASSERT_FUNCTION to __assert_fail. + + * sysdeps/unix/bsd/sun/sparc/vfork.S: Moved to sysdeps/unix/sparc. + Use C_SYMBOL_NAME on __vfork instead of prepending an underscore. + + * sysdeps/unix/sysv/sysv4/solaris2/{start.c,sysdep.S,sysdep.h}: Moved + to sysdeps/unix/sysv/sysv4/solaris2/sparc. + + * sysdeps/unix/{i386,sysv/sysv4/solaris2,sysv/i386/linux,bsd/m68k, + bsd/ultrix4/mips,bsd/vax}/sysdep.S: Don't do EWOULDBLOCK_sys->EAGAIN + mapping #if EWOULDBLOCK_sys == EAGAIN. + + * sysdeps/unix/sparc/sysdep.h [NO_UNDERSCORES]: #define syscall_error + to C_SYMBOL_NAME(__syscall_error). + (PSEUDO): On error, jump to syscall_error instead of setting errno. + * sysdeps/unix/sparc/sysdep.S: New file. + + * sysdeps/unix/sysv/sysv4/i386/__vfork.S: New file, just #include + unix/bsd/i386 version. + + * sysdeps/unix/bsd/i386/__vfork.S: Use `scratch' in place of %edx. + +Thu Jan 27 16:46:03 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (asm-CPPFLAGS): Add new check to see if assembling + a .S file loses without -P. If so, set asm-CPPFLAGS=-P in config.make. + + * configure.in (stddef.h): Print msg under --verbose. + + * manual/Makefile (subdir): Define outside of `export' directive, + for old make. + + * time/mktime.c (search): Take new arg PRODUCER, fn to call + instead of `localtime'. + (_mktime_internal): New function; all code from old `mktime', but + take 2nd arg PRODUCER and pass along to `search'. + (mktime): Rewrite to call _mktime_internal with localtime. + * time/Makefile (routines): Add dysize, timegm, timelocal. + * time/time.h (_mktime_internal): Declare it. + [__USE_MISC]: Declare timegm, timelocal, dysize. + * time/dysize.c: New file. + * time/timegm.c: New file. + * time/timelocal.c: New file. + +Wed Jan 26 20:06:23 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + Remove the hackery on getgroups for most systems. It is no longer + necessary because gid_t is now the same size as int. + * sysdeps/unix/common/Makefile (sysdep_routines): Don't add bsd_getgrp. + * sysdeps/unix/common/bsd_getgrp.S: File removed. + * sysdeps/unix/common/__getgrps.S: New file. + * sysdeps/unix/bsd/sequent/i386/__getgrps.S: New file. + + Clean up the rules for cleaning up. + * Makerules (common-mostlyclean): New target; remove object files. + (common-clean): New target; depend on common-mostlyclean, and + remove dep files and generated files. + (clean): Depend on common-clean. + (mostlyclean): Depend on common-mostlyclean. + * Rules (mostlyclean): Target removed. + (clean): Target removed. + (distclean): New target; depend on clean. + (realclean): New target; depend on distclean. + (subdir_distclean): New target; depend on distclean. + (subdir_realclean): New target; depend on realclean. + (subdir_mostlyclean): New target; depend on mostlyclean. + * Makefile (+subdir_targets): Add subdir_distclean, + subdir_realclean; change mostlyclean to subdir_mostlyclean. + (parent-mostlyclean): New target; depend on common-mostlyclean and + remove libc.a and $(install-lib). + (parent-clean): New target; depend on parent-mostlyclean and + common-clean, and remove sysdirs sysd-dirs sysd-Makefile. + (clean): Depend on parent-clean and just do submake for subdirs. + (mostlyclean): Depend on parent-clean and just do submake for subdirs. + (distclean, realclean): Depend on parent-clean and do submake + distclean-1 passing it variable assignment distclean-1=$@. + (distclean-1): Depend on subdir_$(distclean-1) and remove + $(config-generated), config.status, config.make, Makefile (if not + in srcdir). + * manual/Makefile (subdir_clean): Target removed. + (subdir_%): New rule to handle all such targets. + (distclean): Depend on clean, not mostlyclean. + (realclean): Depend on distclean, not clean. + + * sysdeps/unix/configure (unix_generated_dirpfx): New variable. + Use it to put created .S files in sysdeps/unix if configured in + srcdir, else in current directory. + (unix_generated): Prepend $unix_generated_dirpfx. + Have generated config.make fragment prepend $(objpfx). + * sysdeps/unix/Makefile (generated): Don't set it. + (config-generated): Set this instead; don't prepend any directory + prefix to $(unix-generated). + + Fixes for SVR4 wait from jmc@ksu.ksu.edu (James Michael Chacon): + * sysdeps/unix/sysv/sysv4/siginfo.h (__siginfo_t): Add `__code' + and `__pid' fields. + (EXITED, KILLED, CORED, TRAPPED, STOPPED, CONTINUED): New macros. + * sysdeps/unix/sysv/sysv4/__waitpid.c: Switch on INFOP.__code and + construct *STAT_LOC from INFOP.__status accordingly. + + * stdlib/testsort.c (main): Use puts to add newlines to printed lines. + +Tue Jan 25 14:32:01 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.07.1. + + * manual/Makefile (%.z): Change target pattern to %.gz. + (dist): Comment out dep. Don't really need the separate doc dist. + + * stdio/stdio.h [__OPTIMIZE__] (getchar, putchar, getdelim, + getline, __getline): Use extern inlines instead of macros. + + * sysdeps/unix/sysv/sco3.2.4/__waitpid.S: Fix typo ($eax for %eax). + + * sysdeps/unix/siglist.c [! HAVE_GNU_LD] (_sys_siglist): #define + to sys_siglist. + * sysdeps/posix/__gettod.c [! HAVE_GNU_LD] (__daylight, + __timezone, __tzname): #define to non-__ names. + + * math/math.h [__USE_BSD] (M_E, M_LOG2E, M_LOG10E, M_LN2, M-LN10, + M_PI, M_PI_2, M_PI_4, M_1_PI, M_2_PI, M_2_SQRTPI, M_SQRT2, + M_SQRT1_2): New macros. + +Tue Jan 25 14:01:28 1994 Michael I. Bushnell (mib at ernst.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/start.c (start1): Decide separately whether to + split argv and whether to split envp. + + * sysdeps/mach/hurd/i386/sysdep.h: File deleted. + sysdeps/mach/i386/sysdep.h: Delete SET_SP macro. + sysdeps/mach/hurd/start.c (_start): Don't call GET_SP; set globals + instead of locals from exec_startup message. + + * misc/progname.c: Don't try to set + program_invocation_name or program_invocation_short_name if argv + or argv[0] is invalid. + +Mon Jan 24 16:51:43 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sysv4/__waitpid.c: Return INFOP.__pid instead of + the PID we were called with. + + * sysdeps/unix/sysv/__mkdir.c (__mkdir): Restore errno before + returning, not after (lot of good that did). + + * sysdeps/unix/bsd/ultrix4/system.c, sysdeps/unix/bsd/bsd4.4/system.c, + sysdeps/unix/bsd/osf1/system.c, sysdeps/unix/sysv/sco3.2.4/system.c, + sysdeps/unix/bsd/sun/sunos4/system.c, sysdeps/unix/sysv/sysv4/system.c: + New files. Avoid sysdeps/unix/system.c, which defines NO_WAITPID. + + * set-init.c (__libc_init): Use `n' count field instead of + checking for null terminator. The latter loses when there are no + set elts at all, and only one word is allocated for __libc_subinit. + + * sysdeps/generic/waitstatus.h (__WCOREFLAG): New macro. + * posix/sys/wait.h [__USE_BSD] (WCOREFLAG): New; define to __WCOREFLAG. + + * stdio/fileno.c (fileno): Call __stdio_check_funcs. + + * stdio/tst-fileno.c: New file. + +Fri Jan 21 16:56:50 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Rules (dep-dummy-lib, make-dummy-lib): New variables. + ($(objpfx)dummy.o): New file rule. + * posix/Makefile ($(objpfx)libposix.a): Depend on + $(dep-dummy-lib), and use $(make-dummy-lib) for commands. + * math/Makefile ($(objpfx)libm.a): Likewise. + + * sysdeps/unix/sysv/sysv4/i386/__stat.S: New file. + * sysdeps/unix/sysv/sysv4/i386/__lstat.S: Likewise. + * sysdeps/unix/sysv/sysv4/i386/__fstat.S: Likewise. + + * sysdeps/sparc/bytesex.h: New file. + +Thu Jan 20 12:45:35 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/syscall.c (syscall): Declare arg type as int. + +Wed Jan 19 18:18:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules ($(before-compile) rule): Protect w/`ifdef before-compile'. + + * manual/Makefile: Change all `mv' uses to `mv -f'. + (subdir_install): Depend on stubs. + + * Makerules ($(objpfx)%.dep: %.s): Depend also on $(objpfx)dummy.dep. + +Tue Jan 18 19:12:57 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/testsort.c (main): Swap dimensions of BUFS array. + +Mon Jan 17 17:31:28 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.07 released. + + * Makerules (install-lib rules): Fix typos: missing / after $(libdir). + + * posix/Makefile (lib): Depend on $(objpfx)libposix.a + * malloc/Makefile (lib): Depend on $(objpfx)libmcheck.a. + * math/Makefile (lib): Depend on $(objpfx)libm.a. + * misc/Makefile (lib): Depend on $(objpfx)libbsd-compat.a. + + * sysdeps/unix/sysv/sco3.2.4/__setpgid.c: New file. + + * stdio/internals.c (flushbuf): Don't try aligned-block writing + calculation when FP->__buffer is nil. + +Mon Jan 17 17:27:56 1994 Jim Meyering (meyering@comco.com) + + * sysdeps/generic/memcmp.c [!_LIBC]: Include <sys/types.h> for + definition of size_t. + +Mon Jan 17 17:13:11 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/syscall.h: Add SYS_[gs]etitimer and + SYS_pgrpsys (from scottb). + + * sysdeps/unix/configure: Check for getitimer and setitimer syscalls. + + * sysdeps/unix/bsd/sequent/i386/syscall.S: New file from jason. + +Sun Jan 16 00:41:03 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * string/strerror.c (strerror): Declare BUF to be array of char. + + * Version 1.06.13. + +Sat Jan 15 17:27:26 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/testsort.c (main): Rewrite not to read any input; instead + generate some random alphabetic strings. + + * stdlib/Makefile (testsort.input): Rules removed. + + * sysdeps/unix/sysv/i386/__sigret.S: New file. + + * stdio/Makefile (distribute): Add mpn-copy.mk. + Remove 68k rules; include mpn-copy.mk for dir names needing + translation, and rewrite no-68k rules to be generic for the rest. + (mpn-copy-sysdep): New variable. + (mpn-stuff): Include $(mpn-copy-sysdep). + (clean-mpn): Use rm -f. + + * configure.in (machine): Match m68... and m88..., not mc[68]8.... + + * stdio/printf_fp.c: For length arg to __mpn_extract_double, pass + actual number of limbs allocated for F, not LDBL_MANT_DIG. + +Fri Jan 14 19:09:29 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/i386/sysdep.S: Fixed typo: `movl', not `move'. + + * sysdeps/unix/sysv/sco3.2.4/__sysconf.S: Swap args in cmpl insn. + +Thu Jan 13 17:09:19 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.12. + + * sysdeps/mips/sqrt.c: File removed. Ian says only the r[46]00 + have `sqrt.d' and GCC open codes it anyway. Perhaps someday + Brendan will be able to explain his rationale for writing this. :( + +Tue Jan 11 18:10:17 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/sys/wait.h (__WAIT_STATUS, __WAIT_STATUS_DEFN): Use snazzy + version only for GCC >= 2.6 (was 2.4); 2.5.7 produces bad code on + sparc when the union arg type is used. + + * Makeconfig (libprefix): New variable. + * Makerules ($(libdir)/libc.a, install): Insert $(libprefix) + between `lib' and `c' in the file name. + [install-lib] (install-lib.a, install-lib-non.a): New variables + separate out $(install-lib) elts which do or don't match lib%.a. + ($(libdir)/...): Split into two rules for above two cases. Put + $(libprefix) on installed files; for lib%.a insert it before % + rather than at beginning of file name. + + * Version 1.06.11. + + * Makerules (compilation rules): Move directoryless rules (for + finding sources in .) before include sysd-rules. Omit rules to + compile from sources in $(objpfx) if not using $(objdir). + + * sysdeps/stub/errlist.c [! HAVE_GNU_LD]: #define _sys_errlist to + sys_errlist and _sys_nerr to sys_nerr. + +Mon Jan 10 15:01:32 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/Makefile (z.%): In generated rules, depend on yearistype. + (tzcompile): Pass -y flag with file name of yearistype. + +Sun Jan 9 17:51:43 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/bsd-compat.c (longjmp): Use __NORETURN in type. + + * sysdeps/ieee754/dbl2mpn.c [N == 2]: For denormal, when + RES_PTR[1] is zero, return 1 instead of 2. + +Sun Jan 9 13:10:25 1994 Torbjorn Granlund (tege@adder.cygnus.com) + + * stdio/printf_fp.c: Solve 10+ problems. + * ieee754/dbl2mpn.c: Correctly detect denorms. Get the denom + exponent right. + +Sun Jan 9 00:40:48 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/ieee754/dbl2mpn.c: Test BITS_PER_MP_LIMB and handle + either 32 or 64; #error if not one of those. + + * sysdeps/stub/udiv_qrnnd.c: Renamed from udiv_qrnnd.S. + +Sat Jan 8 00:25:15 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.10. + + * Makerules ($(libdir)/libc.a): Depend on subdir_install. + +Thu Jan 6 02:17:07 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules ($(bindir)/$(install)): Use $(INSTALL_PROGRAM), not + $(INSTALL). + ($(libdir)/libc.a): Don't depend on lib-noranlib; on libobjs and + ar-it instead. Run ranlib on target after installing. + (installdirs): Target removed; deps on it removed. + (install-{bin,lib,data,headers,others,no-libc.a}): Renamed to + `install-*-nosubdir'. + (install-%): New pattern rule. + (install): Depend only on install-no-libc.a-nosubdir. + * Rules (subdir_install): Depend on lib-noranlib and stubs. + * Makefile (headers): Remove stubs.h. + (install-others): Define to include $(includedir)/stubs.h. + ($(includedir)/stubs.h): New target for $(objpfx)stubs.h rule. + Depend only on subdir_install, and install directly. + + * Makerules (sed-remove-objpfx): Require SPC before $(objpfx) to match. + + * time/zic.c (mkdirs): Duplicate passed string in allocated memory + and free it when done. + + * dirent/dirent.h [__USE_BSD || __USE_MISC]: Get size_t from stddef.h. + + * sysdeps/ieee754/dbl2mpn.c: For zero value, return 1 limb not 0. + + * Makerules (make-dummy-dep): Use filter-out to invert sense of + wildcard match, so we produce a command if $@ does *not* exist.c + + * stdio/Makefile (routines): Add dbl2mpn. + +Wed Jan 5 17:52:43 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/i386/sysdep.S (syscall_error): Reverse args in + `cmpl' insn; non-GNU assembler is feeble-minded. + +Mon Jan 3 18:53:45 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (sysnames): Remove / before $mach; it is prepended + already by the loop constructing $mach from $machine. + +Tue Dec 28 07:38:23 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/Makefile [gmp-srcdir] (clean-mpn): New target. + + * configure.in (machine): Turn i[34]86 into i386/&, sparc* into + sparc/&, m68k into m68k/mc68020, mc680?0 into m68k/&, mips or + r2000 into mips/r3000, r[34]000 into mips/&. + (mach): New variable; processed from $machine as $base from $base_os. + Use that in place of $machine in loop finding sysdep directories. + + * stdio/Makefile (aux): Add mp_clz_tab. + (mpn-copy): Add mp_clz_tab.c. + (mpn-routines): Add udiv_qrnnd. + (mpn-sysdep): Look for .s files too. + * sysdeps/stub/udiv_qrnnd.S: New file. + +Sat Dec 25 00:20:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.9. + + * Makefile (distribute): Add install.sh. + * install.sh: New file. + + * sysdeps/i386/Makefile: New file. + (asm-CPPFLAGS): Add -DGAS_SYNTAX. + + * stdio/printf_fp.c: Major rewrite of sysdeps/generic/printf_fp.c, + working with the fractional parts as multiprecision integers + instead of doubles, using mpn functions from GNU MP. Done with + much help from tege@cygnus.com. + * sysdeps/generic/printf_fp.c, sysdeps/ieee754/printf_fp.c, + sysdeps/m68k/fpu/printf_fp.c: Files removed. + +Fri Dec 24 23:09:44 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/dbl2mpn.c, sysdeps/iee754/dbl2mpn.c: New files. + * sysdeps/stub/asm.h: New file. + * sysdeps/m68k/add_n.S, sysdeps/m68k/addmul_1.S, + sysdeps/m68k/mul_1.S, sysdeps/m68k/sub_n.S, + sysdeps/m68k/submul_1.S, sysdeps/m68k/asm.h, + sysdeps/generic/add_1.c, sysdeps/generic/add_n.c, + sysdeps/generic/addmul_1.c, sysdeps/generic/cmp.c, + sysdeps/generic/divmod.c, sysdeps/generic/divmod_1.c, + sysdeps/generic/lshift.c, sysdeps/generic/rshift.c, + sysdeps/generic/mod_1.c, sysdeps/generic/mul.c, + sysdeps/generic/mul_1.c, sysdeps/generic/mul_n.c, + sysdeps/generic/sub_n.c, sysdeps/generic/submul_1.c, + sysdeps/generic/get_str.c, sysdeps/i386/addmul_1.S, + sysdeps/i386/mul_1.S, sysdeps/i386/submul_1.S, + sysdeps/alpha/gmp-mparam.h, sysdeps/generic/gmp-mparam.h, + sysdeps/i386/asm.h, stdio/longlong.h, stdio/gmp.h, + stdio/gmp-impl.h: New files, taken from GNU MP. + * stdio/Makefile (mpn-headers, mpn-routines): New variables. + (routines): Include $(mpn-routines). + (distribute): Include $(mpn-headers). + [gmp-srcdir]: Much code to copy mpn source from $(gmp-srcdir). + * configure.in: Check for a --with-gmp argument and set gmp-srcdir + in config.make to its value (error if no arg given). Move + config_vars initialization before this (right after arg parsing). + +Thu Dec 23 01:44:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/Makefile (m68k-syntax-flag): New variable. + (compile-command.S): Include $(m68k-syntax-flag) in cpp flags. + + * manual/Makefile (install-data): New target. + (install-%): New pattern rule. + + * Makerules ($(bindir)/...): Do $(make-target-directory) first. + +Thu Dec 23 01:03:19 1993 Brendan Kehoe (brendan@zen.org) + + Port to the DEC Alpha running OSF/1. (75% done) + * sysdeps/unix/bsd/osf1/alpha/start.S: New file. + * sysdeps/unix/bsd/osf1/alpha/sysdep.h: New file. + * sysdeps/unix/bsd/osf1/alpha/sysdep.S: New file. + * sysdeps/unix/bsd/osf1/alpha/__brk.S: New file (incomplete). + * sysdeps/unix/bsd/osf1/alpha/__fork.S: New file. + * sysdeps/unix/bsd/osf1/alpha/__pipe.S: New file. + * sysdeps/unix/bsd/osf1/alpha/__getdents.S: New file. + * sysdeps/unix/bsd/osf1/alpha/__waitpid.c: New file. + * sysdeps/unix/bsd/osf1/alpha/__wait4.S: New file. + * sysdeps/unix/bsd/osf1/dirstream.h: New file. + * sysdeps/unix/bsd/osf1/alpha/statbuf.h: New file. + * sysdeps/unix/bsd/osf1/direct.h: New file. + * sysdeps/unix/bsd/osf1/dirstream.h: New file. + * sysdeps/unix/bsd/osf1/Makefile: New file, defining LDFLAGS. + + * sysdeps/unix/ioctls-tmpl.c [__osf1__ && __alpha__]: Clean up the + ioctls that we get for an Alpha running OSF/1. + + * sysdeps/unix/common/glue-ctype.c: Add code for HAVE__LOCP. + (main): If new macro TABLE_NAME is defined, use that for the name + of the array we're writing out, rather than what's defined in TABLE. + * sysdeps/unix/common/configure.in (AC_HAVE_FUNCS): Add `_locp'. + + * sysdeps/unix/bsd/osf1/sigaction.h: Add SA_ONSTACK, SA_RESTART, + and SA_DISABLE. + * sysdeps/alpha/setjmp.S: Add .end directive. + + * time/sys/time.h (struct timeval): Make members TV_SEC and + TV_USEC be `int', not `long', since it won't hurt other hosts, but + kills the Alpha. + * resource/sys/resource.h (struct rusage): Make all non-timeval + members be `long', not `int'. + + * sysdeps/alpha/strlen.c (strlen): Go from 0 to 7, not 3, since + there are 8 bytes in a long on the Alpha. Check for '\0' after + checking for C in initial byte-by-byte loop. + * sysdeps/alpha/strchr.c (strchr): Likewise. Shift out to 64 when + setting CHARMASK. + * sysdeps/alpha/memchr.c (memchr): Likewise. Return NULL if we + didn't find it in N characters, or N == 0. Declare CP to be an + unsigned char*. + + * sysdeps/alpha/Makefile: Add divrem stuff. + * sysdeps/alpha/DEFS.h: New file. + * sysdeps/alpha/divrem.m4: New file. + * sysdeps/alpha/macros.m4: New file. + * sysdeps/alpha/Dist: Add .S files, divrem.m4, macros.m4, and DEFS.h. + + * sysdeps/unix/bsd/osf1/alpha/vhangup.S: New file. (Only a + temporary workaround, until we figure out how to deal with the + SYS_ult syscalls better.) + * sysdeps/unix/bsd/osf1/alpha/killpg.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigvec.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigpause.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/__sigstmsk.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/recv.S: Likewise. + * sysdeps/unix/bsd/osf1/alpha/send.S: Likewise. + + * sysdeps/alpha/__math.h (__copysign): Add __CONSTVALUE. + * sysdeps/alpha/__copysign.c: Define __NO_MATH_INLINES. + * sysdeps/alpha/fabs.c: Likewise. + +Wed Dec 22 17:55:49 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * crypt/*: New version from glad. + + * sysdeps/unix/sysv/sysv4/Dist: Add __getpgid.c and __setpgid.c. + + * dirent/Makefile (headers): Define; include dirent.h & dirstream.h. + +Tue Dec 21 14:24:38 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/i386/statbuf.h (struct stat): Add + missing member ST_FSTYPE. Fixup types on various members to make + this properly reflect what the system has. + + * misc/ioctl.c (ioctl): Declare 2nd arg to be unsigned long int to + match the change in ioctl.h. + +Tue Dec 21 00:01:01 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.8. + + * dirent/dirent.h (struct dirent): Add `d_reclen'; make `d_namlen' + an `unsigned short int' instead of `size_t'. + (DIR): Move typedef to sysdep file dirstream.h. + * sysdeps/unix/dirstream.h: New file, broken out of dirent.h. + * sysdeps/stub/dirstream.h: New file. + * sysdeps/unix/bsd/dirstream.h: New file. + * sysdeps/unix/bsd/readdir.c: New file. + +Mon Dec 20 23:29:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/start.c: Include <sysdep.h>. + * sysdeps/unix/sysv/sysv4/i386/start.c: File removed. + +Sat Dec 18 01:37:25 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/i386/start.c: New file. Same as + sysdeps/unix/i386/start.c, but defines NO_UNDERSCORES. + + * sysdeps/unix/sysv/sysv4/waitflags.h: New file, with non-standard + WEXITED and WTRAPPED macros defined. + * sysdeps/unix/sysv/sysv4/__waitpid.c: New file. + * sysdeps/unix/sysv/sysv4/siginfo.h: New file. + * sysdeps/unix/sysv/sysv4/__waitid.S: New file. + * sysdeps/unix/sysv/sysv4/Makefile (sysdep_routines): Mention __waitid. + * sysdeps/unix/sysv/sysv4/pipestream.c: New file, to avoid having + NO_WAITPID set. + * sysdeps/unix/sysv/sysv4/Dist: Added __waitid.S and siginfo.h. + + * sysdeps/unix/sysv/sysv4/__getpgid.c: New file. + * sysdeps/unix/sysv/sysv4/__setpgid.c: New file. + * sysdeps/unix/sysv/sysv4/Makefile (sysdep_routines): Add them. + + * sysdeps/unix/sysv/sysv4/__getpgrp.c (__getpgrp): It's the 0th + subcall for getpgrp, not 4th. + * sysdeps/unix/sysv/sysv4/__setpgrp.c (__setpgrp): Likewise, it's + the 1st, not the 5th. + +Fri Dec 17 15:05:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/sys/ioctl.h (__ioctl, ioctl): Make second arg `unsigned + long int' instead of `int' (4.4 uses unsigned long). + + * string/string.h (strcat): Parameters names were swapped. + +Fri Dec 17 01:18:27 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * Made the Hurd error system 0x10 again; this undid many + of the changes of Nov 23. Affected all the err_ files in + mach; recreated sysdeps/hurd/err_hurd.sub; changed back + err_kern.sub to have the Unix error codes. + +Thu Dec 16 15:40:25 1993 Brendan Kehoe (brendan@zen.org) + + * stdio/temptest.c (main): Remove the files we created once we're + done. Make return type int, and exit with 0 status. + + * sysdeps/posix/tempname.c (__stdio_gen_tempname): Fix typo of + extra comma in sprintf call. + +Tue Dec 14 13:08:35 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/tempname.c (__stdio_gen_tempname): Rewrote main + logic. Removed INFOS structure array and replaced it with + INDICES, an array of size_t. Removed INFO ptr and replaced it + with IDX, which points to either elt of INDICES. Rewrite main + loop to increment *IDX until it hits 62*62*62. Construct file + name by dividing out two powers of 62 from *IDX and using the + modulus as an index into `letters'. + + * sysdeps/unix/common/Makefile (sysdep_routines): Only add + bsd_getgrp here if the sysdep __getgrps.? chosen is unix/common's. + + * posix/fnmatch.h: #undef FNM_PATHNAME, FNM_NOESCAPE, and + FNM_PERIOD before defining them. + + * time/__tzset.c (compute_change): In M case when tallying time in + months before specified month, count to RULE->m - 1, not ...+1. + + * manual/Makefile (realclean): Remove index, aux, and toc files + created by TeX. + +Mon Dec 13 19:33:33 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/__wait3.c: Use __WAIT_STATUS_DEFN in place of + __WAIT_STATUS in arg type. + +Wed Dec 8 15:59:45 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/memalign.c: Set L->next and _aligned_blocks only when L + is newly allocated, not when we reuse an old one. + +Tue Dec 7 16:04:22 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * io/fcntl.c: Replace function_alias use with: + [HAVE_GNU_LD]: Use symbol_alias. + [! HAVE_GNU_LD]: Define fcntl to use stdarg and call __fcntl. + +Mon Dec 6 17:50:05 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/i386/sysdep.S (syscall_error): Fix labels so + they'll compile. + + Make the Solaris port work dammit. + * sysdeps/unix/sysv/sysv4/solaris2/statbuf.h (struct stat): Make + ST_DEV member be unsigned long, not short. + + * sysdeps/unix/sysv/sysv4/solaris2/direct.h: New file, same as + sysv4/direct.h but uses strlen instead of the offset-based + computation of the name length, since that doesn't reliably work + for Solaris. + + * sysdeps/unix/sysv/sysv4/solaris2/sysdep.h (PSEUDO): Don't move + %g0 into %o0, since that will clobber the real return value. Take + out the retl at the end, why in the world did I put it in there? + +Mon Dec 6 17:27:26 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile ($(objpfx)crt1.o): Add target to $(objpfx)Mcrt1.o + rule; generalize commands. + (install-lib): Add crt1.o. + + * sysdeps/unix/Makefile ($(common-objpfx)ioctls): Use -x flag to + fgrep to match only entire lines. + +Sun Dec 5 01:53:43 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/bsd/ultrix4/mips/start.S: New file. + * sysdeps/unix/bsd/ultrix4/mips/start.c: Deleted. + +Thu Dec 2 18:29:01 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/bsd/ultrix4/mips/sysdep.S: Don't use dollar signs + with the errnos. + + * sysdeps/stub/{__wait, __wait3, __wait4}.c, + sysdeps/unix/bsd/bsd4.4/{__wait, __wait3}.c, + sysdeps/unix/bsd/sun/sunos4/__wait4.c, + sysdeps/posix/{__wait, __wait3}.c, posix/{wait, wait3, wait4}.c: Use + __WAIT_STATUS_DEFN, not __WAIT_STATUS. + + * sysdeps/posix/killpg.c (killpg): Make arg PGRP __pid_t, not pid_t. + * sysdeps/stub/killpg.c (killpg): Likewise. + + * setjmp/longjmp.c (longjmp): Only use __NORETURN if !HAVE_GNU_LD. + * setjmp/_longjmp.c (_longjmp): Likewise. + +Thu Dec 2 17:31:19 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/sys/wait.h (__WAIT_STATUS_DEFN): Define new macro. + + * Makerules (+install): Variable removed. + (install-bin, install-lib, install-data, install-headers, + install-others): New targets. + (install-no-libc.a): Depend on them instead of $(+install). + + * Makefile (+subdir_targets): Add + install-{no-libc.a,bin,lib,data,headers,others}. + (install-no-libc.a): Don't depend on subdir_install. + +Thu Dec 2 17:14:39 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/ieee754/__isnan.c (__isnan): Return __CONSTVALUE, to + match declaration in math/math.h. + +Thu Dec 2 15:48:19 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/africa, time/antarctica, time/asia, time/australasia, + time/emkdir.c, time/europe, time/ialloc.c, time/northamerica, + time/pacificnew, time/private.h, time/solar87, time/solar88, + time/southamerica time/systemv, time/tzfile.h, time/zdump.c, + time/zic.c: New data and code from ADO. + * time/Makefile (tzfiles): Added backward. + * time/backward: New file from ADO. + + * locale/C-ctype_ct.c: Remove _ISspace bit from BS (8). + +Wed Dec 1 00:01:30 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * mach/err_kern.sub: Frob around lack of GNU ld. + + * mach/errsystems.awk: The declaration of __mach_error_systems + should not be static, but it should be const. + + * sysdeps/mach/hurd/errlist.awk (BEGIN): Deal with the case + where you don't have GNU ld. + + * sysdeps/mach/hurd/Makefile: Define mib_hacks to make. + +Tue Nov 30 23:24:07 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * Makefile: install-no-libc.a needs to depend on subdir_install. + +Mon Nov 29 16:21:38 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sysdeps/mach/_strerror.c: Include <mach/errorlib.h>. + + * hurd/setuids.c: Put entire file inside #ifndef MIB_HACKS; + it uses the old auth_makeauth call. + + * hurd/__setauth.c: Put entire file inside #ifndef MIB_HACKS; + it depends on cthreads to compile, which is not yet integrated. + + * hurd/hurdpath.c (__hurd_path_lookup): cast to avoid GCC warning. + +Wed Nov 24 00:59:15 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * hurd/Makefile: Commented out hurdauth; recent changes to + auth.defs prevent it from working now. + + * mach/mach_error_string.c (do_compat): Change name to + __mach_error_map_compat; make it no longer static. + (mach_error_type, mach_error_string_int): Use + __mach_error_map_compat instead of do_compat. + * sysdeps/mach/_strerror.c: Use __mach_error_map_compat. + + * mach/devstream (output/write_some): Cast fourth argument to + device_write_inband to char * to avoid warning. + (output): Call to write_some mentioned variable `start' from + a previous version of the function; changed this to f->__buffer. + +Tue Nov 23 23:16:13 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + [ The net effect of the following change is to eliminate error + systems which are specific to single-server Mach systems, and + to put the Hurd errors where the Unix errors were. ] + * mach/{err_bootstrap.sub,err_ipc.sub,err_server.sub,err_us.sub}: + None of these are used for the Hurd; we shouldn't pretend that + they are meaningful in our environment. The files have been + renamed to equivalent names with an equal sign prepended; this + will inhibit distribution and prevent the Makefile from looking at + them. + * mach/err_kern.sub: Deleted the definitios of err_codes_unix; + get the strings from _sys_errlist. Rename `unix' to `hurd'. + Rename err_os_sub to be err_kern_sub to match what errsystems.awk + expects. + * sysdeps/mach/hurd/err_hurd.sub: Deleted this file. + * sysdeps/mach/hurd/errnos.awk: Changed definition of _HURD_ERRNO + to be correct. + + * sysdeps/mach/hurd/Makefile: use gawk, not awk. + + * mach/errsystems.awk: Generally rewrote the printf. It's now + closer to Roland's original, but without the $i mistake at all, + in any form. + +Tue Nov 23 20:21:06 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/{i386,sysv/sysv4/solaris2,sysv/i386/linux,bsd/m68k, + bsd/ultrix4/mips,bsd/vax}/sysdep.S: Define _ERRNO_H before + including <errnos.h>; otherwise <errnos.h> does not define most + macros (importantly, EAGAIN!). + +Tue Nov 23 12:43:38 1993 Michael I. Bushnell (mib at ernst.gnu.ai.mit.edu) + + * mach/errsystems.awk: $i is not an index; make i a variable and + increment it properly. Don't call `err_get_system'; use the + system number as the index in the array directly. + + * mach/errorlib.h: Added `const' in all the right places. + * sysdeps/mach/hurd/err_hurd.sub: Cast _sys_errlist to + the right type. Better to declare it right in stdio/stdio.h, but + I don't dare change that file lest Roland call me a twit. + * mach/err_us.sub: Add more brackets to initializer to shut GCC up. + + * sysdeps/mach/hurd/err_hurd.sub: Delete keyword `const'; this + is taken care of by the `#define static static const' found in + errsystems.c as created by mach/errsystems.awk. + * mach/errsystems.awk: Ditto for declaration of __mach_error_systems. + + * sysdeps/mach/hurd/err_hurd.sub: Change <errnos.h> to <errno.h>; + errnos.h doesn't define most stuff unless it is included from errno.h. + + * mach/mach_error_string.c (mach_error_string_int): Delete unused + variable `err_str'. + + * mach/mach_error_string.c (do_compat): Declare to be void. + (mach_error_string,mach_error_type, mach_error_string_int): + Declare return type as const char *. + * mach/mach_error.h: Change declarations to match. + + * mach/errsystems.awk: The array that split creates is origin 1, + not origin 0; fixed loop to match. + + * sysdeps/mach/hurd/errnos.awk: Ernst's awk doesn't grok + backslash-newline inside strings. + +Sat Nov 20 19:02:25 1993 Brendan Kehoe (brendan@zen.org) + + * math/__finite.c (__finite): Return __CONSTVALUE, to match math.h. + * math/__scalb.c (__scalb): Likewise. + * math/copysign.c (copysign): Likewise. + * math/drem.c (drem): Likewise. + * math/expm1.c (expm1): Likewise. + * math/finite.c (finite): Likewise. + * math/infnan.c (infnan): Likewise. + * math/isinf.c (isinf): Likewise. + * math/isnan.c (isnan): Likewise. + * math/logb.c (logb): Likewise. + * math/rint.c (rint): Likewise. + * math/scalb.c (scalb): Likewise. + * sysdeps/generic/atan.c (atan): Likewise. + * sysdeps/ieee754/__copysign.c (__copysign): Likewise. + * sysdeps/ieee754/__drem.c (__drem): Likewise. + * sysdeps/ieee754/__isinf.c (__isinf): Likewise. + * sysdeps/ieee754/__logb.c (__logb): Likewise. + * sysdeps/ieee754/ldexp.c (ldexp): Likewise. + * sysdeps/ieee754/log10.c (log10): Likewise. + + * setjmp/_longjmp (_longjmp): Add __NORETURN. + * setjmp/longjmp (longjmp): Likewise. + +Thu Nov 18 04:16:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * string/strerror.c (strerror): Call _strerror_internal to do the + work, passing it a scratch buffer. + * stdio/perror.c: Likewise. + * string/Makefile (routines): Add _strerror. + * sysdeps/generic/_strerror.c (_strerror_internal): New file. + + * configure.in (config.status): Make it pass its args to configure. + +Thu Nov 18 03:52:32 1993 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * stdio/__vfscanf.c (__vfscanf): Put the floating point cases + (e,E,f,g,G) inside #ifndef MIB_HACKS; roland thikgs strtod crashes + the compiler. Wheee. + +Thu Nov 18 03:21:51 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * errno.h [__USE_GNU__]: Declare program_invocation_name and + program_invocation_short_name. + +Thu Nov 18 00:07:37 1993 Michael I. Bushnell (mib at ernst.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/start.c (start1): Don't add one to + the return value of split_args; it counts them just fine by + itself. Do add one when sizing the arrays. + +Mon Nov 15 00:19:48 1993 Noel Cragg (noel@geech.gnu.ai.mit.edu) + + * time/mktime.c: add TIMES_THROUGH_SEARCH variable to make sure + that we don't get caught in an infinite loop (would be bad, + indeed, for a library routine). + +Sun Nov 14 18:48:28 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/sys/cdefs.h (__NORETURN, __CONSTVALUE): Use + `__attribute__', not `__attributes__'. + Test __GNUC_MINOR__ < 6, not < 5. + +Wed Nov 10 05:39:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/morecore.c: Only declare sbrk #ifdef __GNU_LIBRARY__. + Cast its return value. + + * sysdeps/unix/bsd/m68k/syscall.S: Use movel in place of moveal. + + * configure.in (signed size_t check): Don't use AC_DEFINE; do it + by hand and insert -U__SIZE_TYPE__ before -D. + + * posix/unistd.h: Declare syscall. + + * sysdeps/m68k/fpu/__math.h (__isnan, __isinf): Use __CONSTVALUE + in prototypes. + + * configure.in (Makefile): Write ARCH=`pwd`, rather than + substituting in the directory name at configure time. + + * sysdeps/mach/i386/syscall.S: New file. + +Tue Nov 9 06:29:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (os = netbsd* | 386bsd*): base_os=unix/bsd/bsd4.4. + Set --with-gnu-{ld,as} implicitly when base_os is bsd4.4. + + * Version 1.06.7. + + * misc/Makefile (routines): Add syscall. + * sysdeps/unix/syscall.S, sysdeps/stub/syscall.c, + sysdeps/unix/bsd/sun/m68k/syscall.S, sysdeps/unix/bsd/m68k/syscall.S, + sysdeps/unix/i386/syscall.S: New files. + * sysdeps/unix/bsd/hp/m68k/sysdep.h (DO_CALL): First arg + is syscall number, not name. + (PSEUDO): Pass POUND (SYS_ify (syscall_name)) to DO_CALL. + * sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h (DO_CALL, PSEUDO): + Likewise. Also, do movel into d0 before linkw, so the argument + could conceivably pop the stack. + * sysdeps/unix/bsd/hp/m68k/__brk.S: Pass complete number to DO_CALL. + + * sysdeps/unix/sysv/Dist: sys_getdents.S was renamed s_getdents.S. + +Thu Nov 4 01:23:59 1993 Michael I. Bushnell (mib at ernst.gnu.ai.mit.edu) + + * string/stpncpy: Fix typo; according to gnu-stabs.h the name + inside the DEFUN should be the *non* __ version. + * sysdeps/generic/__stpncpy.c: Missing declaration of s. + +Wed Nov 3 09:35:30 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile ($(objpfx)errlist.c): Conditionalize these + rules to be used only when errlist.c is otherwise a stub. + +Fri Oct 29 17:29:20 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * string/stpncpy.c: New file. + * sysdeps/generic/__stpncpy.c: New file. + * string/Makefile (routines): Add stpncpy and __stpncpy. + * string/string.h [__USE_GNU__]: Declare them. + +Thu Oct 28 17:13:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/errnos-tmpl.c (DO): If NAME is "EWOULDBLOCK", + write "#define EWOULDBLOCK EAGAIN" and change NAME to + "EWOULDBLOCK_sys". + * sysdeps/unix/{i386,sysv/sysv4/solaris2,sysv/i386/linux,bsd/m68k, + bsd/ultrix4/mips,bsd/vax}/sysdep.S [EWOULDBLOCK_sys]: Translate + EWOULDBLOCK_sys into EAGAIN. + * Makefile (distribute): Add move-if-change. + * move-if-change: New file. + +Tue Oct 26 18:19:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/sys/cdefs.h: Define __NORETURN and __CONSTVALUE. + For GCC 2.5 and later, use __attributes__ (({volatile,const})). + * stdlib/stdlib.h: Don't define either here. + * math/math.h: Likewise. + * posix/unistd.h: Likewise. + * time/time.h: Likewise. + * stdio/stdio.h: Likewise. + * setjmp/setjmp.h: Likewise. + + * posix/sys/wait.h (__WAIT_STATUS): Use union hack defn for GCC + 2.4 and up (testing __GNUC__ and __GNUC_MINOR__). + + * sysdeps/unix/sysv/sco3.2.4/__sysconf.S: Don't include <limits.h>. + + * Makerules [inhibit-sysdep-asm] + (open-check-inhibit-asm, close-check-inhibit-asm): New variables. + ($(+sysdir_pfx)sysd-rules): Use them around .s and .S rules. + Depend on existing sysdep makefiles. + +Mon Oct 25 15:56:41 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/mach/hurd/killpg.c: Include <sys/types.h> for pid_t. + + * sysdeps/posix/tempname.c (__stdio_gen_tempname): Take new arg + STREAMPTR. When non-nil, use __open with O_EXCL to test for + existence, and set *STREAMPTR to new stream on returned fd. + * stdio/stdio.h: Update prototype. + * sysdeps/stub/tempname.c: Here too. + * stdio/tmpfile.c: Pass &F to __stdio_gen_tempname instead of + using fopen. + * stdio/tmpnam.c: Pass extra NULL arg. + * stdio/tempnam.c: Likewise. + + * configure.in (switches): Only put --os-{release,version} here. + (config.status): Write $configure_args in place of $config $switches. + + * signal/Makefile (routines): Renamed sigaltstack to sigaltstk. + * sysdeps/stub/sigaltstack.c: Renamed to sigaltstk.c. + * sysdeps/unix/bsd/bsd4.4/sigaltstack.S: Renamed to sigaltstk.S. + * sysdeps/unix/sysv/sys_getdents.S: Renamed to s_getdents.S. + * sysdeps/unix/sysv/Makefile (sysdep_routines): Changed reference. + +Fri Oct 22 03:47:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/realloc.c [MEMMOVE_MISSING]: Test this to use safe_bcopy. + [emacs]: Don't define safe_bcopy. + + * time/zdump.c, time/europe: New versions from ADO. + + * Rules (dont_distribute): Export this variable. + (subdir_echo-distinfo): Echo its value for +nodist+. + +Thu Oct 21 15:58:08 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/__dup2.c: Include <limits.h>. + [OPEN_MAX]: Fail with EBADF if FD2>=OPEN_MAX. + + * sysdeps/unix/Makefile (sys/param.h): Conditionalize all this + code to happen only when there is no sysdep sys/param.h. + +Wed Oct 20 03:35:41 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (make-dummy-dep): Change to `ln $(objpfx)dummy.dep $@'. + ($(objpfx)dummy.dep): Create new file containing comment. + ($(objpfx)%.dep: $(objpfx)%.s): Depend on $(objpfx)dummy.dep. + ($(+sysdir_pfx)sysd-rules): Likewise in generated rule. + +Mon Oct 18 04:22:42 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * signal/signal.h (killpg): Make PGRP arg pid_t. + * sysdeps/posix/killpg.c (killpg): Likewise. + * sysdeps/stub/killpg.c (killpg): Here too. + + * posix/glob/configure.in: Use AC_HAVE_HEADERS instead of + AC_MEMORY_H and AC_UNISTD_H; omit AC_USG (not needed). + + * Rules (generated): New target. + + * Makefile (subdirs): Use filters to put mach and hurd first in + the list if they are in it at all. + * Makerules (before-compile): Reorder similarly, matching any + generated mach or hurd files. + +Fri Oct 15 17:57:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/mk-stdiolim.c [! OPEN_MAX]: Use _POSIX_OPEN_MAX + for FOPEN_MAX value. + [! PATH_MAX]: Use 1024 (twice _POSIX_PATH_MAX) for FILENAME_MAX value. + + * Makerules (in-Makerules): Define this variable before including + sysd-Makefile. + +Sun Oct 10 14:31:35 1993 Jim Meyering (meyering@comco.com) + + * posix/fnmatch.c [CONFIG_BROKETS]: Include <config.h> only under + this condition, else "config.h". + +Tue Oct 05 16:08:39 1993 Jim Meyering (meyering@comco.com) + + * time/mktime.c [CONFIG_BROKETS]: Include <config.h> only under + this condition, else "config.h". + +Thu Sep 23 15:14:08 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/__dup2.c: New file. + +Wed Sep 22 16:58:29 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/solaris2/statbuf.h: New file. + * sysdeps/unix/sysv/sysv4/i386: New directory. + * sysdeps/unix/sysv/sysv4/i386/statbuf.h: New file. + +Fri Sep 17 04:03:26 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (+make-deps): Put output in temp file and use atomic mv. + + * Makerules ($(+sysdir_pfx)sysd-rules): New target, the rule part + of what was in sysd-Makefile. Include it. + ($(+sysdir_pfx)sysd-Makefile): Do just includes here. Move the + generated implicit rules to sysd-rules. Put the output into a + temp file and use atomic mv to final target. + (before-compile): Filter out existing files from value, after + sysd-Makefile but before sysd-rules. + +Thu Sep 9 22:28:13 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile (%/configure): Copy rule from Make-dist. + +Mon Sep 6 19:57:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (sources, objects): Move override definitions to + before +depfiles calculation. + + * time/{asia,australasia,europe,zdump.c}: New versions from ADO (93e). + +Mon Aug 30 13:40:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * string/string.h (memmem): Reverse argument order, to be like strstr. + * sysdeps/generic/memmem.c: Here too. + + * dirent/scandir.c: For error return, save errno around closedir. + Call closedir (DP) before returning successfully. + +Thu Aug 26 19:26:06 1993 Brendan Kehoe (brendan@zen.org) + + * sysdeps/unix/sysv/sysv4/solaris2/sysdep.h: Rewritten to not use + the generic sparc sysdep.h. + (PSEUDO): Use trap 8, not 0. Also just put %g0 in %o0, without + subtracting 1. + (ENTRY): Align on 4, and add a `.type' directive. + * sysdeps/unix/sysv/sysv4/solaris2/sysdep.S: New file. + +Fri Aug 20 19:37:55 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/abort.c: Remove unused variable ABORTING. + +Thu Aug 19 17:45:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makeconfig [!objdir] [!..] (common-objdir): Set to `.'. + +Wed Aug 18 15:10:13 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/__vfscanf.c (__vfscanf: number): Reverse sense of + NUMBER_SIGNED conditional in assignment code. + +Mon Aug 16 15:49:13 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (syscall.h): Add sed + s/SYS_syscall_basenum/syscall_basenum/g. SYSCALL_BASENUM is a + macro both defined and used in <syscall.h>; we must undo our + prependation of `SYS_'. + + * Version 1.06.6. + +Fri Aug 13 16:53:02 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/__vfscanf.c: New local variable NUMBER_SIGNED. + (%x, %X, %o, %u): Set it to zero. + (%d, %i): Set it to one. + (number): If NUMBER_SIGNED is set, use strtol and store in ...int*. + If clear, use strtoul an store value in unsigned ...int*. + + * malloc/malloc.h: Undo last change (_AIX32). + (memory_warnings): Use const instead of __const in prototype. + +Fri Aug 13 00:22:01 1993 John Grabowski (johng@whiskey.media.mit.edu) + + * configure.in (os = osf1*): base_os=unix/bsd. + +Thu Aug 12 16:37:13 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/valloc.c [__GNU_LIBRARY__ || _LIBC]: Include <stddef.h> + before trying to use size_t to declare __getpagesize. + Include <sys/cdefs.h> before trying to use __P. + + * posix/{fnmatch,glob}.c, malloc/malloc.h [HAVE_CONFIG_H]: Include + <config.h> instead of "config.h". This is so that a compilation + using -I. -I$srcdir will use ./config.h rather than + $srcdir/config.h (which it would do when glob.c was found in $srcdir). + + * malloc/malloc.h [_AIX32]: Use !__STDC__ defns of __P, const, __ptr_t. + +Mon Aug 9 16:56:31 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (-e check): Don't rely on $(findstring e,$(MAKEFLAGS)) + since that also trips for --no-print-directory. + Instead actually see if -e's functionality is taking place. + + * malloc/realloc.c: Call _free_internal instead of free in most places. + + * configure.in (arg parsing): No spaces around = in eval. + + * sysdeps/i386/abort.c: New file. + * stdlib/abort.c: Moved to sysdeps/generic/abort.c. + (abort): Don't try to do stdio cleanup, since we can't guarantee + it anyway. + +Fri Aug 6 17:59:56 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules ($(+install)): Don't depend on installdirs. + (make-target-directory): New define. + (do-install): Do $(make-target-directory) beforehand. + +Tue Aug 3 02:22:41 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/sys/reboot.h: New file. + * sysdeps/unix/bsd/sys/reboot.h: New file, snarfed from 4.4. + * misc/Makefile (headers): Add sys/reboot.h. + + * stdio/stdio.h (__io_{read,write,seek,close,fileno}): Renamed to + __io_*_fn, so as not to conflict with the Hurd mig stubs. + * internals.c: Changed uses. + + * sysdeps/unix/bsd/signum.h (SIGINFO): Define as 29. + + * Makerules (+includes): Don't set this here. + * Makeconfig (+includes): Put $(+sysdep-includes) in the value here. + + * posix/unistd.h [__USE_MISC]: Declare mktemp and mkstemp. + +Mon Aug 2 16:59:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/valloc.c: Move getpagesize goop to before malloc.h. + [_LIBC]: Test this as well as __GNU_LIBRARY__ (either one) to use + __getpagesize instead of "getpagesize.h". + +Sun Aug 1 16:55:18 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (arg parsing): For `--with-foo=bar', do + "with_foo='bar'". For `--with-fnord', do "with_fnord=yes". + * sysdeps/mach/configure: New file, groks `--with-mach=DIR'. + +Fri Jul 30 00:01:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (os = gnu*): Set $base_os, not $os, to mach/hurd. + +Thu Jul 29 17:46:02 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * ctype/ctype.h (__isctype): Don't test !=0, to avoid possible + extra test insn. + +Sun Jul 25 22:19:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * setjmp/setjmp.h [! __FAVOR_BSD] (_longjmp): Define as longjmp. + +Thu Jul 22 14:57:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/osf1/sigaction.h: New file. + + * sysdeps/stub/signum.h: Deansideclized. + * sysdeps/stub/pipestream.c (pclose): Test STREAM->__ispipe + instead of __ispipe (STREAM). + * sysdeps/stub/__wait3.c: Fix arg types. + * sysdeps/stub/__ioctl.c: Add missing close paren. + * sysdeps/stub/__getpgsz.c: Include <stddef.h> for size_t. + * sysdeps/stub/__get[gu]id.c: Include <sys/types.h>; fix return type. + * sysdeps/stub/__set[gu]id.c: Include <sys/types.h>; fix arg type. + * sysdeps/stub/__mknod.c: Include <sys/types.h>; fix arg types. + + * sysdeps/generic/termbits.h (INLCR, ISTRIP): Fixed typo'd values. + + * stdio/stdio.h (vprintf): Fix last arg type to __gnuc_va_list. + * stdio/vprintf.c (vprintf): Here too. + + * malloc/malloc.c (malloc) [SUNOS_LOCALTIME_BUG]: Put this crap + after hook and initialization. + + * stdio/stdio.h (__validfp): Use a little anonymous struct to find + the real stream ptr from in glue stream. It used to rely on using + `((int *) STREAM)[1]'; but that assumes no struct padding, and + there will be some when int is 32 bits and pointers are 64. + + * malloc/mtrace.c: Use %lx instead of %x for `size_t' formats. + +Wed Jul 21 18:20:41 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * malloc/malloc.c (malloc): Handle SUNOS_LOCALTIME_BUG. + +Wed Jul 21 16:42:14 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/Makefile (extra-objs): Remove gratuitous - in `z.%'. + + * Makefile [+gnu-stabs] (generated): Add $(objpfx)munch-init.c. + (distclean): Also remove sysd-Makefile and sysd-dirs in $(objpfx). + (distclean) [objdir]: Also remove $(objpfx)Makefile. + + * sysdeps/posix/Makefile (generated): Add $(common-objpfx)mk-stdiolim. + (generated, before-compile): Take defns out of ifeq ($(subdir),posix). + + * sysdeps/unix/common/Makefile (generated): Include ctype-glue.c, + not glue-ctype.c. + + * sysdeps/unix/configure (unix_generated): New variable; collect + names of created files in it. + (config_vars): Write an assignment for `unix-generated' to that list. + * sysdeps/unix/Makefile (generated): Append $(unix-generated) + (with either $(objpfx) or $(sysdep_dir)/unix/ prepended to each file). + + * Makefile (clean): Pass no_deps=t to subdir_clean make. + +Sun Jul 18 21:42:05 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/malloc.c (malloc): After getting more core, recompute + BLOCK before adding to _heapinfo[BLOCK].free.size. + +Fri Jul 16 16:32:40 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/Makefile (generated): Prepend $(objpfx). + * sysdeps/unix/sysv/Makefile (generated): Likewise. + + * sysdeps/posix/mktemp.c: Return when stat fails with ENOENT, not + when it succeeds. + +Wed Jul 14 14:51:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * locale/localeconv.c: Fix copying notice to LGPL. + +Mon Jul 12 21:58:27 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/mcheck.c (reallochook): Set HDR->magic to MAGICWORD. + +Mon Jul 5 15:55:08 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * malloc/realloc.c (memmove): Swap the args when calling safe_bcopy. + +Thu Jul 1 16:26:56 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/malloc.c [_LIBC] (_malloc, _free, _realloc): Define these + functions to just call malloc, free, and realloc, respectively. + +Wed Jun 30 16:42:10 1993 Torbjorn Granlund (tege@gnu.ai.mit.edu) + + * sysdeps/generic/memcmp.c (memcmp_bytes): New function for + little endian machines. + (memcmp_common_alignment, memcmp_not_common_alignment): Rework + code computing return values. + +Wed Jun 30 14:42:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (local_lim.h): Only generate local_lim.h + if the sysdep version would be stub. + + * sysdeps/unix/mk-local_lim.c: #include <stdio.h> before all else. + + * configure.in (config_{machine,vendor,os}): Store config.sub's + output in these new variables. + (machine, vendor, os): Set these from those. + (config-name.h, config.make): Write $config_* (the original values + from config.sub). + + * sysdeps/unix/sysv/sysv4/pgrpsys.S: Add arg count (3). + +Tue Jun 29 02:47:46 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.4. + +Mon Jun 28 00:37:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/internals.c (__stdio_check_funcs): New function, broken out + of init_stream. + (init_stream): Call it. + * sysdeps/posix/pipestream.c (popen): Call __stdio_check_funcs + before frobnicating STREAM's functions. + + * sysdeps/posix/pipestream.c (pclose): Free C, our data structure, + not STREAM->__cookie after it's been restored. + + * sysdeps/generic/strchr.c: Check for '\0' as well as C, in initial + byte-by-byte loop. + + * conf/portability.h: #undef BSD. + +Sun Jun 27 23:46:05 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/m68k/__wait.S [__motorola__]: Use Motorola syntax. + * sysdeps/unix/bsd/m68k/sysdep.S: Likewise. + * sysdeps/unix/bsd/m68k/__pipe.S: Likewise. + * sysdeps/m68k/__longjmp.c (__longjmp) [__motorola__]: Use + Motorola syntax in jmp insn. + +Fri Jun 25 16:17:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/{stub,posix,unix/sysv/sysv4}/__sysconf.c (__sysconf): + For _SC_TZNAME_MAX, just return __tzname_max (). + * sysdeps/unix/sysv/sco3.2.4/__sysconf.S: Define __sysconf, not + sysconf. For _SC_TZNAME_MAX, just jump to __tzname_max. + + Undo June 21 change that made __tzname_max a variable + and expected TZNAME_MAX to sometimes be defined. + POSIX.1 does not require that it be defined; sysconf is enough. + * time/time.h (__tzname_max): Declare as a function. + * posix/posix1_lim.h: Don't include <tzname_max.h>. + * sysdeps/stub/tzname_max.h: File removed. + * time/Makefile (headers): Remove tzname_max.h. + (distribute): Remove make-tzlim.c. + (extra-objs): Remove make-tzlim.o and make-tzlim. + ($(common-objpfx)tzname_max.h): Target removed. + * time/make-tzlim.c: File removed. + * time/__tzset.c (__tzname_cur_max): Define this variable instead + of __tzname_max. + (__tz_compute): Set __tzname_cur_max, not __tzname_max. + (__tzname_max): New function. + * time/tzfile.c (compute_tzname_max): Set __tzname_cur_max, not + __tzname_max. + + * malloc/malloc.h [_MALLOC_INTERNAL] [! (_LIBC || STDC_HEADERS || USG)] + (memmove): Don't define. + * malloc/realloc.c [!_LIBC && !STDC_HEADERS && !USG] (safe_bcopy): + New static function. + (memmove): Define to safe_bcopy. + +Wed Jun 23 15:10:51 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/pgrpsys.S: New file, #include sysv4 file. + * sysdeps/unix/sysv/sco3.2.4/Dist: New file, list pgrpsys.S. + +Tue Jun 22 02:44:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/Makefile (sysdep_routines): Use + pgrpsys instead of sco_pgrp. + * sysdeps/unix/sysv/sco3.2.4/{Dist,sco_pgrp.S}: Files removed. + * sysdeps/unix/sysv/sco3.2.4/__{getpgrp,setpgrp,setsid}.c: Just + include the respective unix/sysv/sysv4 files. + + * sysdeps/unix/sysv/sysv4/pgrpsys.S: New file. + * sysdeps/unix/sysv/sysv4/__getpgrp.c: New file. + * sysdeps/unix/sysv/sysv4/__setpgrp.c: New file. + * sysdeps/unix/sysv/sysv4/__setsid.c: New file. + * sysdeps/unix/sysv/sysv4/Dist: Add pgrpsys.S. + * sysdeps/unix/sysv/sysv4/Makefile (sysdep_routines): Add pgrpsys. + + * sysdeps/unix/bsd/bsd4.4/__setsid.S: Moved from unix/sysv/sysv4. + * sysdeps/unix/{bsd/sun/sunos4,bsd/ultrix4,sysv/linux}/__setsid.S: + Include bsd4.4 instead of sysv4 file. + +Mon Jun 21 19:08:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/posix1_lim.h: #include <tzname_max.h>. + * sysdeps/stub/tzname_max.h: New file (no-op). + * time/make-tzlim.c: New file. + * time/Makefile (headers): Add tzname_max.h. + (distribute): Add make-tzlim.c. + (extra-objs): Add make-tzlim.o and make-tzlim. + ($(common-objpfx)tzname_max.h): New target. + + * sysdeps/unix/sysv/sco3.2.4/confname.h (_SC_TZNAME_MAX): Define. + * sysdeps/unix/sysv/sco3.2.4/__sysconf.S: Detect arg being + _SC_TZNAME_MAX, and return max of TZNAME_MAX and __tzname_max. + + * sysdeps/stub/__sysconf.c: Include <time.h> and <limits.h>. + Handle _SC_TZNAME_MAX and return max of TZNAME_MAX and __tzname_max. + * sysdeps/posix/__sysconf.c: Change _SC_TZNAME_MAX code to that. + * sysdeps/unix/sysv/sysv4/__sysconf.c: Likewise. + + * time/time.h (__tzname_max): Declare as variable, not function. + * time/__tzset.c (__tzname_max): Function removed. + (__tz_compute): Set the __tzname_max variable. + * time/tzfile.c (compute_tzname_max): New function. + (__tzfile_{read,default}): Call it. + +Sun Jun 20 18:32:49 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/zic.c, time/asia: New versions from ADO. + +Wed Jun 16 17:24:28 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.3. + +Fri Jun 11 15:44:53 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/m68k/__pipe.S: Use `movel' instead of `moveal', + which sun3 as does not appear to grok. + * sysdeps/unix/bsd/sun/m68k/__vfork.S: Likewise. + +Thu Jun 10 20:23:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/Makefile (as-pipe-ok): Define if -pipe is used in + compiler invocations, or if using GNU as. + (compile-command.S): Define using a pipe if `as-pipe-ok' is defined, + otherwise with a temporary file. + + * Makeconfig (gnu-as): Define if -DHAVE_GNU_AS appears in $(CPPFLAGS). + +Wed Jun 9 15:14:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (os frobnication): Turn underscores as well as + lowercase Vs into dots in os name. + + * sysdeps/unix/start.c [__GNUC__] (_start): Use asm name "start" + only if [! NO_UNDERSCORES]. + +Tue Jun 8 14:51:00 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * sysdeps/unix/bsd/ultrix4/mips/__handler.S: Don't save the stack + pointer. + +Mon Jun 7 21:01:24 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/Makefile (tzcompile): Remove -d switch, since zic-cmd has one. + + * time/{private.h,zic.c}: New versions from ADO. + + * sysdeps/unix/bsd/hp/m68k/__brk.S (error): Renamed label from `1', + (__brk): Use DO_CALL instead of movel and trap. + + * sysdeps/unix/bsd/sony/newsos4: Renamed sysdeps/unix/bsd/sony/newsos. + * sysdeps/unix/bsd/sony/m68k/{Implies,sysdep.h}: Moved there. + + * sysdeps/unix/bsd/hp/m68k/sysdep.h (DO_CALL): New macro, broken + out of PSEUDO. + (PSEUDO): Use it. + * sysdeps/unix/bsd/sony/newsos4/m68k/sysdep.h + (DO_CALL, PSEUDO): Likewise. + + * configure.in: Set --with-gnu-{ld,as} for os=bsd4.4. + +Fri Jun 4 14:11:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/i386/{strlen,memchr}.c: Use `repnz' instead of `repne'. + + * time/Makefile (zonenames): Rename zones-* to z.* so they all fit + in 14 chars. + (extra-objs): Here too. + + * sysdeps/unix/sysv/direct.h (D_RECLEN): New macro. + * sysdeps/unix/readdir.c (D_RECLEN): If not defined, define to use + `d_reclen' member. + (readdir): Use D_RECLEN (DP) in place of DP->d_reclen. + +Thu Jun 3 16:54:29 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/bytesex.h: New file. + + * sysdeps/unix/ioctls-tmpl.c [sony_news]: Define KANJI before + including <sys/ioctl.h>. + +Wed Jun 2 17:45:38 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/Makefile (%.gz): Renamed target from %.z; use -v flag. + (malloc/ChangeLog): Use mv -f. + +Mon May 31 21:49:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.2 released. + + * manual/Makefile: Remove all uses of $(objpfx). Since the + generated files are distributed, they reside in the source + directory. + + * malloc/mtrace.c: #include <stdio.h>; malloc.h no longer does. + + * sysdeps/posix/sleep.c: Restore signal mask to OSET before + returning. Save errno on entry and restore it before returning. + + * Makeconfig (zonedir): New variable. + * time/Makefile (localtime-file, posixrules-file, install-others, + $(localtime-file), $(posixrules-file), tz-cc): Use $(zonedir) in + place of $(datadir)/zoneinfo. + (tzcompile): Omit -d switch. + (zic-cmd): Add `-d $(zonedir)'. + +Sun May 30 20:04:50 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/stdio_init.c: (int)cookie is FD, not *(int*)cookie. + + * time/Makefile ($({localtime,posixrules}-file)): Don't pass -d + switch (no need, since directory is compiled into zic). Don't use + $(<F) to find arg for -{l,p}; just use $({localtime,posixrules}). + + * Makerules ($(libdir)/libc.a): Depend on installdirs. + + * malloc/malloc.c (malloc): #if 0 out ``if (SIZE == 0) return NULL''. + + * malloc/malloc.h [_MALLOC_INTERNAL]: Don't include <stdio.h>. + [_MALLOC_INTERNAL]: Move config.h, limits.h, and mem* to front of file. + (NULL): Move after stddef.h. + + * malloc/valloc.c: Don't include config.h; malloc.h already did. + + * malloc/malloc.c: Undo rms's change. + + * malloc/mcheck.c, malloc/malloc.h: Undo rms's change. + +Sat May 29 13:04:38 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * malloc/malloc.c (malloc) [emacs]: If size is 0, make it 1. + + * malloc/malloc.h (CONST): Define this always, + rather than `const' sometimes. + (memory_warnings): Use CONST, not __const, in decl. + * malloc/mcheck.c (checkhdr): Use CONST, not const. + +Fri May 28 18:29:26 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (ioctls): Use fgrep instead of egrep to + omit unwanted symbols. Filter the list of them through sort|uniq + to remove duplicates first. + + * sysdeps/unix/Makefile (errlist.c): Use dir and notdir + functions to guarantee qualified path name for make_errlist. + +Thu May 27 17:05:04 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06.1. + + * sysdeps/sparc/Dist: Include sdiv.S, not div.S. + + * sysdeps/unix/common/Dist: Remove make_siglist.c. + + * stdio/internals.c: Declare __stdio_fileno before reference. + + * sysdeps/generic/{memchr,strchr,strlen}.c: Abort if words are + bigger than 64 bits. + +Wed May 26 14:44:19 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules [objects] (install-others): Don't add libc.a to this. + (install): Depend on $(libdir)/libc.a. + (intall-no-libc.a): New target, depends on $(+install). + (install): Don't depend on $(+install), just on install-no-libc.a. + * Rules (subdir_install): Depend on install-no-libc.a, not install. + + * Makefile ($(libc.a)): Don't depend on subdir_lib. + (lib-noranlib): Depend on subdir_lib. + + Make `fileno' a per-FILE io operation. + * stdio/stdio.h (__io_fileno): New typedef. + (__io_functions): Add `__fileno' member. + (struct __stdio_file): Remove `__fileno' member. + [__USE_POSIX] [__OPTIMIZE__]: Remove fileno macro defn. + [__USE_POSIX] (fileno): Remove `const' from arg in prototype. + * stdio/fileno.c (fileno): Rewritten to call STREAM's __fileno fn. + * sysdeps/stub/sysd-stdio.c (__stdio_fileno): New function. + (__stdio_open): Return an int (zero for win, nonzero for lose), + and make third arg PTR * (filled in with cookie). + * stdio/stdio.h (__stdio_open): Changed prototype. + * sysdeps/posix/sysd-stdio.c (__stdio_open): Likewise. + (__stdio_{read,write,seek,close}): Use (int) COOKIE as the fd, rather + than *(int *) COOKIE. + (__stdio_fileno): New function; just returns (int) COOKIE. + * sysdeps/posix/fdopen.c: Set cookie to (PTR) FD; don't set fileno. + * stdio/vdprintf.c: Likewise. + * stdio/fmemopen.c: Set STREAM->__io_funcs.__fileno to NULL. + Set STREAM->__cookie to NULL and don't use STREAM->__fileno. + * stdio/internals.c (__default_io_functions): Add __stdio_fileno. + * sysdeps/posix/defs.c (stdstream): Initialize __cookie to (PTR) FD + Remove __fileno initializer. + Add NULL initializer for __io_funcs.__fileno. + * sysdeps/posix/pipestream.c (struct child): Remove `fd' member. + Add `cookie' and `funcs' members. + (FUNC): Macro to define child io_funcs. + (child_funcs): New variable, __io_functions struct of them. + (popen): Store STREAM's original cookie and io_funcs in CHILD, and + then set STREAM->__cookie to CHILD and stream->__io_funcs to + child_funcs. + (pclose): Restore STREAM's original cookie and io_funcs before + calling fclose. + + * configure.in (autoconf checks): Add new check for a + libc-friendly stddef.h. + + * sysdeps/unix/configure: Remove __getpgrp from list of syscalls. + + * sysdeps/generic/memchr.c: Handle 64-bit longwords. + * sysdeps/generic/strlen.c: Likewise. + * sysdeps/generic/strchr.c: Likewise. + + * sysdeps/unix/sysv/sco3.2.4/Makefile: Remove gratuitous `.c'. + + * Makerules [objects] (install-others): Add $(libdir)/libc.a to + this, instead of adding $(libc.a) to install-lib. + ($(libdir)/libc.a): New target to install from $(libc.a). + + * sysdeps/unix/sysv/sco3.2.4/__setsid.S: New file. + * sysdeps/unix/bsd/bsd4.4/__setsid.S: New file. + +Mon May 24 16:49:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/linux/__setsid.S: Moved to unix/sysv/sysv4, + and replaced with #include of that. + * sysdeps/unix/bsd/sun/sunos4/__setsid.S: New file. + * sysdeps/unix/bsd/ultrix4/__setsid.S: New file. + + * posix/Makefile (install): Define to getconf. + + * crypt: New version from glad. + + * sysdeps/unix/sysv/sysv4/__sysconfig.S: Renamed to sysconfig.S. + * sysdeps/unix/sysv/sysv4/Makefile (sysdep_routines): Change reference. + * sysdeps/unix/sysv/sysv4/Dist: Add sysconfig.S. + + * sysdeps/generic/Makefile (siglist.c): Use dir and notdir + functions to guarantee qualified path name for make_siglist. + + * time/Makefile (tzcompile): Use $(@D) for target directory, not + reference to nonexistent 4th dep. + (localtime-file, posixrules-file): Turn these into absolute names. + (install-others): Simply refer to them. + ($(datadir)/zoneinfo/{localtime,posixrules}): Change targets of + these rules to $(localtime-file) and $(posixrules-file), respectively. + Use $(<D) for directory to pass zic. + + * Makerules (installdirs): Use `sort' function to uniquize list of + directories. + + * time/Makefile (install-others): Use $(datadir)/zoneinfo, not + $(datadir)zoneinfo (missing /). + + * Makerules (install-lib): Refer to `$(libc.a)' instead of `libc.a'. + + * setjmp/sigjmp_save.c: Renamed to sigjmp.c. + * setjmp/Makefile (routines): Change reference. + + * sysdeps/unix/common/Makefile (siglist.c, make_siglist): Targets + removed. + * sysdeps/unix/common/make_siglist.c: File removed. + +Sun May 23 01:00:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * manual/Makefile (minimal-dist): Remove COPYING.LIB. + (doc-only-dist): Put it here. + +Sun May 23 00:12:24 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Version 1.06 released. + + * sysdeps/sparc/Dist: Add {u,}{div,rem}.S. + +Sat May 22 18:17:08 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/make_siglist.c (main): Call signame_init, not + init_sigs. + + * Makerules (native-compile): Compile $^, not just $<. + + * sysdeps/unix/i386/sysdep.h (PSEUDO): Omit `.text'. Some + assemblers don't like `.text; ...'. + + * Rules (all): Mention as target first, so it is the default goal. + + * sysdeps/unix/i386/sysdep.S: #undef syscall_error before using it + as a label. + [NO_UNDERSCORES]: Define __syscall_error instead of syscall_error. + + * sysdeps/unix/readdir.c: Decrement d_namlen until it no longer + includes any nulls. + + * Makerules (+install-dirs): Variable removed. + (install): Don't depend on $(+install-dirs). + (installdirs): New target, to make $(dir $(+install)) using + mkinstalldirs. Make $(+install) depend on it. + * Makefile (distribute): Add mkinstalldirs. + * mkinstalldirs: New file. + + * manual/Makefile (installdirs): + New target, using mkinstalldirs to create $(infodir). + ($(infodir)/libc.info): Depend on installdirs. + (minimal-dist): Remove Makefile. + (doc-only-dist): New variable, containing Makefile and mkinstalldirs. + (*.tar): Depend on $(doc-only-dist). + +Sat May 22 16:31:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + Compile zoneinfo files directly into $(datadir)/zoneinfo, rather + than compiling them into the source directory and then copying. + * time/Makefile (zones-%): Put targets of generated rule in + $(datadir)/zoneinfo, not zoneinfo. + Don't make generated rules depend on zoneinfo/. + (zonenames, zones-%): Write into $@.new and then use atomic mv. + (zones, zoneinfo): Targets removed. + (zoneinfo/localtime, zoneinfo/posixrules): Change targets to be in + $(datadir)/zoneinfo; find $(localtime) and $(posixrules) there as well. + ($(localtime-file), $(posixrules-file)): Targets removed. + (install-data): Definition removed. + (install-others): Include $(zonenames) from $(datadir)/zoneinfo; and + $(localtime-file) and $(posixrules-file), from $(datadir)/zoneinfo + if they are not absolute file names. + + * time/zic.c (dolink): If FROMFILE or TOFILE begins with a slash, + just set {FROM,TO}NAME to it, instead of prepending DIRECTORY. + Don't free {FROM,TO}NAME if it is {FROM,TO}FILE. + +Fri May 21 13:23:32 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/i386/sysdep.S: Paste : onto syscall_error. + + * sysdeps/unix/configure: Use grep -i when looking for syscalls. + (unix_syscall_h): Ignore syscall.h found in sysdeps/stub. + Remove __setpgrp from list of syscalls. + + * sysdeps/unix/Makefile ($(common-objpfx)sys/param.h): Write defn + for MAXHOSTNAMELEN. The kludgemeister strikes again. + + * posix/Makefile (glob/ChangeLog): Use mv -f. + + * configure.in (os frobnication): Translate numbers separated by + `v's into numbers separated by dots. + + * sysdeps/unix/sysv/sco3.2.4/syscall.h: New file. + + * sysdeps/unix/sysv/sco3.2.4/__waitpid.S: Rewritten to do the + canonical wait3-style magic. + + * sysdeps/unix/sysv/sco3.2.4/{Makefile,Dist,sco_pgrp.S, + __getpgrp.c,__setpgrp.c,__setsid.c}: New files. + + * Makerules ($(common-objpfx)stub-$(subdir)): Add /dev/null to + inner sed command. + + * manual/Makefile ($(objpfx)%.info, $(objpfx)%.dvi): New rules. + ($(infodir)/libc.info): Take basename of each $<* before using it. + (glibc-targets): Add stubs. + (stubs, $(common-objpfx)stub-manual): New targets. + + * time/Makefile (distribute): Add yearistype. + * time/yearistype: New file. + + * sysdeps/unix/bsd/sequent/i386/__sigvec.S: Don't use ARGS_4 + macro; just set %ecx to %esp instead. Pop the stack before doing + the system call, so the add doesn't clear the condition codes. + + * sysdeps/unix/start.c [HAVE_GNU_LD]: Put `start' symbol alias + under [! NO_UNDERSCORES && ! __GNUC__]. + + * sysdeps/unix/sysdep.h (C_LABEL): Use ## to paste NAME and : together. + + * sysdeps/unix/i386/sysdep.h (DO_CALL): Add missing backslash. + +Thu May 20 18:01:15 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile ($(+subdir_targets)): Remove old rule. Replace with + static pattern rule to depend on DIR/TARGET for each subdir and target. + (all-subdirs-targets): Define variable to contain names of all + those targets. + ($(all-subdir-targets)): Define rule for these to do sub-make. + + * sysdeps/unix/sysv/sysv4/direct.h (D_NAMLEN): Subtract one for + the terminating null character. + * sysdeps/unix/sysv/sco3.2.4/direct.h (D_NAMLEN): Copy defn from + that file. + +Thu May 20 11:02:59 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * sysdeps/posix/__getpgsz.c: New file. + * sysdeps/unix/sysv/sysv4/__getpgsz.c: New file, include the posix one. + * sysdeps/posix/__getdtsz.c: New file. + * sysdeps/unix/sysv/sysv4/__getdtsz.c: New file, include the posix one. + + * sysdeps/unix/sysv/sysv4/{__sysconf.c, __sysconfig.S, + sysconfig.h, Makefile, Dist}: New files. + + * sysdeps/generic/confname.h (enum for sysconf): Add _SC_PAGESIZE. + * sysdeps/posix/__sysconf.c: Include stddef.h. + (__getpagesize): Declare. + (__sysconf, case _SC_PAGESIZE): Call __getpagesize. + +Wed May 19 14:03:07 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * manual/Makefile (routines, aux, sources, objects, headers): + Define empty. + + * Makeconfig (infodir): Define. + * Makefile (+other_dirs): Add manual. + * manual/Makefile: Include ../Makeconfig if it exists. + (subdir): Export it. + (find-includes): Output variable name is $(@F), not $@. + (distribute): Export it. + (mostlyclean, distclean, realclean, clean, subdir_clean): New targets. + (install, subdir_install): New targets. + (infodir, prefix, INSTALL_DATA, INSTALL): Define vars if undefined. + ($(infodir)/libc.info): New target. + (dist): Use ../Make-dist if it exists. + (glibc-targets): New variable. + ($(glibc-targets)): Make no-op targets. + + * config.guess: New file, maintained by Cygnus. + * configure.in: Move AC_PREPARE before arg lossage check. + If $target is unset, try setting it from config.guess. + * Makefile (distribute): Add config.guess. + + * inet/getnetbyad.c: Change first arg type to int32_t. + * inet/inet_mkadr.c: Change arg types to u_int32_t. + * inet/inet_lnaof.c: Change return type to u_int32_t. + * inet/inet_net.c: Likewise. + * inet/inet_netof.c: Likewise. + * inet/res_send.c, inet/res_query.c, inet/res_mkqry.c, + inet/res_init.c, inet/res_debug.c, inet/res_comp.c, + inet/inet_addr.c, inet/herror.c, inet/gethstnmad.c, inet/resolv.h, + inet/netdb.h, inet/arpa/nameser.h, inet/arpa/inet.h: + Snarfed latest code from BIND 4.9.1. + * inet/sys/bitypes.h: New file. + * conf/portability.h: New file. + * inet/Makefile (headers): Add sys/bitypes.h. + (distribute): Define to ../conf/portability.h. + + * mach/__msg_destroy.c: Renamed to __msg_dest.c. + * mach/mig_syms.c: Renamed from mig_support_syms.c. + Added symbol alias for mig_strncpy. + * mach/__mig_strncpy.c: Renamed to mig_strncpy.c. + * mach/mig_strncpy.c: File removed. + * mach/Makefile (routines): Remove __mig_strncpy; change + mig_support_syms to mig_syms; change __msg_destroy to __msg_dest. + + * sysdeps/posix/Makefile: Replace instances of `objpfx' and + `objdir' with `common-objpfx' and `common-objdir'. + +Mon May 17 16:29:29 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/asctime.c: Replace ` %2d' with `%3d' in FORMAT. + (asctime): Check return from sprintf being <0, not <25. + + * sysdeps/unix/opendir.c: Include <stdio.h> for BUFSIZ. + + * sysdeps/unix/i386/sysdep.h (PSEUDO): Put ; after DO_CALL use. + + * sysdeps/i386/ffs.c: Use `nonzero' for asm label, instead of `1f'. + +Sun May 16 17:59:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sequent/i386/__sigvec.S: Don't get fancy with + xchg; just push $trampoline and then push our args again, pop them + after the system call. + + * time/tzfile.c (__tzfile_default): Don't assume TYPES[0] is + standard and TYPES[1] is DST. Instead, loop through all types: + if a type's isdst flag is set, set its idx to STDLEN and its + offset to DSTOFF; if isdst is clear, set its idx to 0 and its + offset to STDOFF. + + * time/__tzset.c: When __tzfile_default returns having set + __use_tzfile, set __tzset_run before returning. + + * sysdeps/posix/sleep.c: Block SIGALRM with sigprocmask before + changing its handler. Use sigaction instead of signal to set the + handler. Use sigsuspend to restore the blocked signals and pause + atomically, instead of using pause. Be sure to disable the alarm + when a signal other than SIGALRM wakes sigsuspend. + + * time/Makefile (zic-cmd): Put the directory before the nondirectory. + + * Makerules (stubs): Remove surrounding `ifdef +depfiles'...`endif'. + + * time/Makefile: Include ../Makeconfig before trying to use $(objpfx). + + * time/tzfile.c (__tzfile_compute): When there are transitions and + TIMER is not before the first one, find the first transition after + TIMER, and then set I to the type of the transition before it. + Set INFO from types[I], not types[type_idxs[I]]. + + * posix/Makefile (glob/configure): cd to glob before running autoconf. + + * time/__tzset.c (compute_change): Don't add 1900 to YEAR. + (__tz_compute): Add 1900 to the year we pass to compute_change. + + * time/gmtime.c: After calling __offtime, zero tm_gmtoff and set + tm_zone to "GMT". + + * time/time.h [__OPTIMIZE__]: Remove gmtime macro version. + + * time/tzfile.c (__tzfile_default): Fail if NUM_TYPES < 2, not if + NUM_TYPES != 2. + + * time/tzfile.c (__tzfile_compute): Don't take arg TM. + Instead take new args long int *LEAP_CORRECT and int *LEAP_HIT. + Don't apply leap second correction to __timezone; instead set + *LEAP_CORRECT and *LEAP_HIT. + * time/__tzset.c (tzset_run): Renamed to __tzset_run, made global. + (__tzset): Change uses. + (__tz_compute): Change use here as well. + Make second arg be a `const struct tm *'. Don't call __tzfile_compute. + * time/localtime.c: Call __tzset if __tzset_run is clear. + New local vars LEAP_CORRECTION and LEAP_EXTRA_SECS. + If __use_tzfile is set, call __tzfile_compute and pass it their + addresses. Only need to call gmtime if __use_tzfile is clear. If + it is clear, pass result of gmtime to __tz_compute, instead of + dereferencing it first; and zero LEAP_CORRECTION and LEAP_EXTRA_SECS. + Subtract LEAP_CORRECTION from __timezone in __offtime call. + After __offtime, add LEAP_EXTRA_SECS to TP->tm_sec. + + * sysdeps/generic/strsep.c: Increment END when writing a null to + it, and set *STRINGP to END rather than END+1, so *STRINGP never + points past the null. + +Sat May 15 17:10:02 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * time/strftime.c: Alphabetize switch cases. + Add GNU extensions %h, %C, %k, %l. + + * time/asctime.c: Make RESULT big enough for each %d to be 2^64. + Protect against tm_wday and tm_mon being out of bounds; use "???" + if they are. + + * time/{emkdir,ialloc,scheck,zic,zdump}.c: New versions from ADO. + + * time/africa, time/antarctica, time/asia, time/australasia, + time/europe, time/northamerica, time/southamerica, + time/pacificnew, time/etcetera, time/factory, time/systemv, + time/solar87, time/solar88, time/solar89, time/leapseconds: + Updated from Arthur David Olsen's latest. + + * sysdeps/generic/__expm1.c, sysdeps/generic/asinh.c, + sysdeps/generic/exp__E.c, sysdeps/generic/log.c, + sysdeps/generic/log1p.c, sysdeps/generic/mathimpl.h, + sysdeps/generic/pow.c, sysdeps/mach/hurd/__ioctl.c, + sysdeps/mach/hurd/stdio_init.c, sysdeps/unix/bsd/clock.c: Put + `const' qualifier always after storage classes. + + * sysdeps/unix/bsd/sequent/i386/__sigvec.S (trampoline): Use + `call', not `jsr'. + (__sigvec): Exchange the scratch reg with 16(%esp) (fourth arg + slot), not 0(%esp) (return PC slot). Use ARGS_4 to point the + syscall at the args. + + * sysdeps/unix/common/__getgrps.c: When gid_t==int, and SIZE!=0, + return N from __bsd_getgroups. + + * posix/unistd.h (__need_NULL): Define before including <stddef.h>. + 1003.1-1990 2.7.1 says it should be here. + +Sat May 15 14:54:25 1993 Noah Friedman (friedman@nutrimat.gnu.ai.mit.edu) + + * time/__tzset.c (compute_change): Add 1900 to YEAR, not 1970. + +Fri May 14 21:24:19 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * sysdeps/unix/sysv/sysv4/solaris2/start.c: Define NO_EXPLICIT_START. + * sysdeps/unix/sparc/start.c [NO_EXPLICIT_START]: Don't asm + `_start' into `start' (e.g., for Solaris). + + * sysdeps/unix/sysv/sysv4/solaris2/sysdep.h: New file. + +Fri May 14 19:34:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/Makefile: Remove depend-malloc dependency on malloc/gmalloc.c. + + * posix/Makefile (headers): Add sys/unistd.h. + * posix/sys/unistd.h: New file, just includes <unistd.h>. + + * sysdeps/unix/common/glue-ctype.c (main): Define generated array + as `unsigned char' rather than `char'. + + * sysdeps/unix/start.c [__GNUC__]: Use asm frob to make `start' + asm name of _start. + + * sysdeps/unix/opendir.c [! _STATBUF_ST_BLKSIZE]: Don't fstat and + use st_blksize; try BUFSIZ instead. + + * sysdeps/unix/Makefile (ioctls): Don't use sed to remove final | + from snarf-ioctls output; just append a dummy alternative instead. + + * sysdeps/posix/__wait3.c: Fix arg types. + + * Makerules ($(common-objpfx)stub-$(subdir)): Use @ for sed + separator char. Pass extra file /dev/null in case `...` gets empty. + + * sysdeps/unix/sysdep.h (C_LABEL): Define new macro. + * sysdeps/unix/i386/sysdep.h (ENTRY): Use it. + * sysdeps/unix/sparc/sysdep.h (ENTRY): Likewise. + * sysdeps/unix/sparc/__brk.S: Use C_LABEL and ENTRY instead of + C_SYMBOL_NAME. + * sysdeps/unix/i386/__brk.S: Use C_LABEL instead of C_SYMBOL_NAME. + +Fri May 14 17:41:42 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * sysdeps/mips/sqrt.c [HAVE_GNU_AS]: Use the IEEE 754 version of + sqrt since gas can't handle the `sqrt.d' synthetic instruction. + +Fri May 14 16:33:47 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/Makefile (routines): Add tempname. + + * sysdeps/unix/common/make_siglist.c: #define const to empty + around #include of <signal.h>. + + * sysdeps/unix/errnos.awk: Surround generated `DO' macro calls + with #ifdef on the E* symbol. + + * sysdeps/unix/common/make_siglist.c [! HAVE_SYS_SIGLIST && + HAVE__SYS_SIGLIST]: Define sys_siglist to _sys_siglist. + + * termios/Makefile (headers): Add termbits.h. + + * posix/Makefile (headers): Add waitflags.h and waitstatus.h. + + * math/math.h (struct __complex): Rename to struct __cabs_complex. + __complex is now a reserved word in GCC. + * sysdeps/generic/cabs.c (cabs): Likewise. + * sysdeps/ieee754/cabs.c (cabs, z_abs): Likewise. + + * sysdeps/unix/common/glue-ctype.c: Test for _ctype__ before _ctype_. + + * posix/Makefile (headers): Add confname.h. + +Thu May 13 00:25:53 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * ctype/Makefile (tags_sources): Don't define. + * MakeTAGS [subdir==ctype] (tags_sources): Put headers before sources. + + * time/__tzset.c (compute_change): Add 1970 to YEAR before using it. + + * sysdeps/unix/readdir.c: Pass a BASEP arg to __getdirentries. + +Wed May 12 20:36:51 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makefile (distribute): Add aclocal.m4. + + * dirent/list.c (test): Clear errno before readdir loop. Complain + if errno is set thereafter. + + * sysdeps/unix/sysv/sysv4/solaris2/utsnamelen.h: New file. + * sysdeps/unix/sysv/sysv4/solaris2/__utimes.S: New file. + * sysdeps/unix/sysv/sysv4/solaris2/sigaltstack.S: New file. + * sysdeps/unix/sysv/sysv4/solaris2/Makefile: New file. + + * sysdeps/unix/bsd/sun/sparc/start.c: Moved to sysdeps/unix/sparc. + * sysdeps/unix/sparc/start.c: Moved from sysdeps/unix/bsd/sun/sparc. + Surround all shared library frobnication code with #ifndef NO_SHLIB. + * sysdeps/unix/sysv/sysv4/solaris2/start.c: New file. + + * configure.in (os = solaris[2-9]*): base_os=unix/sysv/sysv4. + + * sysdeps/sparc/setjmp.S: Include <sysdep.h>, not "DEFS.h". + Use ENTRY(__setjmp) instead of FUNC(___setjmp). + + * sysdeps/sparc/divrem.m4: [__svr4__]: Include <sys/trap.h> + instead of <machine/trap.h>. + + * sysdeps/sparc/__longjmp.S: Include <sysdep.h>, not "DEFS.h". + Use ENTRY(__longjmp) instead of FUNC(___longjmp). + [__svr4__]: Use <sys/trap.h> instead of <machine/trap.h>. + + * sysdeps/unix/i386/sysdep.h (C_SYMBOL_NAME, SYS_ify): Moved to + sysdeps/unix/sysdep.h. + * sysdeps/unix/sparc/sysdep.h: New file. + * sysdeps/unix/bsd/sun/sparc/sysdep.h: File removed. + + * sysdeps/unix/sparc/__brk.S: New file. + * sysdeps/unix/sparc/__brk.c: File removed. + +Wed May 12 19:43:37 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * malloc/cfree.c: Put malloc.h include in _MALLOC_INTERNAL conditional. + +Wed May 12 16:24:23 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makeconfig (+link): Put $(LDFLAGS) in the value. + * sysdeps/unix/bsd/sun/sparc/Makefile (LDFLAGS): Set it. + + * posix/glob.c: Move include <unistd.h> before dir includes. + [HAVE_UNISTD_H] [! POSIX] [_POSIX_SOURCE]: Define POSIX. + + * grp/initgroups.c [! NGROUPS_MAX || NGROUPS_MAX == 0]: Just + return 0 and do nothing. + + * sysdeps/unix/sysv/sco3.2.4/__{sys,path}conf.S: New files. + * posix/unistd.h: Include <confname.h>; remove _{SC,CS,PC}_* defns. + * sysdeps/generic/confname.h: New file. + * sysdeps/unix/sysv/sco3.2.4/confname.h: New file. + + * malloc/cfree.c: Include <malloc.h> instead of <stdlib.h>. + [_LIBC]: Use function_alias only under this conditional. + [! _LIBC] (cfree): Define a function that just calls free. + + * posix/Makefile (glob.tar): Depend on glob/ChangeLog. + (glob/configure): Just run autoconf, don't do a sub-make. + (glob/ChangeLog): New target. + (%.Z, %.z): New rules. + +Mon May 10 16:56:09 1993 Jim Blandy (jimb@geech.gnu.ai.mit.edu) + + * malloc/cfree.c: Put the meat of the file inside a "#if + defined(__GNU_LIBRARY__)" clause, so that gmalloc.c, which + incorporates this file, can be used outside of the C library. + +Sun May 9 16:57:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/fseek.c: Don't call __flshfp unless STREAM is writable. + + * string/tester.c (main): Remove unused variable. + + * sysdeps/unix/bsd/set[er][gu]id.c: New files. + + * sysdeps/unix/mk-local_lim.c (NAME_MAX): Define to 255 if undefined. + + * malloc/Makefile (malloc-dist): Add ChangeLog and mem-limits.h. + (malloc/ChangeLog): New rule using Noah's changelog-extract. + (malloc.tar): Use o flag to tar to make compatible archives. + (gmalloc-routines): Add calloc, valloc, and cfree. + (dist-routines): Remove [cv]alloc from here. + (routines): Remove cfree from here. + +Fri May 7 16:45:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/ttyname.c: Replace fixed-sized NAME array with + static char *NAME and static size_t NAMELEN. + Don't check S_ISCHR. + Don't hack NAME before the loop. + If need more than NAMELEN chars to hold the name, increase NAMELEN + to more than big enough and malloc NAME. + Save errno in local var SAVE before doing anything; restore it + when returning non-error. + + * Makefile (generated): Add $(objpfx)stubs.h. + (README): New rule to call Make-dist to do the work. + + * mach/Makefile: Don't include mach-syscalls.mk if no_deps=t. + + * crypt/GNUmakefile (%.z): New rule for gzipping. + (crypt.tar): Use o flag to tar to make compatible archives. + + * Makeconfig: Find config.make in $(common-objpfx), not $(objpfx). + + * io/Makefile (headers): Remove filebits.h. + + * sysdeps/unix/sysv/sysv4/Dist: File removed. + + * Makefile (README): Move from here. + * Make-dist (README): To here. + + * sysdeps/unix/Makefile (sys/param.h): Don't depend on sys/. It + was causing sys/param.h to be remade all the time. + + * aclocal.m4 (GLIBC_PROVIDES): Add shell comment about configure + being generated and not to be editted. + + * sysdeps/unix/swapon.S: Moved to sysdeps/unix/common. + * sysdeps/unix/configure: Add swapon to list of syscalls to check for. + + * sysdeps/unix/mk-local_lim.c: New file, modified from + sysdeps/unix/common/mk-local_lim.c. + * sysdeps/unix/common/Makefile: Move local_lim.h rules from here. + * sysdeps/unix/Makefile: Put them there. + (local_lim-CFLAGS): Define new variable. + (mk-local_lim): Replace $(native-compile) with its value plus + $(local_lim-CFLAGS). + * sysdeps/unix/common/Dist: Remove mk-local_lim.c. + * sysdeps/unix/Dist: Add it here. + + * Makerules (make-dummy-dep): New variable; canned command. + ($(objpfx)%.dep: {$(objpfx),}%.s): New rules using $(make-dummy-dep). + (sysd-Makefile): Write a $(objpfx)%.dep: $dir/%.s rule using it. + + * misc/ioctl.c: Replace function_alias with: + [HAVE_GNU_LD]: Use symbol_alias. + [! HAVE_GNU_LD]: Write out the function; it must fetch its third arg + with va_arg and then call __ioctl. + +Thu May 6 14:56:16 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/sys/ioctl.h (__ioctl, ioctl): Changed prototype to take 2 + args and ... rather than a 3rd __ptr_t arg. + * sysdeps/stub/__ioctl.c: Changed defn. + + * sysdeps/unix/bsd/sun/sunos4/tcflow.c: Include <sys/ioctl.h>. + + * sysdeps/unix/Makefile (make-ioctls-CFLAGS): Define as + -DHAVE_SYS_TERMIOS_H if $(sysincludedir)/sys/termios.h exists. + (make-ioctls): Replace command `$(common-objdir-compile)' with + that var's contents from Makerules, plus $(make-ioctls-CFLAGS). + * sysdeps/unix/ioctls-tmpl.c [HAVE_SYS_TERMIOS_H]: Get <sys/termios.h>. + + * misc/sys/ioctl.h: Include <sys/ttydefaults.h> after <ioctls.h>. + + * sysdeps/unix/bsd/sun/sunos4/speed.c (cfget[io]speed): Return the + raw speed, rather than using it as an index into `speeds'. + (cfset[io]speed): Treat SPEED being an index into `speeds' just as + if it were the value of that element. + + * termios/termios.h: Remove definitions of B[0-9]+ and EXT[AB]. + * sysdeps/generic/termbits.h: Put them here instead. + * sysdeps/unix/bsd/sun/sunos4/termbits.h: Add new defns for those. + + * sysdeps/unix/Makefile (termbits-edit): If termbits.h is not the + generic version, set this to an | egrep command which filters out + symbols appearing in termbits.h. + (ioctls): Depend on $(sysincludedir)sys/termios.h if it exists. + Pass all deps after first to snarf-ioctls. + Put $(termbits-edit) in cmd line; it may be empty or a pipe. + Pipe through sort|uniq before tr (just to cut down on duplicates). + + * sysdeps/generic/Makefile, sysdeps/unix/Makefile: When deciding + whether to generate files whose stub versions are chosen, also + include the generation rules when the chosen directory is + $(common-objpfx), so they continue to be defined after running once. + + * sysdeps/posix/Makefile: Use patsubst instead of substition + references when the substitution or replacement contains a $. + Make has a bug (which I just fixed) with such substitution references. + + * posix/wait3.c: Fixed arg types in fn alias. + * posix/wait4.c: Likewise. + + * sysdeps/posix/Makefile: Remove vpath %.h line. + * Makerules: Add vpath %.h directive. + + * sysdeps/posix/Makefile (generated, before-compile): Add + $(common-objpfx)stdio_lim.h, not just plain stdio_lim.h. + + * Makerules (depend-$(subdir)): Put $(objpfx) in the output, not + its expansion. + (+make-deps): Add sed clause to translate the expansion of + $(objpfx) back into the variable reference. + +Wed May 5 15:59:40 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2/local_lim.h: New file. + + * sysdeps/unix/sysv/sco3.2/Makefile: New file + * sysdeps/unix/sysv/sco3.2/Dist: New file. + * sysdeps/unix/sysv/sco3.2/__fltused.c: New file. + + * sysdeps/unix/configure: New file. + * sysdeps/unix/inet/__select.S: Moved to sysdeps/unix/common. + This is because select is a call sysdeps/unix/configure wants to + check for, and it simplifies life for all those to be in unix/common. + + * sysdeps/tahoe/Implies: Remove $(bsdmath)tahoe line. + + * sysdeps/unix/sysv/sco3.2.4/{__sigact,__sigproc, + sigpending,sigsuspend}.S: New files. + + * Makefile (INSTALL): Depend on manual/maint.texi, not + manual/maint.texinfo. Use -- instead of + for long options. + + * configure.in: After setting $sysnames initially and adding the + FPU directory, expand and uniquize the list with code that used to + be in find-sysdirs. Make $sysnames blank-separated rather than + newline-separated. Generalize loop iterating over $sysnames, so + it sets $uname and sources sysdep configure scripts. Move + sys_siglist and ctype checks to sysdeps/unix/common/configure.in. + Set Make variable `config-sysdirs' to $sysnames in config.make, + and don't frob Sysnames or sysdirs files at all. + * find-sysdirs: File removed. + * Makefile (distribute): Remove find-sysdirs. + (sysd-dirs): Depend on config.make instead of config.make. + Use $(sysdirs) in place of `cat $<`. + * aclocal.m4: New file. + * sysdeps/unix/common/configure.in: New file, contains checks for + sys_siglist and ctype glue moved from top-level configure.in. + * Makerules (sysdirs, Sysnames): Rules removed. + Don't include sysdirs. + (sysdirs): Define variable from $(config-sysdirs). + (sysd-Makefile): Depend on config.make instead of sysdirs. + Use $(sysdirs) instead of filtering the sysdirs file. + * Make-dist (+sysdep-tsrcs): Include configure and configure.in + from sysdep dirs. + (dist.tar): Use o flag to tar for compatible archives. + (dist): Depend on foo.z instead of foo.Z. + ($(tardir){-crypt,}.tar.z): Renamed from .Z. + (%.z: %): New rule. + (%/configure: %/configure.in): New rule. + +Mon May 3 17:45:06 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/sco3.2.4/__waitpid.S: New file. + + * sysdeps/unix/sysv/sco3.2.4/direct.h: New file. + + * sysdeps/unix/readdir.c: Moved from unix/bsd, rewritten to always + use __getdirentries and D_NAMLEN macro, no #ifdefs. + * sysdeps/unix/sysv/readdir.c, sysdeps/unix/bsd/bsd4.4/readdir.c, + sysdeps/unix/bsd/ultrix4/readdir.c, + sysdeps/unix/bsd/hp/m68k/readdir.c, + sysdeps/unix/bsd/sun/readdir.c: Files removed. + * sysdeps/unix/common/{close,open,rewind,seek,tell}dir.c: Moved to + sysdeps/unix. + * sysdeps/unix/sysv/direct.h: New file. + * sysdeps/unix/bsd/direct.h (D_NAMLEN): Define to use d_namlen. + * sysdeps/unix/sysv/sysv4/direct.h (D_NAMLEN): Define to calculate + from d_reclen. + * sysdeps/unix/__getdents.c: New file. + * sysdeps/stub/direct.h: New file. + * sysdeps/unix/bsd/Dist: Remove bsddir.h. + * sysdeps/unix/sysv/sysv4/readdir.c: Moved to unix/sysv. + * sysdeps/unix/sysv/sysv4/bsddir.h: Renamed to direct.h. + * sysdeps/unix/bsd/bsddir.h: Likewise. + * sysdeps/unix/common/opendir.c: Include "direct.h", not "bsddir.h". + * sysdeps/unix/sysv/sysv4/readdir.c: Likewise. + * dirent/Makefile (distribute): Define to include direct.h. + + * sysdeps/unix/common/opendir.c: Be sure to close FD if fcntl fails. + + * sysdeps/generic/memcopy.h: #include <sys/cdefs.h> and use __P + prototypes instead of EXFUN. + + * sysdeps/generic/memcmp.c (__ptr_t, const): Define as appropriate + conditional on [__cplusplus || __STDC__]. + +Thu Apr 29 21:48:37 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile ($(libc.a)): Make this, not lib, depend on subdir_lib. + + * Makerules ($(objpfx)%.{o,dep} rules): Remove spurious / after + $(objpfx) in dependency patterns. + + * sysdeps/unix/bsd/sun/sparc/start.c (_start): Define with + `asm ("start")', so its asm name is `start' rather than `__start'. + Remove asm that did a `.set' pseudo-op, which Sun as seems not to grok. + +Wed Apr 28 12:59:46 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/system.c: Return 0 if LINE is nil. + + * sysdeps/unix/__execve.S [!SYS_execve && SYS_exec]: Define + SYS_execve to be SYS_exec. + + * time/mktime.c: Include <sys/types.h>. + +Mon Apr 26 17:10:21 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/generic/memcmp.c: Deansideclized. + [HAVE_CONFIG_H]: Include "config.h". + [HAVE_STRING_H || _LIBC]: Put #include <string.h> under this. + [_LIBC]: Put #include <memcopy.h> under this conditional. + [! _LIBC]: Define op_t, OPSIZ, byte, and MERGE. + + * time/mktime.c: Define __isleap if not defined. + +Fri Apr 23 18:08:33 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/__getdents.c: New file. + * sysdeps/unix/sysv/sysv4/sys_getdents.S: Moved to unix/sysv. + * sysdeps/unix/sysv/Makefile [subdir==dirent]: Add sys_getdents to + sysdep_routines. + * sysdeps/unix/sysv/Dist: Add sys_getdents.S. + * sysdeps/unix/sysv/sysv4/Dist: Remove it from here. + * sysdeps/unix/sysv/sysv4/Makefile: File removed. + +Thu Apr 22 17:40:28 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sony/newsos4/m68k/sysdep.h: New file. + + * sysdeps/generic/strsep.c: Set *STRINGP to END+1, not END. + + * configure.in (arg parsing): Grok --verbose and set verbose=yes. + + * sysdeps/sparc/{umul,mul}.S: Remove ' from ! comment. + + * sysdeps/sparc/Makefile (*.S): Find divrem.m4 in this sysdeps dir. + + * sysdeps/unix/bsd/sun/sunos4/speed.c (cfset[io]speed): Typo fix. + + * sysdeps/unix/bsd/sun/sparc/vfork.S: Use a sethi insn and %g1 as + a temporary, rather than expecting the address to fit into a short + jump. + + * sysdeps/unix/bsd/__fork.S: Moved to sysdeps/unix/__fork.S; we + want unix/MACHINE/__fork.S to come first. + + * sysdeps/unix/bsd/bsd4.4/__wait3.c: Make STAT_LOC type + `__WAIT_STATUS' (defined in <sys/wait.h>). + * sysdeps/unix/bsd/sun/sunos4/__wait4.c: Likewise. + + * signal/sigvec.c: Change args from `struct __sigvec *' to + `struct sigvec *' in function alias. + + * signal/sigproc.c: Make arg SET `const sigset_t *' in fn alias. + + * signal/sigaction.c: Change args from `struct __sigaction *' to + `struct sigaction *' in function alias. + + * sysdeps/unix/common/glue-ctype.c (main) [! TABLE]: Write just a + comment saying we don't know the table name, rather than barfing + with `TABLE' an undefined variable. + + * sysdeps/generic/printf_fp.c: Fixed test to chose %e format. + Make loop condition --J > 0; break out of loop when FPNUM < F. + After loop, use %e format iff J <= 0. + + * posix/glob/Makefile.in (.c.o): Put $(CFLAGS) last. + (glob.o): Depend on glob.c. + (fnmatch.o): Depend on fnmatch.c. + +Wed Apr 21 12:40:03 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/Makefile (before-compile): Add stdio_lim.h. + + * configure.in (signed size_t test): Remove 's from rhs of AC_DEFINE. + + * stdio/internals.c (seek_to_target): If __stdio_check_offset + fails with ESPIPE, do nothing. + + * sysdeps/generic/printf_fp.c: For %e type, add K-1 to CUTOFF, + rather than K. + When there are no post-decimal digits, never write a decimal point + for a %g spec unless it had a # modifier. + Move K==-1 test to write decimal point before K==CUTOFF test to + round and write last digit. + Merge code for first post-decimal digit with code for remaining digits. + Move code to write leading fractional zeros inside K<0 test which + determines if any will be needed. + In decimal fraction notation code, use R10 temporary instead of + repeating (R * 10) twice. + + * stdio/fwrite.c: Only fail when __stdio_check_offset fails if it + failed with ESPIPE. If offset==-1, don't change it or target. + + * sysdeps/posix/defs.c (stdstream): Rearrange initializers, as + FILE has been rearranged. Set offset and target to -1, not 0. + + * sysdeps/posix/stdio_init.c: If STREAM isatty, set its seek + function to NULL. Unix bites. + + * stdio/ungetc.c: Call __flshfp if linebuf_active or put_limit>buffer. + + * sysdeps/unix/bsd/sun/sparc/start.c [__GNUC__ < 2]: #error. + + * time/mktime.c: Deansideclized. + Don't include <errno.h> or <limits.h>; we don't need them. + [DEBUG] (printtm): Made static. + [HAVE_CONFIG_H]: Include "config.h". + [__GNU_LIBRARY__ || HAVE_LIMITS_H]: Surround #include <limits.h> + with these conditionals. + + * time/offtime.c (__mon_lengths): Move defn to mktime.c; replace + with extern decl. + * time/mktime.c (__mon_lengths): Define here; remove extern decl. + +Mon Apr 19 18:42:59 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/tempname.c: New file. + * sysdeps/stub/sysd-stdio.c (__stdio_gen_tempname): Moved there. + * sysdeps/posix/tempname.c: New file. + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Moved there. + + * stdio/fopen.c: Don't set the offset to zero. That can falsely + give the impression that an unseekable object is seekable. + + * stdio/internals.c (__flshfp): Discard any pushed back character + first thing after sanity checks. + (__flshfp): Deconditionalize code to call the output-room + function; we always want to give it a chance to prime the stream. + Remove code that reset bufp if put_limit==buffer. We want to let + the output-room function do that--that is priming the stream. + +Fri Apr 16 12:24:21 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules ($(libc.a)): Depend on lib-noranlib and have ranlib + command line. + (lib): Just depend on $(libc.a). + + * sysdeps/unix/bsd/sun/sparc/start.c (init_shlib): Use __environ, + not environ. + + * stdio/internals.c (__flshfp): Don't check that the buffer + actually contains anything when setting the put_limit to the end of + the buffer if linebuf_active. + (__flshfp): To write C into the buffer !FLUSH_ONLY, don't check + that bufp > buffer and get_limit == buffer. Check against + put_limit unless linebuf_active (in which case check against the + real put_limit, fp->__buffer + fp->__bufsize). + (__flshfp): Bother to call the output-room function if !FLUSH_ONLY + or bufp > buffer and get_limit <= linebuf-corrected put_limit. + (__flshfp): Check for a NULL output-room function before checking + if C will fit in the buffer. + (flushbuf): After putting C into the buffer, + set BUFFER_WRITTEN to zero and goto end instead of returning. + + * stdio/ungetc.c: Test STREAM->__pushed_back before flushing the + STREAM if it's writable. + + * posix/glob.c, posix/fnmatch.c: Surround code with + #if defined (_LIBC) || !defined (__GNU_LIBRARY__) + +Thu Apr 15 19:35:59 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * string/tester.c (main): Added tests for strsep. + + * sysdeps/ieee754/frexp.c: New file. + +Wed Apr 14 12:49:10 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (ar-it): Add c flag to ar commands. + + * posix/glob.c [USG, NeXT]: Don't test these. + [HAVE_STRING_H]: Test this to include string.h and define ANSI_STRING. + [HAVE_MEMORY_H]: Test this instead of NEED_MEMORY_H. + [! ANSI_STRING]: Put decls of bcopy and #define of memcpy et al here. + + * posix/fnmatch.c [HAVE_CONFIG_H]: #include "config.h". + +Mon Apr 12 16:34:53 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob.c: Rationalize directory header conditionals. + +Sun Apr 11 18:53:50 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/internals.c: Remove __libc_fatal. + * sysdeps/stub/sysd-stdio.c: Remove __stdio_errmsg. + * sysdeps/posix/sysd-stdio.c: Likewise. + * sysdeps/stub/libc_fatal.c, sysdeps/posix/libc_fatal.c: New files. + * stdio/Makefile (routines): Add libc_fatal. + + * stdio/stdio.h (FILE): Add new member `__linebuf_active' (flag). + Rearranged order of members slightly. + * stdio/setvbuf.c: Clear the linebuf_active flag. + * stdio/fseek.c: Likewise. + * stdio/internals.c (__flshfp): Test linebuf_active, not linebuf, + to decide to reset put_limit before calling the output-room function. + After calling it, if line-buffered, set put_limit to the + beginning of the buffer and set the linebuf_active flag. + (__fillbf): If linebuf_active is set, reset put_limit to the end + of the buffer, and clear the flag. + + * stdio/ungetc.c: If STREAM is writable and has something in its + buffer, flush it. + + * stdio/internals.c (__fillbf): When flushing all line-buffered + streams, don't test for their put_limits being > than their + buffers. We should let __flshfp figure it out. + + * stdio/setvbuf.c: Always set the put_limit to the beginning of + the buffer. + + * stdio/stdio.h (__putc): Rewritten to remove all knowledge of + magic for line-buffered streams. It now always calls __flshfp when + the bufp hits the put_limit. + + * stdio/fwrite.c: When recalculating BUFFER_SPACE after calling + __flshfp, ignore the put_limit for the sake of line-buffered streams. + + * stdio/fseek.c (fseek): Call __flshfp on STREAM unconditionally. + We don't want to try to put the conditions for when it is + necessary here as well. + + * sysdeps/generic/printf_fp.c: When deciding whether to use %e + format for %g, break out of the loop on J as soon as F reaches + FPNUM; after the loop, set TYPE to 'e' if J<0, meaning we went all + the way through. + + * misc/getpass.c (TCSASOFT): Define to 0 if undefined. + (getpass): Use a variable OUT to store the stream where output goes. + Use a variable NREAD to notice how much was read; if the last char + in the buffer is a newline, clobber it to a null terminator. + + * posix/fnmatch.h [__cplusplus || __STDC__]: Don't #define const. + +Thu Apr 8 19:29:37 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/tst-printf.c (main): Added some floating-point tests. + + * sysdeps/unix/bsd/sequent/i386/__sigvec.S: New file. + + * sysdeps/unix/sysv/i386/__sigret.S: Moved to sysdeps/unix/i386. + Use DO_CALL instead of magic. + + * sysdeps/unix/bsd/i386/__wait3.S: Use DO_CALL instead of magic. + Use scratch instead of %ecx and r1 instead of %edx. + + * sysdeps/unix/bsd/i386/__vfork.S: Rewritten to not use SYSCALL__. + Use DO_CALL instead, and save the return PC in a register around + the trap. + + * sysdeps/unix/i386/sysdep.h (DO_CALL): New macro to do syscall trap. + (PSEUDO): Use it instead of putting the code here. + + * stdio/vfprintf.c (number): Write "0x" before padding, not after. + + * sysdeps/unix/bsd/sequent/i386/sysdep.h: New file. + + * sysdeps/unix/bsd/__setuid.c: #include <sys/types.h>. + Change argument type to uid_t. + * sysdeps/unix/bsd/__setgid.c: #include <sys/types.h>. + Change argument type to gid_t. + + * sysdeps/unix/common/__getgrps.c: Restore errno after erroneous + syscall failure. + + * stdio/tst-printf.c (fp_test): New function, batch of tests from + a bug report. + (main): Call it. + +Wed Apr 7 17:17:17 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/pow.c (pow_p): Don't initialize K; was a dead store. + +Mon Apr 5 21:17:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/common/__getgrps.c: If __bsd_getgroups returns an + error and SIZE==0, alloc temp space for NGROUPS_MAX elts and call + it again on that, so we can find the number of groups. + + * stdio/__vfscanf.c (input_error): If DONE is nonzero, return it; + else return EOF. + (%c): Don't check for C==EOF at the end; let the following spec get it. + (%[eEfgG]): EOF after sign is conv_error, not input error. + + * sysdeps/unix/common/__getgrps.c: If gid_t==int, pass LIST to + __bsd_getgroups, not NULL. + No error for SIZE > NGROUPS_MAX. + +Sun Apr 4 18:52:34 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/{bsd,sysv}/i386/Implies: Files removed. + They should no longer be necessary, since configure now tries more + sysdeps directory permutations. + + * sysdeps/unix/bsd/{i386,sun/sparc,hp/m68k,ultrix4/mips}/__set[ug]id.S: + Files removed. They should no longer be necessary, since the new + sysdeps scheme should find unix/bsd/__set[gu]id.c before + unix/__set[gu]id.S. + + * sysdeps/unix/i386/__pipe.S: Use r1 in place of %edx and scratch + in place of %ecx. + * sysdeps/unix/i386/__wait.S: Likewise. + * sysdeps/unix/i386/__fork.S: Use r1 in place of %edx and r0 in + place of %eax. + * sysdeps/unix/i386/__vfork.S: Likewise. + * sysdeps/unix/i386/sysdep.h (scratch): #define as %ecx. + * sysdeps/unix/sysv/i386/linux/sysdep.h: Likewise. + + * configure.in ($uname = generic): Set kernel_{version,release} to + empty before all else. + If /vmunix doesn't exist, try grovelling over /dynix instead. + + * sysdeps/unix/Makefile (syscall.h): Double $ in sed cmd. + +Fri Apr 2 15:15:44 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (config_vars): New variable; text to go in config.make. + Use AC_HEADER_EGREP to grovel stdarg.h for __gnuc_va_list and set + stdarg.h in config_vars if we find it. + + * sysdeps/unix/bsd/sun/sunos4/tcsendbrk.c, + sysdeps/unix/bsd/sun/sunos4/tcflow.c, + sysdeps/unix/bsd/sun/sunos4/tcflush.c, + sysdeps/unix/bsd/sun/sunos4/tcsetattr.c, + sysdeps/unix/bsd/sun/sunos4/__tcgetatr.c: New files. + + * sysdeps/unix/Makefile (syscall.h): Add sed cmd to terminate + unterminated comments at the ends of lines. + + * sysdeps/posix/getcwd.c: Deansideclized and added four tons of + portability goop. + +Mon Mar 29 13:18:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sunos4/speed.c: New file. + + * sysdeps/generic/termbits.h: New file, contents taken from termios.h. + * termios/termios.h: Remove type & macro defns; #include <termbits.h>. + [__OPTIMIZE__] (cf[gs]et[io]speed): Remove macro versions. They + just cause trouble because they want to be in termbits.h (since + they are sysdep) and also to come after the prototypes (which must + come after termbits.h to get speed_t and struct termios defined). + The optimization was insignificant anyway. + * termios/speed.c: Moved to sysdeps/generic. + + * termios/cfsetspeed.c: Call cfset[io]speed, rather than doing it + ourselves. + + * time/__tzset.c (tz_rule): Make member `secs' not a bitfield. + (compute_change): Complete rewrite; code basically stolen from + localtime3/localtime.c:transtime. + #include "tzfile.h" for SECSPERDAY; #define NOID first. + + * sysdeps/unix/bsd/i386/__vfork.S: Don't try to #include __fork.S. + Instead, copy that code here and change `fork' to `vfork'. + + * Makeconfig (+default_cflags): Rename to default_cflags. + (+cflags): Use that name. + + * Makefile (configure): New rule. + +Sun Mar 28 16:12:33 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/fnmatch.c (case '*'): Before final loop, fold C1, rather + than foling *P before it goes into C1. C might need folding instead. + + * posix/Makefile (tests): Add testfnm. + * posix/testfnm.{c,args}: New files. + +Fri Mar 26 15:04:27 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/mktime.c: Wholly new implementation from Noel Cragg. + + * sysdeps/unix/bsd/sun/__sigret.S: New file. + * sysdeps/unix/bsd/sun/m68k/{Makefile,Dist}: New files. + * sysdeps/unix/bsd/sun/m68k/{sigcontext.h,sigtramp.c}: New files. + * sysdeps/unix/bsd/sun/sparc/__sigvec.S: Moved to sysdeps/unix/bsd/sun. + + * Makefile (clean): Remove sysd-Makefile, sysd-dirs, sysdirs + (distclean): New target. + * sysdeps/unix/common/Makefile (generated): Add local_lim.h, + mk-local_lim, glue-ctype, glue-ctype.c, siglist.c, make_siglist. + * sysdeps/generic/Makefile (generated): Add bytesex.h, + det_endian, siglist.c, make_siglist. + * sysdeps/unix/Makefile (generated): Add errnos.h, errnos, + make-errnos, make-errnos.c, ioctls.h, ioctls, make-ioctls, + make-ioctls.c, errlist.c, make_errlist, syscall.h, sys/param.h, + param.h.c, param.h.dep, $(sys/param.h-includes). + + * misc/Makefile (extra-objs): Define new var to include bsd-compat.o. + +Fri Mar 26 14:53:30 1993 Michael John Haertel (mike@skinner.cs.uoregon.edu) + + * malloc/malloc.c (malloc): Start searching at _heapindex, not + MALLOC_SEARCH_START. + * malloc/malloc.h (MALLOC_SEARCH_START): Macro removed. + * malloc/realloc.c (realloc): When malloc returns NULL, handle the + case of the block we need to unfree (which was just freed) having + been coalesced with its neighbors. + +Thu Mar 25 13:40:17 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Rules (all): Depend on others. + + * time/Makefile (zonenames): Change target to $(objpfx)zonenames. + Make the generated file prepend $(objpfx) to + Include that instead of zonenames. + (zones-%): Change target to $(objpfx)zones-%. + + * Makefile ($(objpfx)Mcrt1.o): Put temporary Mcrt1.c file in + $(objdir), rather than the current directory. + + * configure.in (arg parsing): Recognize `--exec-prefix' rather + than `--exec_prefix'. + + * Rules (mostlyclean): Remove the .o files for $(tests) and $(others). + Remove $(objpfx)depend-$(subdir). + (clean): Remove $(extra-objs). + * Makefile (clean): Remove $(install-lib) from $(objdir). + Don't try to remove ansi/ and trad/ or dist.tar or lint.out. + Remove $(objpfx)depend-. + * time/Makefile (extra-objs): Define new var. + * malloc/Makefile (extra-objs): Likewise. + + * Rules (+objs): Variable removed. + (clean): Use $(objects) in place of $(+objs). + + * sysdeps/unix/Makefile (sys/param.h-includes): Move all this + outside of ifeq ($(subdir),misc). + Fixed sed command to filter out [hn]to[nh][sl]. + (sys/param.h-includes): New target; dep on $(sys/param.h-includes). + + * posix/fnmatch.h [!_POSIX_C_SOURCE || ...]: Make this test + _GNU_SOURCE, not _BSD_SOURCE; these are our extensions, not theirs. + (FNM_CASEFOLD): New bit. + (__FNM_FLAGS): Removed macro. + * posix/fnmatch.c (fnmatch): Don't test for bogus flag bits; who cares? + (FOLD): New macro to casefold a char if FNM_CASEFOLD. + Use it to fold all chars before comparison. + +Wed Mar 24 16:09:26 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/Makefile (malloc/%.c, malloc/%.h): Rules removed. + + * stdio/stdio.h (fopencookie): Rename parameter IO_FUNCTIONS to + IO_FUNCS. The former conflicted with a typedef name, which ist + verboten. + + * time/sys/time.h (enum __itimer_which): Remove trailing comma. + +Mon Mar 22 15:35:54 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/malloc.h [_MALLOC_INTERNAL] + [__GNU_LIBRARY__ || STDC_HEADERS || USG] (memmove): Define in + terms of bcopy. + * malloc/malloc/gmalloc-head.c: Redo previously undone change. + +Thu Mar 18 04:59:21 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * malloc/malloc/gmalloc-head.c: Undo previous change. + +Wed Mar 17 12:22:21 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * mach/mach.h: New file. + + * Rules (clean): Remove $(generated), not $(clean-extras). + (subdir_echo-distinfo): Use $(generated) instead of $(dont_distribute). + (generated): Export this instead of dont_distribute. + * stdlib/Makefile (generated): Set this, not dont_distribute. + * sysdeps/posix/Makefile: Likewise. + * sysdeps/unix/sysv/Makefile: Likewise. + * sysdeps/unix/Makefile: Likewise. + * Makefile (generated): Export this instead of dont_distribute. + (parent_echo-distinfo): Use $(generated) instead of $(dont_distribute). + * Make-dist (+tsrcs): Filter out $(generated), not $(dont_distribute). + + * mach/mach_init.h (__mach_task_self): Define so as not an lvalue. + (mach_task_self): Surround defn with parens. + + * sysdeps/unix/Makefile (sys/param.h): Put "#include <endian.h>" in. + ($(sys/param.h-includes)): Edit out #define's of *_ENDIAN and + BYTE_ORDER. + + * stdlib/tst-strtol.c (tests): Fully bracket initializers. + + * stdio/bug4.c: Change #ifdef LIBC to #ifdef _LIBC. + + * misc/progname.c (set_progname): Make a useless reference to + set_progname to avoid a `defined but not used' warning. + + * sysdeps/mach/i386/start.c (_cthread_{init,exit}_routine): Remove + `extern'; these want to be uninitialized common defns. + +Mon Mar 15 18:41:05 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/__times.c (timeval_to_clock_t): Put __inline + before storage class in defn. + + * sysdeps/unix/sysv/signum.h (SIG_ERR, SIG_DFL, SIG_IGN): Cast + values to __sighandler_t, rather than obsolete ansidecl magic. + + * sysdeps/unix/__execve.S [!SYS_execve && SYS_exece]: Define + SYS_execve to be SYS_exece. + + * sysvipc: New directory. + * sysvipc/Makefile: New file. + * sysvipc/sys/ipc.h: New file. + +Fri Mar 12 15:31:44 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/execlp.c (execlp): Remove spurious second declared parameter. + Don't fill ARGV[0] specially; just let the loop do it. + * posix/unistd.h (execlp): Remove spurious second declared parameter. + +Thu Mar 11 13:58:47 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makerules (sysd-Makefile): Write %.dep: %.S and %.dep: %.c rules. + Depend on Makerules. + ($(objpfx)%.{o,dep}: $(objpfx)/%.{S,c,s}): New rules to find + sources in $(objpfx) before sysdep directories. + + * configure.in (signed size_t check): Use eval on $CPP, since it + contains unexpanded variable refs. + Send grep output to /dev/null. + Put quotes around 'unsigned long int'. + +Wed Mar 10 18:32:11 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * features.h [! _LIBC]: #include <stubs.h>. + * Makerules (stubs): New phony target. + ($(common-objpfx)stub-$(subdir)): New target. + * Makefile (headers): Add stubs.h. + ($(objpfx)stubs.h): New target. + + * Makeconfig (CPPFLAGS): Define _LIBC, not LIBC. + + * Makerules (.SUFFIXES): Remove .m4; we no longer have any such files. + + * inet/netinet/in.h: Don't #include <inet-cvt.h>. + (ntohl, ntohs, htonl, htons): Declare. + #include <endian.h>. + [__BYTE_ORDER == __BIG_ENDIAN] (ntohl, ntohs, htonl, htons): + Define no-op macros. + * inet/Makefile (headers): Remove inet-cvt.h. + * sysdeps/vax/inet-cvt.h, sysdeps/generic/inet-cvt.h: Files removed. + * sysdeps/generic/{ntohl,ntohs,htonl,htons}.c + [BYTE_ORDER == LITTLE_ENDIAN]: Byte-swap X before returning it. + +Tue Mar 9 11:32:35 1993 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu) + + * malloc/malloc/gmalloc-head.c: Remove #definitions of memset, + memcpy, and memmove; this is taken care of by malloc.h anyway. + +Mon Mar 8 15:12:32 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/mips/jmp_buf.h (JB_PC): Protect with #ifdef __USE_MISC. + + * sysdeps/unix/sysv/sysv4/sigaction.h: Put SA_* except for + SA_NOCLDSTOP inside #ifdef __USE_MISC. + +Mon Mar 8 15:05:13 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * sysdeps/mips/jmp_buf.h (jmp_buf): Use `__ptr_t', not `PTR', for + member types. + (JB_PC): New define, for backwards compatability with Ultrix. + + * sysdeps/unix/sysv/sysv4/sigaction.h: New file. + +Mon Mar 8 13:20:02 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/glob/Makefile.in (VPATH): Set this to @srcdir@. + (srcdir): Set this to $(VPATH). + + * posix/glob.c (glob): In no matches with GLOB_NOCHECK set case, + add NULL terminator to PGLOB->gl_pathv. + (prefix_array): Renamed arg PREFIX to DIRNAME, local var PRELEN to + DIRLEN. If DIRNAME is just "/", don't prepend it, so we get + "/foo" instead of "//foo". + (glob): Move qsort call outside of the else clause of the + glob_pattern_p test; it should always be done. + +Thu Feb 25 14:49:52 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * malloc/malloc.h [_MALLOC_INTERNAL]: Move #include <stdio.h> to + front of file; it needs to come before size_t/ptrdiff_t frobnication. + +Wed Feb 24 16:34:58 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (compile-command.[Ssc]): New variables; define them if + they are not already defined. + (sysd-Makefile): For each directory, write three rules: + %.o: $dir/%.[Ssc]; $(compile-command.[Ssc]). + (sysdep_path): Remove definition and vpath directives. + * sysdeps/m68k/Makefile (compile-command.S): Define our own version. + ($(objpfx)%.o: %.S): Rule removed. + + * sysdeps/unix/sysv/linux/{__dup2,__mkdir,__rmdir,__setpgrp}.S: + Removed. + * sysdeps/unix/sysv/linux/Implies: Created; implies unix/common. + + * sysdeps/unix/sysv/sysv4/{sete[gu]id.S,fchdir.S,signum.h,__sigproc.S}: + New files. + + * sysdeps/unix/sysv/sysv4/time.S: New file. + + * sysdeps/unix/common/Dist: New file; everything from + sysdeps/unix/bsd/Dist except for bsdtty.h and bsddir.h. + * sysdeps/unix/bsd/Dist: Remove things now in sysdeps/unix/common/Dist. + + * sysdeps/unix/bsd/sun/sparc/{__brk.c,__fork.S,__pipe.S,__vfork.S}: + Moved to new directory sysdeps/unix/sparc. + + * sysdeps/unix/common/Implies: New file, in new directory; implies + unix/inet only. + * sysdeps/unix/bsd/Implies, sysdeps/unix/sysv/sysv4/Implies: New + files; both imply unix/common. + * sysdeps/unix/common/Makefile: Moved from sysdeps/unix/bsd. + Changed references to unix/bsd to unix/common. + * unix/bsd/{__access.S,__adjtime.S,__fchmod.S,__fchown.S,__getgrps.c, + __getitmr.S,__getpgrp.S,__getrusag.S,__gettod.S,__lstat.S,__mkdir.S, + __readlink.S,__rmdir.S,__setitmr.S,__setpgrp.S,__symlink.S, + bsd_getgrp.S,closedir.c,ftruncate.S,getrlimit.S,glue-ctype.c, + make_siglist.c,mk-local_lim.c,opendir.c,readv.S,rename.S,rewinddir.c, + seekdir.c,setgroups.S,setrlimit.S,telldir.c,truncate.S,vhangup.S, + writev.S,__dup2.S}: Moved to sysdeps/unix/common. + * sysdeps/unix/sysv/sysv4/{__access.S,closedir.c,opendir.c, + rewinddir.c,seekdir.c,telldir.c}: Removed. + +Mon Feb 22 12:19:19 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/pow.c (pow): Use __isnan to test for NaN rather + than expecting "x!=x" to work. + (pow_p): When testing if Y is an integer, use long int rather than + int; they are different on some systems. Compare against + LONG_MIN+1, not LONG_MIN; (long int) (double) LONG_MIN might overflow. + + * malloc/dist-Makefile (gmalloc.c): Depend on Makefile. + + * malloc/Makefile (gmalloc-routines): New variable. + (dist-routines): Use it. + (malloc/Makefile): Also replace <GMALLOC-SOURCES> with + $(gmalloc-routines). + (malloc/Makefile): Make it unwritable to avoid accidental lossage. + Depend on Makefile. + + * malloc/dist-Makefile (gmalloc): New variable: <GMALLOC-SOURCES>. + (gmalloc.c): Use $(gmalloc), not $(sources). + Make the file unwritable to avoid accidental lossage. + + * malloc/mtrace.c: Don't #include <stdio.h> because <malloc.h> did + it for us. + + * malloc/valloc.c [! __GNU_LIBRARY__]: Replace hairy conditionals + with #include "getpagesize.h". + * malloc/Makefile (distribute, malloc-dist): Add getpagesize.h. + +Sun Feb 21 18:29:30 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/sparc/Makefile (nodist-routines): Don't define. + We want to distribute the generated divrem files; otherwise anyone + building the library must have an m4 that works. + ($(divrem).S): Put these in sysdeps/sparc, not in $(objdir). + (routines): Only put this inside ifeq ($(subdir),gnulib). + + * sysdeps/unix/bsd/sun/m68k/Makefile: File removed. + +Sat Feb 20 16:43:55 1993 Torbjorn Granlund (tege@sics.se) + + * sysdeps/i386/memset.c: Move adjustment of LEN before first stosb. + * sysdeps/i386/bzero.c: Likewise. + +Thu Feb 18 14:34:00 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/mcheck.c (checkhdr): Use `const', not `__const'. + +Mon Feb 1 19:19:13 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/m68k/fpu/__logb.c: Use two-operand forms of 68881 insns + rather than the one-operand source==dest form. Sun's sun3 + assembler apparently doesn't grok the one-operand form. + + * sysdeps/posix/getcwd.c: Call __lstat instead of stat. + We should not lose on nonexistent symlink targets. + +Thu Jan 21 20:12:25 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/glob.c: Put #includes of <glob.h> and <fnmatch.h> after + all system includes, in case one of them has conflicting defns of + FNM_* or GLOB_*, so we will redefine. #undef FNM_* and GLOB_* + before including our headers. + +Tue Jan 19 16:16:05 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * mach/Makefile (routines): Removed __bcopy. + * mach/__bcopy.c: File removed. + + * posix/glob.c (my_realloc): Cast result of malloc/realloc to (char *). + +Sat Jan 16 14:19:07 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu) + + * manual/summary.awk: Handle single word in braces. + +Thu Jan 14 13:52:43 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob/Makefile.in (realclean): Remove Makefile. + +Mon Jan 11 18:32:56 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sony/m68k/Implies: Imply unix/bsd/hp/m68k, not + unix/hp/m68k. + + * sysdeps/unix/bsd/tcsetattr.c: Use cbreak mode if ISIG is set, + not if OPOST is set. + Fixed typo in TOSTOP frobbing. + +Tue Jan 5 15:11:31 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/Makefile (glob.tar): Include glob/configure.in. + +Mon Jan 4 17:05:44 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/glob/Makefile.in (RANLIB): Define to @RANLIB@. + (RANLIB_TEST): Removed. + (libglob.a): Don't use it. + +Thu Dec 31 13:08:20 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/bsd4.4/{chflags,fchflags,setlogin}.S: Fix arg count. + + * sysdeps/posix/Makefile (mk-stdiolim): Use $(cded-objdir-CPPFLAGS). + (cded-objdir-CPPFLAGS): Define new var. + + * sysdeps/unix/Makefile ($(sys/param.h-includes)): Strip trailing + slash from directory name for mkdir. + +Tue Dec 29 18:18:58 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/posix/sysd-stdio.c (exists): Return true if stat fails + with other than ENOENT. + + * sysdeps/posix/__flock.c: New file. + + * malloc/Makefile (dist-headers): Define to malloc.h. + (headers): Replace malloc.h with $(dist-headers). + (malloc/Makefile): Use $(dist-headers) in place of $(headers). + (malloc-dist, distribute): Replace ChangeLog with OChangeLog. + + * malloc/dist-Makefile (malloc.tar{,.Z}): Depend on FORCE. + (FORCE): Define empty target. + +Tue Dec 29 16:45:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/sparc/{umul,mul}.S: Use tege's shift+mask hack to avoid + a test and branch for sign fixup. + + * limits.h [__GNUC__ >= 2]: #ifndef _GCC_LIMITS_H_, not _LIMITS_H_, + to #include_next <limits.h>. + + * sysdeps/posix/getcwd.c: Call closedir after copying from the + `struct dirent' buffer, not before. That buffer is freed by closedir. + + * posix/gnu/types.h (__fd_set): Renamed member to `fds_bits' for + compatibility with braindead extant code. + + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Check for BUF + being too small before doing sprintf. + + * malloc/malloc.h [_MALLOC_INTERNAL], malloc/valloc.c + [HAVE_CONFIG_H]: #include "config.h". + + * Makefile (doc): Removed rule. + (dvi, info): New rule. + +Mon Dec 28 15:50:31 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob.c [HAVE_CONFIG_H]: Test this, not SHELL, to decide + whether or not we want to #include "config.h". + +Wed Dec 16 12:01:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * inet/Makefile (routines): Removed ruserpass. Why did it get + included in the first place? That version does not match the one + in the NET2 ftp source; whence came it? + +Sat Dec 12 16:41:03 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sparc/start.c: Use .set, not GNU ld magic, + to alias asm symbol `start' to `__start'. + +Fri Nov 20 18:20:50 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/vfprintf.c (%p): Tests of LEFT for "(nil)" were inverted. + + * stdio/tst-printf.c (main): Add `printf ("%#03x\n", 1);'. + Add a width to %p test. + + * stdio/vfprintf.c (unsigned_integer): Clear SHOWSIGN and SPACE + flags before falling into `number:'. The `+' and ` ' flags are + only meaningful for signed numbers. + + * string/tester.c (main): For strstr #11, correct return is first + arg, not end of first arg. + + * stdlib/mbtowc.c: If S is "", return 0. How was I convinced + before that this is not what ANSI says? + + * stdio/__vfscanf.c: Initialize MALLOC_STRING to zero on each + iteration (when we zero is_short et al). + + * sysdeps/posix/mkstemp.c (mkstemp): New file. + * sysdeps/stub/mkstemp.c (mkstemp): New file. + * misc/Makefile (routines): Add mkstemp. + + * sysdeps/posix/mktemp.c: Use `getpid ()' in place of undefined + variable PID. + #include <sys/stat.h>. + + * dirent/scandir.c: If SELECT is nil, don't try to call it. + If CMP is nil, don't sort. + +Wed Nov 18 13:42:09 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/__wait4.c: Changed type of 2nd arg to __WAIT_STATUS. + + * posix/sys/wait.h (__WAIT_STATUS): #if 0 out gcc2 magic defn. + GCC is broken as of 2.3.1. + + * signal/signal.h (__sigaction, sigaction): Fixed type in + prototype from `struct __sigaction' to `struct sigaction'. + + * sysdeps/m68k/fpu/atan2.c (PI, PIo4, PIo2): Removed static vars. + (atan2): Declare PIo4 and PIo2 locally, and compute them from pi. + + * Makerules (native-CFLAGS): Define as $(config-defines). + + * sysdeps/unix/bsd/glue-ctype.c: Upcased all HAVE_* names in #ifdef's. + + * posix/fnmatch.h (FNM_LEADING_DIR): New flag. + * posix/fnmatch.c (fnmatch): Support it. + + * sysdeps/i386/bytesex.h: New file. + * sysdeps/i386/endian.h: Removed. + * sysdeps/stub/bytesex.h: New file. + * sysdeps/stub/endian.h: Removed. + * sysdeps/generic/Makefile (bytesex.h): Create with det_endian. + (endian.h): Removed old rule. + (before-compile): Replace endian.h with bytesex.h. + * string/Makefile (headers): Add bytesex.h. + * string/endian.h: New file. + * sysdeps/generic/det_endian.c: Rewritten to output just one line, + a #define of __BYTE_ORDER to 1234, or 4321, etc. + * inet/arpa/nameser.h: #include <endian.h>, rather than #ifdef'ing + on misc. things to #define BYTE_ORDER. + * sysdeps/generic/waitstatus.h: Test value of __BYTE_ORDER, not + whether __LITTLE_ENDIAN is #define'd. + * sysdeps/generic/mathimpl.h: Likewise. + * sysdeps/generic/memcopy.h: Likewise. + * sysdeps/ieee754/huge_val.h: Likewise. + * sysdeps/ieee754/nan.h: Likewise. + * sysdeps/ieee754/ieee754.h: Likewise. + +Mon Nov 16 12:19:10 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makeconfig (ARCH): Define to empty if $(..)config.make exists. + + * misc/getusersh.c (initshells): malloc (STATB.st_size + 1), to + contain the terminating NUL. Pass fgets the real amount of space + left in the buffer, instead of the random number (MAXPATHLEN + 1). + + * configure.in (minix*): base_os=unix/sysv. + * sysdeps/unix/sysv/minix/sigaction.h: New file. + + * sysdeps/generic/sigaction.h (__SA_*): Renamed to SA_*. + [__USE_BSD]: Put all but SA_NOCLDSTOP under this #ifdef. + * signal/signal.h (SA_*): Remove #define's. + (SIG_*): Moved #define's to sigaction.h. + + * sysdeps/generic/sigset.h (__sigmask): Shift ((sigset_t) 1), not + just 1. + + * signal/signal.h (kill): Fix type of first arg to __pid_t, not int. + + * sysdeps/unix/Makefile (errnos): Changed regexp to disallow + E[^A-Z0-9], and not to require that the defn be numeric only. + + * stdlib/stdlib.h: Don't #include <huge_val.h>; ANSI doesn't say + <stdlib.h> defines HUGE_VAL. + + * stdlib/stdlib.h (__compar_fn_t): Use __P around prototype. + + * posix/Makefile (headers): Add utsnamelen.h, so it gets installed. + (distribute): Remove it from here. + + * setjmp/setjmp.h (sigjmp_buf): Rename `__savemask' to + `__mask_was_saved' and `__sigmask' to `__saved_mask'. + * setjmp/sigjmp_save.c (__sigjmp_save): Change use. + * setjmp/siglongjmp.c (siglongjmp): Likewise. + +Fri Nov 13 17:34:00 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure.in (config.make): Write assignments for INSTALL, + INSTALL_PROGRAM, INSTALL_DATA, and RANLIB. + +Thu Nov 12 17:11:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/stime.c: #include <stddef.h> for NULL. + + * sysdeps/stub/morecore.c: Fixed arg type to ptrdiff_t. + + * sysdeps/stub/ptrace.c: Fixed `va_start' uses to pass 2nd arg. + + * sysdeps/unix/sysv/sysv4/fcntlbits.h: New file, modified from + unix/bsd/sun/sunos4 version. + + * sysdeps/unix/bsd/bsd4.4/fcntlbits.h: New file, modified from + unix/bsd version. + + * sysdeps/unix/bsd/ultrix4/fcntlbits.h: New file, modified from + unix/bsd version. + + * sysdeps/unix/bsd/sun/sunos4/fcntlbits.h: New file, modified from + unix/bsd version. + + * sysdeps/unix/sysv/fcntlbits.h: Rewritten from stub version. + * sysdeps/unix/sysv/filebits.h: File removed. + + * sysdeps/unix/bsd/fcntlbits.h: Rewritten from stub version. + * sysdeps/unix/bsd/filebits.h: File removed. + + * io/fcntl.h: Don't #include <filebits.h>. + Removed all #define's of foo to __foo; <fcntlbits.h> now defines + the unmarked cases. + + * sysdeps/stub/fcntlbits.h: Remove leading __ from all symbols. + + * misc/sys/file.h (L_SET, L_INCR, L_XTND): Define to literal + values, not to __ versions. These are not system-dependent. + (LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB): Define to literal values, + not to __ versions. These are not actually system-dependent, + because no system has `flock' except for BSD compatibility, and + then they use the same numbers. + * sysdeps/stub/fcntlbits.h (__L_SET, __L_INCR, __L_XTND): Removed. + (__LOCK_SH, __LOCK_EX, __LOCK_UN, __LOCK_NB): Removed. + +Tue Nov 10 17:01:11 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/stub/fcntlbits.h: Merged in contents of filebits.h. + (struct __flock): Renamed to `struct flock'. + * sysdeps/stub/filebits.h: File removed. + + * posix/unistd.h (access, lseek, close, read, write, pipe, chown, + fchown, chdir, dup, dup2, execve, pathconf, fpathconf, sysconf, + getpid, getppid, setpgrp, setpgid, setsid, getuid, getgid, + geteuid, getegid, setuid, setreuid, setgid, setregid, fork, vfork, + isatty, link, symlink, readlink, unlink, rmdir, gethostname, + getpagesize, getdtablesize): Remove #define's to __ versions. + + * posix/sys/types.h: Don't #include <gnu/time.h>. + Instead, use forward decl `struct timeval;'. + (__select): Use `struct timeval', not `struct __timeval', in prototype. + Move into #ifdef __USE_BSD. + (select): Removed #define to __select; added real prototype. + + * sysdeps/generic/waitstatus.h: New file. + * sysdeps/stub/waitflags.h: New file. + * sysdeps/unix/bsd/waitflags.h: New file. + * posix/sys/wait.h: Don't #include <gnu/wait.h>. + Do #include <waitflags.h> and <waitstatus.h>. + (WHOHANG, WUNTRACED): Don't #define to __ versions; <waitflags.h> + will define the unmarked cases. + (union __wait): Remove type decl and associated #define's for w_*; + `union wait' (no __) is now defined in <waitstatus.h>. + [__USE_BSD && __GNUC__ >= 2] (__WAIT_STATUS): Define as funky union. + (waitpid, wait3, wait4, wait): Removed #define's to __ versions; + added real prototypes. + * posix/gnu/wait.h: File removed. + * posix/Makefile (headers): Remove gnu/wait.h. + + * posix/sys/times.h [__OPTIMIZE__] (times): Removed #define to __times. + + * posix/sys/utsname.h: Removed decl of __uname_getnode. + + * time/sys/time.h: Don't #include <gnu/time.h>. + Don't support __need_timeval. + (struct timeval, struct timezone, struct itimerval, + enum __itimer_which): Declare these types here. + (gettimeofday, settimeofday, adjtime, getitimer, setitimer, + utimes): Removed #define's to __ versions. Added real prototypes. + Use `struct timeval' instead of `struct __timeval', etc. + * time/gnu/time.h: File removed. + * time/Makefile (headers): Removed gnu/time.h. + + * resource/sys/resource.h: Don't #include <gnu/time.h>. + +Mon Nov 9 18:41:03 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * socket/sys/socket.h (SO_STYLE): Define instead of SO_TYPE. + (SO_TYPE): Define as SO_STYLE. + + * inet/netinet/in.h (struct ip_opts): New type. + (IP_*): New constants snarfed from 4.4's in.h. + +Fri Nov 6 15:34:41 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * resource/sys/resource.h (struct rusage): #include <sys/time.h> + before struct defn. Use `struct timeval', not `struct __timeval' + for `ru_utime' and `ru_stime' members. + + * resource/sys/resource.h [__OPTIMIZE__] (getrusage, ulimit), + misc/sys/ioctl.h [__OPTIMIZE__] (ioctl): Remove #define's to __ + versions. + + * string/strings.h: Protect against multiple inclusion. + * termios/sys/termios.h: Ditto. + + * string/string.h [__GNUC__ && __OPTIMIZE__] (ffs): Remove #define + to __builtin_ffs. + + * stdlib/stdlib.h (comparison_fn_t): Use a typedef, not a #define. + Define this #ifdef __USE_GNU, not #ifdef __GNUC__. + [__GNUC__ && __OPTIMIZE__] (abs, labs): Remove #define's to __builtin_. + +Thu Nov 5 20:01:25 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * signal/Makefile (headers): Remove gnu/signal.h; + add sigaction.h, sigset.h. + * sysdeps/generic/sigaction.h: New file. + * sysdeps/generic/sigset.h: New file. + * signal/gnu/signal.h: Removed. + * signal/signal.h: Move __{BEGIN,END}_DECLS outside all the #if's + (except the outermost one that protects against multiple inclusion). + Don't #include <gnu/signal.h>. Instead #include <sigset.h> + outside of #if's, and #include <sigaction.h> inside #ifdef __USE_POSIX. + (__sighandler_t): Define here; it is not system-specific. + (kill, ssignal, gsignal, sigblock, sigsetmask, sigpause, sigvec, + sigreturn): Remove #define's to __ versions. + (sighandler_t, sigset_t): Use a typedef, not a #define. + [__OPTIMIZE__] (sig{empty,fill,add,del}set, sigismember): Make + these macros take args. + (sigaction): Remove #define. + (struct __sigvec): Renamed `struct sigvec'. + (__sigvec): Use `struct sigvec', not `struct __sigvec', in prototype. + +Fri Oct 30 19:45:26 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * configure.in (sco*): base_os=unix/sysv. + +Thu Oct 29 16:29:26 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * configure.in: New file; mostly contents of old file `configure'. + (srcdir guessing): Removed this code. + Instead, call AC_PREPARE. + Call AC_PROG_INSTALL and AC_PROG_RANLIB to find those programs. + Use AC_HAVE_FUNCS to find what sys_siglist and _ctype_ are called. + (config.make): Write new var `config-defines' with what autoconf + put in $DEFS. + Append -DHAVE_GNU_LD and -DHAVE_GNU_AS to DEFS if appropriate; + don't write gnu_ld and gnu_as variables. + * configure: Removed. + * Makefile (distribute): Add configure.in. + * Makeconfig (+defines): Include $(config-defines) before $(defines); + don't include $(gnu_as) and $(gnu_ld). + + * sysdeps/unix/bsd/glue-ctype.c (TABLE): Test HAVE_* for several + different names and #define this. + (STRINGIFY): Define macro. + (main): Use TABLE instead of hardcoded name. + + * configure (sysnames): Try successively less specific base os's. + + * Makerules (ar-it): Define commands only ifdef objects. + + * sysdeps/mips/setjmp.S: Jump to __setjmp_aux, not ___setjmp_aux. + We are NO_UNDERSCORES. + +Tue Oct 27 18:11:19 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/posix/pipestream.c, sysdeps/posix/system.c: Always use + __vfork instead of expecting FORK to be defined. + * sysdeps/unix/bsd/system.c, sysdeps/unix/bsd/pipestream.c: + Removed. sysdeps/unix versions are now what we want. + + * sysdeps/unix/bsd/sun/sunos3/m68k/__wait.S: Removed. + * sysdeps/unix/bsd/hp/m68k/__wait.S: Moved to unix/bsd/m68k. + + * sysdeps/unix/bsd/hp/m68k/{__pipe,sysdep}.S: Moved to unix/bsd/m68k. + * sysdeps/unix/bsd/sun/m68k/{__pipe,sysdep}.S: Removed. + + * sysdeps/unix/bsd/sun/m68k/start.c: Moved to unix/bsd/m68k. + * sysdeps/unix/bsd/sony/m68k/start.c: Removed. + + * sysdeps/unix/bsd/bsd4.4/__sigstmsk.c: Correct file name in #include. + + * sysdeps/unix/bsd/sun/m68k/__fork.S: Removed. + * sysdeps/unix/bsd/hp/m68k/__fork.S: Removed. + * sysdeps/unix/bsd/vax/__fork.S: Moved to unix/bsd. + + * sysdeps/generic/__vfork.c: New file; fn alias to __fork. + * sysdeps/stub/__vfork.c: Removed. + + * limits.h: Only do #include_next #ifndef _LIMITS_H_. + + * malloc/mcheck.c (mcheck): Set abortfunc to either FUNC or abort; + never leave it unchanged. + Return 0 if mcheck_used; -1 if not. + * malloc/malloc.h (mcheck): Change return type in decl. + + * Makerules (+depfiles): Don't include them if there are none. + +Mon Oct 26 16:30:52 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/fdopen.c: Use fcntl to check that FD is valid and + allows the access MODE specifies. + + * sysdeps/stub/getcwd.c: #include <stddef.h>. + + * sysdeps/stub/sleep.c: #include <errno.h>. + +Sun Oct 25 02:24:47 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (+includes): Add $(+sysdep-includes) to this, leaving + CPPFLAGS alone. + + * sysdeps/stub/stime.c: #include <time.h>. + +Thu Oct 22 13:36:48 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Rules (clean): Also remove $(clean-extras). + +Tue Oct 20 18:36:40 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * configure: Write error message and lose for option with missing arg. + + * stdio/__vfscanf.c: Add `a' modifier, which makes %s and %[ fill + in a char ** with a malloc'd string. + (STRING_ADD_CHAR, STRING_ARG): New macros to deal with this hair. + (%s, %[): Use them. + + * posix/gnu/types.h [__GNUC__] (__fsid_t): Define as long long. + + * stdio/vfprintf.c: Add %m, which is %s of strerror (errno). + +Mon Oct 19 14:19:36 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * socket/sys/socket.h (PF_FILE, AF_FILE): Define new macros. + (PF_UNIX, AF_UNIX): Make aliases for [PA]F_FILE. + + * sysdeps/ieee754/huge_val.h: #include <sys/cdefs.h>. + [!__GNUC__]: Use __const, not CONST. + + * posix/wordexp.h: Fix indentation and syntax errors. + + * stdio/vasprintf.c (vasprintf): Set seen bit. + +Fri Oct 16 17:18:34 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makefile (Mcrt1.o): Create an empty .c file and compile it, + rather than creating an empty .o file. + + * sysdeps/unix/Makefile (sys/param.h): Strip / from name for mkdir. + + * sysdeps/m68k/fpu/atan2.c [! __GNUC__]: Include generic, not iee754. + + * sysdeps/sparc/Makefile ({divrem}.S): Use $(M4) for m4 in cmds. + * Makeconfig (M4): Define it. + + * stdio/newstream.c (__newstream): Link STREAM onto __stdio_head + after malloc'ing it. + + * time/emkdir.c: #define unix if not already defined. + +Thu Oct 15 19:55:45 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdlib/wctomb.c: When passed 0, store a '\0' and return 1. + * stdlib/mbtowc.c: When passed "", store a 0 and return 1. + + * sysdeps/generic/strstr.c: When NEEDLE is "", return HAYSTACK. + +Thu Oct 15 19:25:46 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/malloc.h (__after_morecore_hook): Declare new var. + * malloc/malloc.c (__after_morecore_hook): Define it. + (align): Call it. + +Mon Oct 12 15:56:07 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/malloc.h (r_alloc, r_alloc_free, r_re_alloc): Declare. + + * Makerules (native-compile, common-objdir-compile): Pass + $(native-CFLAGS) to the compiler. + + * Makeconfig (+gccwarn): Removed -Wstrict-prototypes and + -Wpointer-arith. They were not really helping, and caused extra + warnings for harmless code. + + * malloc/Makefile (dist-routines): Add ralloc. + (gpl2lgpl): Add ralloc.c. + + * time/zic.c: #define unix if not already defined. + + * Makerules ($(gpl2lgpl)): Make output unwritable; use mv -f. + +Mon Oct 12 15:27:40 1992 Brendan Kehoe (brendan@mole.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/ultrix4/mips/__set[gu]id.S: Handle returning to + the proper caller ourselves, since setre[gu]id won't be doing it. + +Mon Oct 12 13:37:16 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/malloc.h: Declare memory_warnings. + * malloc/Makefile (dist-routines): Add vm-limit. + (distribute): Add mem-limits.h. + (gpl2lgpl): Add vm-limit.c, mem-limits.h. + + * gpl2lgpl.sed: Remove "This file is part of ..." lines. + Changed regexp to match "foo is free software", not just "This + program ...". + + * Makerules (+make-deps): Put file name before options on command line. + + * Makefile (install-lib): Remove libc.a from here. + * Makerules [objects] (install-lib): Append it here instead. + + * io/sys/stat.h (S_IRWXO): Fixed typo. + +Sun Oct 11 16:58:36 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob.c (__glob_{open,read,close}dir_hook): New vars. + (glob_in_dir): Use them. + * posix/glob.h: Declare them. + +Thu Oct 8 20:03:30 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * configure (config.make): Write comment to edit configparms instead. + +Wed Oct 7 17:15:05 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/stub/__chown.c: Fixed arg types (int -> [ug]id_t). + + * sysdeps/stub/__geteuid.c: Fixed return type (int -> __uid_t). + + * sysdeps/stub/__getegid.c: Fixed return type (int -> __gid_t). + + * configure: Write defns in config.make for vars config-machine, + config-vendor, and config-os. + + * ctype/ctype.h (__isctype, __tolower, __toupper): Cast argument + and return value to `int'. + + * ctype/ctype.h (__ctype_tolower, __ctype_toupper): Changed type + to `short int *'. + (toupper, tolower): Removed inline functions; restored macros. + * ctype/ctype.c (tolower, toupper): Just call the __ macros. + * ctype/ctype-info.c: Change types here too. + * locale/localeinfo.h: And here. + * locale/C-ctype_ct.c: Ditto. + + * crypt: New code from Michael Glad. + + * Makefile (munch-init.c), sysdeps/unix/Makefile + ($(sys/param.h-includes), make-errnos.c, make-ioctls.c), + sysdeps/unix/bsd/Makefile (local_lim.h, ctype-glue.c), + sysdeps/posix/Makefile (stdio_lim.h): Changed rules to use a + shorter suffix than `-tmp', to avoid exceeding 14 char limit. + +Tue Oct 6 15:13:57 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile (README, INSTALL): Moved rules here. + * Make-dist: From here. + + * sysdeps/unix/bsd/sun/m68k/{__pipe,__fork,sysdep}.S: Change uses + of sysdeps/unix/bsd/hp9k3bsd to sysdeps/unix/bsd/hp/m68k. + + * sysdeps/m68k/Makefile: Put .S rule here. + * sysdeps/unix/bsd/hp/m68k/Makefile: Removed file. + +Mon Oct 5 19:40:22 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/pow.c (pow_p): Changed code to KY jelly. + + * sysdeps/unix/bsd/ultrix4/utsnamelen.h: New file. + * sysdeps/unix/bsd/ultrix4/uname.S: New file. + +Fri Oct 2 17:43:32 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/posix/mktemp.c: Don't use a static index and increment + it on each call. Instead, always start at the beginning and + iterate until we find a file that does not exist. + + * sysdeps/unix/sysv/i386/signal.S: Use C_SYMBOL_NAME for __sigreturn. + Added comment about gas bug with `lcall' insn. + + * sysdeps/unix/i386/__brk.S: Use C_SYMBOL_NAME for __curbrk and _end. + + * sysdeps/unix/i386/sysdep.S: #include <sysdep.h>. + Use C_SYMBOL_NAME(errno) in place of _errno. + + * sysdeps/unix/sysdep.h (___errno): Removed #define to _errno. + `errno' is an ANSI name; it doesn't need to be aliased. + * sysdeps/unix/bsd/sun/m68k/sethostid.S, + sysdeps/unix/bsd/sun/m68k/__vfork.S, + sysdeps/unix/bsd/sun/sparc/sysdep.h, + sysdeps/unix/bsd/sun/sparc/sethostid.S, + sysdeps/unix/bsd/vax/sysdep.S, + sysdeps/unix/bsd/vax/__vfork.S: Use _errno, not ___errno. + + * sysdeps/unix/sysv/sysdep.h: File removed. + * sysdeps/unix/sysv/i386/sysdep.h: Don't #include it. + #define NO_UNDERSCORES before #include <sysdeps/unix/i386/sysdep.h>. + + * sysdeps/unix/i386/sysdep.h (C_SYMBOL_NAME): Define new macro. + [NO_UNDERSCORES]: #define syscall_error to __syscall_error, so we + stay name space tidy. + + * sysdeps/unix/sysv/sysv4/sys_getdents.S: Added missing arg count (3). + + * sysdeps/unix/sysv/i386/time.S: Fixed to not use bogus addressing + mode `4(%esp,1)'; use `4(%esp)' instead. Added comments. + + * sysdeps/stub/__fchmod.c (__fchmod): Fixed arg type to mode_t. + + * sysdeps/posix/__wait3.c: #include <stddef.h> for NULL. + + * sysdeps/unix/i386/__wait.S: Use asm label `null' instead of + `1f', and actually define the label! Added comments. + + * sysdeps/i386/memchr.c: Renamed asm label to `done'; not all + assemblers support numbered labels like `1f' or `1b'. + + * stdio/fseek.c (fseek): Discard char pushed back by ungetc. + * stdio/ftell.c (ftell): If we have a pushed-back char, decrement + the file position we return. + + * sysdeps/unix/bsd/sun/sparc/vfork.S: New file. + +Wed Sep 30 18:48:38 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * limits.h (_LIBC_LIMITS_H_): Define today's name for this. + RMS said it was to be `_LIBC_LIMITS_H', but that is not what + gcc actually uses. + +Tue Sep 29 18:17:12 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * time/Makefile (zic-cmd): Define variable. + (tzcompile, zoneinfo/localtime, zoneinfo/posixrules): Use it for + name of `zic' command. + + * sysdeps/unix/bsd/Makefile (ctype-glue.c): Make sure the command + is not an unqualified name. + + * sysdeps/stub/statbuf.h (struct stat): Contain only POSIX.1 + members, with the POSIX.1 types. + (_STATBUF_ST_BLKSIZE): #undef and comment. + * sysdeps/unix/bsd/statbuf.h (_STATBUF_ST_BLKSIZE): Define it. + * sysdeps/posix/stdio_init.c (__stdio_init_stream): Only try to + use st_blksize #ifdef _STATBUF_ST_BLKSIZE. + + * sysdeps/unix/__getpgsz.c: #include <stddef.h> for size_t. + + * sysdeps/stub/__fchown.c: Fixed arg types ([ug]id_t, not int). + + * io/sys/stat.h: #include <gnu/types.h> for __mode_t et al. + + * sysdeps/unix/__gete[ug]id.S [SYS_gete[ug]id]: Add arg count of 0. + [! SYS_gete[ug]id]: Fixed arg count to be 0. + + * sysdeps/unix/__get[ug]id.S: Fixed arg count to be 0. + + * sysdeps/unix/sysv/linux/syscall.h: #if 0'd out 2nd defn of SYS_brk. + +Sun Sep 27 21:56:56 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (sys/param.h): Depend on $(common-objpfx)sys/. + +Fri Sep 25 12:47:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makeconfig (INSTALL_DATA): Pass -m 644. + +Thu Sep 24 16:13:47 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/linux/getpeername.S: Renamed to getpeernam.S. + * sysdeps/unix/sysv/linux/getsockname.S: Renamed to getsocknam.S. + * sysdeps/unix/sysv/linux/setsid.S: Renamed to __setsid.S; + function renamed to __setsid. + + * Version 1.05. + + * Makefile (dist): Depend on $(distribute). + + * stdio/__vfscanf.c (%c): Fixed DO_ASSIGN case loop condition to + not write one char too many. + +Wed Sep 23 16:32:18 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/qsort.c (_quicksort): Return immediately if TOTAL_ELEMS==0. + +Tue Sep 22 19:10:59 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makerules [! OUTPUT_OPTION && objpfx]: Define OUTPUT_OPTION. + +Mon Sep 21 22:40:55 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/mk-local_lim.c: Use MAXNAMLEN for NAME_MAX, + rather than hard-wiring 255. + [! MAXNAMLEN]: Define it to 255. + [LINK_MAX && ! MAXLINK]: #define MAXLINK LINK_MAX. + + * sysdeps/unix/bsd/glue-ctype.c [ultrix]: #define _ctype_ _ctype__. + + * configure: Rename var `gas' to `gnu_as' and use consistently. + +Fri Sep 18 16:32:16 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sys/errno.h: New file. + * Makefile (headers): Add it. + + * Makeconfig (+make-deps): Use = not define. + + * time/Makefile (zones-%): Don't clobber zonenames; append to it. + Depend on Makefile so we rebuild when the rule changes. + Changed implicit rule from zoneinfo/%/... to zone%/... so it will + actually match. + + * sysdeps/unix/Makefile (syscall.h): Filter out "#ident" lines. + + * Makeconfig (+link): Use $(gnulib) instead of -lgcc. + (gnulib): Define to -lgcc. + + * posix/glob/Makefile.in (AR, ARFLAGS): Define. + (libglob.a): Use those vars instead of hardcoding. + + * Makeconfig (ARCH) [machine]: Don't define if $(..)config.make exists. + + * Makerules (compile.S): Include $(asm-CPPFLAGS). + (S-CPPFLAGS): Define = $(asm-CPPFLAGS). + (+make-deps): Include $(sfx-CPPFLAGS), where `sfx' is S or c. + * Makeconfig (asm-CPPFLAGS): Define (empty) and comment. + + * sysdeps/unix/Makefile ($(sys/param.h-includes)): Filter out + decls or macros for host<->net conversion (htonl et al). + +Thu Sep 17 17:33:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/statbuf.h: Define __S_*. + + * misc/Makefile (headers): syslog.h -> sys/syslog.h. + * misc/syslog.h: Moved to misc/sys/syslog.h. + + * limits.h [__GNUC__ >= 2]: #define _LIBC_LIMITS_H before + #include_next <limits.h>. + Define _LIMITS_H unconditionally. + +Wed Sep 16 17:43:59 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (syscall.h): Don't use \< in sed commands. + Some seds don't seem to grok it. + + * Makerules (+install-dirs): Sort them. + + * Makeconfig (stdarg.h): Use $(wildcard va-*.h) instead of va-*.h, + and := instead of =. + + * Makeconfig (prefix): Default to $(exec_prefix), not /usr/local. + + * Makeconfig (+link): Use $(common-objpfx) rather than $(objpfx) + to find start.o; use $(libc.a) instead of $(objpfx)libc.a. + + * sysdeps/sparc/Makefile: crypt subdir is not called uf-crypt. + + * sysdeps/unix/Makefile (sys/param.h-includes): Fixed filtering + out of existent glibc headers to remove $(..) pfx after wildcard. + + * misc/paths.h: New file, snarfed from 4.4 BSD. + * misc/Makefile (headers): Add paths.h. + +Tue Sep 15 14:55:11 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (+sysdir_pfx): Define as $(common-objpfx). + + * MakeTAGS (TAGS) [subdir && ! tags_sources]: Create an empty + file, rather than no commands at all. + + * string/string.h [__GNUC__ && __OPTIMIZE__] (ffs): Take arg. + + * sysdeps/unix/sysv/linux/__wait4.S: New file. + + * sysdeps/unix/sysv/linux/syscall.h: New version from hlu. + + * sysdeps/unix/Makefile (syscall.h): Upcase `sys_' in input. + + * sysdeps/unix/bsd/ultrix4/mips/sysdep.h (MOVE): Insn is `move', + not `movl'. + + * sysdeps/unix/bsd/ultrix4/mips/sigcontext.h: Deansideclized. + + * sysdeps/unix/ioctls-tmpl.c [DIOCGETPT, DEVGETGEOM]: Include + headers for these. + [ultrix]: Mondo cruft. + +Sat Sep 12 12:08:29 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * misc/Makefile (routines): Add ttyslot, syslog. + * misc/ttyslot.c, misc/syslog.[ch]: New, snarfed from 4.4 BSD. + (headers): Add syslog.h + + * misc/getttyent.c (getttyent): Parse _TTYS_TRUSTED keyword and + set TTY_TRUSTED bit. + * misc/ttyent.h (TTY_TRUSTED): New bit in ty_status. + (_TTYS_TRUSTED): New keyword. + (_TTYS_CONSOLE): New keyword. + (TTY_CONSOLE): New bit in ty_status. + + * dirent/scandir.c (scandir): Don't keep using V after realloc'ing + it. Use the returned new ptr instead. + +Thu Sep 10 18:59:23 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/div.c, stdlib/ldiv.c: Rewritten from Berkeley code that works. + + * Makeconfig (stdarg.h): Add va-*.h. + + * stdlib/Makefile (dont_distribute): Define: testsort.input. + + * sysdeps/mach/hurd/i386/_hurd_start_sigthread.c, + sysdeps/stub/_hurd_start_sigthread.c: Renamed to .../startsig.c. + * sysdeps/mach/hurd/sys_errlist.awk: Renamed to .../errlist.awk. + * sysdeps/mach/hurd/Makefile (sys_errlist.c): Change dep. + * sysdeps/unix/bsd/make-local_lim.c: Renamed to .../mk-local_lim.c. + * sysdeps/unix/bsd/Makefile (local_lim.h): Change dep. + (make-local_lim): Change target and dep. + * hurd/_hurd_dead_recv.c: Renamed to hurd/dead_recv.c. + * hurd/setdtablesize.c: Renamed to hurd/setdtsz.c. + * hurd/Makefile (routines): Change references. + * stdio/tstgetline.c: Renamed to stdio/tstgetln.c. + * stdio/tstgetline.input: Renamed to stdio/tstgetln.input. + * stdio/Makefile (tests): Change ref. + * README.template: Remove note about long file names. + + * sysdeps/unix/bsd/sun/sunos4/utsnamelen.h (_UTSNAME_LENGTH): + Define here, rather than #include'ing sysv/utsnamelen.h. + This file gets installed. + +Wed Sep 9 17:06:14 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makeconfig (localtime-file): Put in $(prefix)/etc, not /etc. + + * setjmp/Makefile (routines): Remove sigsetjmp. + + * sysdeps/posix/Makefile (objdir-CPPFLAGS) [! subdir]: Rewrote + totally broken defn. + + * sysdeps/unix/Makefile (syscall.h): Keep lines starting + with #, not only those starting with #define. + We want to preserve any #ifdef in the original. + + * Makerules (install): Dep $(+install-dirs), not $(dir $(+install)). + (+install-dirs): Define to get two levels of dirs. + + * time/Makefile (tz-cc): Use = instead of define directive. + + * sysdeps/unix/bsd/sun/sparc/start.c (_start): Give ARGC, ARGV, + and ENVP `register' storage class; can then clear the FP early. + +Sat Sep 5 13:14:09 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Makerules (sysdirs): Pass sysdep_dir in child's environment. + +Fri Sep 4 15:37:23 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Makeconfig (common-objpfx): Add trailing slash. + Move comment to prev line to avoid extra whitespace. + +Thu Sep 3 17:31:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/setgroups.S: New file. How did this manage not + to exist already?? + + * Version 1.04. + + * sysdeps/generic/memmem.c (memmem): Fixed loop condition not to + use nonexistent variable. + + * string/string.h (memmem): Put const qualifier on args. + + * sysdeps/stub/sigaltstack.c (sigaltstack): Fix arg type. + + * setjmp/sigsetjmp.c: #undef sigsetjmp before defining the function. + +Wed Sep 2 16:43:58 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * misc/Makefile (headers): Add syscall.h. + * sysdeps/unix/Makefile: Only generate syscall.h if it would + otherwise come from stub. + * sysdeps/stub/syscall.h: New file. + + * time/Makefile (routines): Add stime. + + * io/Makefile (routines): Add fchdir. + + * signal/Makefile (routines): Add sigaltstack. + + * string/Makefile (routines): Add memmem. + + * setjmp/Makefile (routines): Add sigsetjmp, _setjmp. + + * misc/Makefile (routines): Add getpass. + + * Makefile (distribute): Add NEWS. + + * Makerules (ar-it) [! objdir]: Pass `ru' instead of `u' to ar. + Use $(..)libc.a instead of $(libc.a). + + * sysdeps/unix/sysv/i386/linux/sysdep.h (PSEUDO): Call numbers are + SYS_*, not __NR_*. + + * sysdeps/unix/sysv/i386/linux/__wait.S: Prepend extra _ to + `__waitpid' for jmp. + + * Makerules (check): New rule; alias for `tests'. + + * sysdeps/stub/__setregid.c: Args are gid_t, not int. + + * sysdeps/posix/readv.c: #include <string.h>. + + * sysdeps/generic/printf_fp.c: If LDBL_DIG or LDBL_MAX_10_EXP is + defined by float.h, #define each to DBL_*. + +Tue Sep 1 16:29:07 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/Makefile (syscall.h): Add missing backslashes. + + * Makeconfig [!objdir && !..] (common-objpfx): Define as + `sysdeps/..'; The Almighty KludgeMeister 2000 wins again. + + * Makerules (sysdep-Makefile): Rename to sysd-Makefile. + + * Makeconfig (CC): Don't use -pipe by default. + + * configure (switches): Put quotes around os-release and + os-version values. + +Mon Aug 31 19:33:15 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/stub/cbrt.c: New file. + + * sysdeps/generic/cabs.c: New file. + + * sysdeps/generic/ceil.c: New file, split from floor.c. + * sysdeps/generic/__rint.c: Replaced with code split from floor.c. + * sysdeps/generic/Makefile (routines): Don't remove ceil, __rint. + +Thu Aug 27 15:58:13 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * malloc/malloc.h [! __STDC__] (ptrdiff_t): #define. + +Wed Aug 26 18:15:47 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/free.c (__free): Rename to _free_internal. + (free), malloc/malloc.c (morecore): Change callers. + * malloc/malloc.h: Change decl. + +Tue Aug 18 17:38:13 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/generic/__copysign.c: New file. + + * sysdeps/unix/sysv/sysdep.h: #include <syscall.h>, not + <sys/syscall.h>. Don't #define _SYS_SYS_S; should no longer be + necessary. + + * sysdeps/unix/Makefile (syscall.h): Replaced simple code to just + find the file in any of several places, with hairier code to find + it and massage it. + + * malloc/Makefile (obstack.%): Remove rule. + (gpl2lgpl): Define this instead. + * posix/Makefile (gpl2lgpl): Define to include getopt source files. + * Makerules ($(gpl2lgpl)): New rule to snarf code and frob its + copying notices. + +Fri Aug 14 13:28:39 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makeconfig (common-objdir, common-objpfx): Define new vars. + (libc.a): Define in terms of $(common-objpfx). + Find config.make with $(common-objpfx), not $(objpfx). + * Makerules (common-objdir-compile): Define canned sequence. + (native-compile): Use $(@D)/$(@F) instead of stripping off $(objpfx). + * sysdeps/unix/Makefile, sysdeps/unix/bsd/Makefile, + sysdeps/generic/Makefile: Use it. + Use $(common-objpfx) for generated things not specific to one subdir. + + * sysdeps/unix/Makefile (sysdep_headers): Add + $(sys/param.h-includes) to this instead of to headers. + +Thu Aug 13 18:30:58 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob.c: Always #include <sys/types.h>. + [! USG]: Don't do it here. + [STDC_HEADERS]: Test this instead of __STDC__ for size_t. + [HAVE_STRCOLL]: Test this instead of ANSI_STRING for strcoll. + + * posix/glob/Makefile.in (Makefile): Remove rule. + +Wed Aug 12 16:12:52 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/sparc/jmp_buf.h: Deansideclized. + + * sysdeps/generic/make_siglist.c: #undef HAVE_SYS_SIGLIST, not + SYS_SIGLIST_MISSING. + * sysdeps/generic/signame.[ch]: Re-symlinked from /gd/gnu/lib. + Who's been removing random things from my source tree?? + +Tue Aug 11 15:01:50 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/getconf.c (main): Cast printf field with arg to int. + + * Makefile (distribute): Remove ansidecl, ansidecl.m4. + + * posix/glob.c [_AIX]: Don't declare alloca. + +Mon Aug 10 17:09:40 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/m68k/fpu/__math.h (__expm1): Define just like expm1. + + * sysdeps/unix/ioctls-tmpl.c [SMIOSTATS, SMIOGETREBOOT0, + ZIOCBCMD]: Include headers for these. + +Fri Aug 7 16:01:43 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * string/tester.c (main): Use sys_nerr and sys_errlist, not _sys_*. + + * stdio/stdio.h [__USE_GNU] (_sys_nerr, _sys_errlist): Declare. + + * string/strerror.c, stdio/perror.c + [HAVE_GNU_LD] (_sys_errlist, _sys_nerr): Remove decls. + + * stdio/memstream.c (enlarge_buffer): Notice when target is -1 and + don't treat it as a huge value. + + * stdio/tst-printf.c: #if 0 code that tickles printf_fp bugs. + + * grp/testgrp.c: Don't bomb if uid not in passwd file. + + * stdlib/tst-strtol.c (tests): C-t on LONG_MIN and LONG_MIN-1 elts. + + * stdlib/strtol.c: Use int flag NEGATIVE instead of char 1/-1 SIGN. + Fixed checking for overflow of long int that fits in unsigned long + int--must cast LONG_MIN before negating! + +Thu Aug 6 18:46:24 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/bug3.c (main): Define ansideclifily. + + * sysdeps/unix/bsd/sun/sparc/__pipe.S: Define __pipe, not ___pipe. + + * math/test-math.c (main): Remove unused vars. + + * io/flock.c: #include <sys/file.h>, and not fcntl.h or sys/types.h. + + * sysdeps/m68k/fpu/__math.h (__rint): Define just like rint. + + * math/math.h (__rint): Declare. + + * configure (esix*): base_os=unix/sysv. + + * dirent/getdents.c: #include <dirent.h>. + + * Rules (subdir): Avoid TAB before # at end of defn. + + * sysdeps/unix/bsd/bsd4.4/__wait3.c: Last arg type is struct rusage *. + +Tue Aug 4 18:19:43 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/ieee754/Makefile: Removed. + + * math/math.h: Declare __expm1. + +Mon Aug 3 13:02:05 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/ieee754/cabs.c (cabs, z_abs): Members of structure have __. + + * sysdeps/unix/bsd/seq386: Remove directory. + +Thu Jul 30 15:42:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sparc/sigcontext.h: Deansideclized. + + * sysdeps/unix/bsd/sun/sunos4/__wait4.c: Make last arg struct rusage + instead of PTR. + + * sysdeps/unix/morecore.c (__default_morecore): Make arg ptrdiff_t. + + * sysdeps/ieee754/cabs.c (cabs, z_abs): Use `struct __complex' for arg. + + * sysdeps/generic/pow.c: #include <limits.h>. + + * sysdeps/generic/mathimpl.c: #include <math.h> before frobnication. + + * misc/getusersh.c (okshells): Make const. + (initshells): Properly declare static. + + * sysdeps/unix/bsd/__tcgetatr.c: Cast sg_[io]speed to (unsigned char) + to avoid gcc warnings. + + * math/bsd/common/atan2.c, math/bsd/common/tan.c, + math/bsd/common/sincos.c, math/bsd/common/trig.h, + math/bsd/common_source/__expm1.c, math/bsd/common_source/fmod.c, + math/bsd/common_source/acosh.c, math/bsd/common_source/log.c, + math/bsd/common_source/asincos.c, math/bsd/common_source/asinh.c, + math/bsd/common_source/log1p.c, math/bsd/common_source/atan.c, + math/bsd/common_source/log__L.c, math/bsd/common_source/atanh.c, + math/bsd/common_source/mathimpl.h, math/bsd/common_source/cosh.c, + math/bsd/common_source/exp.c, math/bsd/common_source/sinh.c, + math/bsd/common_source/exp__E.c, math/bsd/common_source/tanh.c, + math/bsd/common_source/floor.c: Moved to sysdeps/generic. + * math/bsd/ieee/{cabs,cbrt,support}.c: Moved to sysdeps/ieee754. + * All above + sysdeps/generic/mathimpl.h, sysdeps/generic/pow.c: New + code from 4.4/net2. + + * sysdeps/generic/ffs.c: #include <string.h>, not <bstring.h>. + + * posix/glob/Makefile.in (Makefile): Depend on config.status; invoke + it directly instead of using $(SHELL). + + * posix/glob.c [! USG]: #include <sys/types.h> before <sys/dir.h>. + +Tue Jul 28 17:54:23 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/ultrix42: Renamed to ultrix4. + + * sysdeps/unix/sysv/isc2.2/__rename.S: New. + * configure (isc*): base_os=unix/sysv. + + * Makefile, Makerules, Rules, math/Makefile, ctype/Makefile: Use + "export foo := $(foo)" instead of ifdef have_export_directive. + * Makeconfig (have_export_directive): Remove; move .NOEXPORT down. + +Mon Jul 27 18:01:30 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure: Remove redundant test to set os_used. + +Sun Jul 26 17:03:31 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * README.template: Don't mention Q+A. + * Makefile (distribute): Remove Q+A. + + * Makefile, Makerules, Rules, math/Makefile, ctype/Makefile: Put + "ifdef have_export_directive" around uses of `export' directive. + They are only needed for dist and tags anyway. + * Makeconfig (have_export_directive): Add commented-out defn, and + comment to explain. + (.NOEXPORT): Add special target for old versions of GNU make. + + * posix/glob.c [_AIX]: #pragma alloca first thing. + [ANSI_STRING]: Remove #define's for index et al. + +Thu Jul 23 21:49:53 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/getpass.c: New. + * posix/unistd.h (getpass): Declare. + + * posix/unistd.h (getusershell, setusershell, endusershell): Declare. + * misc/Makefile (routines): Add getusersh. + * misc/getusersh.c: New. + +Tue Jul 14 20:03:57 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/Makefile (tests): Add testdiv. + * stdlib/testdiv.c: New. + + * sysdeps/unix/sysv/i386/linux/{rename,__mkdir,__rmdir,__dup2, + getpgrp,__setpgrp,setsid}.S: New files. + + * sysdeps/unix/__getppid.S: If SYS_getppid is defined, use it rather + than alternate value of getpid. + * __gete[ug]id.S: Similar. + + * sysdeps/unix/sysv/i386/linux/__waitpid.S: New file. + * sysdeps/unix/sysv/i386/linux/__wait.S: New file. + * sysdeps/posix/__wait3.c: New file. + + * sysdeps/unix/sysv/i386/linux/socket.S: New file. + * bind.S, connect.S, listen.S, accept.S, getsockname.S, + getpeername.S, socketpair.S: Also new (and trivial). + +Mon Jul 13 17:41:46 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/i386/linux/sysdep.[hS]: New files. + + * configure (linux*): base_os=unix/sysv + (gnu*, linux*): Always set --with-gnu-ld and --with-gnu-as. + + * stdio/obstream.c: #include <string.h> + (obstack_vprintf): Use bzero rather than memset. + + * stdio/glue.c (unix_FILE.glue): Add two members, which will overlap + get_limit and put_limit in GNU stdio. + (_iob): Initialize them to same as `streamp'. + +Thu Jul 9 21:27:39 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/stdio.h (open_obstack_stream, obstack_printf, + obstack_vprintf): Declare. + + * posix/glob.c [STDC_STRINGS]: Don't test this. + [! ANSI_STRING]: Put memcpy, strrchr, memset defns here instead. + + * posix/glob/Makefile.in (glob.o, fnmatch.o): / after $(srcdir). + +Tue Jul 7 03:11:23 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/Makefile (routines): Add obstream. + + * Makerules (%.o: %.S, %.o: %.c): If using gcc, put the file name + before the options on the command line. + + * malloc/Makefile (dist-routines): Define with routines for malloc.tar. + (routines): Define with that plus the rest. + (nodist): Remove. + (routines): Add obstack. + (headers): Add obstack.h. + (obstack.%): New rule. + + * stdio/glue.c: Add comments. + + * stdio/printf.h (struct printf_info.spec): Make unsigned char. + + * stdio/stdio.h (__validfp): Fixed glued-stream snarfing. + +Mon Jul 6 20:00:47 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/i386/jmp_buf.h: Deansideclized. + + * sysdeps/posix/Makefile (objdir-CPPFLAGS): Define; if in parent + dir, add ..s to -Is. + (mk-stdiolim): Use it in place of $(CPPFLAGS). + +Sat Jul 4 20:44:42 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob/Makefile.in (glob.o, fnmatch.o): Put $(srcdir) on deps. + +Wed Jul 1 00:13:40 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/strstr.c: If NEEDLE is "", return end of HAYSTACK. + + * string/tester.c (main): Remove decls of sys_nerr and sys_errlist. + + * configure: Accept --prefix=*, --exec_prefix=* options. + Set values in config.make and config.status. + + * io/umask.c: Fixed return type in fn alias. + + * posix/glob.c [! ANSI_STRING]: #define strcoll to strcmp. + Remove extra decls of free, qsort, malloc, and realloc. + + * dirent/alphasort.c: #include <string.h>, and not <stdlib.h>. + + * sysdeps/unix/bsd/i386/__wait3.S: Load SYS_wait into %eax before + trapping. Use literal .byte instead of lcall to avoid gas bug. + Use 0(REG), not (REG), for register-indirect addressing. + + * configure: Make config.status executable. + +Tue Jun 30 21:14:53 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * configure: Add --os-release=* and --os-version=* options. Record + settings (which might be automagically guessed) in config.status. + + * misc/mknod.c: Use __mode_t for arg in fn alias. + + * posix/unistd.h (setregid): Declare to take __gid_t args. + + * sysdeps/unix/bsd/i386/__wait3.S: Don't use lcall insn gas barfs on. + + * posix/vfork.c: Move to sysdeps/generic/. + + * Rules (others, tests): Export them. + + * io/umask.c, io/mkdir.c, io/chmod.c: Use mode_t not int in arg decls. + + * sysdeps/i386/ffs.c: #include <string.h>, not <bstring.h>. + + * stdio/vfscanf.c: Use function_alias. + + * stdio/vsscanf.c: Use va_list, not PTR, in arg decl in fn alias. + + * sysdeps/unix/i386/sysdep.h (PSEUDO): Enough backslashes and + semicolons. + + * stdio/stdio.h: For __gnuc_va_list, #test __GNUC_VA_LIST, not + __va_list_defined. + + * stdio/fmemopen.c: Use memchr to find NUL for append mode. + + * stdio/memstream.c (enlarge_buffer): Double the buffer size, rather + than adding 100. Don't clobber *INFO->bufsize when called with the + put limit reset. If the target has been set, extend and zero-fill + the buffer. + (seek): New function. + (open_memstream): Use it for seek io fn. Call fmemopen with "w+" mode. + +Sun Jun 28 19:01:01 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/fseek.c: Fail with EINVAL for a negative file pos. + +Fri Jun 26 00:07:53 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makeconfig (stdarg.h): New variable. + * Makefile (headers): Add $(stdarg.h). + + * stdio/stdio.h: Change __va_list to __gnuc_va_list in decls. + + * sysdeps/unix/morecore.c: Include malloc.h #ifndef _MALLOC_INTERNAL. + Don't include <stdio.h>. + (NULL): Define to 0 if not defined. + + * sysdeps/i386/bzero.c: Include string.h, not bstring.h. + +Thu Jun 25 21:01:40 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/perror.c, string/strerror.c (_sys_errlist, _sys_nerr): Don't + declare #ifndef HAVE_GNU_LD. + + * stdio/fwrite.c: Cast arg to write io func to const char * (from uns). + + * sysdeps/unix/Makefile: If syscall.h doesn't exist in + $(sysincludedir), look for sys/syscall.h and create $(objpfx)syscall.h + to #include it. + + * sysdeps/unix/morecore.c (__default_morecore): Deansideclized. + * malloc/*.c: Only #include <malloc.h> #ifndef _MALLOC_INTERNAL. + +Wed Jun 24 19:09:04 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/snarf-ioctls: Avoid looking at a few particular + headers which tend to mislead us. + + * Makefile (distribute): Add COPYING. + + * configure (Makefile): When invoking make in srcdir, set ARCH + rather than objdir on the cmd line. + + * posix/glob.c [DIRENT] (direct): Don't define to dirent. + [! DIRENT] (direct): Define to dirent. + + * Make-dist [!subdir] (+tsrcs): Don't include $(distribute). It was + already included above. + +Mon Jun 22 16:58:34 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makerules (sysdep_routines): Export it. + +Wed Jun 17 17:58:05 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/glob.c (my_realloc): Test only __GNU_LIBRARY__. Can't trust + STDC_HEADERS. + +Tue Jun 16 20:20:01 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * resource/sys/resource.h (enum __rlimit_resource): Added MEMLOCK, + NPROC, OFILE. + + * posix/Makefile (glob.tar): Include Makefile.in & configure, and not + Makefile. + (glob/configure): New rule. + + * posix/glob/Makefile: Moved to posix/glob/Makefile.in. + (VPATH, srcdir, CPPFLAGS): Define to be replaced by autoconf. + + * posix/glob.c: Rearranged conditionals for use with autoconf. + +Thu Jun 11 15:47:43 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sparc/start.c: Added alias for start -> __start. + +Tue Jun 9 20:15:12 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/posix/rename.c: Return failure and don't remove the old + link if the link failed with other than EEXIST. + + * posix/glob/Makefile: Fixed copyright notice. + (realclean): Don't remove ~ backup files. + +Thu Jun 4 16:41:56 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * time/Makefile (install-data): Don't include zoneinfo/. + Makerules already makes sure the necessary directories exist. + + * setjmp/setjmp.h (sigsetjmp) [__GNUC__]: Use typeof hackery to + construct the type of the temporary var for the arg. + (_setjmp) [__FAVOR_BSD]: Make same as setjmp. + + * malloc/malloc.h (mtrace): Declare. + + * malloc/malloc.h, malloc/calloc.c, malloc/free.c, malloc/malloc.c, + malloc/mcheck.c, malloc/memalign.c, malloc/mstats.c, + malloc/mtrace.c, malloc/realloc.c, malloc/valloc.c: Deansideclized; + changed copyright notices to be independent of libc. + * malloc/Makefile (glob/%.c, glob/%.h): Don't need to ansideclificate. + + * io/ftw.h, io/ftw.c: New. + * io/Makefile (headers): Added ftw.h. + (routines): Added ftw. + +Tue Jun 2 21:49:22 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/signum.h (SIG_ERR, SIG_DFL, SIG_IGN): Use + __sighandler_t. + + * posix/glob.c (__ptr_t): Define. + +Thu May 28 06:57:14 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/m68k/jmp_buf.h: Don't use PTR. + +Wed May 27 18:09:40 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/{glob,fnmatch}.[ch]: Deansideclized; changed copyright + notice to be independent of libc. + * posix/Makefile (glob/%.c, glob/%.h): Don't need to ansideclificate. + + * posix/unistd.h (_SC_2_FORT_RUN, _SC_2_LOCALDEF): Define. + + * posix/unistd.h: Define _POSIX2_* without #ifdef __USE_POSIX2. + + * posix/unistd.h (_POSIX2_FORT_DEV): Removed. + + * posix/fnmatch.h (FNM_FILE_NAME): Alias for FNM_PATHNAME. + +Tue May 26 00:39:39 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * time/Makefile (install-data): Include zoneinfo/, so the directory + gets made. + + * Makeconfig (+gcc-nowarn): Define to -w if using gcc. + * time/Makefile (tz-cc): Use it to suppress warnings for grody code. + + * posix/Makefile (libposix.a), math/Makefile (libm.a): Make archive + containing /dev/null instead of nothing; ar won't create an empty + archive. + + * Makerules (%/): Added generic mkdir rule. + + * posix/Makefile (install-lib): Define to libposix.a. + (libposix.a): Create empty archive. + + * posix/Makefile (distribute): Added utsnamelen.h. + + * ctype/ctype.c (tolower, toupper): If the arg doesn't fit in a + char, return it unchanged. + * ctype/ctype.h (tolower, toupper): Don't define as macros. + [__GNUC__]: Define as extern inline functions. + + * sysdeps/unix/bsd/sun/sunos4/utsnamelen.h, + sysdeps/unix/bsd/sun/sunos4/uname.S: New. + + * configure: Only do hacking to snarf uname info if the config uses + the generic uname implementation. + + * Makeconfig (+defines): Define to include $(gnu_ld), rather than + -DHAVE_GNU_LD. + * configure: Write config.make with gnu_ld/gnu_as defns. + + * sysdeps/unix/bsd/sun/sunos411: Renamed back to .../sunos4. + * sysdeps/unix/bsd/bsd44: Renamed to .../bsd4.4. + + * Makeconfig: include $(objpfx)configparms instead of + $(objdir)/Makeconfig. + Define objpfx as soon as objdir is defined, so we can use it. + + * sysdeps/generic/uname.c: Use UNAME_* from config-name.h. + +Mon May 25 19:33:07 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * configure: Accept all standard GNU configure options. + Expect to be run in object directory, and find source directory + elsewhere. + Write config.status as a shell script that can be run to recreate + the configuration. + Grok os names containing dots by trying each successively + less-precise substring. + Write Sysnames and config-name.h in current directory. + Write #define's for uname sysname, release, version, and machine + elts in config-name.h. Hackery to intuit release and version info. + + * stdio/vsnprintf.c, stdio/vsprintf.c, stdio/vasprintf.c, + stdio/vdprintf.c, stdio/vfscanf.c, stdio/vscanf.c, + stdio/__vsscanf.c: Take arg list as va_list, not PTR. + + * stdio/stdio.h: Replaced #include <stdarg.h> with magic. + Properly use __va_list in prototypes. + + * Makeconfig (exec_prefix): Define. + (libdir, includedir, bindir): Use it. + + * sysdeps/unix/sysv/Makefile [subdir==io] (sysdep-routines): Removed + __utssys. + * sysdeps/unix/sysv/Dist: Removed __utssys.S. + * sysdeps/unix/sysv/__utssys.S, sysdeps/unix/sysv/uname.c: Removed. + * sysdeps/unix/sysv/uname.S, sysdeps/unix/sysv/utsnamelen.h: New. + + * posix/sys/utsname.h (_UTSNAME_LENGTH): Don't define; instead, + #include <utsnamelen.h> to define it. + * sysdeps/generic/utsnamelen.h: New. + +Sun May 24 00:07:45 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/generic/inet-cvt.h: Deansideclized. + + * string/string.h (memfrob): First arg is __ptr_t, not char *. + + * misc/sys/cdefs.h (__ptr_t): Made #define rather than a typedef. + +Fri May 22 01:52:04 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makefile, Rules, Makerules: Remove all rules for ansideclificating + headers. + + * posix/glob.h, posix/fnmatch.h: Use explicit cruft for C++. + Define __P and const for C++/ANSI vs old C ourselves, to avoid + dependence on <sys/cdefs.h>. + + * inet/Makefile: Remove cruft to snarf things from bsd/. + * inet/bsd/*.c: Moved to inet/. + + * Makerules: Install headers from source directories into + $(includedir), rather than ansidecl madness. + * Makeconfig (ansi-incldir, trad-incldir): Removed. + (includedir): Define instead. + + * assert/assert.h, ctype/ctype.h, dirent/dirent.h, grp/grp.h, + locale/locale.h, locale/localeinfo.h, math/math.h, + misc/sys/file.h, misc/sys/ioctl.h, misc/sys/ptrace.h, + misc/sys/uio.h, misc/sgtty.h, misc/nlist.h, posix/gnu/types.h, + posix/sys/wait.h, posix/sys/types.h, posix/sys/times.h, + posix/sys/utsname.h, posix/unistd.h, posix/tar.h, posix/utime.h, + posix/wordexp.h, posix/glob.h, posix/fnmatch.h, pwd/pwd.h, + resource/sys/resource.h, resource/sys/vlimit.h, + resource/sys/vtimes.h, setjmp/setjmp.h, signal/signal.h, + signal/gnu/signal.h, socket/sys/socket.h, stdio/stdio.h, + stdio/printf.h, stdlib/alloca.h, stdlib/stdlib.h, string/string.h, + termios/termios.h, time/sys/time.h, time/time.h, io/sys/stat.h, + io/fcntl.h, errno.h, stddef.h, malloc/malloc.h: + Deansideclized. Use <sys/cdefs.h> macros instead of ansidecl and + C++ cruft. + * features.h: #include <sys/cdefs.h>. + + * string/string.h (strfry, memfrob): Declare. + * string/Makefile (routines): Added strfry and memfrob. + * string/strfry.c, string/memfrob.c: New. + + * locale/C-ctype_ct.c: Made BS be isspace. + + * sysdeps/generic/strstr.c: Return HAYSTACK, not its end, if NEEDLE + is the empty string. + + * sysdeps/generic/strncase.c: Fixed for case of empty string. + +Wed May 20 02:36:09 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * io/sys/stat.h (fchmod): Declare, rather than two __fchmod decls. + + * configure (sysv, bsd): Don't make base_os=unix; unix/{sysv,bsd} + instead. + Set os_used if base_os is used. + +Tue May 19 21:00:11 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * crypt/*: New files from glad. + + * stdio/stdio.h (sys_nerr, sys_errlist): Don't declare const. + +Sun May 17 15:50:00 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * io/Makefile (headers): Remove gnu/stat.h; add sys/stat.h. + + * posix/glob.c (glob): Don't let us fall off the end without returning. + + * sysdeps/stub/setenv.c, sysdeps/posix/setenv.c: New. + * stdlib/stdlib.h [__USE_BSD] (setenv): Declare. + * stdlib/Makefile (routines): Add setenv. + + * malloc/mtrace.c (old_{free,malloc,realloc}_hook): Renamed to tr_& + to not conflict with mcheck.c when combined into gmalloc.c. + +Fri May 15 19:07:54 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * socket/sys/socket.h (PF_NBS, AF_NBS): Removed. + (PF_ISO, PF_OSI, PF_APPLETALK, PF_ROUTE, PF_LINK): Define. + (PF_MAX): Increase accordingly. + + * inet/bsd/*.c: Snarfed latest code from 4.4. + + * misc/sys/cdefs.h (__BEGIN_DECLS, __END_DECLS): Define cruft for C++. + +Thu May 14 01:45:12 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/glob.h (GLOB_MAGCHAR): Check user feature-test macros, + rather than __USE_BSD, so we don't depend on features.h. + + * sysdeps/stub/__wait4.c: Last arg is struct rusage *, not PTR. + + * math/bsd/common_source/mathimpl.h: Don't #define const. + #include <sys/cdefs.h> instead. + + * Makefile (+other_dirs): Add crypt, but only if it exists at run time. + * crypt/GNUmakefile: New file. + * sysdeps/sparc/Makefile, sysdeps/m68k/Makefile (crypt): + Define to use machine-dependent assembly code in crypt/crypt.*.S. + * crypt: New directory. + + * find-sysdirs: Don't lose if there are no sysnames. + + * termios/Makefile (headers): Added sys/termios.h. + * termios/sys/termios.h: New file; just #include <termios.h>. + + * stdlib/qsort.c: Define _quicksort rather than qsort. + * stdlib/msort.c: New file; defines qsort function that does merge + sort. Falls back to _quicksort if it fails to allocate a temp array. + * stdlib/Makefile (routines): Added msort. + + * string/string.h (memccpy, strdup): Also declare #ifdef __USE_BSD. + [__USE_BSD] (index, rindex, bcmp, bzero, ffs): Declare. + * string/strings.h: Just #include <string.h>. + * string/Makefile (headers): Removed bstring.h. + + * misc/Makefile (routines): Removed swab. + * string/Makefile (routines): Put it here instead. + * misc/swab.c: Moved to string/swab.c. + + * stdio/stdio.h [__USE_BSD] (sys_nerr, sys_errlist): Declare. + + * grp/grp.h (setgrent, endgrent, getgrent): Also do #ifdef __USE_BSD. + + * posix/glob.h [__USE_BSD] (GLOB_MAGCHAR): Declare. + (glob_t): Added member `gl_flags'. + * posix/glob.c (glob, glob_in_dir): Set gl_flags member to FLAGS; + or in GLOB_MAGCHAR if any metachars are seen. + + * sysdeps/unix/bsd/bsd44/readdir.c: New. + + * sysdeps/unix/bsd/sun/readdir.c: Don't need to declare + __getdirentries here. Use off_t and ssize_t. + + * misc/Makefile (routines): Removed getdents and __getdents. + * dirent/Makefile (routines): Put them here instead. + * misc/getdents.c: Moved to dirent/getdents.c. + * dirent/dirent.h [__USE_BSD] (__getdirentries, getdirentries): + Declare. + + * dirent/Makefile (routines): Added scandir and alphasort. + * dirent/scandir.c, dirent/alphasort.c: New. + * dirent/dirent.h [__USE_BSD] (scandir, alphasort): Declare. + + * sysdeps/unix/bsd/nice.c, sysdeps/unix/sysv/nice.S, + sysdeps/stub/nice.c: New. + * resource/Makefile (routines): Added nice. + + * misc/sys/cdefs.h [__USE_BSD] (const, signed, volatile): #define to + __ versions, for the sake of 4.4 header files. + +Wed May 13 00:35:12 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * stdlib/tst-strtol.c: Fixed typo in test table. + + * stdlib/strtol.c: Fixed checking for overflow of long int that fits + in unsigned long int. + + * misc/Makefile (headers): Added ttyent.h. + (routines): Added getttyent. + * misc/ttyent.h, misc/getttyent.h: New; snarfed from 4.4. + + * posix/sys/wait.h [__USE_BSD]: Added forward decl for struct rusage. + (__wait4, __wait3): Declare arg as struct rusage, not PTR. + + * inet/arpa/*.h, inet/protocols/*.h, inet/netdb.h, inet/resolv.h: + New files from 4.4. + * inet/Makefile (headers): Snarf *.h from arpa/ and protocols/. + + * sysdeps/m68k/fpu/__math.h, assert/assert.h: #include <sys/cdefs.h> + and use its macros rather than rolling our own. + + * misc/sys/cdefs.h: New file. + * misc/Makefile (headers): Add it. + + * Makerules: Moved check for headers coming from env to Rules. + +Tue May 12 01:04:10 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/generic/strsep.c: New. + * string/string.h [__USE_BSD] (strsep): Declare. + * string/Makefile (routines): Added strsep. + + * sysdeps/unix/sysv/__settod.c, sysdeps/unix/sysv/stime.S, + sysdeps/unix/bsd/stime.c, sysdeps/stub/stime.c: New. + * time/time.h [__USE_SVID] (stime): Declare it. + + * sysdeps/unix/bsd/bsd44/__getdents.S: New. + + * posix/wordexp.h, posix/utime.h, posix/unistd.h, time/time.h, + termios/termios.h, posix/tar.h, string/strings.h, string/string.h, + stdlib/stdlib.h, signal/signal.h, stdio/stdio.h, misc/sgtty.h, + setjmp/setjmp.h, inet/resolv.h, pwd/pwd.h, stdio/printf.h, + misc/nlist.h, inet/netdb.h, math/math.h, malloc/malloc.h, + locale/locale.h, grp/grp.h, posix/glob.h, posix/getopt.h, + posix/fnmatch.h, io/fcntl.h, errno.h, dirent/dirent.h, + ctype/ctype.h, string/bstring.h, assert/assert.h, stdlib/alloca.h, + misc/a.out.h [__cplusplus]: Added stupid cruft for losing C++. + +Mon May 11 01:40:49 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * math/Makefile (headers): Added huge_val.h and nan.h. + + * io/Makefile (headers): Changed gnu/stat.h to statbuf.h. + + * time/Makefile (install-data): Include $(localtime-file) and + $(posixrules-file) if they are relative. + (install-others): Include them if absolute. + ($(posixrules-file), $(localtime-file)): Define rules to install if + absolute file names. + * Makerules (+install): Include $(install-others) verbatim. + * Makeconfig (localtime-file): Made default /etc/localtime. + + * sysdeps/generic/Makefile (endian.h): Only generate if would + otherwise use stub version. + * sysdeps/stub/endian.h, sysdeps/i386/endian.h: New. + + * Rules, Makefile: Export distribute and dont_distribute. + * Make-dist: Export sysdep_dirs. Unexport things rather than + clobbering their values. + + * misc/sys/ptrace.h: Fixed typo. + + * stdio/stdio.h (__io_read, __io_write, __io_seek, __io_close): + Added comments. + + * stdio/internals.c (flushbuf): If in append mode, don't do aligned + writing, seek to the target, or update the offset. + + * posix/unistd.h (lseek): Doc fix. + + * misc/swab.c: New. + * misc/Makefile (routines): Added swab. + +Wed May 6 12:32:18 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * math/Makefile, inet/Makefile (source_dirs): Export it. + * MakeTAGS (all-dirs): Include $(source_dirs). + + * Makefile (TAGS): Removed dep on subdir_TAGS. + (+subdir_targets): Removed subdir_TAGS. + * MakeTAGS [! subdir] (TAGS): Depend on subdir_TAGS. + [! subdir] (subdir_TAGS): Recurse on subdirectories. + + * Makerules (headers): Don't take value from the environment. + + * Makerules (sysdirs, sysdep_dir): Export them. + + * MakeTAGS: New makefile. + * Makefile (distribute): Include it. + * Makefile (TAGS), Rules (TAGS): Removed rules. + * Makerules (TAGS): New rule that uses MakeTAGS. + * Makefile (TAGS): Depend on subdir_TAGS. + + * Makerules (install, install-lib, install-data, routines, aux): + Don't bother removing these if they come from the environment, since + they won't with make >= 3.62.8. + * Rules (distribute, headers): Ditto. + (subdir): Export it. + * Makerules (sources, headers): Export these. + * Makefile (subdirs): Export it. + + * Rules (+tags_sources): Removed. + * Makerules (tags-sources): Define here. + * ctype/Makefile (tags-sources): Redefine to give headers precedence + over sources. + * Rules (TAGS), Makefile (TAGS): Rewrote rules. + * Makeconfig (+ctags): Removed. + (ETAGS): Define. + + * sysdeps/posix/getcwd.c: Don't closedir twice. + + * sysdeps/unix/bsd/hp/m68k/__wait3.S: Define __wait3, not ___wait3. + + * posix/sys/types.h [__USE_BSD] (fsid_t): Define. + * posix/gnu/types.h (__fsid_t): Define. + + * io/fcntl.h (F_GETLK): Define. + +Tue May 5 18:36:46 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * misc/Makefile (routines): Added seteuid and setegid. + * sysdeps/stub/sete[ug]id.c, sysdeps/unix/bsd/bsd44/sete[ug]id.S: New. + * posix/unistd.h [__USE_BSD] (seteuid, setegid): Declare. + + * sysdeps/unix/bsd/tcsendbrk.c: #include <sys/types.h> + + * Makerules: Strip whitespace from $(headers) so ifdef wins. + + * sysdeps/unix/bsd/bsdtty.h: #undef a bunch more things. + + * sysdeps/unix/bsd/bsd44/errnos.h: New, hacked from 4.4 <sys/errno.h>. + + * sysdeps/unix/Makefile (ioctls.h, errnos.h): Only generate if + the files that would be used otherwise are the stub versions. + + * sysdeps/unix/bsd/tcflow.c: Don't write VSTOP or VSTART if it is + _POSIX_VDISABLE. + + * sysdeps/unix/bsd/tcflush.c: Use FREAD|FWRITE for TCIOFLUSH. + + * sysdeps/unix/bsd/usleep.c: Use select rather than itimers to wait. + + * sysdeps/unix/bsd/tcsendbrk.c: Use select rather than itimers to wait. + + * termios/cfmakeraw.c: New. + * termios/Makefile (routines): Added cfmakeraw. + + * sysdeps/unix/bsd/bsd44/ioctls.h: New file, hacked from 4.4 + <sys/ioctl.h>. + * sysdeps/unix/bsd/bsd44/__tcgetatr.c: New. + * sysdeps/unix/bsd/bsd44/tcsetattr.c: New. + * sysdeps/unix/bsd/bsd44/tcdrain.c: New. + + * termios/sys/ttydefaults.h: New, snarfed from 4.4. + * termios/Makefile (headers): Define. + * termios/termios.h [__USE_BSD]: #include <sys/ttydefaults.h> + + * sysdeps/posix/getcwd.c: Removed unused variable. + + * time/__tzset.c: Cast string literal to (char *). + + * setjmp/sigjmp_save.c: Declare properly to return void. + + * sysdeps/ieee754/nan.h: Created; somehow it disappeared. + +Mon May 4 18:30:52 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/bsd44/__wait4.S: New. + + * sysdeps/unix/bsd/4.4: Renamed to sysdeps/unix/bsd/bsd44. + + * signal/gnu/signal.h (__SA_DISABLE, __SA_NOCLDSTOP): Use same bits + 4.4 uses. + +Sun May 3 13:57:25 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/fwrite.c: Use unsigned char to avoid sign extension. + + * stdlib/__random.c (randtbl): Replaced default constants so they + match the state produced by "srandom (1)". + + * stdlib/mbtowc.c: Test for S == "" before testing for no mbchars. + + * stdlib/Makefile (tests): Added testrand. + * stdlib/testrand.c: New test for rand. + + * stdlib/testmb.c: Added 2 mblen tests. + + * stdlib/wcstombs.c: Don't do anything strange for EOF. + Copy non-MB characters as they are. + Properly increment S after writing. + + * stdlib/testmb.c: Added test case for wcstombs. + + * signal/signal.h (SA_DISABLE): Define. + * signal/gnu/signal.h (__SA_DISABLE): Define. + + * signal/signal.h (struct sigaltstack): Define new type. + (sigaltstack): Declare new fn. + * sysdeps/stub/sigaltstack.c: New. + * sysdeps/unix/bsd/4.4/sigaltstack.S: New. + + * misc/Makefile (routines): Added reboot. + * posix/unistd.h (reboot): Declare. + * sysdeps/stub/reboot.c: New. + + * sysdeps/unix/bsd/ulimit.c [! HAVE_GNU_LD]: #define _etext -> etext. + + * sysdeps/unix/bsd/sun/sparc/sethostid.S: #define _ERRNO_H before + #include <errnos.h>. + + * configure (newos*): base_os=unix/bsd. + +Fri May 1 12:21:47 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * io/gnu/stat.h: Moved to sysdeps/unix/bsd/statbuf.h. + * sysdeps/unix/bsd/statbuf.h: Define struct stat, not struct __stat. + * io/stat.c: Use struct stat, not struct __stat. + * sysdeps/stub/statbuf.h: New. + * io/sys/stat.h: #include <statbuf.h> instead of gnu/stat.h. + (stat, fstat, lstat, chmod, fchmod, umask, mkdir, mknod): Don't + #define; declare as fns instead. + * sysdeps/unix/sysv/stat.h: New. + * sysdeps/unix/sysv/sysv_stat.h, sysdeps/unix/sysv/sys_stat.S, + sysdeps/unix/sysv/sys_fstat.S: Removed. + * sysdeps/unix/sysv/Makefile (sysdep_routines): Removed sys_stat, + sys_fstat. + * sysdeps/unix/sysv/Dist: Removed sys_stat.S, sys_fstat.S. + * sysdeps/unix/bsd/__stat.S, sysdeps/unix/bsd/__fstat.S: Moved to + sysdeps/unix. + + * sysdeps/m68k/fpu/switch/Makefile: Refer to dirs fpu and + fpu/switch, not 68881 and 68881-switch. + + * sysdeps/m68k/fpu/switch/switch.c: #include <68881-sw.h>, not + 68881-switch.h. + + * sysdeps/m68k/fpu/__expm1.c, sysdeps/m68k/fpu/__rint.c, + sysdeps/m68k/fpu/asin.c, sysdeps/m68k/fpu/atan.c, + sysdeps/m68k/fpu/atanh.c, sysdeps/m68k/fpu/ceil.c, + sysdeps/m68k/fpu/cos.c, sysdeps/m68k/fpu/cosh.c, + sysdeps/m68k/fpu/exp.c, sysdeps/m68k/fpu/fabs.c, + sysdeps/m68k/fpu/floor.c, sysdeps/m68k/fpu/log.c, + sysdeps/m68k/fpu/log10.c, sysdeps/m68k/fpu/log1p.c, + sysdeps/m68k/fpu/sin.c, sysdeps/m68k/fpu/sinh.c, + sysdeps/m68k/fpu/sqrt.c, sysdeps/m68k/fpu/tan.c, + sysdeps/m68k/fpu/tanh.c: #include <acos.c> without explicit path + (which has changed). + + * sysdeps/unix/bsd/sun/sparc/start.c: #include <syscall.h>. + (syscall): Removed C function; define all inside asm instead. + (init_shlib): Cast return value of syscall to right types. + +Thu Apr 30 01:15:33 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sparc/start.c: Added code to use dynamic + linker from trq@dionysos.thphys.ox.ac.uk. + + * sysdeps/unix/bsd/sun/sunos4: Renamed to sunos411. + + * setjmp/setjmp.h (sigsetjmp): Don't declare as a function. + Define as a macro instead. + (__sigjmp_save): Declare; internal fn used by sigsetjmp macro. + (_setjmp), [__FAVOR_BSD] (setjmp): Always define as a macro. + * setjmp/sigjmp_save.c: New file. + * setjmp/_setjmp.c, setjmp/sigsetjmp.c: Removed. + * Makefile (routines): Removed _setjmp, sigsetjmp; added sigjmp_save. + * misc/bsd-compat.c (setjmp): Don't define. + + * configure (sysv, bsd): base_os=unix + + * configure: Fatal error if the machine or os did not generate any + sysdep dirs. + + * configure: No error message after config.sub fails. + + * sysdeps/mips, sysdeps/unix/bsd/ultrix42: New port from + brendan@cs.widener.edu. + + * Reorganized sysdeps: + unix/bsd/ + hp9k3bsd -> hp/m68k + news -> sony/m68k + sun/ + sun3/os3 -> sunos3/m68k + sun3 -> m68k + sun4 -> sparc + unix/sysv/ + r4 -> sysv4 + m68k/ + 68881 -> fpu + 68881/68881-switch -> fpu/switch + * sysdeps/unix/bsd/sony/m68k/start.c: Changed #include. + * configure: Use config.sub to canonicalize name. + Then use combinations of machine, vendor, and os (with special + hacks for os flavors) for sysdep dirs to try. + * Makefile (distribute): Added config.sub. + +Wed Apr 29 23:06:06 1992 Brendan Kehoe (brendan@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/hp9k3bsd/sysdep.h, + sysdeps/unix/bsd/sun/sun3/sysdep.h, sysdeps/unix/bsd/sun/sun4/sysdep.h, + sysdeps/unix/bsd/vax/sysdep.h,sysdeps/unix/i386/sysdep.h, + sysdeps/mach/i386/sysdep.h: Change all definitions of movl/mov to + MOVE(s, d), for insn sets with d,s instead of s,d move insns. + * sysdeps/unix/__getegid.S, sysdeps/unix/__geteuid.S, + sysdeps/unix/__getppid.S: Use that in each of these. + +Wed Apr 29 17:58:21 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * io/getwd.c: Default PATH_MAX if not defined. + + * sysdeps/unix/getlogin.c, sysdeps/posix/ttyname.c: Make buffers + only as big as needed, avoiding PATH_MAX. + + * sysdeps/posix/getcwd.c: Dynamically extend the buffer as we go, + not afterwards; default PATH_MAX if not defined. + + * posix/execvp.c: Dynamically allocate an array on the stack for the + path name, rather than using a fixed-size array. + + * pwd/putpwent.c: Print pw_dir field. + + * sysdeps/posix/mktemp.c: If the pid has changed, update OLDPID. + +Tue Apr 28 19:25:21 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * malloc/valloc.c [emacs]: #include "config.h" + +Thu Apr 23 13:55:34 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/m68k/68881/__drem.c: Define __drem, not drem. + Call ____drem, not __drem. + + * malloc/realloc.c, malloc/malloc.c: Don't #define memcpy or memset + if already #define'd. + +Tue Apr 21 04:16:56 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * malloc/Makefile: Moved include ../Rules after malloc.tar rules. + They need $(routines), which Rules clears. + + * malloc/realloc.c (MIN): Renamed to min. Conflicted with HPUX + system header files. + + * Makefile (sysdep-subdirs): Is not called +sysdep-subdirs. + + * configure: Don't try to create config.status if . is not writable. + + * sysdeps/generic/printf_fp.c: Fixed padding loop condition for zero + case. + + * math/math.h: Don't #include <float.h> for HUGE_VAL. + Instead, #include <huge_val.h>. + * stdlib/stdlib.h: Ditto. + * math/math.h [__USE_GNU]: #include <nan.h> to get NAN value. + * float.h: Removed. + * Makefile (headers): Removed float.h and fl.h. + * sysdeps/ieee754/huge_val.h, sysdeps/ieee754/nan.h, + sysdeps/stub/huge_val.h, sysdeps/stub/nan.h, sysdeps/vax/huge_val.h: + Created (from old fl.h files). + + * math/bsd/common_source/pow.c (pow_p): When checking if Y is an + integer, don't let it overflow a `long int'. + (pow): Check for NaN with __isnan, not (X != X). + +Tue Apr 21 02:26:19 1992 Brendan Kehoe (brendan@cs.widener.edu) + + * sysdeps/unix/bsd/sun/sun4/__pipe.S, + sysdeps/unix/bsd/vax/__wait3.S, sysdeps/unix/bsd/hp9k3bsd/__wait3.S: + Use the ENTRY macro for each beginning + + * sysdeps/unix/sysdep.h, sysdeps/unix/bsd/hp9k3bsd/sysdep.h, + sysdeps/unix/bsd/sun/sun3/sysdep.h, + sysdeps/unix/bsd/sun/sun4/sysdep.h, sysdeps/unix/bsd/vax/sysdep.h, + sysdeps/unix/i386/sysdep.h, sysdeps/unix/sysdep.h, + sysdeps/unix/sysv/sysdep.h [SYSCALL, SYSCALL__, PSEUDO]: Modify to + also receive the number of args the syscall takes; added for future + ports that will require this information. + + * sysdeps/unix/i386/__pipe.S, sysdeps/unix/bsd/vax/__pipe.S, + sysdeps/unix/bsd/sun/sun4/__pipe.S, + sysdeps/unix/bsd/hp9k3bsd/__pipe.S, sysdeps/unix/i386/__brk.S, + sysdeps/unix/bsd/sun/__getdents.S, sysdeps/unix/i386/__fork.S, + sysdeps/unix/bsd/vax/__fork.S, sysdeps/unix/bsd/sun/sun4/__fork.S, + sysdeps/unix/__setgid.S, sysdeps/unix/__setuid.S, + sysdeps/unix/bsd/sun/sun3/__vfork.S, + sysdeps/unix/bsd/sun/sun4/__vfork.S, + sysdeps/unix/bsd/vax/__wait.S, sysdeps/unix/bsd/hp9k3bsd/__wait.S, + sysdeps/unix/i386/__wait.S, + sysdeps/unix/bsd/sun/sunos4/sys_wait4.S, + sysdeps/unix/bsd/sun/sun3/sethostid.S, + sysdeps/unix/bsd/sun/sun4/sethostid.S, + sysdeps/unix/bsd/__sigvec.S, sysdeps/unix/bsd/sun/sun4/__sigvec.S, + sysdeps/unix/sysv/i386/__sigret.S, sysdeps/unix/__getppid.S, + sysdeps/unix/bsd/__access.S, sysdeps/unix/sysv/signal.S, + sysdeps/unix/__getegid.S, sysdeps/unix/__geteuid.S, + sysdeps/unix/bsd/bsd_getgrp.S, sysdeps/unix/bsd/__dup2.S, + sysdeps/unix/bsd/__fchmod.S, sysdeps/unix/bsd/__fchown.S, + sysdeps/unix/bsd/__flock.S, sysdeps/unix/bsd/__fstat.S, + sysdeps/unix/bsd/__lstat.S, sysdeps/unix/bsd/__mkdir.S, + sysdeps/unix/bsd/__readlink.S, sysdeps/unix/bsd/__rmdir.S, + sysdeps/unix/bsd/__stat.S, sysdeps/unix/bsd/__symlink.S, + sysdeps/unix/bsd/4.4/chflags.S, sysdeps/unix/bsd/4.4/fchflags.S, + sysdeps/unix/bsd/4.4/sstk.S, sysdeps/unix/bsd/4.4/setlogin.S, + sysdeps/unix/bsd/__getdtsz.S, sysdeps/unix/bsd/__getpgsz.S, + sysdeps/unix/bsd/__setregid.S, sysdeps/unix/bsd/__setreuid.S, + sysdeps/unix/bsd/__utimes.S, sysdeps/unix/bsd/ftruncate.S, + sysdeps/unix/bsd/readv.S, sysdeps/unix/bsd/truncate.S, + sysdeps/unix/bsd/vhangup.S, sysdeps/unix/bsd/writev.S, + sysdeps/unix/bsd/__getpgrp.S, sysdeps/unix/bsd/__setpgrp.S, + sysdeps/unix/bsd/__getrusag.S, sysdeps/unix/bsd/getprio.S, + sysdeps/unix/bsd/getrlimit.S, sysdeps/unix/bsd/setprio.S, + sysdeps/unix/bsd/__sigblock.S, + sysdeps/unix/bsd/__sigpause.S, sysdeps/unix/bsd/__sigstmsk.S, + sysdeps/unix/bsd/killpg.S, sysdeps/unix/bsd/sigstack.S, + sysdeps/unix/bsd/rename.S, sysdeps/unix/bsd/__adjtime.S, + sysdeps/unix/bsd/__setitmr.S, sysdeps/unix/bsd/__settod.S, + sysdeps/unix/sysv/sys_stat.S, sysdeps/unix/sysv/sys_fstat.S, + sysdeps/unix/sysv/__utssys.S, sysdeps/unix/sysv/utime.S, + sysdeps/unix/sysv/__times.S, sysdeps/unix/sysv/i386/time.S, + sysdeps/unix/sysv/alarm.S, sysdeps/unix/sysv/pause.S, + sysdeps/unix/sysv/ulimit.S, sysdeps/unix/__chdir.S, + sysdeps/unix/__chmod.S, sysdeps/unix/__chown.S, + sysdeps/unix/__close.S, sysdeps/unix/__dup.S, + sysdeps/unix/__fcntl.S, sysdeps/unix/__link.S, + sysdeps/unix/__lseek.S, sysdeps/unix/__open.S, + sysdeps/unix/__read.S, sysdeps/unix/__umask.S, + sysdeps/unix/__unlink.S, sysdeps/unix/__write.S, + sysdeps/unix/__ioctl.S, sysdeps/unix/__mknod.S, + sysdeps/unix/acct.S, sysdeps/unix/chroot.S, sysdeps/unix/fsync.S, + sysdeps/unix/ptrace.S, sysdeps/unix/swapon.S, sysdeps/unix/sync.S, + sysdeps/unix/__execve.S, sysdeps/unix/__getgid.S, + sysdeps/unix/__getpid.S, sysdeps/unix/__getuid.S, + sysdeps/unix/_exit.S, sysdeps/unix/__kill.S, + sysdeps/unix/inet/__gethstnm.S, sysdeps/unix/inet/__select.S, + sysdeps/unix/inet/gethostid.S, sysdeps/unix/inet/sethostid.S, + sysdeps/unix/inet/sethostnam.S, sysdeps/unix/inet/accept.S, + sysdeps/unix/inet/bind.S, sysdeps/unix/inet/connect.S, + sysdeps/unix/inet/getpeernam.S, sysdeps/unix/inet/getsocknam.S, + sysdeps/unix/inet/getsockopt.S, sysdeps/unix/inet/listen.S, + sysdeps/unix/inet/recv.S, sysdeps/unix/inet/recvfrom.S, + sysdeps/unix/inet/recvmsg.S, sysdeps/unix/inet/send.S, + sysdeps/unix/inet/sendmsg.S, sysdeps/unix/inet/sendto.S, + sysdeps/unix/bsd/vax/__wait3.S, sysdeps/unix/bsd/hp9k3bsd/__wait3.S, + sysdeps/unix/inet/setsockopt.S, sysdeps/unix/inet/shutdown.S, + sysdeps/unix/inet/socket.S, sysdeps/unix/inet/socketpair.S: Added the + argument count to every use of SYSCALL, SYSCALL__ or PSEUDO. + +Tue Apr 21 00:06:52 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * limits.h [__GNUC__ >= 2]: Use #include_next to get GCC's <limits.h>. + + * sysdeps/posix/sysd-stdio.c (__stdio_read, __stdio_write, + __stdio_errmsg) [EINTR && EINTR_REPEAT]: Do EINTR looping. + * sysdeps/unix/sysv/sysd-stdio.c: New. + #define EINTR_REPEAT and #include posix/sysd-stdio.c. + + * stdlib/mbstowcs.c: Copy non-MB chars verbatim, instead of error. + + * sysdeps/generic/printf_fp.c: Note sign of exponent and take its + absolute value for arithmetic. + + * stdlib/testmb.c: New. + * stdlib/Makefile (tests): Added testmb. + + * sysdeps/generic/frexp.c [NAN]: If VALUE is infinite, return NAN. + If VALUE is NAN, set errno to EDOM and return VALUE. + If VALUE is zero, return it. In all special cases, clear *EXP. + + * stdio/test-fseek.c: New. + * stdio/Makefile (tests): Added test-fseek. + + * stdio/fseek.c: Position returned from io_funcs.seek is absolute, + not EOF-relative when using SEEK_END. + + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Set errno to + EEXIST when we run out. + + * sysdeps/posix/sysd-stdio.c (exists): Use stat rather than open, so + we don't need read access. + + * sysdeps/posix/mk-stdiolim.c (TMP_NAM): is 62 ** 3. + +Mon Apr 20 23:08:02 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Don't return + the same name twice when the file doesn't exist. + + * stdio/vfprintf.c (%c format): Tests of LEFT for padding were + reversed. + + * sysdeps/generic/printf_fp.c: If we have written some fractional + digits, write zeros up to the precision. + + * sysdeps/unix/bsd/sun/sun4/start.c: Don't clear the FP until just + before calling main. + +Wed Apr 15 01:43:38 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makerules (libc.a): Don't depend on libc.a(...); only on lib. + (lib-noranlib): Depend on libobjs. + (+libobjs): New var. + (libobjs): Depend on $(+libobjs). + * Rules (others, tests): Don't depend on lib; on libc.a instead. + + * locale/C-numeric.c: grouping is "". + + * locale/localeconv.c: Set int_frac_digits. + + * locale/setlocale.c: Accept "" to mean "C". + + * sysdeps/unix/sysv/r4/bsddir.h: Protect against multiple inclusion. + + * sysdeps/unix/sysv/r4/Dist: Created; includes bsddir.h and + sys_getdents.S. + + * sysdeps/unix/i386/sysdep.h [! HAVE_SYSCALLS]: Don't #inlcude + unix/sysdep.h. + * sysdeps/unix/sysv/sysdep.h, sysdeps/unix/sysdep.h + (HAVE_SYSCALLS): #define. + * sysdeps/unix/sysv/i386/sysdep.h: #include unix/sysv/sysdep.h, then + unix/i386/sysdep.h. + + * sysdeps/unix/sysv/Makefile: Fixed typos. + + * sysdeps/unix/sysv/Dist: Add utmp.h. + + * sysdeps/posix/Makefile (mk-stdiolim): Explicit commands, to + compile it without normal gcc flags. + + * configure (i386-sysv): unix/i386/sysv -> unix/sysv/i386. + (i386-sysvr4): New configuration. + +Tue Apr 14 16:47:47 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * setjmp/setjmp.h: Put sigjmp_buf before typedef for jmp_buf, which + needs sigjmp_buf #ifdef __FAVOR_BSD. + + * posix/unistd.h (getgroups): Don't #define. + + * sysdeps/stub/ptrace.c: #include <stdarg.h>; declare AP in fn. + Avoid "PTR a, b". + + * sysdeps/posix/sigintr.c: New; sets global sigset_t `_sigintr'. + * sysdeps/posix/signal.c: Use SA_RESTART unless SIG is in _sigintr. + * signal/sigintr.c: Removed. + * sysdeps/stub/sigintr.c: New. + + * sysdeps/posix/sysd-stdio.c (__stdio_read, __stdio_write, + __stdio_errmsg): Don't treat EINTR specially. + + * sysdeps/unix/Makefile (sys/param.h): Touch the target after mv'ing + from the tmp file, so the file is newer than the directory. + + * sysdeps/generic/strcasecmp.c: Simplified loop; fixed returning + wrong value on equal comparison. + + * stdlib/bsearch.c: Don't lose if NMEMB is zero. + + * sysdeps/unix/bsd/__times.c (timeval_to_clock_t): Microseconds are + not milliseconds. + +Mon Apr 13 18:25:17 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/strncase.c: New. + * string/Makefile (routines): Add strncase. + * string/string.h [__USE_GNU]: Declare strncasecmp. + + * time/__tzset.c: Correctly default DST offset to one hour later + than standard offset. + + * time/__tzset.c (tz_rule): Made `name' not be const. + + * string/tester.c [! HAVE_GNU_LD]: #define _sys_nerr and + _sys_errlist to sys_nerr and sys_errlist. + + * stdio/test_rdwr.c: Fixed printf call missing arg. + + * posix/getgrps.c: #undef getgroups first. + + * misc/brk.c: Declare __brk. + * misc/sbrk.c: Declare __sbrk. + * misc/setreuid.c, misc/setregid.c: #include <unistd.h>. + Fixed types in DEFUN in fn alias. + * misc/getpgsz.c, misc/getdtsz.c, misc/gethstnm.c: #include <unistd.h>. + * misc/getdents.c: Declare __getdirentries. + * misc/mknod.c: #include <sys/stat.h>. + * posix/unistd.h: Declare many __ versions of things. + [__OPTIMIZE__]: Many #define foo(...) -> __foo(...). + + * io/fcntl.c: #include <sys/file.h>. + + * sysdeps/unix/Makefile: New hair to install other headers the + system sys/param.h #includes. + + * time/__tzset.c (__tzfile_default): Declare. + + * time/sys/time.h (timezone): #define to __timezone. + + * sysdeps/ieee754/printf_fp.c: #undef outchar before #including + generic/printf_fp.c. + + * stdio/__vfscanf.c: For %c, don't lose the first char. + For %s, properly consume the last char when we hit max width. + + * posix/gnu/types.h (__dev_t, __mode_t): Made int rather than short. + * io/gnu/stat.h (struct stat): Made st_dev, st_rdev, and st_mode use + {,unsigned} short int instead of __dev_t/__mode_t. + +Fri Apr 10 13:55:07 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * setjmp/setjmp.h: Rearranged so that jmp_buf is defined before any + prototypes are used. + (longjmp): Declare with jmp_buf, not __jmp_buf, to win in BSD mode. + (_longjmp): #define as __longjmp, not longjmp. + (_longjmp, _setjmp): Take jmp_buf args, not __jmp_buf. + Call sig{set,long}jmp with SAVEMASK==0, rather than __{set,long}jmp. + * _longjmp.c, _setjmp.c: #define _BSD_SOURCE before all else. + (_setjmp): Call sigsetjmp, not __setjmp. + + * io/sys/stat.h (__fchmod, __mknod): Fixed arg types. + + * io/fchmod.c: Fixed typo. + + * time/Makefile (\n): Renamed to nl. + + * Makerules (native-compile): New variable. + * sysdeps/generic/Makefile, sysdeps/unix/Makefile, + sysdeps/unix/bsd/Makefile: Use it in cmds for generator progs. + + * sysdeps/unix/sysv/sysv_termio.h (_SYSV_TAB3): New; same as XTABS. + + * sysdeps/unix/sysv/setrlimit.c: Removed extern decl of etext (unused). + + * sysdeps/unix/sysv/__tcgetatr.c, sysdeps/unix/sysv/tcdrain.c, + sysdeps/unix/sysv/tcflow.c, sysdeps/unix/sysv/tcflush.c, + sysdeps/unix/sysv/tcgetpgrp.c, sysdeps/unix/sysv/tcsendbrk.c, + sysdeps/unix/sysv/tcsetattr.c, sysdeps/unix/sysv/tcsetpgrp.c: + #include <sys/ioctl.h> + + * sysdeps/unix/sysv/__rmdir.c, sysdeps/unix/sysv/__mkdir.c, + sysdeps/posix/writev.c: #include <string.h>. + + * sysdeps/posix/clock.c: Removed unused variable. + +Thu Apr 9 01:49:39 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 1.03. + + * grp/testgrp.c: Print members correctly. + + * stdio/test-popen.c: Pipe to cat rather than more, and then check + output file. Better error checking. + + * setjmp/tst-setjmp.c: Notice if we didn't jump the right number of + times. + + * signal/tst-signal.c, string/testcopy.c, stdio/bug[12345].c: Print + msgs that more clearly say whether we won or lost. Better error + checking. + + * sysdeps/generic/printf_fp.c: Completely rewritten from scratch. + Now uses Steele & White's "Dragon4" algorithm to do things right. + +Wed Apr 8 01:08:41 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/i386/__longjmp.c: Test for VAL==0 before clobbering regs. + Wire V to AX, rather than DX. Use "a" constraint on unused operand + in jmp asm, rather than global reg var, to force value into AX. + +Tue Apr 7 17:51:25 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/Makefile (headers): Added tar.h. + * posix/tar.h: New file, from djm. + +Mon Apr 6 01:39:07 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * time/tzfile.c (struct ttinfo): Made `isstd' member be unsigned + char instead of 1-bit bitfield. + + * time/tzfile.c (__tzfile_default): New function. + * time/__tzset.c: Call it when no rule is given. + * time/Makefile: Install posixrules just like localtime. + * time/Makeconfig (posixrules, posixrules-file): New config vars. + + * time/time.h (struct tm): Add `tz_gmtoff', `tz_zone'. + * time/localtime.c: Set those members. + + * sysdeps/ieee754/__drem.c: XOR the signs of X and the result, + rather than setting the sign of the result to that of X. + + * sysdeps/unix/bsd/make-local_lim.c: Don't do MAXUPRC or MAXLINK if + <sys/param.h> didn't define them. + + * sysdeps/posix/__sigvec.c: Fixed braino: SA_ONSTACK should be + SA_RESTART. + + * pwd/getpw.c, pwd/putpwent.c: Use %u fmt for uid and gid (which are + unsigned). + + * time/time.h (tzname, daylight, timezone): Don't #define to __. + * time/tzfile.c, time/__tzset.c, time/localtime.c, time/strftime.c + [! HAVE_GNU_LD]: #define __ to plain for above three vars. + +Thu Apr 2 03:39:04 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * locale/Makefile (routines): Add localeconv. + + * sysdeps/i386/jmp_buf.h: Removed `__dx' elt; replaced with `__pc'. + __bp and __sp are PTRs. + * sysdeps/i386/setjmp.c: Rewritten. Use global reg vars to save regs. + Use arithmetic on address of arg to get caller's PC, BP, and SP. + * sysdeps/i386/__longjmp.c: Rewritten. Use global reg vars to + restore regs. + +Wed Apr 1 23:13:57 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Moved sysdeps/unix/i386/{bsd,sysv} to + sysdeps/unix/{bsd,sysv}/i386, and updated Implies files. + Implied dirs come before parents, and we want unix/i386 before + unix/{sysv,bsd}. + + * io/chown.c: Fixed types in fn alias. + +Wed Apr 1 14:18:58 1992 Torbjorn Granlund (tege@mole.gnu.ai.mit.edu) + + * sysdeps/generic/memcmp.c + (memcmp_common_alignment, memcmp_not_common_alignment): + Move back do0 label to its original position, after the loop. + Add comment before do0 labels. + * sysdeps/generic/wordcopy.c (_wordcopy_fwd_aligned): Indentation. + Add comment before do0 labels. + +Wed Apr 1 02:16:19 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/Makefile [subdir==misc]: Generate sysdep header + termio.h from sysv_termio.h. + + * sysdeps/generic/make_siglist.c: New file. + * sysdeps/generic/signame.[ch]: Symlink'd from /gd/gnu/lib. + * sysdeps/generic/Makefile: Generate siglist.c with above. + * sysdeps/generic/Dist: Add make_siglist.c, signame.[ch]. + + * sysdeps/unix/bsd/Makefile (before-compile): Define properly as a + variable. + + * sysdeps/unix/bsd/make_siglist.c: Generate #define _sys_siglist + sys_siglist #ifndef HAVE_GNU_LD. + * stdio/psignal.h, string/strsignal.h [! HAVE_GNU_LD]: + #define _sys_siglist sys_siglist. + + * sysdeps/unix/sysv/signum.h (SIGCHLD): Changed #. + (SIGUSR1, SIGUSR2, SIGPWR): Added. + (_NSIG): Updated. + + * sysdeps/unix/sysv/utmp.h: New. + + * sysdeps/unix/bsd/getlogin.c: Moved to sysdeps/unix/getlogin.c. + + * sysdeps/unix/sysv/r4/bsddir.h, sysdeps/unix/sysv/r4/readdir.c, + sysdeps/unix/sysv/r4/closedir.c, sysdeps/unix/sysv/r4/rewinddir.c, + sysdeps/unix/sysv/r4/opendir.c, sysdeps/unix/sysv/r4/sys_getdents.S, + sysdeps/unix/sysv/r4/Makefile: New. + + * sysdeps/unix/sysv/tcflow.c: New. + + * sysdeps/unix/sysv/sysv_termio.h: Add lots of bits; VMIN and VTIME + elts of c_cc. + * sysdeps/unix/sysv/__tcgetatr.c, sysdeps/unix/sysv/tcsetattr.c: Use + VMIN and VTIME elts from sysv termio struct. + + * sysdeps/unix/sysv/__gethstnm.c: New. + + * sysdeps/unix/sysv/local_lim.h (NGROUPS_MAX): Define as 0. + + * sysdeps/unix/sysv/fcntlbits.h (struct __flock): Changed l_pid to + short; added l_sysid. + + * sysdeps/unix/sysv/__sigact.c: New. + + * sysdeps/unix/sysv/r4/__access.S: New; just #include bsd/__access.S. + + * sysdeps/unix/sysv/Makefile: Fixed typo: sysdep-routines => + sysdep_routines. + + * sysdeps/unix/i386/sysv/__sigret.S, + sysdeps/unix/i386/sysv/signal.S: New. + + * signal/Makefile (routines): Added sigret, __sigret. + * signal/sigret.c: New; fn alias to __sigreturn. + * sysdeps/stub/__sigret.c: New. + + * sysdeps/unix/i386/sysdep.h (PSEUDO): Use hard-coded numbers for + lcalls insn--GAS bug. + + * sysdeps/unix/bsd/readdir.c (D_NAMLEN): New macro; define if not + already defined, to return length of a direct elt. + + * sysdeps/stub/__getgrps.c: #include <limits.h>; if NGROUPS_MAX is + defined as 0, always return 0, and no stub warning. + + * sysdeps/posix/system.c: Don't fail if sigprocmask fails with ENOSYS. + + * sysdeps/posix/sysd-stdio.c, sysdeps/stub/sysd-stdio.c: Doc fix. + + * sysdeps/posix/__gettod.c: Use CONST where appropriate and not + where not. + + * sysdeps/i386/memchr.c, sysdeps/i386/strlen.c: Changed `repnz' to + `repne'. + + * stdio/fgets.c: Notice returned char from __fillbf in length calc. + + * misc/sys/ioctl.h: Always define `struct sgttyb'. + + * stdlib/alloca.h: #undef __alloca, too. + Always #define alloca == __alloca. + + * signal/signal.h (__kill): Fixed type in decl. + * posix/unistd.h (setgid): Fixed type in decl. + * posix/setpgid.c, posix/setgid.c, signal/kill.c, posix/fork.c, + posix/vfork.c, posix/getpid.c, posix/getppid.c, posix/setsid.c: + Fixed DEFUNs in fn aliases. + * pwd/getpw.c: Fixed type in defn. + +Mon Mar 30 17:06:54 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/generic/printf_fp.c: In %f, decrement PREC for each + leading zero in the fractional part. + + * sysdeps/ieee754/ieee754.h: Made all elts unsigned. + * sysdeps/ieee754/__drem.c: Return NAN if Y is zero. + * sysdeps/ieee754/ldexp.c: Rewritten. + * sysdeps/ieee754/__logb.c: Handle denormalized numbers. + + * posix/sys/wait.h: #include <endian.h> + + * sysdeps/ieee754/fl.h: Fixed NAN and HUGE_VAL bit patterns; added + code for little endian. + + * sysdeps/generic/frexp.c: Add one to exponent to give the result a + digit before the point. Use negative exponent rather than division. + + * math/__finite.c: Return zero for NaN. + * math/math.h: Doc fix for same. + + * stdio/__getdelim.c: Correctly notice when the buffer is full. + + * sysdeps/unix/bsd/opendir.c: Pass arg to fcntl F_SETFD by value, + not by reference. + + * time/__tzset.c: Correct default rule: M4.1.0,M10.5.0. + + * time/__tzset.c: Move ptr past Mfoobar syntax after parsing it. + + * time/__tzset.c: Properly parse the DST offset (or its absence). + + * sysdeps/unix/make_errlist.c: Write an #ifdef HAVE_GNU_LD, rather + than testing it when compiling make_errlist. + + * time/tzfile.c (__tzfile_read): Convert transitions to host byte + order. + + * Makeconfig (localtime-file): New config var. + * time/Makefile (tzfile.o, zic.o): Use it for TZDEFAULT. + + * stdio/Makefile (tests): Added tstgetline. + * stdio/tstgetline.c: New; test for getline. + + * Makeconfig (sysincludedir): Define and document. + * sysdeps/unix/snarf-ioctls, sysdeps/unix/Makefile: Use + ${sysincludedirs} in place of hard-coded /usr/include. + +Fri Mar 27 13:33:37 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * string/Makefile (headers): Added endian.h. + + * sysdeps/ieee754/__drem.c: Fixed typo which made X and Y be the + same location. + + * sysdeps/generic/__lstat.c: #include <gnu-stabs.h> + + * stdio/internals.c (flushbuf): Increment target as well as offset + when we write out the single char. + + * grp/Makefile (tests): Add testgrp (formerly bug1). + +Thu Mar 26 14:59:45 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * stdio/fread.c: Don't read directly when we need to seek first. + +Wed Mar 25 02:34:49 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/alarm.c: There are 1000000 usecs in a sec. + + * sysdeps/unix/bsd/sun/ptrace.c: Removed. + + * stdio/fgets.c: For unbuffered stream, don't return EOF after + reading some data. + Added missing parens. + +Tue Mar 24 18:31:07 1992 Torbjorn Granlund (tege@hal) + + * sysdeps/i386/memset.c: Move code that puts C in all four nibbles of + X inside `if' statement. Include sysdeps/i386/memset.c (not bzero). + * sysdeps/i386/memchr.c: Rewrite to be faster. Include + sysdeps/generic/memchr.c (not bzero). + +Tue Mar 24 01:21:32 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * io/Makefile (routines): Add getdirname. + * posix/unistd.h [__USE_GNU]: Declare getdirname. + * io/getdirname.c: New. + + * Makeconfig (stddef.h): Define and document. + * Makefile (headers): Use $(stddef.h) for stddef.h. + +Mon Mar 23 18:04:56 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/posix/mktemp.c: Do PID % 100000 for 5 digits. + + * time/Makefile (tzfiles): Remove pacificnew; it won't compile. + (distribute): Put it here instead. + + * stdio/printf-prs.c [HAVE_LONGLONG]: Fixed missed var name change + from code snarf. + + * stdio/fgets.c: Return NULL when we get EOF. + + * posix/execvp.c, sysdeps/posix/putenv.c [! HAVE_GNU_LD]: Define + __environ as environ. + + * sysdeps/unix/bsd/Makefile, sysdeps/unix/Makefile: In rules to + compile generator programs, cd into $(objdir) first to avoid + braindead cc clobbering foo.o in cwdir. + + * sysdeps/m68k/setjmp.c: Deref fpregs array in asm. + + * time/Makefile (zones-%): Fixed generated rules. + + * math/Makefile (libm.a): Use r cmd to ar. + + * time/Makefile (zones-%): In echo commands, put \\\\n outside of + quotes instead of \\n inside single quotes. SysV echo is braindead. + + * io/fchown.c, io/fchmod.c, misc/bsd-compat.c: Fixed DEFUNs in fn + aliases. + + * time/Makefile (echo-zonenames): New target; tell user what all + timezones defined in all zone files are. + * Makeconfig (localtime): Comment about using above. + +Sun Mar 22 18:34:02 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * time/australasia (NZ): Updated rules. + +Sat Mar 21 01:00:49 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * stdio/printf-prs.c [__GNUC__]: Define HAVE_LONGLONG. + +Fri Mar 20 00:35:36 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 1.02. + + * stdio/Makefile (routines): Add __getdelim, __getline. + + * sysdeps/unix/i386/start.c: No ../ in #include file name. + + * sysdeps/posix/sysd-stdio.c, sysdeps/stub/sysd-stdio.c + (__stdio_seek): Doc fix. + + * sysdeps/posix/mk-stdiolim.c: Add one to L_tmpnam, for the null + terminator. + + * sysdeps/posix/__dup2.c: Use an extra fcntl call to check that the + first fd is valid. Close the second fd before doing the dup. + + * pwd/pwdread.c, grp/grpread.c: Use __getline. Ignore lines + beginning with #. + + * Makeconfig (objdir): If $(ARCH) starts with a slash, don't prepend + $(..). + +Thu Mar 19 21:36:57 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makefile (install-lib): Add Mcrt1.o. + (Mcrt1.o): Create empty file. + +Wed Mar 18 16:00:18 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Makeconfig (+link): Use $(libdir) for gnulib. + +Tue Mar 17 20:12:35 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * math/bsd/common_source/mathimpl.h: Include <endian.h>. + [__LITTLE_ENDIAN]: #define national. + + * stdio/__vfscanf.c: EOF at end of string is not + an error. + + * stdio/tstscanf.c: Added new sscanf test. + + * stdio/vfprintf.c: For %#x, print 0x after padding 0s, not before. + + * stdio/fputs.c: Reverse size args to fwrite and test for returning + LEN, rather than 1, so 0-length wins. + + * io/gnu/fcntl.h: Moved to sysdeps/unix/bsd/fcntlbits.h. + * io/Makefile (headers), io/fcntl.h: gnu/fcntl.h -> fcntlbits.h. + * sysdeps/stub/fcntlbits.h, sysdeps/unix/sysv/fcntlbits.h: New. + + * stdio/fopen.c (__getmode): Don't fall through in switch after 'a' + case. + + * locale/C-ctype_ct.c (__ctype_b_C): Use symbolic constants. + 9..12 are not _NOgraph. + +Tue Mar 17 19:04:01 1992 Torbjorn Granlund (tege@hal.gnu.ai.mit.edu) + + * string/testcopy.c: Fix typo in comment. + +Tue Mar 17 19:57:49 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/generic/strstr.c, string/string.h, string/tester.c + (strstr): Arguments were reversed. + +Tue Mar 17 18:52:39 1992 Torbjorn Granlund (tege@hal.gnu.ai.mit.edu) + + * sysdeps/i386/memcopy.h (WORD_COPY_BWD): Divide nbytes by 4. + * sysdeps/i386/memchr.c: Rewrite. Handle zero length correctly. + Don't ask gcc to allocate eax to two regs. + +Tue Mar 17 17:31:06 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/unistd.h (getpagesize): Declare as size_t. + + * Makeconfig (CC): Define unless origin is default. + + * stdio/__getdelim.c: Be sure to leave room for the terminating null. + + * string/testcopy.c: New version from tege. + + * malloc/dist-README: Changed mailing list addr to bug-glibc. + + * sysdeps/unix/bsd/__sigproc.c: Use right mask for SIG_UNBLOCK. + + * Makefile, Rules (clean, mostlyclean): Put - before rm commands. + +Tue Mar 17 11:14:40 1992 Torbjorn Granlund (tege@hal.gnu.ai.mit.edu) + + * sysdeps/rs6000/memcopy.h (BYTE_COPY_BWD): Assign __nbytes. + * sysdeps/m68k/memcopy.h (WORD_COPY_BWD): Copy memory, not just + pointers. Clean up switch expression. + +Mon Mar 16 05:09:23 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * posix/wordexp.c: New. + + * time/tzfile.c (__tzfile_read): Don't die if some of the sections + of the datafile are empty. + + * stdio/getline.c, stdio/getdelim.c: Moved to + __getline.c/__getdelim.c. + New files with fn aliases. + * stdio/stdio.h (__getline, __getdelim): Declare. + + * time/Makefile (zonenames): Hair to find the names of zones + described by $(tzfiles). + (install-data): Install zoneinfo/$(zonenames). + Rules to make zones from tzfiles. + [localtime] (zoneinfo/localtime): Make from zoneinfo/$(localtime). + * Makeconfig (localtime): New user-frobbable variable. + +Sun Mar 15 00:01:05 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Makerules (sysdep-Makefile): Do if ... else true to avoid bogus + nonzero status. + + * Makefile: Denewlinify +sysdep-subdirs after including sysd-dirs. + + * sysdeps/vax/__infnan.c [!__GNUC__]: Error. + + * zic.c, scheck.c, emkdir.c, ialloc.c, private.h, tzfile.h: Snarfed + from localtime3 dist. + * time/Makefile (others): Added zic. + (distribute): Added private.h, emkdir.c, ialloc.c, scheck.c. + (install): Defined: zic, zdump. + + * Makeconfig (bindir): Define. + * Makerules: Add rule to install $(install) in $(bindir). + (+install): Include $(install) in $(bindir). + + * sysdeps/unix/Makefile: Moved siglist.c rules to unix/bsd/Makefile. + * sysdeps/unix/make_siglist.c: Moved to bsd/. + * sysdeps/unix/Dist: Remove it. + * sysdeps/unix/bsd/Dist: Add it. + + * malloc/Makefile (malloc/gmalloc.c): Depend on headers and sources. + + * sysdeps/unix/bsd/sun/sun4/__sigvec.S: Doc fix. + + * sysdeps/stub/stty.c, sysdeps/stub/gtty.c: Include <stddef.h>. + + * sysdeps/unix/sysv/__fstat.c: Include sysv_stat.h. + + * misc/bsd-compat.c: Define _BSD_SOURCE rather than __FAVOR_BSD. + (longjmp): Use function_alias_void. + + * time/Makefile (tzfile.o): Compile with + -DTZDIR='"$(datadir)/zoneinfo"'.d + +Sat Mar 14 23:26:46 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Makeconfig (INSTALL_DATA, INSTALL_PROGRAM, INSTALL): Don't define + if already defined. + + * setjmp/longjmp.c: Use function_alias_void. + + * gnu-stabs.h (function_alias_void): New macro. + + * gnu-stabs.h [!HAVE_GNU_LD] (function_alias): Fixed not to loop. + +Fri Mar 13 17:20:19 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Include null + terminator in length calculation. + + * stdio/fgets.c: Be sure to return NULL on error/eof for unbuffered + stream. If N==1, don't write the first char if !seen. + When the buffer is empty, notice the effect of __fillbf after + calling it, avoiding a (costly) no-op iteration. + Don't return NULL for reading no chars; only for EOF or error. + Don't write terminator at beginning of S if eof on first char. + + * malloc/Makefile (libmcheck.a), Makefile (crt0.o): Remove target + first; don't use -f to ln. + + * posix/execl.c, posix/execv.c, sysdeps/posix/getenv.c, + sysdeps/posix/system.c [HAVE_GNU_LD]: #define __environ environ + + * posix/unistd.h [__OPTIMIZE__] (execv): Removed defn. Can't know + whether to use __environ or environ. + + * io/fchown.c, io/chown.c, io/open.c, misc/select.c, + signal/sigvec.c, time/adjtime.c: Fixed DEFUNs in fn aliases. + + * time/__tzset.c: Don't dereference NULL if getenv returns it. + +Thu Mar 12 16:01:33 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/ieee754/sqrt.c: Replaced undefined var ref `k' with constant. + + * sysdeps/i386/__longjmp.c: #include <stdlib.h>. + + * time/tzfile.c (__tzfile_compute): Use types[0] if TIMER falls + between transitions[0] and transitions[1]. + Always set __tzname[INFO->isdst] to the name for INFO. + + * sysdeps/i386/__longjmp.c: Changed register names for gcc; eax/%eax + -> ax. + + * sysdeps/unix/snarf-ioctls: Avoid infinite recursion. + +Wed Mar 11 00:16:18 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * Version 1.01. + + * Makefile (munch-init.c): Made $(objpfx)munch-init.c. + + * signal/sigvec.c, signal/sigaction.c, stdio/vsscanf.c: Fixed DEFUNs + in fn aliases. + + * sysdeps/m68k/68881/68881-switch/switch.c: Merged vars have_fpu and + test_fpu into one. + + * sysdeps/mach/i386/start.c, sysdeps/vax/setjmp.c, + sysdeps/vax/__longjmp.c, sysdeps/vax/__infnan.c, + sysdeps/unix/start.c, sysdeps/unix/bsd/sun/sun4/sigtramp.c, + sysdeps/unix/bsd/sun/sun4/start.c, + sysdeps/unix/bsd/hp9k3bsd/start.c, sysdeps/sparc/sqrt.c, + sysdeps/rs6000/ffs.c, sysdeps/m88k/ffs.c, sysdeps/m68k/setjmp.c, + sysdeps/m68k/__longjmp.c, sysdeps/m68k/68881/printf_fp.c, + sysdeps/m68k/68881/atan2.c, sysdeps/m68k/68881/__logb.c, + sysdeps/m68k/68881/68881-switch/switch.c, sysdeps/m68k/ffs.c, + sysdeps/i386/memset.c, sysdeps/i386/memchr.c, sysdeps/i386/ffs.c, + sysdeps/i386/bzero.c, sysdeps/i386/__longjmp.c, sysdeps/am29k/ffs.c + [! __GNUC__]: Either include the generic (or in some cases, ieee754) + version, or do a #error. + + * Rules: Null out `objects' at end to shrink environment some. + (+objs): Define with := from $(objects). + (clean): Use that instead of $(objects). + + * sysdeps/i386/setjmp.c: Doubled % where it wanted to be literal. + + * posix/getgrps.c, io/flock.c, io/mkdir.c, io/read.c, io/write.c, + io/stat.c, misc/getdents.c, misc/mknod.c, misc/utimes.c: Fixed + DEFUNs in fn aliases. + + * sysdeps/unix/bsd/hp9k3bsd/sysdep.S: Use # instead of kludge cookie. + + * posix/getegid.c: Fixed type in DEFUN. + + * time/tzfile.c (__tzfile_compute): If TIMER is before any + transition in the file, use the first non-DST type, rather than the + type of the first transition in the file. + +Tue Mar 10 20:01:55 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * configure: Take optional -nfp arg. + (news, sun3, hp300): Prepend m68k/68881 unless -nfp is given. + * sysdeps/unix/bsd/hp9k3bsd/Implies: Don't specify 68881. + + * stdio/getdelim.c: When the buffer is empty, notice the effect of + __fillbf after calling it, avoiding a (costly) no-op iteration. + + * sysdeps/vax/__memccpy.c: Fixed comments. + + * stdio/fmemopen.c: Set all fns and seen bit before we might call + something that would care (fclose). + + * configure (sun3, sun-3): Mean sun3os4, not sun3os3. + (sun3os3): Use just unix/bsd/sun/sun3/os3. + * sysdeps/unix/bsd/sun/sun3/os3: New directory. + (sysdeps/unix/bsd/sun/sunos3/__wait.S): Moved to there. + * sysdeps/unix/bsd/sun/sun3/sysdep.h: Fixed; took hp9k3bsd/sysdep.h + and changed movel foo, d0 to pea foo for syscall no. + * sysdeps/unix/bsd/sun/sun3/__brk.S: Fixed pea addr mode. + * sysdeps/unix/bsd/sun/sun3/sethostid.S: errnos.h, not gnu/errno.h. + Use .stabs directly, not gnu-stabs.h (which uses `asm'). + * sysdeps/m68k/setjmp.c: Changed asm for first moveml, so it works + on sun3. + * sysdeps/unix/bsd/sun/sun3/start.c: Removed ../ from #include path. + +Sun Mar 8 16:33:33 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * misc/makefile (headers): Added stab.h, stab.def. + * Many files: Changed __GNU_STAB__ to HAVE_GNU_LD. + +Sat Mar 7 21:21:10 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * time/mktime.c: Normalize the struct values before checking for out + of range values. + +Fri Mar 6 11:43:35 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/ieee754/ldexp.c: New. + + * stdio/internals.c (flushbuf): When priming the stream for writing, + advance the target pos to account for chars gotten from the buffer. + + * sysdeps/generic/Makefile: For math routines, don't filter out + __finite. + + * sysdeps/posix/sysd-stdio.c (__stdio_gen_tempname): Fixed bugs. + + * misc/Makefile (routines): Remove flock. + + * stdlib/strtod.c: Fixed typo in checking for exponent overflow. + Do set *ENDPTR on overflow or underflow. + + * sysdeps/sparc/fl.h: Removed. Should use ieee754 version. + + * sysdeps/generic/Makefile: For math routines, don't filter out + __copysign, __scalb, __drem and __logb; and don't add support. + + * sysdeps/ieee754/__drem.c: New. + * sysdeps/ieee754/sqrt.c: New. + * sysdeps/stub/__drem.c: New. + * sysdeps/stub/sqrt.c: New. + * sysdeps/stub/__logb.c: New. + * sysdeps/ieee754/__logb.c: New. + + * sysdeps/ieee754/__infnan.c: Include <float.h> and use NAN macro + rather than cooking one up by hand. + + * sysdeps/unix/bsd/getlogin.c: Open /dev/tty, rather than using stdin. + Make sure the name is always null-terminated. + +Thu Mar 5 17:11:46 1992 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * sysdeps/m68k/68881/__scalb.c: Removed. + * sysdeps/m68k/68881/__math.h: Removed defn of __scalb. + * math/math.h [__OPTIMIZE__]: Define __scalb to be ldexp. + * math/__scalb.c: New; fn alias for ldexp. + + * stdio/Makefile (tests): Added bug4 and bug5. + * stdio/bug4.c, stdio/bug5.c: Test cases from reported bugs just fixed. + + * stdio/internals.c (flushbuf): If nothing was written by the user, + but there is previously gotten data, don't write anything out. + + * stdio/internals.c (seek_to_target): Call __stdio_check_offset first. + + * sysdeps/unix/sysv/sysv_termio.h: New file. + * sysdeps/unix/sysv/Dist: Include it. + * sysdeps/unix/sysv/tcsetattr.c, sysdeps/unix/sysv/tcsetpgrp.c, + sysdeps/unix/sysv/tcsendbrk.c, sysdeps/unix/sysv/tcgetpgrp.c, + sysdeps/unix/sysv/tcflush.c, sysdeps/unix/sysv/tcdrain.c, + sysdeps/unix/sysv/__tcgetatr.c: New files. + + * stdio/internals.c (fillbuf): Don't set the put_limit on writable + streams. Wait for first write attempt to prime them, so we don't + flush the unchanged data unnecessarily. + + * stdlib/exit.c: Look for NULL terminator on ld set, rather than + using length word. + + * Makefile (headers): Remove stdarg.h and varargs.h. + Users will get them from GCC. + * stdio/printf.h: Include <stdarg.h> to use va_list. + * stdio/stdio.h: Don't include <stdarg.h> with magic. + Use PTR in place of __va_list in prototypes. + * stdio/__vsscanf.c, stdio/vscanf.c, stdio/vfscanf.c, + stdio/__vfscanf.c, stdio/vdprintf.c, stdio/vasprintf.c, + stdio/vsprintf.c, stdio/vsnprintf.c, stdio/vprintf.c, + stdio/vfprintf.c: Fixed DEFUNs. + + * sysdeps/ieee754/ieee754.h: New file; declares union ieee754_double. + * sysdeps/ieee754/Dist: Add it. + * sysdeps/ieee754/__copysign.c, sysdeps/ieee754/__infnan.c, + sysdeps/ieee754/__isinf.c, sysdeps/ieee754/__isnan.c, + sysdeps/ieee754/__printf_fp.c: Use it. + + * sysdeps/unix/sysv/uname.c: New. + * sysdeps/unix/sysv/__utssys.S: New. + * sysdeps/unix/sysv/Makefile (routines): Add __utssys. + * sysdeps/unix/sysv/Dist: Add __utssys.S. + + * sysdeps/unix/sysv/__rmdir.c: New; runs `rmdir' shell command. + + * sysdeps/unix/sysv/__mkdir.c: New; runs `mkdir' shell command. + + * sysdeps/generic/__lstat.c: New; fn alias for __stat. + + * sysdeps/unix/sysv/__gethostname.c: New; uses uname. + + * sysdeps/unix/Makefile (sys/params.h): Protect with + _GNU_SYS_PARAM_H, in case the system's file uses _SYS_PARAM_H itself. + + * stdio/internals.c (__stdio_check_offset): Call init_stream to make + sure we have fns. + + * stdio/fread.c: Don't call __fillbf if the put_limit is past the + beginning of the buffer; only if !seen, no buffer, or pushed back. + + * stdio/fopen.c (__getmode): Set create bit for "a" mode. + + * io/mkdir.c: #undef mkdir before fn alias. + + * time/tzfile.c (__tzfile_compute): Don't decrement I if it's zero. + + * Makefile (crt0.o): Use ln -f. + + * math/Makefile (install): Install libm.a. + (libm.a): Make an empty archive. + +Wed Mar 4 19:54:50 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * README.template: Added note about long filenames in dist. + + * io/Makefile (routines): flock -> __flock + * flock.c: New file, fn alias. + * sysdeps/unix/bsd/flock.S: Renamed to sysdeps/unix/bsd/__flock.S; + made __flock. + * sysdeps/mach/hurd/flock.c: Renamed to sysdeps/mach/hurd/__flock.c; + made __flock. + * sysdeps/stub/flock.c: Renamed to sysdeps/stub/__flock.c; made + __flock. + + * time/time.h (__isleap): Fixed; every 400th year is not a leap + year, not every 1000th. + + * stdio/internals.c (flushbuf): Increment the target position the + amount the user wrote into the buffer, not the amount we wrote out + to the file (which is greater if we read a block and modified it + in the middle). + + * stdio/internals.c (flushbuf): Set get_limit to the beginning of + the buffer for all streams, except when we have just read in a block. + +Sat Feb 29 15:56:22 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * posix/Makefile (others): Removed logname, id. + * time/Makefile (others): Removed date. + + * sysdeps/unix/bsd/sun/sun4/start.c: Make an alias called `start' + (no leading underscore, so it can't conflict with C symbols) for + `_start'. + +Thu Feb 27 14:32:20 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * set-init.c: Look for NULL terminator on set. ld is broken and + doesn't set the length word correctly. + + * setjmp/_longjmp.c, signal/sigaction.c, signal/sigvec.c, + signal/ssignal.c, string/bcmp.c, time/setitmr.c, posix/execve.c, + posix/getegid.c, posix/geteuid.c, posix/getgid.c, posix/getuid.c, + posix/getgrps.c, posix/setuid.c, posix/wait3.c, posix/wait4.c, + posix/waitpid.c, io/lseek.c, io/open.c, io/read.c, io/write.c, + resource/getrusage.c, misc/getpgsz.c, misc/gethstnm.c, + misc/select.c: Fixed DEFUNs in fn aliases. + +Wed Feb 26 00:20:25 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/generic/Makefile (routines): Add asincos. + + * time/tzfile.c (__tzfile_compute): Set __tzname properly, so isdst + is the right index into it. + +Tue Feb 25 01:42:16 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/unix/bsd/sun/sun4/sysdep.h (ENTRY): .align 2, not .align 4. + This one is powers of two. + + * time/__tzset.c: If TZ is :FILE, try FILE and if __tzfile_read + fails, then use defaults. + + * sysdeps/generic/Makefile (routines): Add sincos. + + * sysdeps/posix/cuserid.c: Set the result to the empty string on + failure. + + * string/string.h, string/strings.h, sysdeps/i386/memchr.c: Fixed + spelling in comment. + + * string/makefile (tests): Include (uncomment) testcopy. We do have + papers for it from tege. + + * malloc/dist-README: Fixed mailing list addr. + + * resource/sys/vtimes.h (struct vtimes): Renamed vm_outblk to + vm_oublk; fixed comment. + * sysdeps/generic/vtimes.c: Renamed here too. + + * Make-dist (README): Depend on version.c. + +Tue Feb 18 18:14:50 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Version 1.00. + + * time/tzfile.c (__tzfile_compute): Fixed transition comparison. + + * sysdeps/unix/bsd/sun/sun3/Makefile: Fixed typo. + +Mon Feb 17 05:04:00 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Version 0.6. + + * Makefile (distribute): Add Q+A. + * Q+A: New doc file from rich@cygnus.com. + + * malloc/Makefile (distribute): Add mcheck-init.c. + +Mon Feb 17 00:39:38 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/unix/sysv/utime.c: Removed. + * sysdeps/unix/sysv/utime.S: New file. + + * sysdeps/unix/sysv/signum.h: New file. + + * sysdeps/unix/sysv/local_lim.h: New file. + + * sysdeps/unix/sysv/sysv_stat.h: New file. + * sysdeps/unix/sysv/__stat.c, sysdeps/unix/sysv/__fstat.c: New files. + * sysdeps/unix/sysv/Makefile: New file. + (+sysdep-routines): Define to sys_stat and sys_fstat. + * sysdeps/unix/sysv/sys_stat.S, sysdeps/unix/sysv/sys_fstat.S: New + files. + * sysdeps/unix/sysv/Dist: Created to include sysv_stat.h, + sys_stat.S, and sys_fstat.S. + + * sysdeps/stub/__setreuid.c: Include <sys/types.h>. + + * sysdeps/posix/__sigblock.c: Fixed typo. + + * stdio/internals.c (__flshfp): Don't return EOF if at EOF; only + for errors. + + * signal/gnu/signal.h: Move #include <signum.h> outside repeat #ifdef. + + * sysdeps/unix/sysv/filebits.h: Created. + + * misc/Makefile (distribute): Define to bsd-compat.c. + + * misc/Makefile (headers): Remove filebits.h. + * io/Makefile (headers): Put it here. + + * Makefile (+posix_dirs): Add io. + * io/Makefile: New file for new subdir. + Contains many headers and routines moved from posix. + * posix/Makefile: Remove many headers and routines now in io. + * Moved many files from posix to io. + + * stdlib/alloca.h: Get size_t from stddef.h. + + * misc/bsd-compat.c (getgroups): Removed. Not needed, because gid_t + is now the same size as int. + + * Makefile (distribute): Include NOTES. + * NOTES: New file, infoized node from intro.texinfo about the + feature-test macros. + * README.template: Mention NOTES. + + * sysdeps/unix/bsd/sun/sun3/Makefile: include hp9k3bsd version. + + * Makeconfig: Use $(..) for config.status. + + * configure (i386-sysv): unix/i386/sysv, not unix/sysv/i386. + * unix/i386/sysv/Implies: unix/sysv, not unix/i386. + +Sun Feb 16 00:42:53 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Version 0.5. + + * posix/Makefile (headers): Remove confstr.h. + (distribute): Define this instead to contain it. + + * ansidecl: Added copyright notice. + + * stdio/getdelim.c: New file. + * stdio/getline.c (getsome): Renamed to getdelim and moved there. + * stdio/Makefile (routines): Add getdelim. + * stdio/stdio.h: Declare getdelim. + + * misc/gnu/file.h: Moved to sysdeps/unix/bsd/filebits.h. + * sysdeps/stub/filebits.h: New file. + * misc/Makefile: gnu/file.h is now filebits.h. + * posix/fcntl.h: Changed #include. + + * stdio/getline.c (getsome): If MAX_CANON isn't defined, use a default. + Don't leak old *LINEPTR storage if *N < 2. + Don't bang *LINEPTR to NULL if realloc fails. + + * Makerules: Don't use override when nulling out sources, routines, + and aux if they came from the environment. Better not make with -e. + + * Makefile (sysdirs, Sysnames): Put outside of ifndef sysdirs. + + * string/Makefile (tests): No testcopy, pending papers. + + * Makefile (headers): No sysdep.h. + (distribute): Here instead. + (no-install): No longer needed. + +Sat Feb 15 17:10:38 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Makefile (distribute): Add INSTALL. + * Make-dist (INSTALL): Make from manual/maint.texinfo. + (README): Make from README.template. + + * Makefile (+other-dirs): Removed inet. + * sysdeps/unix/inet/Subdirs: Created, adding inet. + + * sysdeps/unix/sysv/setrlimit.c: Include stddef and errno.h. + + * math/drem.c, setjmp/longjmp.c, malloc/cfree.c, string/bcmp.c, + time/getitmr.c, misc/ioctl.c: Fixed defuns in function_alias. + + * Makefile (headers): Put sysdep.h back. + (no-install): And define this to it. + * Makerules (+install): Filter out $(no-install) from the list. + + * string/testcopy.c: New test program for bcopy from tege. + * string/Makefile (tests): Add it. + + * Makefile (sysdep-subdirs): Renamed to sysd-dirs. + + * Make-dist (tardir): Omit the release name; it made names too long. + +Sat Feb 15 12:53:02 1992 Torbjorn Granlund (tege at mole.gnu.ai.mit.edu) + + * sysdeps/rs6000/memcopy.h (WORD_COPY_FWD, WORD_COPY_BWD): + Use CTR register for looping (speed enhancement). Don't emit + labels, jump relative from `$' instead (makes multiple expansions + possible). Clean up indentation of asm code (were different in each + macro). + * sysdeps/rs6000/memcopy.h (WORD_COPY_BWD): + Add asm output specs (were missing completely). + + * sysdeps/generic/{memcpy.c,memmove.c}: Make DSTP and SRCP unsigned + (safer with non-ANSI compilers). + +Fri Feb 14 01:52:12 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * Version 0.4.1. + + * Makefile, Rules: Changed clean and clobber targets into + mostlyclean, clean, and realclean. + + * Makeconfig: Added comments describing objdir/Makeconfig and + editting Makeconfig. + (prefix, libdir, INSTALL, INSTALL_DATA): New variables for installing. + * Makerules (install): New target. + * Makefile (+subdir_targets): Add subdir_install. + (install): Depend on subdir_install. + (install-lib): Define variable to install libc.a and crt0.o. + * misc/Makefile (install-lib): Install bsd-compat. + * malloc/Makefile (install-lib): Install mcheck-init. + + * Version 0.4. + +Thu Feb 13 21:39:31 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/unix/glue-ctype.c: Moved to unix/bsd. + * sysdeps/unix/Makefile: Moved glue-ctype stuff to unix/bsd/Makefile. + * sysdeps/unix/Dist: No glue-ctype. + * sysdeps/unix/bsd/Dist: Here instead. + + * sysdeps/sparc/divrem.m4: Don't use insn aliases Sun as doesn't grok. + +Wed Feb 12 12:12:12 1992 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * sysdeps/m68k/setjmp.c: Use m, rather than g, constraint when + saving fp regs. + + * Renamed oodles of files, changed all the relevant Makefiles (I + think). File names now fit in 14 chars for losing System V. Gag me + with a death star. + See =longnames for translations, and =shorten.el for method. + + * grp/initgroups.c: Removed redundant test. + + * malloc/mtrace.c: Use %p fmt for pointers. + +Tue Feb 11 02:04:39 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/alloca.h: New file. + * stdlib/stdlib.h: Moved alloca decls there; #include <alloca.h> + instead. + * stdlib/Makefile (headers): Added alloca.h. + + * stdio/getline.c (getsome): Fixed bugs. + + * math/bsd/common_source/mathimpl.h: #define expm1 __expm1. + * math/bsd/common_source/expm1.c: Renamed to __expm1.c + * math/bsd/mc68881/expm1.s: Renamed to __expm1.s; renamed fn too. + * math/expm1.c: New file, fn alias expm1 -> __expm1. + + * math/Makefile (routines): Add __rint. + * math/rint.c: New file, fn alias rint -> __rint. + * math/bsd/common_source/floor.c (rint): Renamed to __rint. + * sysdeps/generic/Makefile: Remove __rint, not rint. + + * math/Makefile (BSDmath-files): Always include it, and don't depend + on undependable things. + + * Makerules (sysdep-Makefile): Always include it, and make it + without depending on make vars that might not be right yet. + +Mon Feb 10 00:55:58 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdlib/stdlib.h: #undef alloca before declaring it. + + * sysdeps/sparc/__longjmp.S: Use be instead of bz. + + * sysdeps/unix/bsd/Dist: Add bsdtty.h. + + * tzfile.c (__tzfile_read): Don't allocate space for 0 leaps. + Don't loop infinitely. + + * sysdeps/unix/Makefile (make-errnos.c): Use tr to eat newlines in + errnos file. + + * sysdeps/unix/bsd/sun/sun4/__brk.S: Fix andn arg order. + + * posix/Makefile: Don't get getopt by vpath. Turns out to be too + much hassle for dist. Just made symlinks in posix/ instead. + + * manual/Makefile: Renamed summary.out to summary.texinfo. + + * manual/summary.awk: New file, to make summary.out. + Replaces `process-definitions.el'. + * manual/Makefile (summary.out): Create using summary.awk. + + * manual/Makefile: Created. + * Makefile, Make-dist: Use it to format and distribute the manual. + +Mon Feb 10 00:32:17 1992 Jim Meyering (meyering@churchy.gnu.ai.mit.edu) + + * All Makefiles: + Whenever using shell redirection to create a target, + do not create the target directly like this + + foo: bar + process $< > $@ + + That loses when `process' fails (interrupt, disk full, ...) + and bar exists and looks up-to-date, but isn't. + This sort of failure is particularly insidious when + the initial error message is obscured by lots of subsequent + output (echoed commands etc). + + Instead use rules like this + + foo: bar + process $< > $@-tmp + mv $@-tmp $@ + + Using this paradigm, as long as process returns non-zero + whenever it fails, the target won't be touched. + +Sun Feb 9 22:58:51 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/unistd.h (getopt): Fixed prototype. + * sysdeps/generic/memset.c, stdio/vdprintf.c: Fixed DEFUNs. + + * Makerules (lib): Use $(RANLIB) for ranlib. + * Makeconfig: Define it. + + * configure: Create config.status to set ARCH, if successful. + * Makeconfig: include config.status ifndef ARCH. + +Thu Feb 6 20:57:10 1992 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * ansidecl.h (INCLUDE, STARTCOMMENT, ENDCOMMENT): New magic words. + * sysdeps/m68k/68881/fl.h: Use new magic to snarf ieee754/fl.h during + ansideclification. + + * sysdeps/ieee754/fl.h: New file, taken mostly from the old + 68881 file. HUGE_VAL redone to be machine independent. + (NAN): New macro for an IEEE NaN, done like HUGE_VAL. + * sysdeps/m68k/68881/fl.h: Now #includes ieee754/fl.h, and overrides + FLT_ROUNDS for 68881 magic. NB: the #include is a prob. for install. + +Wed Jan 29 17:11:25 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/posix/getcwd.c: Don't use chdir; use a long ../../../... + path name instead. + +Fri Jan 17 02:51:10 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * posix/Makefile (headers): Added getopt.h. + (routines): Added getopt1. + Get getopt* from /home/gd/gnu/lib by vpath. + + * Makerules (+ansideclificate): Don't assume . is in PATH. + +Thu Jan 16 18:43:05 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * posix/glob.c [sgi]: No alloca.h, after all. + +Wed Jan 15 14:17:37 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * termios/termios.h: Reworked to be compatible with 4.4BSD. + * termios/speed.c, sysdeps/unix/bsd/{__tcgetattr,tcsetattr}.c: Store + speeds as their own values (B9600==9600, etc.) and translate to BSD + values only for ioctl. + * termios/cfsetpseed.c: New fn to set both speeds at once (from 4.4). + +Tue Jan 14 21:18:10 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/unix/i386/__brk.S: __end, not ___end. + Get the arg off the stack correctly. + + * sysdeps/unix/Makefile: Allow errnos like EL3HLT. + + * sysdeps/posix/{readv,writev}.c: Typos. + + * sysdeps/posix/__sigpause.c: Rewritten to know that sigset_t is a + mask, and to pass a (sigset_t *) instead of sigset_t to sigsuspend. + + * sysdeps/i386/memset.c: Include <memcopy.h>. + + * sysdeps/generic/uname.c (uname): Save and restore errno if + gethostname gets ENOSYS. + + * stdio/perror.c (perror): Check correctly for S == "". + Check correctly for ERRNUM being in range. + + * find-sysdirs: Don't use fgrep -s, since USG apparently doesn't + have that flag. Just >/dev/null instead. + +Mon Jan 13 17:00:15 1992 Torbjorn Granlund (tege at mole.gnu.ai.mit.edu) + + * sysdeps/generic/wordcopy.c (all four functions): Move do0 label to + the ultimate store statement at the end of each function. (Used to + be in the loop.) + +Tue Jan 7 18:40:18 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * resource/sys/resource.h (struct rusage): Change `ru_outblock' to + `ru_oublock'. + + * sysdeps/generic/stpcpy.c: Fixed off-by-one bug. + +Thu Jan 2 15:19:01 1992 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * sysdeps/sparc/Dist: Add umul.S and mul.S. + +Tue Dec 31 15:33:39 1991 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * signal/signal.h [__USE_GNU]: Add user-visible `sighandler_t' == + __sighandler_t. + + * termios/speed.c (speedtab): Made const. + + * posix/Makefile (routines): Add flock. + +Tue Dec 31 03:38:30 1991 Richard Stallman (rms at mole.gnu.ai.mit.edu) + + * termios/speed.c: Accept and return speeds as actual baud rates. + * termios/termios.h (B110, etc.): Define B110 as 110, etc. + Likewise for _B110, etc. + +Thu Oct 24 16:19:49 1991 Roland McGrath (roland@wookumz.gnu.ai.mit.edu) + + * ansidecl: Put `M4OPTS=+quiet' in the environment make GNU m4 quiet. + +Sun Oct 20 19:31:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Make-dist (tardir): Define as `libc-RELEASE-VERSION', strings + snarfed from version.c. + ($(..)$(tardir)): Add rule to make as symlink to . (parent dir). + [subdir] (dist), [parent] (dist.tar): Depend on that. + [subdir] (tarsources), [parent] (+tsrcs): Add $(tardir)/ to files. + + * sysdeps/sparc/Makefile (distribute): Move data into Dist file. + +Fri Oct 18 15:27:58 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile (subdirs): Add $(sysdep-subdirs), so sysdep makefiles can + add subdirs. + + * posix/glob.c [sgi]: Use <sys/dir.h>. + + * stdio/fopen.c: If not appending, initialize the offset to 0. + + * sysdeps/generic/strcasecmp.c: Fixed losing braindead code. + +Tue Oct 8 15:27:54 1991 Roland McGrath (roland@albert.gnu.ai.mit.edu) + + * Version 0.1. + * This ChangeLog is lacking much information. + * After this release, I hope to maintain the log well. + +Fri Jul 26 18:02:57 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/Makefile (routines): Remove _cleanup. + +Thu Jul 25 23:12:45 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * stdio/memstream.c (close_memstream): Removed. + (trim_buffer): New fn to be io_funcs->__close for memstreams. + (open_memstream): Take arg char **BUFLOC. Stuff it in + stream->__fd, and store the location of the initial buffer in + *BUFLOC. + (enlarge_buffer): Keep *(char **) stream->__fd updated to be the + location of the buffer. + +Tue Jul 23 14:11:29 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * posix/glob.c: Don't #include <stddef.h> #ifdef sun. + Is there anyone on the face of the planet other than me capable of + implementing the ANSI C standard to spec???? + + * posix/glob.c [DIRENT]: #include <sys/types.h> before <dirent.h> + #ifdef USG. + +Mon Jul 22 17:06:24 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * sysdeps/posix/make-stdio_limits.c: #include <posix1_limits.h>, + not <posix_limits.h>. + + * README: Refer to COPYING.LIB, not COPYING. + + * config.libc: Renamed to `configure'. + +Local Variables: +mode: change-log +End: diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..1476bd8246 --- /dev/null +++ b/INSTALL @@ -0,0 +1,832 @@ +Library Maintenance +******************* + +How to Install the GNU C Library +================================ + + Installation of the GNU C library is relatively simple. + + You need the latest version of GNU `make'. Modifying the GNU C +Library to work with other `make' programs would be so hard that we +recommend you port GNU `make' instead. *Really.* + + To configure the GNU C library for your system, run the shell script +`configure' with `sh'. Use an argument which is the conventional GNU +name for your system configuration--for example, `sparc-sun-sunos4.1', +for a Sun 4 running Sunos 4.1. *Note Installation: +(gcc.info)Installation, for a full description of standard GNU +configuration names. If you omit the configuration name, `configure' +will try to guess one for you by inspecting the system it is running +on. It may or may not be able to come up with a guess, and the its +guess might be wrong. `configure' will tell you the canonical name of +the chosen configuration before proceeding. + + The GNU C Library currently supports configurations that match the +following patterns: + + alpha-dec-osf1 + i386-ANYTHING-bsd4.3 + i386-ANYTHING-gnu + i386-ANYTHING-isc2.2 + i386-ANYTHING-isc3.N + i386-ANYTHING-sco3.2 + i386-ANYTHING-sco3.2v4 + i386-ANYTHING-sysv + i386-ANYTHING-sysv4 + i386-force_cpu386-none + i386-sequent-bsd + i960-nindy960-none + m68k-hp-bsd4.3 + m68k-mvme135-none + m68k-mvme136-none + m68k-sony-newsos3 + m68k-sony-newsos4 + m68k-sun-sunos4.N + mips-dec-ultrix4.N + mips-sgi-irix4.N + sparc-sun-solaris2.N + sparc-sun-sunos4.N + + While no other configurations are supported, there are handy aliases +for these few. (These aliases work in other GNU software as well.) + + decstation + hp320-bsd4.3 hp300bsd + i386-sco + i386-sco3.2v4 + i386-sequent-dynix + i386-svr4 + news + sun3-sunos4.N sun3 + sun4-solaris2.N sun4-sunos5.N + sun4-sunos4.N sun4 + + Here are some options that you should specify (if appropriate) when +you run `configure': + +`--with-gnu-ld' + Use this option if you plan to use GNU `ld' to link programs with + the GNU C Library. (We strongly recommend that you do.) This + option enables use of features that exist only in GNU `ld'; so if + you configure for GNU `ld' you must use GNU `ld' *every time* you + link with the GNU C Library, and when building it. + +`--with-gnu-as' + Use this option if you plan to use the GNU assembler, `gas', when + building the GNU C Library. On some systems, the library may not + build properly if you do *not* use `gas'. + +`--nfp' + Use this option if your computer lacks hardware floating point + support. + +`--prefix=DIRECTORY' + Install machine-independent data files in subdirectories of + `DIRECTORY'. (You can also set this in `configparms'; see below.) + +`--exec-prefix=DIRECTORY' + Install the library and other machine-dependent files in + subdirectories of `DIRECTORY'. (You can also set this in + `configparms'; see below.) + + The simplest way to run `configure' is to do it in the directory +that contains the library sources. This prepares to build the library +in that very directory. + + You can prepare to build the library in some other directory by going +to that other directory to run `configure'. In order to run configure, +you will have to specify a directory for it, like this: + + mkdir sun4 + cd sun4 + ../configure sparc-sun-sunos4.1 + +`configure' looks for the sources in whatever directory you specified +for finding `configure' itself. It does not matter where in the file +system the source and build directories are--as long as you specify the +source directory when you run `configure', you will get the proper +results. + + This feature lets you keep sources and binaries in different +directories, and that makes it easy to build the library for several +different machines from the same set of sources. Simply create a build +directory for each target machine, and run `configure' in that +directory specifying the target machine's configuration name. + + The library has a number of special-purpose configuration parameters. +These are defined in the file `Makeconfig'; see the comments in that +file for the details. + + But don't edit the file `Makeconfig' yourself--instead, create a +file `configparms' in the directory where you are building the library, +and define in that file the parameters you want to specify. +`configparms' should *not* be an edited copy of `Makeconfig'; specify +only the parameters that you want to override. To see how to set these +parameters, find the section of `Makeconfig' that says "These are the +configuration variables." Then for each parameter that you want to +change, copy the definition from `Makeconfig' to your new `configparms' +file, and change the value as appropriate for your system. + + It is easy to configure the GNU C library for cross-compilation by +setting a few variables in `configparms'. Set `CC' to the +cross-compiler for the target you configured the library for; it is +important to use this same `CC' value when running `configure', like +this: `CC=TARGET-gcc configure TARGET'. Set `BUILD_CC' to the compiler +to use for for programs run on the build system as part of compiling +the library. You may need to set `AR' and `RANLIB' to cross-compiling +versions of `ar' and `ranlib' if the native tools are not configured to +work with object files for the target you configured for. + + Some of the machine-dependent code for some machines uses extensions +in the GNU C compiler, so you may need to compile the library with GCC. +(In fact, all of the existing complete ports require GCC.) + + The current release of the C library contains some header files that +the compiler normally provides: `stddef.h', `stdarg.h', and several +files with names of the form `va-MACHINE.h'. The versions of these +files that came with older releases of GCC do not work properly with +the GNU C library. The `stddef.h' file in release 2.2 and later of GCC +is correct. If you have release 2.2 or later of GCC, use its version +of `stddef.h' instead of the C library's. To do this, put the line +`override stddef.h =' in `configparms'. The other files are corrected +in release 2.3 and later of GCC. `configure' will automatically detect +whether the installed `stdarg.h' and `va-MACHINE.h' files are +compatible with the C library, and use its own if not. + + There is a potential problem with the `size_t' type and versions of +GCC prior to release 2.4. ANSI C requires that `size_t' always be an +unsigned type. For compatibility with existing systems' header files, +GCC defines `size_t' in `stddef.h' to be whatever type the system's +`sys/types.h' defines it to be. Most Unix systems that define `size_t' +in `sys/types.h', define it to be a signed type. Some code in the +library depends on `size_t' being an unsigned type, and will not work +correctly if it is signed. + + The GNU C library code which expects `size_t' to be unsigned is +correct. The definition of `size_t' as a signed type is incorrect. +Versions 2.4 and later of GCC always define `size_t' as an unsigned +type, and GCC's `fixincludes' script massages the system's +`sys/types.h' so as not to conflict with this. + + In the meantime, we work around this problem by telling GCC +explicitly to use an unsigned type for `size_t' when compiling the GNU C +library. `configure' will automatically detect what type GCC uses for +`size_t' arrange to override it if necessary. + + To build the library, type `make lib'. This will produce a lot of +output, some of which looks like errors from `make' (but isn't). Look +for error messages from `make' containing `***'. Those indicate that +something is really wrong. + + To build and run some test programs which exercise some of the +library facilities, type `make tests'. This will produce several files +with names like `PROGRAM.out'. + + To format the `GNU C Library Reference Manual' for printing, type +`make dvi'. To format the Info version of the manual for on line +reading with `C-h i' in Emacs or with the `info' program, type +`make info'. + + To install the library and its header files, and the Info files of +the manual, type `make install', after setting the installation +directories in `configparms'. This will build things if necessary, +before installing them. + +Reporting Bugs +============== + + There are probably bugs in the GNU C library. There are certainly +errors and omissions in this manual. If you report them, they will get +fixed. If you don't, no one will ever know about them and they will +remain unfixed for all eternity, if not longer. + + To report a bug, first you must find it. Hopefully, this will be the +hard part. Once you've found a bug, make sure it's really a bug. A +good way to do this is to see if the GNU C library behaves the same way +some other C library does. If so, probably you are wrong and the +libraries are right (but not necessarily). If not, one of the libraries +is probably wrong. + + Once you're sure you've found a bug, try to narrow it down to the +smallest test case that reproduces the problem. In the case of a C +library, you really only need to narrow it down to one library function +call, if possible. This should not be too difficult. + + The final step when you have a simple test case is to report the bug. +When reporting a bug, send your test case, the results you got, the +results you expected, what you think the problem might be (if you've +thought of anything), your system type, and the version of the GNU C +library which you are using. Also include the files `config.status' +and `config.make' which are created by running `configure'; they will +be in whatever directory was current when you ran `configure'. + + If you think you have found some way in which the GNU C library does +not conform to the ANSI and POSIX standards (*note Standards and +Portability::.), that is definitely a bug. Report it! + + Send bug reports to the Internet address `bug-glibc@prep.ai.mit.edu' +or the UUCP path `mit-eddie!prep.ai.mit.edu!bug-glibc'. If you have +other problems with installation or use, please report those as well. + + If you are not sure how a function should behave, and this manual +doesn't tell you, that's a bug in the manual. Report that too! If the +function's behavior disagrees with the manual, then either the library +or the manual has a bug, so report the disagreement. If you find any +errors or omissions in this manual, please report them to the Internet +address `bug-glibc-manual@prep.ai.mit.edu' or the UUCP path +`mit-eddie!prep.ai.mit.edu!bug-glibc-manual'. + +Adding New Functions +==================== + + The process of building the library is driven by the makefiles, which +make heavy use of special features of GNU `make'. The makefiles are +very complex, and you probably don't want to try to understand them. +But what they do is fairly straightforward, and only requires that you +define a few variables in the right places. + + The library sources are divided into subdirectories, grouped by +topic. The `string' subdirectory has all the string-manipulation +functions, `stdio' has all the standard I/O functions, etc. + + Each subdirectory contains a simple makefile, called `Makefile', +which defines a few `make' variables and then includes the global +makefile `Rules' with a line like: + + include ../Rules + +The basic variables that a subdirectory makefile defines are: + +`subdir' + The name of the subdirectory, for example `stdio'. This variable + *must* be defined. + +`headers' + The names of the header files in this section of the library, such + as `stdio.h'. + +`routines' +`aux' + The names of the modules (source files) in this section of the + library. These should be simple names, such as `strlen' (rather + than complete file names, such as `strlen.c'). Use `routines' for + modules that define functions in the library, and `aux' for + auxiliary modules containing things like data definitions. But the + values of `routines' and `aux' are just concatenated, so there + really is no practical difference. + +`tests' + The names of test programs for this section of the library. These + should be simple names, such as `tester' (rather than complete file + names, such as `tester.c'). `make tests' will build and run all + the test programs. If a test program needs input, put the test + data in a file called `TEST-PROGRAM.input'; it will be given to + the test program on its standard input. If a test program wants + to be run with arguments, put the arguments (all on a single line) + in a file called `TEST-PROGRAM.args'. + +`others' + The names of "other" programs associated with this section of the + library. These are programs which are not tests per se, but are + other small programs included with the library. They are built by + `make others'. + +`install-lib' +`install-data' +`install' + Files to be installed by `make install'. Files listed in + `install-lib' are installed in the directory specified by `libdir' + in `configparms' or `Makeconfig' (*note Installation::.). Files + listed in `install-data' are installed in the directory specified + by `datadir' in `configparms' or `Makeconfig'. Files listed in + `install' are installed in the directory specified by `bindir' in + `configparms' or `Makeconfig'. + +`distribute' + Other files from this subdirectory which should be put into a + distribution tar file. You need not list here the makefile itself + or the source and header files listed in the other standard + variables. Only define `distribute' if there are files used in an + unusual way that should go into the distribution. + +`generated' + Files which are generated by `Makefile' in this subdirectory. + These files will be removed by `make clean', and they will never + go into a distribution. + +`extra-objs' + Extra object files which are built by `Makefile' in this + subdirectory. This should be a list of file names like `foo.o'; + the files will actually be found in whatever directory object + files are being built in. These files will be removed by + `make clean'. This variable is used for secondary object files + needed to build `others' or `tests'. + +Porting the GNU C Library +========================= + + The GNU C library is written to be easily portable to a variety of +machines and operating systems. Machine- and operating system-dependent +functions are well separated to make it easy to add implementations for +new machines or operating systems. This section describes the layout of +the library source tree and explains the mechanisms used to select +machine-dependent code to use. + + All the machine-dependent and operating system-dependent files in the +library are in the subdirectory `sysdeps' under the top-level library +source directory. This directory contains a hierarchy of +subdirectories (*note Hierarchy Conventions::.). + + Each subdirectory of `sysdeps' contains source files for a +particular machine or operating system, or for a class of machine or +operating system (for example, systems by a particular vendor, or all +machines that use IEEE 754 floating-point format). A configuration +specifies an ordered list of these subdirectories. Each subdirectory +implicitly appends its parent directory to the list. For example, +specifying the list `unix/bsd/vax' is equivalent to specifying the list +`unix/bsd/vax unix/bsd unix'. A subdirectory can also specify that it +implies other subdirectories which are not directly above it in the +directory hierarchy. If the file `Implies' exists in a subdirectory, +it lists other subdirectories of `sysdeps' which are appended to the +list, appearing after the subdirectory containing the `Implies' file. +Lines in an `Implies' file that begin with a `#' character are ignored +as comments. For example, `unix/bsd/Implies' contains: + # BSD has Internet-related things. + unix/inet + +and `unix/Implies' contains: + posix + +So the final list is `unix/bsd/vax unix/bsd unix/inet unix posix'. + + `sysdeps' has two "special" subdirectories, called `generic' and +`stub'. These two are always implicitly appended to the list of +subdirectories (in that order), so you needn't put them in an `Implies' +file, and you should not create any subdirectories under them. +`generic' is for things that can be implemented in machine-independent +C, using only other machine-independent functions in the C library. +`stub' is for "stub" versions of functions which cannot be implemented +on a particular machine or operating system. The stub functions always +return an error, and set `errno' to `ENOSYS' (Function not +implemented). *Note Error Reporting::. + + A source file is known to be system-dependent by its having a +version in `generic' or `stub'; every system-dependent function should +have either a generic or stub implementation (there is no point in +having both). + + If you come across a file that is in one of the main source +directories (`string', `stdio', etc.), and you want to write a machine- +or operating system-dependent version of it, move the file into +`sysdeps/generic' and write your new implementation in the appropriate +system-specific subdirectory. Note that if a file is to be +system-dependent, it *must not* appear in one of the main source +directories. + + There are a few special files that may exist in each subdirectory of +`sysdeps': + +`Makefile' + A makefile for this machine or operating system, or class of + machine or operating system. This file is included by the library + makefile `Makerules', which is used by the top-level makefile and + the subdirectory makefiles. It can change the variables set in the + including makefile or add new rules. It can use GNU `make' + conditional directives based on the variable `subdir' (see above) + to select different sets of variables and rules for different + sections of the library. It can also set the `make' variable + `sysdep-routines', to specify extra modules to be included in the + library. You should use `sysdep-routines' rather than adding + modules to `routines' because the latter is used in determining + what to distribute for each subdirectory of the main source tree. + + Each makefile in a subdirectory in the ordered list of + subdirectories to be searched is included in order. Since several + system-dependent makefiles may be included, each should append to + `sysdep-routines' rather than simply setting it: + + sysdep-routines := $(sysdep-routines) foo bar + +`Subdirs' + This file contains the names of new whole subdirectories under the + top-level library source tree that should be included for this + system. These subdirectories are treated just like the + system-independent subdirectories in the library source tree, such + as `stdio' and `math'. + + Use this when there are completely new sets of functions and header + files that should go into the library for the system this + subdirectory of `sysdeps' implements. For example, + `sysdeps/unix/inet/Subdirs' contains `inet'; the `inet' directory + contains various network-oriented operations which only make sense + to put in the library on systems that support the Internet. + +`Dist' + This file contains the names of files (relative to the + subdirectory of `sysdeps' in which it appears) which should be + included in the distribution. List any new files used by rules in + the `Makefile' in the same directory, or header files used by the + source files in that directory. You don't need to list files that + are implementations (either C or assembly source) of routines + whose names are given in the machine-independent makefiles in the + main source tree. + +`configure' + This file is a shell script fragment to be run at configuration + time. The top-level `configure' script uses the shell `.' command + to read the `configure' file in each system-dependent directory + chosen, in order. The `configure' files are often generated from + `configure.in' files using Autoconf. + + A system-dependent `configure' script will usually add things to + the shell variables `DEFS' and `config_vars'; see the top-level + `configure' script for details. The script can check for + `--with-PACKAGE' options that were passed to the top-level + `configure'. For an option `--with-PACKAGE=VALUE' `configure' + sets the shell variable `with_PACKAGE' (with any dashes in PACKAGE + converted to underscores) to VALUE; if the option is just + `--with-PACKAGE' (no argument), then it sets `with_PACKAGE' to + `yes'. + +`configure.in' + This file is an Autoconf input fragment to be processed into the + file `configure' in this subdirectory. *Note Introduction: + (autoconf.info)Introduction, for a description of Autoconf. You + should write either `configure' or `configure.in', but not both. + The first line of `configure.in' should invoke the `m4' macro + `GLIBC_PROVIDES'. This macro does several `AC_PROVIDE' calls for + Autoconf macros which are used by the top-level `configure' + script; without this, those macros might be invoked again + unnecessarily by Autoconf. + + That is the general system for how system-dependencies are isolated. + +Layout of the `sysdeps' Directory Hierarchy +------------------------------------------- + + A GNU configuration name has three parts: the CPU type, the +manufacturer's name, and the operating system. `configure' uses these +to pick the list of system-dependent directories to look for. If the +`--nfp' option is *not* passed to `configure', the directory +`MACHINE/fpu' is also used. The operating system often has a "base +operating system"; for example, if the operating system is `sunos4.1', +the base operating system is `unix/bsd'. The algorithm used to pick +the list of directories is simple: `configure' makes a list of the base +operating system, manufacturer, CPU type, and operating system, in that +order. It then concatenates all these together with slashes in +between, to produce a directory name; for example, the configuration +`sparc-sun-sunos4.1' results in `unix/bsd/sun/sparc/sunos4.1'. +`configure' then tries removing each element of the list in turn, so +`unix/bsd/sparc' and `sun/sparc' are also tried, among others. Since +the precise version number of the operating system is often not +important, and it would be very inconvenient, for example, to have +identical `sunos4.1.1' and `sunos4.1.2' directories, `configure' tries +successively less specific operating system names by removing trailing +suffixes starting with a period. + + As an example, here is the complete list of directories that would be +tried for the configuration `sparc-sun-sunos4.1' (without the `--nfp' +option): + + sparc/fpu + unix/bsd/sun/sunos4.1/sparc + unix/bsd/sun/sunos4.1 + unix/bsd/sun/sunos4/sparc + unix/bsd/sun/sunos4 + unix/bsd/sun/sunos/sparc + unix/bsd/sun/sunos + unix/bsd/sun/sparc + unix/bsd/sun + unix/bsd/sunos4.1/sparc + unix/bsd/sunos4.1 + unix/bsd/sunos4/sparc + unix/bsd/sunos4 + unix/bsd/sunos/sparc + unix/bsd/sunos + unix/bsd/sparc + unix/bsd + unix/sun/sunos4.1/sparc + unix/sun/sunos4.1 + unix/sun/sunos4/sparc + unix/sun/sunos4 + unix/sun/sunos/sparc + unix/sun/sunos + unix/sun/sparc + unix/sun + unix/sunos4.1/sparc + unix/sunos4.1 + unix/sunos4/sparc + unix/sunos4 + unix/sunos/sparc + unix/sunos + unix/sparc + unix + sun/sunos4.1/sparc + sun/sunos4.1 + sun/sunos4/sparc + sun/sunos4 + sun/sunos/sparc + sun/sunos + sun/sparc + sun + sunos4.1/sparc + sunos4.1 + sunos4/sparc + sunos4 + sunos/sparc + sunos + sparc + + Different machine architectures are conventionally subdirectories at +the top level of the `sysdeps' directory tree. For example, +`sysdeps/sparc' and `sysdeps/m68k'. These contain files specific to +those machine architectures, but not specific to any particular +operating system. There might be subdirectories for specializations of +those architectures, such as `sysdeps/m68k/68020'. Code which is +specific to the floating-point coprocessor used with a particular +machine should go in `sysdeps/MACHINE/fpu'. + + There are a few directories at the top level of the `sysdeps' +hierarchy that are not for particular machine architectures. + +`generic' +`stub' + As described above (*note Porting::.), these are the two + subdirectories that every configuration implicitly uses after all + others. + +`ieee754' + This directory is for code using the IEEE 754 floating-point + format, where the C type `float' is IEEE 754 single-precision + format, and `double' is IEEE 754 double-precision format. Usually + this directory is referred to in the `Implies' file in a machine + architecture-specific directory, such as `m68k/Implies'. + +`posix' + This directory contains implementations of things in the library in + terms of POSIX.1 functions. This includes some of the POSIX.1 + functions themselves. Of course, POSIX.1 cannot be completely + implemented in terms of itself, so a configuration using just + `posix' cannot be complete. + +`unix' + This is the directory for Unix-like things. *Note Porting to + Unix::. `unix' implies `posix'. There are some special-purpose + subdirectories of `unix': + + `unix/common' + This directory is for things common to both BSD and System V + release 4. Both `unix/bsd' and `unix/sysv/sysv4' imply + `unix/common'. + + `unix/inet' + This directory is for `socket' and related functions on Unix + systems. The `inet' top-level subdirectory is enabled by + `unix/inet/Subdirs'. `unix/common' implies `unix/inet'. + +`mach' + This is the directory for things based on the Mach microkernel + from CMU (including the GNU operating system). Other basic + operating systems (VMS, for example) would have their own + directories at the top level of the `sysdeps' hierarchy, parallel + to `unix' and `mach'. + +Porting the GNU C Library to Unix Systems +----------------------------------------- + + Most Unix systems are fundamentally very similar. There are +variations between different machines, and variations in what +facilities are provided by the kernel. But the interface to the +operating system facilities is, for the most part, pretty uniform and +simple. + + The code for Unix systems is in the directory `unix', at the top +level of the `sysdeps' hierarchy. This directory contains +subdirectories (and subdirectory trees) for various Unix variants. + + The functions which are system calls in most Unix systems are +implemented in assembly code in files in `sysdeps/unix'. These files +are named with a suffix of `.S'; for example, `__open.S'. Files ending +in `.S' are run through the C preprocessor before being fed to the +assembler. + + These files all use a set of macros that should be defined in +`sysdep.h'. The `sysdep.h' file in `sysdeps/unix' partially defines +them; a `sysdep.h' file in another directory must finish defining them +for the particular machine and operating system variant. See +`sysdeps/unix/sysdep.h' and the machine-specific `sysdep.h' +implementations to see what these macros are and what they should do. + + The system-specific makefile for the `unix' directory (that is, the +file `sysdeps/unix/Makefile') gives rules to generate several files +from the Unix system you are building the library on (which is assumed +to be the target system you are building the library *for*). All the +generated files are put in the directory where the object files are +kept; they should not affect the source tree itself. The files +generated are `ioctls.h', `errnos.h', `sys/param.h', and `errlist.c' +(for the `stdio' section of the library). + +Contributors to the GNU C Library +================================= + + The GNU C library was written almost entirely by Roland McGrath, who +now maintains it. Some parts of the library were contributed or worked +on by other people. + + * The `getopt' function and related code were written by Richard + Stallman, David J. MacKenzie, and Roland McGrath. + + * Most of the math functions are taken from 4.4 BSD; they have been + modified only slightly to work with the GNU C library. The + Internet-related code (most of the `inet' subdirectory) and several + other miscellaneous functions and header files have been included + with little or no modification. + + All code incorporated from 4.4 BSD is under the following + copyright: + + Copyright (C) 1991 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. + + * The random number generation functions `random', `srandom', + `setstate' and `initstate', which are also the basis for the + `rand' and `srand' functions, were written by Earl T. Cohen for + the University of California at Berkeley and are copyrighted by the + Regents of the University of California. They have undergone minor + changes to fit into the GNU C library and to fit the ANSI C + standard, but the functional code is Berkeley's. + + * The merge sort function `qsort' was written by Michael J. Haertel. + + * The quick sort function used as a fallback by `qsort' was written + by Douglas C. Schmidt. + + * The memory allocation functions `malloc', `realloc' and `free' and + related code were written by Michael J. Haertel. + + * Fast implementations of many of the string functions (`memcpy', + `strlen', etc.) were written by Torbjorn Granlund. + + * Some of the support code for Mach is taken from Mach 3.0 by CMU, + and is under the following copyright terms: + + Mach Operating System + Copyright (C) 1991,1990,1989 Carnegie Mellon University + All Rights Reserved. + + Permission to use, copy, modify and distribute this software + and its documentation is hereby granted, provided that both + the copyright notice and this permission notice appear in all + copies of the software, derivative works or modified + versions, and any portions thereof, and that both notices + appear in supporting documentation. + + CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS + IS" CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF + ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + THIS SOFTWARE. + + Carnegie Mellon requests users of this software to return to + + Software Distribution Coordinator + School of Computer Science + Carnegie Mellon University + Pittsburgh PA 15213-3890 + + or `Software.Distribution@CS.CMU.EDU' any improvements or + extensions that they make and grant Carnegie Mellon the + rights to redistribute these changes. + + * The `tar.h' header file was written by David J. MacKenzie. + + * The port to the MIPS DECStation running Ultrix 4 + (`mips-dec-ultrix4') was contributed by Brendan Kehoe and Ian + Lance Taylor. + + * The DES encryption function `crypt' and related functions were + contributed by Michael Glad. + + * The `ftw' function was contributed by Ian Lance Taylor. + + * The code to support SunOS shared libraries was contributed by Tom + Quinn. + + * The `mktime' function was contributed by Noel Cragg. + + * The port to the Sequent Symmetry running Dynix version 3 + (`i386-sequent-bsd') was contributed by Jason Merrill. + + * The timezone support code is derived from the public-domain + timezone package by Arthur David Olson. + + * The Internet resolver code is taken directly from BIND 4.9.1, + which is under both the Berkeley copyright above and also: + + 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. + + * The port to the DEC Alpha running OSF/1 (`alpha-dec-osf1') was + contributed by Brendan Kehoe, using some code written by Roland + McGrath. + + * The floating-point printing function used by `printf' and friends + was written by Roland McGrath and Torbjorn Granlund. The + multi-precision integer functions used in that function are taken + from GNU MP, which was contributed by Torbjorn Granlund. + + * The code to support Sun RPC is taken verbatim from Sun's + RPCSRC-4.0 distribution, and is covered by this copyright: + + Copyright (C) 1984, Sun Microsystems, Inc. + + Sun RPC is a product of Sun Microsystems, Inc. and is + provided for unrestricted use provided that this legend is + included on all tape media and as a part of the software + program in whole or part. Users may copy or modify Sun RPC + without charge, but are not authorized to license or + distribute it to anyone else except as part of a product or + program developed by the user. + + SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND + INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND + FITNESS FOR A PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF + DEALING, USAGE OR TRADE PRACTICE. + + Sun RPC is provided with no support and without any + obligation on the part of Sun Microsystems, Inc. to assist in + its use, correction, modification or enhancement. + + SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT + TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY + PATENTS BY SUN RPC OR ANY PART THEREOF. + + In no event will Sun Microsystems, Inc. be liable for any + lost revenue or profits or other special, indirect and + consequential damages, even if Sun has been advised of the + possibility of such damages. + + Sun Microsystems, Inc. + 2550 Garcia Avenue + Mountain View, California 94043 + + * The port to SGI machines running Irix 4 (`mips-sgi-irix4') was + contributed by Tom Quinn. + + * The port of the Mach and Hurd code to the MIPS architecture + (`mips-ANYTHING-gnu') was contribued by Kazumoto Kojima. + diff --git a/Make-dist b/Make-dist new file mode 100644 index 0000000000..33e257b67c --- /dev/null +++ b/Make-dist @@ -0,0 +1,223 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +dist: + +ifdef subdir +.. := ../ +else +.. := +endif + +include $(..)Makeconfig + +foo:=$(shell echo 'distribute=$(distribute)'>&2) +foo:=$(shell echo 'foobar=$(filter %.c %.S %.s %.h,$(distribute))'>&2) + +ifndef sysdep_dirs +# Find all sysdep directories. +export sysdep_dirs := $(shell find $(..)sysdeps -type d ! -name RCS -print) +else +# Defined by the parent. +sysdep_dirs := $(addprefix $(..),$(sysdep_dirs)) +endif + +sysdep-Subdir-files := $(wildcard $(addsuffix /Subdirs,$(sysdep_dirs))) +ifdef sysdep-Subdir-files +subdirs := $(sort $(subdirs) \ + $(shell sed -e 's/\#.*$$//' $(sysdep-Subdir-files))) +endif + + +# Makefiles can define `source_dirs' to list nonstandard directories +# where source files might be found. + +ifdef subdir +all-headers = $(headers) +else ++distinfo := $(shell MAKEFLAGS= MFLAGS= $(MAKE) -s no_deps=t \ + inhibit_interface_rules=t inhibit_mach_syscalls=t \ + subdirs='$(subdirs)' echo-distinfo | grep -v '^make') +foo:=$(shell echo>&2 '+distinfo=$(+distinfo)') +all-headers := $(patsubst +header+%,%,$(filter +header+%,$(+distinfo))) +# Ignore subdir headers without top-level indirections. +all-headers := $(sort $(headers) $(wildcard $(all-headers))) ++subdir-nodist := $(patsubst +nodist+%,%,$(filter +nodist+%,$(+distinfo))) ++subdir-headers := $(filter-out $(headers),$(all-headers)) +endif +foo:=$(shell echo 'IS THIS WORKING??? all-headers=$(all-headers)' >&2) + +# Find all sysdep sources and headers. ++maybe-sysdeps := $(sources) $(sources:.c=.s) $(sources:.c=.S) $(all-headers) \ + $(filter %.c %.S %.s %.h %.sub,$(distribute)) +foo:=$(shell echo '+maybe-sysdeps=$(+maybe-sysdeps)'>&2) +# Find all the files that have a stub or generic version. +try-sysdeps := $(foreach dir,$(..)sysdeps/stub $(..)sysdeps/generic,\ + $(addprefix $(dir)/,$(+maybe-sysdeps))) +foo:=$(shell echo 'try-sysdeps=$(try-sysdeps)'>&2) ++sysdeps := $(wildcard $(try-sysdeps)) +foo:=$(shell echo 'stub/generic +sysdeps=$(+sysdeps)'>&2) ++sysdep-names := $(sort $(notdir $(+sysdeps))) +foo:=$(shell echo '+sysdep-names=$(+sysdep-names)' >&2) + +# Now find all the sysdep versions of those files. ++sysdeps := $(wildcard $(foreach dir,$(sysdep_dirs) $(source_dirs),\ + $(addprefix $(dir)/, \ + $(+sysdep-names) \ + $(+sysdep-names:.c=.s) \ + $(+sysdep-names:.c=.S) \ + ))) + + +# Source and header files to go in the distribution tar file. + +.S.s := $(wildcard $(sources:.c=.S) $(sources:.c=.s)) +sources := $(filter-out $(addsuffix .c,$(basename $(.S.s))),$(sources)) $(.S.s) + ++out := $(patsubst %.S,%.c,$(+sysdep-names:.s=.c)) \ + $(addsuffix .c,$(sysdep_routines)) \ + $(+subdir-nodist) +#foo:=$(shell echo '+out=$(+out)' >&2; echo foofoo >&2) ++tsrcs := $(filter-out $(+out) $(addprefix %/,$(+out)), \ + $(sources) $(all-headers) $(distribute)) \ + $(+sysdeps) +foo:=$(shell echo made +tsrcs >&2) +foo:=$(shell echo generated='$(generated)' >&2) +generated := $(sort $(generated) $(generated:.S=.c) $(generated:.s=.c)) +foo:=$(shell echo now generated='$(generated)' >&2) ++tsrcs := $(sort $(filter-out $(generated),$(+tsrcs))) +foo:=$(shell echo '+tsrcs=$(+tsrcs)'>&2) +foo:=$(shell echo foobie, dammit! >&2) + +ifndef tardir +rel+vers := $(shell sed -n -e 's/^.*libc_release.*\"\([^"]*\)";$$/\1/p' \ + -e 's/^.*libc_version.*\"\([^"]*\)";$$/\1/p' \ + < $(..)version.c) +release := $(word 1,$(rel+vers)) +version := $(word 2,$(rel+vers)) +export tardir := glibc-$(version) +endif + +$(..)glibc-$(version): + ln -s . $@ + ++tsrcs := $(+tsrcs) \ + TAGS +.PHONY: TAGS +TAGS: $(..)MakeTAGS + $(MAKE) -f $< $@ -o subdir_TAGS + +ifdef subdir + +foo:=$(shell echo subdir foo >&2) + ++tsrcs := Makefile $(+tsrcs) \ + $(addsuffix .c,$(others) $(tests)) \ + $(wildcard $(addsuffix .input,$(tests)) \ + $(addsuffix .args,$(tests))) ++tardeps := $(strip $(+tsrcs)) ++tsrcs := $(addprefix $(tardir)/$(subdir)/,$(+tardeps)) + +verbose = v + +.PHONY: dist +dist: $(..)$(tardir) $(+tardeps) + @cd ..; if test -f dist.tar; then c=u; else c=c; fi; \ + $(+cmdecho) "cd ..; tar $${c}h$(verbose)f dist.tar ..."; \ + tar $${c}h$(verbose)f dist.tar $(+tsrcs) + +else # Parent makefile. + +# Find what other things sysdep directories want to distribute. + +foo:=$(shell echo parent foobie>&2) ++sysdep-distfiles := $(wildcard $(addsuffix /Dist,$(sysdep_dirs))) +foo:=$(shell echo +sysdep-distfiles='$(+sysdep-distfiles)'>&2) ++sysdep-dist := $(foreach file,$(+sysdep-distfiles),\ + $(addprefix $(dir $(file)), \ + $(shell sed -e 's/\#.*$$//' $(file)))) \ + $(+sysdep-distfiles) \ + $(sysdep-Subdir-files) +foo:=$(shell echo '+sysdep-dist=$(+sysdep-dist)' >&2) + +subdirs := $(filter-out crypt,$(subdirs)) + ++sysdep-tsrcs := $(wildcard $(foreach file,Makefile Implies \ + configure configure.in,\ + $(addsuffix /$(file),$(sysdep_dirs)))) \ + $(+sysdep-dist) + ++tsrcs := $(+tsrcs) $(+sysdep-tsrcs) + +define autoconf-it +autoconf $(ACFLAGS) $< > $@.new +mv -f $@.new $@ +test -d CVS && cvs commit -m'Regenerated: autoconf $(ACFLAGS) $<' $@ +endef + +configure: configure.in; $(autoconf-it) +%/configure: %/configure.in; $(autoconf-it) + +.PHONY: dist +dist: $(tardir).tar.gz $(tardir)-crypt.tar.gz + +$(tardir)-crypt.tar.gz: crypt/crypt.tar.gz + ln $< $@ +crypt/%: FORCE + $(MAKE) -C $(@D) $(@F) +FORCE: + +subdir_dist: dist.tar +dist.tar: $(tardir) $(+tsrcs) + tar chvf $@ $(addprefix $(tardir)/,$(filter-out $(tardir),$^)) + +$(tardir).tar: dist.tar subdir_dist + tar xfv $< -C /tmp | doschk + tar covf $@ -C /tmp $(tardir) + -rm -fr /tmp/$(tardir) & + +%.Z: % + compress -c $< > $@ + +%.gz: % + gzip -9 -v -c $< > $@ + +foo:=$(shell echo subdirs=$(subdirs) >&2) +dist-subdirs := $(addprefix dist-,$(subdirs)) # dist-manual +.PHONY: subdir_dist $(dist-subdirs) +subdir_dist: $(dist-subdirs) +$(dist-subdirs): + $(MAKE) -C $(patsubst dist-%,%,$@) dist + +# This is here instead of in Makefile so it can use $(release) and $(version). +README: README.template version.c + -rm -f $@ + sed -e 's/RELEASE/$(release)/' -e 's/VERSION/$(version)/' < $< > $@ +# Make it unwritable so I won't change it by mistake. + chmod 444 $@ + + +endif # Subdirectory vs. parent makefile + +# Get these things out of the environment because they take up lots of space. +unexport distribute generated + +# Fnord. +export inhibit_mach_syscalls=t +export no_deps=t +export inhibit_interface_rules=t diff --git a/MakeTAGS b/MakeTAGS new file mode 100644 index 0000000000..acea142bf6 --- /dev/null +++ b/MakeTAGS @@ -0,0 +1,107 @@ +# Make the TAGS files. + +# Copyright (C) 1992, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Make this the default goal. +TAGS: + +ifdef subdir +.. := ../ +endif + +include $(..)Makeconfig + +ifndef tags_sources +ifeq ($(subdir),ctype) +# In most cases, we want the C source files to come before +# the header files so tags for optimizing #define's in the +# headers won't be put in the tags files, but for ctype, +# the functions are just backup for the #define's in the header. +tags_sources = $(all-headers) $(all-sources) +else # Not ctype. +tags_sources = $(all-sources) $(all-headers) +endif # ctype +endif # No tags_sources + +sysdep-dirs := $(addprefix $(sysdep_dir)/,$(sysdirs)) + +ifndef sysdep_dirs +# Find all sysdep directories. +sysdep_dirs := $(shell find $(..)sysdeps -type d ! -name RCS -print) +endif + +# Find all sysdep dirs there are, but putting the ones +# we are configured to use first and preserving their order. +all-dirs := $(objdir) \ + $(sysdep-dirs) \ + $(source_dirs) \ + $(filter-out $(sysdep-dirs),$(sysdep_dirs)) + +# Find all the subdirs there are, but putting the ones +# we are configured to use first and preserving their order. +ifndef subdir +subdirs := $(subdirs) \ + $(filter-out $(subdirs),\ + $(shell sed -e 's/\#.*$$//' \ + $(wildcard $(addsuffix /Subdirs,\ + $(all-dirs)))\ + /dev/null)) +all-dist = $(foreach Dist,$(wildcard $(all-dirs:%=%/Dist)),\ + $(addprefix $(Dist:%/Dist=%)/,\ + $(filter %.c %.h %.S %.s,\ + $(shell cat $(Dist))))) +tags_sources = $(all-sources) $(all-headers) $(all-dist) +endif + +# All different versions of $(sources), preserving the configured sysdep +# directory order. +all-sources = $(wildcard $(foreach file,$(sources),\ + $(file) \ + $(foreach dir,$(all-dirs),\ + $(dir)/$(file) \ + $(dir)/$(file:.c=.S) \ + $(dir)/$(file:.c=.s)))) + +all-headers = $(wildcard $(foreach file,$(headers),\ + $(file) \ + $(foreach dir,$(all-dirs),$(dir)/$(file)))) + +tags_sources := $(strip $(tags_sources)) + +TAGS: $(tags_sources) +ifdef subdir +ifdef tags_sources + $(ETAGS) -o $@ $^ +else +# No sources. Create a dummy file. + touch $@ +endif # tags_sources +else # parent +TAGS: subdir_TAGS +# Note that this uses the -i switch, and thus requires v19 etags. + $(ETAGS) -o $@ \ + $(subdirs:%=-i %/TAGS) \ + $(filter-out subdir_TAGS,$^) + +.PHONY: subdir_TAGS $(subdirs:%=%/TAGS) +subdir_TAGS: $(subdirs:%=%/TAGS) +$(subdirs:%=%/TAGS): + $(MAKE) -C $(@D) no_deps=t $(@F) + +endif # subdir diff --git a/Makeconfig b/Makeconfig new file mode 100644 index 0000000000..434f8b2d19 --- /dev/null +++ b/Makeconfig @@ -0,0 +1,358 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile configuration options for the GNU C library. +# +ifneq (,) +This makefile requires GNU Make. +endif + +ifneq "$(origin +included-Makeconfig)" "file" + ++included-Makeconfig := yes + +ifdef subdir +.. := ../ +endif + +# If config.make exists, the source directory was configured, +# so don't try to be clever and find another directory to build in. +ifneq (,$(wildcard $(..)config.make)) +ARCH = +machine = +else # Not configured. +ifndef ARCH +ifdef machine +ARCH = $(machine) +endif # machine +endif # ARCH +endif # config.make + +# Directory for object files and libc.a. If this is not defined, the +# object files live in the subdirectories where their sources live, and +# libc.a lives in the parent directory (this probably doesn't work any +# more). +ifdef ARCH +ifeq ($(filter /%,$(ARCH)),) +objdir := $(..)$(ARCH) +else +objdir = $(ARCH) +endif +endif + +# $(common-objdir) is the place to put objects and +# such that are not specific to a single subdir. +ifdef objdir +objpfx = $(objdir)/ +common-objpfx = $(objpfx) +common-objdir = $(objdir) +else +objpfx := +ifdef .. +common-objpfx = $(..) +common-objdir = .. +else +# This is a kludge. make wizards might grok. +common-objpfx = sysdeps/../ +common-objdir = . +endif +endif + +libc.a = $(common-objpfx)libc.a + + +# Get the values defined by options to `configure'. +include $(common-objpfx)config.make + +# Force the user to configure before making. +$(common-objpfx)config.make: + @echo The GNU C library has not been configured. >&2 + @echo Run \`configure\' to configure it before building. >&2 + @exit 1 + +# Get the user's configuration parameters. +ifneq ($(wildcard $(..)configparms),) +include $(..)configparms +endif +ifneq ($(objpfx),) +ifneq ($(wildcard $(objpfx)configparms),) +include $(objpfx)configparms +endif +endif + +sysdep_dir := $(..)sysdeps +export sysdep_dir := $(sysdep_dir) + +#### +#### These are the configuration variables. You can define values for +#### the variables below in the file `configparms'. +#### Do NOT edit this file. +#### + + +# Common prefix for machine-independent installation directories. +ifndef prefix +prefix = /usr/local +endif + +# Common prefix for machine-dependent installation directories. +ifndef exec_prefix +exec_prefix = $(prefix) +endif + +# Where to install the library and object files. +ifndef libdir +libdir = $(exec_prefix)/lib +endif + +# Prefix to put on files installed in $(libdir). For libraries `libNAME.a', +# the prefix is spliced between `lib' and the name, so the linker switch +# `-l$(libprefix)NAME' finds the library; for other files the prefix is +# just prepended to the whole file name. +ifndef libprefix +libprefix = +endif + +# Where to install the header files. +ifndef includedir +includedir = $(exec_prefix)/include +endif + +# Define if the library should install its own <stddef.h>. +# Do this unless you are using version 2.2 or later of GCC. +ifndef stddef.h +stddef.h = stddef.h +endif + +# Where to install machine-independent data files. +# These are the timezone database, and eventually the locale database. +ifndef datadir +datadir = $(prefix)/share +endif + +# Where to install the timezone data files (which are machine-independent). +ifndef zonedir +zonedir = $(datadir)/zoneinfo +endif + +# Where to install programs. +ifndef bindir +bindir = $(exec_prefix)/bin +endif + +# Where to install administrative programs. +ifndef sbindir +sbindir = $(exec_prefix)/sbin +endif + +# Where to install the Info files. +ifndef infodir +infodir = $(prefix)/info +endif + +# Where to install default configuration files. These include the local +# timezone specification and network data base files. +ifndef sysconfdir +sysconfdir = $(prefix)/etc +endif + +# What timezone should be the installed default (e.g., US/Eastern). +# Run `make -C time echo-zonenames' to see a list of available zone names. +# The local timezone can be changed with `zic -l TIMEZONE' at any time. +ifndef localtime +localtime = Factory +endif + +# Where to install the "localtime" timezone file; this is the file whose +# contents $(localtime) specifies. If this is a relative pathname, it is +# relative to $(zonedir). It is a good idea to put this somewhere +# other than there, so the zoneinfo directory contains only universal data, +# localizing the configuration data elsewhere. +ifndef localtime-file +localtime-file = $(sysconfdir)/localtime +endif + +# What timezone's DST rules should be used when a POSIX-style TZ +# environment variable doesn't specify any rules. For 1003.1 compliance +# this timezone must use rules that are as U.S. federal law defines DST. +# Run `make -C time echo-zonenames' to see a list of available zone names. +# This setting can be changed with `zic -p TIMEZONE' at any time. +# If you want POSIX.1 compatibility, use `America/New_York'. +ifndef posixrules +posixrules = America/New_York +endif + +# Where to install the "posixrules" timezone file; this is file +# whose contents $(posixrules) specifies. If this is a relative +# pathname, it is relative to $(zonedir). +ifndef posixrules-file +posixrules-file = posixrules +endif + + +# Directory where your system's native header files live. +# This is used on Unix systems to generate some GNU libc header files. +ifndef sysincludedir +sysincludedir = /usr/include +endif + + +# Commands to install files. +ifndef INSTALL_DATA +INSTALL_DATA = $(INSTALL) -m 644 +endif +ifndef INSTALL_PROGRAM +INSTALL_PROGRAM = $(INSTALL) +endif +ifndef INSTALL +INSTALL = install +endif + + +# The name of the C compiler. +# If you've got GCC, and it works, use it. +ifeq ($(origin CC),default) +CC := gcc +endif + +# The name of the C compiler to use for compilations of programs to run on +# the host that is building the library. If you set CC to a +# cross-compiler, you must set this to the normal compiler. +ifndef BUILD_CC +BUILD_CC = $(CC) +endif + +# Default flags to pass the C compiler. +ifndef default_cflags +default_cflags := -g +endif + +# Flags to pass the C compiler when assembling preprocessed assembly code +# (`.S' files). On some systems the assembler doesn't understand the `#' line +# directives the preprocessor produces. If you have troubling compiling +# assembly code, try using -P here to suppress these directives. +ifndef asm-CPPFLAGS +asm-CPPFLAGS = +endif + +# Command for linking programs with the C library. +ifndef +link ++link = $(CC) -nostdlib $(LDFLAGS) -o $@ \ + $(common-objpfx)start.o $(^:lib=$(libc.a)) $(gnulib) $(libc.a) +endif +ifndef gnulib +gnulib := -lgcc +endif + +ifndef LD +LD := ld -X +endif + +ifndef RANLIB +RANLIB = ranlib +endif + +# Extra flags to pass to GCC. ++gccwarn := -Wall -Wwrite-strings -Wno-parentheses + +# This is the program that generates makefile +# dependencies from C source files. +ifndef +mkdep ++mkdep = $(CC) -M +endif + +# The program that makes Emacs-style TAGS files. +ETAGS := etags -T + +# The `m4' macro processor; this is used by sysdeps/sparc/Makefile (and +# perhaps others) to preprocess assembly code in some cases. +M4 = m4 + +#### +#### End of configuration variables. +#### + +# This tells some versions of GNU make before 3.63 not to export all variables. +.NOEXPORT: + +# We want to echo the commands we're running without +# umpteem zillion filenames along with it (we use `...' instead) +# but we don't want this echoing done when the user has said +# he doesn't want to see commands echoed by using -s. +ifneq "$(findstring s,$(MAKEFLAGS))" "" # if -s ++cmdecho := echo >/dev/null +else # not -s ++cmdecho := echo +endif # -s + +# These are the flags given to the compiler to tell +# it what sort of optimization and/or debugging output to do. +ifndef +cflags +# If `CFLAGS' was defined, use that. +ifdef CFLAGS ++cflags := $(filter-out -I%,$(CFLAGS)) +endif # CFLAGS +endif # +cflags + +# If none of the above worked, default to "-g". +ifeq "$(strip $(+cflags))" "" ++cflags := $(default_cflags) +endif # $(+cflags) == "" + +# If using gcc, add flags that only it will grok. +ifneq "$(findstring gcc,$(CC))" "" ++cflags := $(+cflags) $(+gccwarn) ++gcc-nowarn := -w +else ++gcc-nowarn := +endif # gcc + +# Don't duplicate options if we inherited variables from the parent. ++cflags := $(sort $(+cflags)) + + +# These are flags given to the C compiler to tell it to look for include +# files (including ones given in angle brackets) in the current directory +# and in the parent library source directory. +# `+sysdep-includes' will be defined by Makerules. ++includes = -I. $(filter-out -I,-I$(patsubst %/,%,$(..))) \ + $(includes) $(+sysdep-includes) $(last-includes) + + +# These are the variables that the implicit compilation rules use. +CPPFLAGS = $(+includes) $(defines) -include $(..)libc-symbols.h \ + $(sysdep-CPPFLAGS) +override CFLAGS = $(+cflags) $(sysdep-CFLAGS) + + +# This is the macro that the implicit linking rules use. +ifneq "$(filter -g,$(+cflags))" "" # -g is in $(+cflags) +LDFLAGS := -g +endif + ++gnu-stabs = $(shell echo>&2 '*** BARF ON ME') + +ifneq ($(BUILD_CC),$(CC)) +cross-compiling := yes +else +cross-compiling := no +endif + + +endif # Makeconfig not yet included diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..6a3fb17d4c --- /dev/null +++ b/Makefile @@ -0,0 +1,233 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Master Makefile for the GNU C library +# +ifneq (,) +This makefile requires GNU Make. +endif + + +# This is the default target; it makes everything except the tests. +.PHONY: all +all: lib others + +define autoconf-it +autoconf $(ACFLAGS) $< > $@.new +mv -f $@.new $@ +test -d CVS && cvs commit -m'Regenerated: autoconf $(ACFLAGS) $<' $@ +endef + +configure: configure.in; $(autoconf-it) +%/configure: %/configure.in; $(autoconf-it) + +include Makeconfig + +ifndef avoid-generated +include $(objpfx)sysd-dirs +define \n + + +endef +sysdep-subdirs := $(subst $(\n), ,$(sysdep-subdirs)) +endif + +# These are the subdirectories containing the library source. ++ansi_dirs := assert ctype locale math setjmp \ + signal stdio stdlib malloc string time ++posix_dirs := dirent grp pwd posix io termios ++other_dirs := resource socket misc gnulib $(wildcard crypt) manual csu +subdirs := $(strip $(+ansi_dirs) $(+posix_dirs) $(+other_dirs) \ + $(sysdep-subdirs)) +export subdirs := $(subdirs) # Benign, useless in GNU make before 3.63. + +# The mach and hurd subdirectories have many generated header files which +# the much of rest of the library depends on, so it is best to build them +# first (and mach before hurd, at that). The before-compile additions in +# sysdeps/{mach,hurd}/Makefile should make it reliably work for these files +# not to exist when making in other directories, but it will be slower that +# way with more somewhat expensive `make' invocations. +subdirs := $(filter mach,$(subdirs)) $(filter hurd,$(subdirs)) \ + $(filter-out mach hurd,$(subdirs)) + +# All initialization source files. ++subdir_inits := $(wildcard $(foreach dir,$(subdirs),$(dir)/init-$(dir).c)) +# All subdirectories containing initialization source files. ++init_subdirs := $(patsubst %/,%,$(dir $(+subdir_inits))) + + +# These are the targets that are made by making them in each subdirectory. ++subdir_targets := subdir_lib objects objs others subdir_mostlyclean \ + subdir_clean subdir_distclean subdir_realclean \ + tests subdir_lint.out \ + subdir_echo-headers subdir_echo-distinfo \ + subdir_install $(addprefix install-, \ + no-libc.a bin lib \ + data headers others) + +headers := features.h errno.h sys/errno.h errnos.h limits.h $(stddef.h) +aux = sysdep $(libc-init) version + +echo-headers: subdir_echo-headers + +# What to install. +install-others = $(includedir)/stubs.h + +ifeq (yes,$(gnu-ld)) +libc-init = set-init +else +libc-init = munch-init +$(objpfx)munch-init.c: munch.awk munch-tmpl.c $(+subdir_inits) + awk -f $< subdirs='$(+init_subdirs)' $(word 2,$^) > $@-t + mv -f $@-t $@ +generated := $(generated) munch-init.c +endif + + +include Makerules + +# Install from subdirectories too. +install: subdir_install + +lib-noranlib $(libc.a)(__.SYMDEF): subdir_lib + + +$(objpfx)sysd-dirs: $(+sysdir_pfx)config.make + (echo define sysdep-subdirs; \ + for dir in $(sysdirs); do \ + if [ -r $(sysdep_dir)/$$dir/Subdirs ]; then \ + sed 's/#.*$$//' $(sysdep_dir)/$$dir/Subdirs; \ + else true; \ + fi; \ + done; \ + echo endef) > $@-tmp + mv -f $@-tmp $@ + +# Makerules creates a file `stub-$(subdir)' for each subdirectory, which +# contains `#define __stub_FUNCTION' for each function which is a stub. +# Here we paste all of these together into <stubs.h>. + +subdir-stubs := $(foreach dir,$(subdirs),$(common-objpfx)stub-$(dir)) + +# Since stubs.h is never needed when building the library, we simplify the +# hairy installation process by producing it in place only as the last part +# of the top-level `make install'. It depends on subdir_install, which +# iterates over all the subdirs; subdir_install in each subdir depends on +# the subdir's stubs file. Having more direct dependencies would result in +# extra iterations over the list for subdirs and many recursive makes. +$(includedir)/stubs.h: subdir_install + @rm -f $(objpfx)stubs.h + (echo '/* This file is automatically generated.';\ + echo ' It defines a symbol `__stub_FUNCTION'\'' for each function';\ + echo ' in the C library which is a stub, meaning it will fail';\ + echo ' every time called, usually setting errno to ENOSYS. */';\ + sort $(subdir-stubs)) > $(objpfx)stubs.h + $(INSTALL_DATA) $(objpfx)stubs.h $@ + rm -f $(objpfx)stubs.h + +# This makes the Info or DVI file of the documentation from the Texinfo source. +.PHONY: info dvi +info dvi: + $(MAKE) -C manual $@ + +# This makes all the subdirectory targets. + +# For each target, make it depend on DIR/target for each subdirectory DIR. +$(+subdir_targets): %: $(addsuffix /%,$(subdirs)) + +# Compute a list of all those targets. +all-subdirs-targets := $(foreach dir,$(subdirs),\ + $(addprefix $(dir)/,$(+subdir_targets))) + +# The action for each of those is to cd into the directory and make the +# target there. +$(all-subdirs-targets): + $(MAKE) -C $(@D) $(@F) + +.PHONY: $(+subdir_targets) $(all-subdirs-targets) + +# Targets to clean things up to various degrees. + +.PHONY: clean realclean distclean distclean-1 parent-clean parent-mostlyclean + +# Subroutines of all cleaning targets. +parent-mostlyclean: common-mostlyclean # common-mostlyclean is in Makerules. + -rm -f $(libc.a) $(addprefix $(objpfx),$(install-lib)) +parent-clean: parent-mostlyclean common-clean + -rm -f $(addprefix $(common-objpfx),$(common-generated)) + -rm -f $(addprefix $(+sysdir_pfx),sysd-Makefile sysd-dirs sysd-rules) + +clean: parent-clean +# This is done this way rather than having `subdir_clean' be a +# dependency of this target so that libc.a will be removed before the +# subdirectories are dealt with and so they won't try to remove object +# files from it when it's going to be removed anyway. + @$(MAKE) subdir_clean no_deps=t +mostlyclean: parent-mostlyclean + @$(MAKE) subdir_mostlyclean no_deps=t + +# The realclean target is just like distclean for the parent, but we want +# the subdirs to know the difference in case they care. +realclean distclean: parent-clean +# This is done this way rather than having `subdir_distclean' be a +# dependency of this target so that libc.a will be removed before the +# subdirectories are dealt with and so they won't try to remove object +# files from it when it's going to be removed anyway. + @$(MAKE) distclean-1 no_deps=t distclean-1=$@ avoid-generated=yes + +# Subroutine of distclean and realclean. +distclean-1: subdir_$(distclean-1) + -rm -f $(config-generated) + -rm -f $(addprefix $(objpfx),config.status cache.cache) + -rm -f $(addprefix $(objpfx),config.make config-name.h) +ifdef objdir + -rm -f $(objpfx)Makefile +endif + -rm -f $(sysdep-$(distclean-1)) + +.PHONY: echo_subdirs +echo_subdirs:;@echo '$(subdirs)' + +.PHONY: echo-distinfo parent_echo-distinfo +echo-distinfo: parent_echo-distinfo subdir_echo-distinfo +parent_echo-distinfo: + @echo $(addprefix +header+,$(headers)) \ + $(addprefix +nodist+,$(generated)) + +# Make the distribution tarfile. + +distribute := README INSTALL NOTES COPYING.LIB COPYING ChangeLog NEWS \ + Makefile Makeconfig Makerules Rules Make-dist MakeTAGS \ + ansidecl.h mkinstalldirs move-if-change install-sh \ + configure configure.in aclocal.m4 config.sub config.guess\ + config.make.in config-name.in Makefile.in \ + munch-tmpl.c munch.awk sysdep.h set-hooks.h libc-symbols.h + +distribute := $(strip $(distribute)) +generated := $(generated) stubs.h + +README: README.template version.c ; # Make-dist should update README. + +define format-me +@rm -f $@ +makeinfo --no-validate --no-warn --no-headers $< -o $@ +-chmod a-w $@ +endef +INSTALL: manual/maint.texi; $(format-me) +NOTES: manual/creature.texi; $(format-me) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000000..6ec07a64c6 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,6 @@ +# Generated from $Id$. + +srcdir = @srcdir@ + +all .DEFAULT: + $(MAKE) -C $(srcdir) objdir=`pwd` $@ diff --git a/Makerules b/Makerules new file mode 100644 index 0000000000..76ed429e9d --- /dev/null +++ b/Makerules @@ -0,0 +1,544 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Common rules for making the GNU C library. This file is included +# by the top-level Makefile and by all subdirectory makefiles +# (through Rules). +# +ifneq (,) +This makefile requires GNU Make. +endif + + +ifdef subdir +.. := ../ +endif # subdir + +# If `sources' was defined by the parent makefile, undefine it so +# we will later get it from wildcard search in this directory. +ifneq "$(findstring env,$(origin sources))" "" +sources := +endif + +headers := $(headers) $(sysdep_headers) + +oPATH := $(PATH) +PATH := this definition should take precedence over $(oPATH) +ifeq ($(PATH),$(oPATH)) +You must not use the -e flag when building the GNU C library. +else +PATH := $(oPATH) +endif + +ifndef +included-Makeconfig +include $(..)Makeconfig +endif + +# `configure' writes a definition of `config-sysdirs' in `config.make'. +sysdirs = $(config-sysdirs) + ++sysdir_pfx = $(common-objpfx) + +export sysdirs := $(sysdirs) + ++sysdep_dirs := $(addprefix $(sysdep_dir)/,$(sysdirs)) +ifdef objdir ++sysdep_dirs := $(objdir) $(+sysdep_dirs) +endif + +# Add -I switches to get the right sysdep directories. +# `+includes' in Makeconfig references $(+sysdep-includes). ++sysdep-includes := $(addprefix -I,$(+sysdep_dirs)) + +# Include any system-specific makefiles. + +# This is here so things in sysdep Makefiles can easily depend on foo.h as +# appropriate and not worry about where foo.h comes from, which may be +# system dependent and not known by that Makefile. +vpath %.h $(subst $(empty) ,:,$(strip $(common-objpfx) \ + $(addprefix $(sysdep_dir)/,$(sysdirs)) \ + $(..))) + +ifeq ($(wildcard $(+sysdir_pfx)sysd-Makefile),) +# Don't do deps until this exists, because it might change the sources list. +no_deps=t +endif + +# Some sysdep makefiles use this to distinguish being included here from +# being included individually by a subdir makefile (hurd/Makefile needs this). +in-Makerules := yes + +ifndef avoid-generated +include $(+sysdir_pfx)sysd-Makefile +$(+sysdir_pfx)sysd-Makefile: $(+sysdir_pfx)config.make $(..)Makerules + -@rm -f $@T + (for dir in $(sysdirs); do \ + file=sysdeps/$$dir/Makefile; \ + if [ -f $(..)$$file ]; then \ + echo include "\$$(..)$$file"; \ + else true; fi; \ + done; \ + echo 'sysd-Makefile-done=t') > $@T + mv -f $@T $@ +endif + +# Reorder before-compile so that mach things come first, and hurd things +# second, before all else. The mach and hurd subdirectories have many +# generated header files which the much of rest of the library depends on, +# so it is best to build them first (and mach before hurd, at that). +before-compile := $(filter $(common-objpfx)mach% $(common-objpfx)hurd%,\ + $(before-compile)) \ + $(filter-out $(common-objpfx)mach% $(common-objpfx)hurd%,\ + $(before-compile)) + +# Remove existing files from `before-compile'. Things are added there when +# they must exist for dependency generation to work right, but once they +# exist there is no further need for every single file to depend on them, +# and those gratuitous dependencies result in many gratuitous +# recompilations. +before-compile := $(filter-out $(wildcard $(before-compile)),$(before-compile)) + +# Don't let any before-compile file be an intermediate and get removed. +ifdef before-compile +$(before-compile): +endif + +# Generate an ordered list of implicit rules which find the source files in +# each sysdep directory. The old method was to use vpath to search all the +# sysdep directories. However, that had the problem that a .S file in a +# later directory would be chosen over a .c file in an earlier directory, +# which does not preserve the desired sysdeps ordering behavior. + +# When making the list of .d files to include, we can't know which ones +# have source in .s files, and thus do not in fact need a .d file. +# So we must define rules to make .d files for .s files. +define make-dummy-dep +$(addprefix ln $(objpfx)dummy.d ,$(filter-out $(wildcard $@),$@)) +endef +$(objpfx)dummy.d: + echo '# .s files cannot contain includes, so they need no deps.' > $@ + +# It matters that this set of rules, for compiling from sources in +# the current directory (the $srcdir/$subdir) come before the +# generated sysdep rules in included from sysd-rules below. When +# compiling in the source tree, generated sources go into the current +# directory, and those should be chosen before any sources in sysdeps. +$(objpfx)%.o: %.S $(before-compile); $(compile-command.S) +$(objpfx)%.d: %.S $(before-compile); $(+make-deps) +$(objpfx)%.o: %.s $(before-compile); $(compile-command.s) +$(objpfx)%.d: %.s $(objpfx)dummy.d; $(make-dummy-dep) +$(objpfx)%.o: %.c $(before-compile); $(compile-command.c) +$(objpfx)%.d: %.c $(before-compile); $(+make-deps) + +# Omit the objpfx rules when building in the source tree, because +# objpfx is empty and so these rules just override the ones above. +ifdef objpfx +# Define first rules to find the source files in $(objpfx). +# Generated source files will end up there. +$(objpfx)%.o: $(objpfx)%.S $(before-compile); $(compile-command.S) +$(objpfx)%.d: $(objpfx)%.S $(before-compile); $(+make-deps) +$(objpfx)%.o: $(objpfx)%.s $(before-compile); $(compile-command.s) +$(objpfx)%.d: $(objpfx)%.s $(objpfx)dummy.d; $(make-dummy-dep) +$(objpfx)%.o: $(objpfx)%.c $(before-compile); $(compile-command.c) +$(objpfx)%.d: $(objpfx)%.c $(before-compile); $(+make-deps) +endif + +# System-dependent makefiles can put in `inhibit-sysdep-asm' wildcard +# patterns matching sysdep directories whose assembly source files should +# be suppressed. +ifdef inhibit-sysdep-asm +define open-check-inhibit-asm +case $$sysdir in $(subst $(empty) ,|,$(inhibit-sysdep-asm))) : ;; *) +endef +close-check-inhibit-asm = ;; esac +endif + +# Don't include sysd-rules until sysd-Makefile is already there and has been +# included. It might define inhibit-sysdep-asm, which would affect the +# contents of sysd-rules. +ifdef sysd-Makefile-done +include $(+sysdir_pfx)sysd-rules +endif +$(+sysdir_pfx)sysd-rules: $(+sysdir_pfx)config.make $(..)Makerules \ + $(wildcard $(foreach dir,$(sysdirs),\ + $(sysdep_dir)/$(dir)/Makefile)) + -@rm -f $@T + (for sysdir in $(sysdirs); do \ + dir="\$$(sysdep_dir)/$$sysdir"; \ + $(open-check-inhibit-asm) \ + echo "\$$(objpfx)%.o: $$dir/%.S \$$(before-compile); \ + \$$(compile-command.S)"; \ + echo "\$$(objpfx)%.d: $$dir/%.S \$$(before-compile); \ + \$$(+make-deps)"; \ + echo "\$$(objpfx)%.o: $$dir/%.s \$$(before-compile); \ + \$$(compile-command.s)"; \ + echo "\$$(objpfx)%.d: $$dir/%.s \$$(objpfx)dummy.d; \ + \$$(make-dummy-dep)" $(close-check-inhibit-asm); \ + echo "\$$(objpfx)%.o: $$dir/%.c \$$(before-compile); \ + \$$(compile-command.c)"; \ + echo "\$$(objpfx)%.d: $$dir/%.c \$$(before-compile); \ + \$$(+make-deps)"; \ + done) > $@T + mv -f $@T $@ + +ifndef compile-command.S +compile-command.S = $(compile.S) $(OUTPUT_OPTION) +endif +ifndef compile-command.s +compile-command.s = $(COMPILE.s) $< $(OUTPUT_OPTION) +endif +ifndef compile-command.c +compile-command.c = $(compile.c) $(OUTPUT_OPTION) +endif + +ifneq ($(filter %gcc,$(notdir $(firstword $(CC)))),) +# GCC can grok options after the file name, and it looks nicer that way. +compile.S = $(CC) $< -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS) +compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS) +else +compile.S = $(COMPILE.S) -DASSEMBLER $(asm-CPPFLAGS) $< +compile.c = $(COMPILE.c) $< +endif + +ifndef OUTPUT_OPTION +ifdef objpfx +# We need this for the output to go in the right place. It will default to +# empty if make was configured to work with a cc that can't grok -c and -o +# together. You can't compile the C library with such a compiler. +OUTPUT_OPTION = -o $@ +endif +endif + +S-CPPFLAGS = $(asm-CPPFLAGS) +define +make-deps +-@rm -f $@ +$(+mkdep) $< $(CPPFLAGS) $($(<:$*.%=%)-CPPFLAGS) | \ +sed -e 's,$*\.o,$(@:.d=.o) $@,' $(sed-remove-objpfx) > $(@:.d=.T) +mv -f $(@:.d=.T) $@ +endef +ifneq (,$(objpfx)) +sed-remove-objpfx = -e 's@ $(subst @,\@,$(objpfx))@ $$(objpfx)@g' \ + -e 's@^$(subst @,\@,$(objpfx))@$$(objpfx)@g' +endif + +# Figure out the source filenames in this directory. + +override sources := $(addsuffix .c,$(filter-out $(elided-routines),\ + $(routines) $(aux) \ + $(sysdep_routines))) +sysdep_routines := $(sysdep_routines) + +# This is the list of all object files, gotten by +# replacing every ".c" in `sources' with a ".o". +override objects := $(addprefix $(objpfx),$(sources:.c=.o)) + ++depfiles := $(strip $(sources:.c=.d) \ + $(patsubst %.o,%.d,$(filter %.o,$(extra-objs))) \ + $(addsuffix .d,$(others) $(tests))) ++depfiles := $(addprefix $(objpfx),\ + $(filter-out $(addsuffix .d,$(omit-deps)),\ + $(+depfiles))) + +$(objpfx)depend-$(subdir): Makefile +ifdef +depfiles + for file in $(+depfiles:$(objpfx)%=%); do \ + echo "include \$$(objpfx)$$file"; \ + done > $@-tmp + mv -f $@-tmp $@ +else + cp /dev/null $@ +endif + +ifneq ($(no_deps),t) +# Include the generated dependencies of the sources in this directory. +include $(objpfx)depend-$(subdir) +endif + +# Maximize efficiency by minimizing the number of rules. +.SUFFIXES: # Clear the suffix list. +# Add the suffixes we use. +.SUFFIXES: .a .o .S .s .c .h .d + +# Generic rule for making directories. +%/: +# mkdir isn't smart enough to strip a trailing /. + mkdir $(@:%/=%) + +# Make sure that object files are not removed +# when they are intermediates between sources and library members. +# This can go away with make v4. +.PRECIOUS: %.o + +# Make sure that the parent library archive is never removed. +.PRECIOUS: $(libc.a) + +# Use the verbose option of ar and tar when not running silently. +ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s +verbose := v +else # -s +verbose := +endif # not -s + +ARFLAGS := r$(verbose) + +# This makes all the object files in the parent library archive. + +.PHONY: lib libobjs lib-noranlib +$(libc.a): $(libc.a)(__.SYMDEF) +lib: $(libc.a) + ++libobjs := $(patsubst %,$(libc.a)(%),$(notdir $(objects))) +libobjs: $(+libobjs) +lib-noranlib: libobjs + +# Define a pattern rule that will match many targets libc.%(foo.o), for +# each foo in $(objects) (% will just happen always to match `a'). This is +# the only way to define a rule that updates many targets at once with one +# sequence of commands. +ifdef objects +$(patsubst %,$(libc.a:a=)\%(%),$(notdir $(objects))): $(objpfx)stamp-$(subdir); +$(objpfx)stamp-$(subdir): $(objects) +# $(+libc_lock_open) +ifdef objdir + cd $(objdir); $(AR) cru$(verbose) libc.a $(patsubst $(objpfx)%,%,$^) +else + $(AR) cru$(verbose) $(..)libc.a $^ +endif +# $(+libc_lock_close) + touch $@ +endif + +$(libc.a)(__.SYMDEF): $(+libobjs) + $(RANLIB) $@ + +define +libc_lock_open +@. $(..)libc-lock-open +endef +define +libc_lock_close +@rm -f $(..)LOCK-libc.a +endef + +# This makes all the object files. +.PHONY: objects objs +objects objs: $(objects) $(addprefix $(objpfx),$(extra-objs)) + +# Installation. + +# $(install-lib) are installed from the object directory into $(libdir); +# files in $(install-lib) matching `lib%.a' are ranlib'd after installation +# unless they also appear in $(non-lib.a). $(install-data) are installed +# as they are into $(datadir). $(headers) are installed as they are in +# $(includedir). $(install-bin) and $(install-sbin) are installed from the +# object directory into $(bindir) and $(sbindir), respectively. +# $(install-others) are absolute path names of files to install; rules to +# install them are defined elsewhere. + +# The simple library name to install libc.a under. +# This could be defined by a sysdep Makefile. +ifndef libc-name +libc-name := c +endif + +define do-install +$(make-target-directory) +$(INSTALL_DATA) $< $@ +endef + +# Make the target directory if it doesn't exist. Because of make's +# directory cache, this will produce the `mkdir' command when the directory +# already exists, if it didn't exist at the start of the `make' run. The +# `-' prefix ignores errors from mkdir, so there will just be some +# gratuitous but harmless `File exists' messages. +define make-target-directory +$(addprefix -mkdir ,$(filter-out $(wildcard $(@D:%/=%)),$(@D:%/=%))) +endef + +# Any directory (parent or subdir) that has any object files to build +# should install libc.a; this way "make install" in a subdir is guaranteed +# to install everything it changes. +ifdef objects +install: $(libdir)/lib$(libprefix)$(libc-name).a +# We avoid depending on lib-noranlib because that makes the parent make +# subdir_lib in all the subdirs, when the make install run they do will +# update the library anyway. Running ranlib after installing makes the +# __.SYMDEF time stamp up to date, which avoids messages from some linkers. +# Depending on subdir_install gets all the subdirs to update the library, +# and is optimal for `make install' at top level. +$(libdir)/lib$(libprefix)$(libc-name).a: libobjs subdir_install + $(make-target-directory) + $(INSTALL_DATA) $(libc.a) $@ + $(RANLIB) $@ +endif + +ifdef install-bin +$(addprefix $(bindir)/,$(install-bin)): $(bindir)/%: $(objpfx)% + $(make-target-directory) + $(INSTALL_PROGRAM) $< $@ +endif +ifdef install-sbin +$(addprefix $(sbindir)/,$(install-sbin)): $(sbindir)/%: $(objpfx)% + $(make-target-directory) + $(INSTALL_PROGRAM) $< $@ +endif +ifdef install-lib +install-lib.a := $(filter lib%.a,$(install-lib)) +install-lib-non.a := $(filter-out lib%.a,$(install-lib)) +ifdef install-lib-non.a +$(addprefix $(libdir)/$(libprefix),$(install-lib-non.a)): \ + $(libdir)/$(libprefix)%: $(objpfx)% + $(do-install) +endif +ifdef install-lib.a +$(install-lib.a:lib%.a=$(libdir)/lib$(libprefix)%.a): \ + $(libdir)/lib$(libprefix)%.a: $(objpfx)lib%.a + $(do-install) + $(patsubst %,$(RANLIB) $@,$(filter-out $(non-lib.a),$(<F))) +endif +endif +ifdef install-data +$(addprefix $(datadir)/,$(install-data)): $(datadir)/%: %;$(do-install) +endif +headers := $(strip $(headers)) +ifdef headers +$(addprefix $(includedir)/,$(headers)): \ + $(includedir)/%: %;$(do-install) +endif # headers + +.PHONY: install-bin-nosubdir install-sbin-nosubdir install-lib-nosubdir \ + install-data-nosubdir install-headers-nosubdir +install-bin-nosubdir: $(addprefix $(bindir)/,$(install-bin)) +install-sbin-nosubdir: $(addprefix $(sbindir)/,$(install-sbin)) +install-lib-nosubdir: $(addprefix $(libdir)/,\ + $(patsubst lib%.a,lib$(libprefix)%.a,$(install-lib.a)) \ + $(addprefix $(libprefix),$(install-lib-non.a))) +install-data-nosubdir: $(addprefix $(datadir)/,$(install-data)) +install-headers-nosubdir: $(addprefix $(includedir)/,$(headers)) +install-others-nosubdir: $(install-others) + +# We need all the `-nosubdir' targets so that `install' in the parent +# doesn't depend on several things which each iterate over the subdirs. +# This rule makes `install-FOO' always use `install-FOO-nosubdir' as a +# subroutine. Then in the parent `install-FOO' also causes subdir makes. +install-%:: install-%-nosubdir ; + +.PHONY: install install-no-libc.a-nosubdir +install-no-libc.a-nosubdir: install-headers-nosubdir install-data-nosubdir\ + install-bin-nosubdir install-lib-nosubdir \ + install-others-nosubdir install-sbin-nosubdir +install: install-no-libc.a-nosubdir + +# Command to compile $< in $(objdir) using the native libraries. +define native-compile +cwd=`pwd`; cd $(@D); $(BUILD_CC) $(BUILD_CFLAGS) \ + $(addprefix $$cwd/,$^) -o $(@F) +endef + +# Command to compile $< in $(common-objdir) using the native libraries. +define common-objdir-compile +cd $(@D); $(BUILD_CC) $(BUILD_CFLAGS) $(<:$(common-objpfx)%=%) -o $(@F) +endef + +# We always want to use configuration definitions. +BUILD_CFLAGS = -include $(common-objpfx)config.h + +# Support the GNU standard name for this target. +.PHONY: check +check: tests + +.PHONY: TAGS +TAGS: distinfo $(..)MakeTAGS + $(MAKE) $(addprefix -f ,$^) + +.PHONY: echo-headers +echo-headers: + @echo $(headers) + + +# Common cleaning targets. + +.PHONY: common-mostlyclean common-clean mostlyclean clean +clean: common-clean +mostlyclean: common-mostlyclean + +# Remove the object files. +common-mostlyclean: + -rm -f $(addprefix $(objpfx),$(tests) $(others) \ + $(addsuffix .o,$(tests) $(others)) \ + $(addsuffix .out,$(tests))) + -rm -f $(objects) $(addprefix $(objpfx),$(extra-objs) stamp-$(subdir)) + -rm -f core TAGS + +# Also remove the dependencies and generated source files. +common-clean: common-mostlyclean + -rm -f $(objpfx)depend-$(subdir) $(+depfiles) + -rm -f $(addprefix $(objpfx),$(generated)) + +# Produce a file `stub-$(subdir)' which contains `#define __stub_FUNCTION' +# for each function which is a stub. We grovel over all the .d files +# looking for references to source files in sysdeps/stub. Then we grovel +# over each referenced source file to see what stub function it defines. + +.PHONY: stubs # The parent Makefile calls this target. +stubs: $(common-objpfx)stub-$(subdir) +s = $(sysdep_dir)/stub +$(common-objpfx)stub-$(subdir): $(+depfiles) +# Use /dev/null since `...` might expand to empty. + s=`cd $s; /bin/pwd`; \ + $(patsubst %,cd %;,$(objdir)) \ + sed -n 's/^stub_warning *(\([^)]*\).*$$/#define __stub_\1/p' \ + `sed -n 's@^.*$s/\([a-z0-9_-]*\.c\).*$$@'"$$s"/'\1@p' \ + $(patsubst $(objpfx)%,%,$^) /dev/null` \ + /dev/null > $@T + mv -f $@T $@ + +# Make the distribution tar file. + +.PHONY: dist +dist: distinfo $(..)Make-dist + $(MAKE) -f $< -f $(word 2,$^) $(Make-dist-args) + +dist: $(distribute) + +# We used to simply export all these variables, but that frequently made the +# environment get too large. Instead, we write all the information into +# a generated makefile fragment `distinfo', and then include it with -f in +# the sub-make that makes the distribution (above). +distinfo: Makefile $(..)Makerules + $(distinfo-vars) + mv -f $@.new $@ + +define distinfo-vars +rm -f $@.new +$(foreach var,subdir sources elided-routines headers distribute \ + dont_distribute generated others tests, +echo >> $@.new '$(var) := $($(var))') +echo >> $@.new 'sources := $$(sources) $$(addsuffix .c,$$(elided-routines))' +endef + +ifneq (,$(strip $(gpl2lgpl))) +ifneq (,$(wildcard $(..)gpl2lgpl.sed)) +# Snarf from the master source and frob the copying notice. +$(gpl2lgpl): %: $(..)gpl2lgpl.sed /home/gd/gnu/lib/% + sed -f $^ > $@-tmp +# So I don't edit them by mistake. + chmod a-w $@-tmp + mv -f $@-tmp $@ + test -d CVS && cvs commit -m'Updated from $^' $@ +endif +endif @@ -0,0 +1,323 @@ +GNU C Library NEWS -- history of user-visible changes. 26 January 1995 + +Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +See the end for copying conditions. + +Please send GNU C library bug reports to bug-glibc@prep.ai.mit.edu. + +Version 1.10 + +* The library has changed from using GNU ld symbol aliases to using weak + symbols where available. The ELF object file format supports weak + symbols; GNU ld also supports weak symbols in the a.out format. (There + is also now support for other GNU ld extensions in ELF. Use the + `--with-elf' option to configure to indicate you have elf, and + `--with-gnu-ld' if using GNU ld.) This changed resulted in the deletion + of many files which contained only symbol aliases, reducing the size of + the source and the compiled library; many other files were renamed to + less cryptic names previously occupied by the symbol alias files. + +* The pgrp functions have been regularized, slightly incompatibly but much + less confusingly. The core functions are now `getpgid' and `setpgid', + which take arguments for the PID to operate on; the POSIX.1 `getpgrp' (no + argument) and BSD `setpgrp' (identical to `setpgid') functions are + provided for compatibility. There is no longer an incompatible `getpgrp' + with an argument declared under _BSD_SOURCE; no BSD code uses it. + +* The new header file <fts.h> and suite of functions simplify programs that + operate on directory trees. This code comes from 4.4 BSD. + +* Converted to Autoconf version 2, so `configure' has more options. + Run `configure --help' to see the details. + +* The resolver code has been updated from the BIND-4.9.3-BETA14 release. + +* The new function `malloc_find_object_address' finds the starting address + of a malloc'd block, given any address within the block. This can be + useful for debugging. + +* The new functions `strtoq' and `strtouq' parse integer values from + strings, like `strtol' and `strtoul', but they return `long long int' and + `unsigned long long int' values, respectively (64-bit quantities). + +* There is a new malloc debugging hook `__memalign_hook'. + +* There are new typedefs `ushort' for `unsigned short int' and `uint' for + `unsigned int' in <sys/types.h>. These are for compatibility only and + their use is discouraged. + +* The `-lmcheck' library to enable standard malloc debugging hooks is now + done differently, so that it works even without GNU ld. + +Version 1.09 + +* For cross-compilation you should now set `BUILD_CC' instead of `HOST_CC'. + +* New header file <fstab.h> and new functions `getfsspec', `getfsent' and + friends, for parsing /etc/fstab. This code comes from 4.4 BSD. + +* The new function `daemon' from 4.4 BSD is useful for server programs that + want to put themselves in the background. + +* Joel Sherrill has contributed support for several standalone boards that + run without an operating system. + +* `printf', `scanf' and friends now accept a `q' type modifier for long + long int as well as `ll'. Formats using these might be `%qu' or `%lld'. + +* All of the code taken from BSD (notably most of the math and networking + routines) has been updated from the BSD 4.4-Lite release. + +* The resolver code has been updated from the BIND-4.9.3-BETA9 release. + +* The new functions `getdomainname' and `setdomainname' fetch or change the + YP/NIS domain name. These are system calls which exist on systems which + have YP (aka NIS). + +* The time zone data files have been updated for the latest international + conventions. + +* The SunRPC programs `portmap' and `rpcinfo' are now installed in + $(sbindir) (usually /usr/local/sbin) instead of $(bindir). + +Version 1.08 + +* The C library now includes support for Sun RPC, from Sun's free + RPCSRC-4.0 distribution. The `portmap', `rpcinfo', and `rpcgen' programs + are included. (There is still no support for YP.) + +* Tom Quinn has contributed a port of the C library to SGI machines running + Irix 4 (mips-sgi-irix4). + +* The new `lockf' function is a simplified interface to the locking + facilities of `fcntl', included for compatibility. + +* New time functions `timegm', `timelocal', and `dysize' for compatibility. + +* New header file <sys/timeb.h> and new function `ftime' for compatibility. + +* New header files <poll.h> and <sys/poll.h> and new function `poll' for + compatibility. + +* The error message printed by `assert' for a failed assertion now includes + the name of the program (if using GNU ld) and the name of the calling + function (with versions of GCC that support this). + +* The `psignal' function is now declared in <signal.h>, not <stdio.h>. + +* The library now includes the <sys/mman.h> header file and memory + management functions `mmap', `munmap', `mprotect', `msync', and + `madvise', on systems that support those facilities. + +* The interface for `mcheck' has changed slightly: the function called to + abort the program when an allocation inconsistency is detected now takes + an argument that indicates the type of failure. The new function + `mprobe' lets you request a consistency check for a particular block at + any time (checks are normally done only when you call `free' or `realloc' + on a block). + +* It is now possible to easily cross-compile the C library, building on one + system a library to run on another machine and/or operating system. All + you need to do is set the variable `HOST_CC' in `configparms' to the + native compiler for programs to run on the machine you are building on (a + few generator programs are used on Unix systems); set `CC' to the + cross-compiler. + +* The new function `fexecve' (only implemented on the GNU system) executes + a program file given a file descriptor already open on the file. + +Version 1.07 + +* Brendan Kehoe has contributed most of a port to the DEC Alpha + running OSF/1 (alpha-dec-osf1). He says it is 75% complete. + +* You can set the variable `libprefix' in `configparms' to specify a prefix + to be prepended to installed library files; this makes it easy to install + the GNU C library to be linked as `-lgnuc' or whatever. + +* The new `stpncpy' is a cross between `stpcpy' and `strncpy': It + copies a limited number of characters from a string, and returns the + address of the last character written. + +* You no longer need to check for whether the installed `stddef.h' is + compatible with the GNU C library. configure now checks for you. + +* You can now define a per-stream `fileno' function to convert the + stream's cookie into an integral file descriptor. + +* ``malloc (0)'' no longer returns a null pointer. Instead, it + allocates zero bytes of storage, and returns a unique pointer which + you can pass to `realloc' or `free'. The behavior is undefined if + you dereference this pointer. + +* The C library now runs on Sony NEWS m68k machines running either + NewsOS 3 or NewsOS 4. + +* The new `syscall' function is a system-dependent primitive function + for invoking system calls. It has the canonical behavior on Unix + systems, including unreliable return values for some calls (such as + `pipe', `fork' and `getppid'). + +* The error code `EWOULDBLOCK' is now obsolete; it is always defined + to `EAGAIN', which is the preferred name. On systems whose kernels + use two distinct codes, the C library now translates EWOULDBLOCK to + EAGAIN in every system call function. + +Version 1.06 + +* The GNU C Library Reference Manual is now distributed with the library. + `make dvi' will produce a DVI file of the printed manual. + `make info' will produce Info files that you can read on line using C-h i + in Emacs or the `info' program. + Please send comments on the manual to bug-glibc-manual@prep.ai.mit.edu. + +* The library now supports SVR4 on i386s (i386-unknown-sysv4). + +* Brendan Kehoe has contributed a port to Sun SPARCs running Solaris 2. + +* Jason Merrill has contributed a port to the Sequent Symmetry running + Dynix version 3 (i386-sequent-dynix). + +* The library has been ported to i386s running SCO 3.2.4 (also known as SCO + ODT 2.0; i386-unknown-sco3.2.4) or SCO 3.2 (i386-unknown-sco3.2). + +* New function `memory_warnings' lets you arrange to get warnings when + malloc is running out of memory to allocate, like Emacs gives you. + +* The C library now contains the relocating allocator used in Emacs 19 for + its editing buffers. This allocator (ralloc) minimizes allocation + overhead and fragmentation by moving allocated regions around whenever it + needs to. You always refer to a ralloc'd region with a "handle" (a + pointer to a pointer--an object of type `void **'). + +* There is a new `printf' format: `%m' gives you the string corresponding + to the error code in `errno'. + +* In `scanf' formats, you can now use `%as' or `%a[' to do the normal `%s' + or `%[' conversion, but instead of filling in a fixed-sized buffer you + pass, the `a' modifier says to fill in a `char **' you pass with a + malloc'd string. + +* The `fnmatch' function supports the new flag bits `FNM_LEADING_DIR' and + `FNM_CASEFOLD'. `FNM_LEADING_DIR' lets a pattern like `foo*' match a + name like `foo/bar'. `FNM_CASEFOLD' says to ignore case in matching. + +* `mkstemp' is a traditional Unix function to atomically create and open a + uniquely-named temporary file. + +Version 1.05 + +* The standard location for the file that says what the local timezone is + has changed again. It is now `/usr/local/etc/localtime' (or more + precisely, `${prefix}/etc/localtime') rather than `/etc/localtime'. + +* The distribution no longer contains any files with names longer than 14 + characters. + +* `struct ttyent' has two new flag bits: TTY_TRUSTED and TTY_CONSOLE. + These are set by the new `trusted' and `console' keywords in `/etc/ttys'. + +* New functions `ttyslot' and `syslog' from 4.4 BSD. + +Version 1.04 + +* The configuration process has changed quite a bit. The `configure' + script is now used just like the configuration scripts for other GNU + packages. The `sysdeps' directory hierarchy is much rearranged. + The file `INSTALL' explains the new scheme in detail. + +* The header files no longer need to be processed into ANSI C and + traditional C versions. There is just one set of files to install, and + it will work with ANSI or old C compilers (including `gcc -traditional'). + +* Brendan Kehoe and Ian Lance Taylor have ported the library to the + MIPS DECStation running Ultrix 4. + +* The Sun 4 startup code (crt0) can now properly load SunOS 4 shared libraries. + Tom Quinn contributed the initial code. The GNU C library can NOT yet be + made itself into a shared library. + +* Yet further improved support for the i386, running 4.3 BSD-like systems + (such as Mach 3 with the Unix single-server), or System V. + +* New function `strncasecmp' to do case-insensitive string comparison + with limited length. + +* New function `strsep' is a reentrant alternative to `strtok'. + +* New functions `scandir' and `alphasort' for searching directories. + +* New function `setenv' is a better interface to `putenv'. + +* Ian Lance Taylor has contributed an implementation of the SVID `ftw' + function for traversing a directory tree. + +* The GNU obstack package is now also part of the C library. + The new function `open_obstack_stream' creates a stdio stream that + writes onto an obstack; `obstack_printf' and `obstack_vprintf' do + formatted output directly to an obstack. + +* Miscellaneous new functions: reboot, nice, sigaltstack (4.4 BSD only), + cfmakeraw, getusershell, getpass, swab, getttyent, seteuid, setegid. + +* `FNM_FILE_NAME' is another name for `FNM_PATHNAME', used with `fnmatch'. + +* The new functions `strfry' and `memfrob' do mysterious and wonderful + things to your strings. + +* There are some new test programs: test-fseek, testmb, and testrand. + +* Some work has been done to begin porting the library to 4.4 BSD and Linux. + These ports are not finished, but are a good starting place for really + supporting those systems. + +* `/etc/localtime' is now the standard location for the file that says what + the local timezone is, rather than `/usr/local/lib/zoneinfo/localtime'. + This follows the general principle that `/etc' is the place for all local + configuration files. + +* The C library header files now use `extern "C"' when used by the C++ + compiler, so the C library should now work with C++ code. + +* The header file <bstring.h> is gone. <string.h> now declares bcopy, + bcmp, bzero, and ffs. + +* Mike Haertel (of GNU e?grep and malloc fame) has written a new sorting + function which uses the `merge sort' algorithm, and is said to be + significantly faster than the old GNU `qsort' function. Merge sort is + now the standard `qsort' function. The new algorithm can require a lot + of temporary storage; so, the old sorting function is called when the + required storage is not available. + +* The C library now includes Michael Glad's Ultra Fast Crypt, which + provides the Unix `crypt' function, plus some other entry points. + Because of the United States export restriction on DES implementations, + we are distributing this code separately from the rest of the C library. + There is an extra distribution tar file just for crypt; it is called + `glibc-VERSION-crypt.tar.Z', e.g. `glibc-1.04-crypt.tar.Z'. You can just + unpack the crypt distribution along with the rest of the C library and + build; you can also build the library without getting crypt. Users + outside the USA can get the crypt distribution via anonymous FTP from + ftp.uni-c.dk [129.142.6.74], or another archive site outside the U.S. + +* The code and header files taken from 4.4 BSD have been updated with the + latest files released from Berkeley. + +---------------------------------------------------------------------- +Copyright information: + +Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + + Permission is granted to anyone to make or distribute verbatim copies + of this document as received, in any medium, provided that the + copyright notice and this permission notice are preserved, + thus giving the recipient permission to redistribute in turn. + + Permission is granted to distribute modified versions + of this document, or of portions of it, + under the above conditions, provided also that they + carry prominent notices stating who last changed them. + +Local variables: +version-control: never +end: @@ -0,0 +1,95 @@ +Feature Test Macros +------------------- + + The exact set of features available when you compile a source file +is controlled by which "feature test macros" you define. + + If you compile your programs using `gcc -ansi', you get only the +ANSI C library features, unless you explicitly request additional +features by defining one or more of the feature macros. *Note GNU CC +Command Options: (gcc.info)Invoking GCC, for more information about GCC +options. + + You should define these macros by using `#define' preprocessor +directives at the top of your source code files. These directives +*must* come before any `#include' of a system header file. It is best +to make them the very first thing in the file, preceded only by +comments. You could also use the `-D' option to GCC, but it's better +if you make the source files indicate their own meaning in a +self-contained way. + + - Macro: _POSIX_SOURCE + If you define this macro, then the functionality from the POSIX.1 + standard (IEEE Standard 1003.1) is available, as well as all of the + ANSI C facilities. + + - Macro: _POSIX_C_SOURCE + If you define this macro with a value of `1', then the + functionality from the POSIX.1 standard (IEEE Standard 1003.1) is + made available. If you define this macro with a value of `2', + then both the functionality from the POSIX.1 standard and the + functionality from the POSIX.2 standard (IEEE Standard 1003.2) are + made available. This is in addition to the ANSI C facilities. + + - Macro: _BSD_SOURCE + If you define this macro, functionality derived from 4.3 BSD Unix + is included as well as the ANSI C, POSIX.1, and POSIX.2 material. + + Some of the features derived from 4.3 BSD Unix conflict with the + corresponding features specified by the POSIX.1 standard. If this + macro is defined, the 4.3 BSD definitions take precedence over the + POSIX definitions. + + Due to the nature of some of the conflicts between 4.3 BSD and + POSIX.1, you need to use a special "BSD compatibility library" + when linking programs compiled for BSD compatibility. This is + because some functions must be defined in two different ways, one + of them in the normal C library, and one of them in the + compatibility library. If your program defines `_BSD_SOURCE', you + must give the option `-lbsd-compat' to the compiler or linker when + linking the program, to tell it to find functions in this special + compatibility library before looking for them in the normal C + library. + + - Macro: _SVID_SOURCE + If you define this macro, functionality derived from SVID is + included as well as the ANSI C, POSIX.1, and POSIX.2 material. + + - Macro: _GNU_SOURCE + If you define this macro, everything is included: ANSI C, POSIX.1, + POSIX.2, BSD, SVID, and GNU extensions. In the cases where POSIX.1 + conflicts with BSD, the POSIX definitions take precedence. + + If you want to get the full effect of `_GNU_SOURCE' but make the + BSD definitions take precedence over the POSIX definitions, use + this sequence of definitions: + + #define _GNU_SOURCE + #define _BSD_SOURCE + #define _SVID_SOURCE + + Note that if you do this, you must link your program with the BSD + compatibility library by passing the `-lbsd-compat' option to the + compiler or linker. *Note:* If you forget to do this, you may get + very strange errors at run time. + + We recommend you use `_GNU_SOURCE' in new programs. If you don't +specify the `-ansi' option to GCC and don't define any of these macros +explicitly, the effect is the same as defining `_GNU_SOURCE'. + + When you define a feature test macro to request a larger class of +features, it is harmless to define in addition a feature test macro for +a subset of those features. For example, if you define +`_POSIX_C_SOURCE', then defining `_POSIX_SOURCE' as well has no effect. +Likewise, if you define `_GNU_SOURCE', then defining either +`_POSIX_SOURCE' or `_POSIX_C_SOURCE' or `_SVID_SOURCE' as well has no +effect. + + Note, however, that the features of `_BSD_SOURCE' are not a subset of +any of the other feature test macros supported. This is because it +defines BSD features that take precedence over the POSIX features that +are requested by the other macros. For this reason, defining +`_BSD_SOURCE' in addition to the other feature test macros does have an +effect: it causes the BSD features to take priority over the conflicting +POSIX features. + diff --git a/README b/README new file mode 100644 index 0000000000..b9b43e3f4d --- /dev/null +++ b/README @@ -0,0 +1,67 @@ +This directory contains the version 1.09.5 test release of the GNU C Library. +Many bugs have been fixed since the last release. +Some bugs surely remain. + +As of this release, the GNU C library has been ported to the following +configurations: + + alpha-dec-osf1 + i386-bsd4.3 + i386-force_cpu386-none + i386-gnu (for Hurd development only) + i386-isc2.2 + i386-isc3 + i386-sco3.2 + i386-sco3.2v4 + i386-sequent-bsd + i386-sysv + i386-sysv4 + i960-nindy960-none + m68k-hp-bsd4.3 + m68k-mvme135-none + m68k-mvme136-none + m68k-sony-newsos3 + m68k-sony-newsos4 + m68k-sun-sunos4 + mips-dec-ultrix4 + mips-sgi-irix4 + sparc-sun-solaris2 + sparc-sun-sunos4 + +Porting the library is not hard. If you are interested in doing a port, +please get on the mailing list by sending electronic mail to +bug-glibc-request@prep.ai.mit.edu. + +The GNU C library now includes Michael Glad's Ultra Fast Crypt, which +provides the Unix `crypt' function, plus some other entry points. +Because of the United States export restriction on DES implementations, +we are distributing this code separately from the rest of the C +library. There is an extra distribution tar file just for crypt; it is +called `glibc-1.09.5-crypt.tar.gz'. You can just unpack the crypt +distribution along with the rest of the C library and build; you can +also build the library without getting crypt. Users outside the USA +can get the crypt distribution via anonymous FTP from ftp.uni-c.dk +[129.142.6.74], or another archive site outside the USA. Archive +maintainers are encouraged to copy this distribution to their archives +outside the USA. Please get it from ftp.uni-c.dk; transferring this +distribution from prep.ai.mit.edu (or any other site in the USA) to a +site outside the USA is in violation of US export laws. + +See the file INSTALL to find out how to configure, build, install, and port +the GNU C library. + +The GNU C Library is completely documented by the Texinfo manual found +in the `manual/' subdirectory. The manual is still being updated and +contains some known errors and omissions; we regret that we do not have +the resources to work on the manual as much as we would like. Please +send comments on the manual to bug-glibc-manual@prep.ai.mit.edu, and +not to the library bug-reporting address. + +The file NOTES contains a description of the feature-test macros used +in the GNU C library, explaining how you can tell the library what +facilities you want it to make available. + +Send bug reports to bug-glibc@prep.ai.mit.edu. + +The GNU C Library is free software. See the file COPYING.LIB for copying +conditions. diff --git a/README.template b/README.template new file mode 100644 index 0000000000..6cd5ffab91 --- /dev/null +++ b/README.template @@ -0,0 +1,67 @@ +This directory contains the version VERSION test release of the GNU C Library. +Many bugs have been fixed since the last release. +Some bugs surely remain. + +As of this release, the GNU C library has been ported to the following +configurations: + + alpha-dec-osf1 + i386-bsd4.3 + i386-force_cpu386-none + i386-gnu (for Hurd development only) + i386-isc2.2 + i386-isc3 + i386-sco3.2 + i386-sco3.2v4 + i386-sequent-bsd + i386-sysv + i386-sysv4 + i960-nindy960-none + m68k-hp-bsd4.3 + m68k-mvme135-none + m68k-mvme136-none + m68k-sony-newsos3 + m68k-sony-newsos4 + m68k-sun-sunos4 + mips-dec-ultrix4 + mips-sgi-irix4 + sparc-sun-solaris2 + sparc-sun-sunos4 + +Porting the library is not hard. If you are interested in doing a port, +please get on the mailing list by sending electronic mail to +bug-glibc-request@prep.ai.mit.edu. + +The GNU C library now includes Michael Glad's Ultra Fast Crypt, which +provides the Unix `crypt' function, plus some other entry points. +Because of the United States export restriction on DES implementations, +we are distributing this code separately from the rest of the C +library. There is an extra distribution tar file just for crypt; it is +called `glibc-VERSION-crypt.tar.gz'. You can just unpack the crypt +distribution along with the rest of the C library and build; you can +also build the library without getting crypt. Users outside the USA +can get the crypt distribution via anonymous FTP from ftp.uni-c.dk +[129.142.6.74], or another archive site outside the USA. Archive +maintainers are encouraged to copy this distribution to their archives +outside the USA. Please get it from ftp.uni-c.dk; transferring this +distribution from prep.ai.mit.edu (or any other site in the USA) to a +site outside the USA is in violation of US export laws. + +See the file INSTALL to find out how to configure, build, install, and port +the GNU C library. + +The GNU C Library is completely documented by the Texinfo manual found +in the `manual/' subdirectory. The manual is still being updated and +contains some known errors and omissions; we regret that we do not have +the resources to work on the manual as much as we would like. Please +send comments on the manual to bug-glibc-manual@prep.ai.mit.edu, and +not to the library bug-reporting address. + +The file NOTES contains a description of the feature-test macros used +in the GNU C library, explaining how you can tell the library what +facilities you want it to make available. + +Send bug reports to bug-glibc@prep.ai.mit.edu. + +The GNU C Library is free software. See the file COPYING.LIB for copying +conditions. @@ -0,0 +1,128 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Rules for making a subdirectory in the GNU C library. +# Each subdirectory Makefile defines some variables and includes this. +# +ifneq (,) +This makefile requires GNU Make. +endif + +all: # Don't let the default goal come from Makeconfig. + +include ../Makeconfig + +ifndef subdir +Each subdirectory makefile must define the `subdir' variable. +endif +# This is benign and useless in GNU make before 3.63. +export subdir := $(subdir) + +# This is the default target; it makes the library and auxiliary programs. +.PHONY: all +all: lib others + +ifneq "$(findstring env,$(origin headers))" "" +headers := +endif + +ifneq "$(findstring env,$(origin generated))" "" +generated := +endif + +ifeq "$(strip $(headers))" "" +ifneq "$(wildcard $(subdir).h)" "" +override headers := $(subdir).h +endif +endif + +include ../Makerules + +.PHONY: subdir_lib +subdir_lib: lib-noranlib + +# Some subdirs need to install a dummy library. +# They can use "$(objpfx)libfnord.a: $(dep-dummy-lib); $(make-dummy-lib)". +dep-dummy-lib = $(objpfx)dummy.o +define make-dummy-lib +$(AR) cr$(verbose) $@ $< +endef +$(objpfx)dummy.o: + @rm -f $(@:.o=.c) + echo 'void __dummy__ () { }' > $(@:.o=.c) + $(CC) -c $(@:.o=.c) -o $@ + +# This makes all the auxilliary and test programs. + +.PHONY: others tests +others: $(addprefix $(objpfx),$(others)) +ifeq ($(cross-compiling),yes) +tests: $(addprefix $(objpfx),$(tests)) +else +tests: $(tests:%=$(objpfx)%.out) +endif + +ifneq "$(strip $(others) $(tests))" "" +$(addprefix $(objpfx),$(others) $(tests)): %: %.o $(libc.a) + $(+link) +endif + +ifneq "$(strip $(tests))" "" +# These are the implicit rules for making test outputs +# from the test programs and whatever input files are present. +$(objpfx)%.out: $(objpfx)% %.args %.input + $(dir $<)$(notdir $<) `cat $(word 2,$^)` < $(word 3,$^) > $@ +$(objpfx)%.out: $(objpfx)% %.args + $(dir $<)$(notdir $<) `cat $(word 2,$^)` > $@ +$(objpfx)%.out: $(objpfx)% %.input + $(dir $<)$(notdir $<) < $(word 2,$^) > $@ +$(objpfx)%.out: $(objpfx)% + $(dir $<)$(notdir $<) > $@ +endif # tests + +.PHONY: distclean realclean subdir_distclean subdir_realclean \ + subdir_clean subdir_mostlyclean +subdir_mostlyclean: mostlyclean +subdir_clean: clean +subdir_distclean: distclean +subdir_realclean: realclean +realclean: distclean +distclean: clean + +.PHONY: subdir_echo-headers +subdir_echo-headers: echo-headers + +.PHONY: subdir_echo-distinfo +subdir_echo-distinfo: + @echo $(addprefix +header+,$(headers)) \ + $(addprefix +nodist+,$(generated) $(dont_distribute)) + +# We want to install everything except the library itself, but update all +# our portions of the library because the parent make will install it later +# (likewise the stubs file). +.PHONY: subdir_install +subdir_install: install-no-libc.a lib-noranlib stubs + +.PHONY: subdir_TAGS subdir_dist +subdir_TAGS: TAGS +subdir_dist: dist + +# Convenient target to update all the generated source files. +.PHONY: generated +generated: $(addprefix $(objpfx),$(generated)) diff --git a/a.out.h b/a.out.h new file mode 100644 index 0000000000..9582d72ba0 --- /dev/null +++ b/a.out.h @@ -0,0 +1 @@ +#include <misc/a.out.h> diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000000..1d48b8f875 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,32 @@ +dnl We define the macro GLIBC_PROVIDES to do an AC_PROVIDE for each macro +dnl which appears in configure.in before the sysdep configure scripts are run. +dnl Each sysdep configure.in does GLIBC_PROVIDES first, to avoid any +dnl AC_REQUIREs or AC_BEFOREs duplicating their code. +dnl +define(AC_FD_MSG,4)dnl Autoconf lossage. +AC_DEFUN([GLIBC_PROVIDES], [dnl +AC_PROVIDE([AC_PROG_INSTALL])dnl +AC_PROVIDE([AC_PROG_RANLIB])dnl +AC_PROVIDE([AC_PROG_CC])dnl +AC_PROVIDE([AC_PROG_CPP])dnl +# This file is generated from configure.in by Autoconf. DO NOT EDIT! +])dnl +dnl +dnl Check for a symbol +dnl +AC_DEFUN(AC_CHECK_SYMBOL, [dnl +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL(ac_cv_check_symbol_$1, [dnl +AC_TRY_LINK(, +changequote(,)dnl +extern char *$1[]; puts(*$1);, +changequote([,])dnl + ac_cv_check_symbol_$1=yes, ac_cv_check_symbol_$1=no)]) +if test "$ac_cv_check_symbol_$1" = yes; then +changequote(,)dnl + ac_tr_symbol=`echo $1 | tr '[a-z]' '[A-Z]'` +changequote([,])dnl + AC_DEFINE_UNQUOTED(HAVE_${ac_tr_symbol}) +fi +AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl +dnl diff --git a/alloca.h b/alloca.h new file mode 100644 index 0000000000..34eeeab78e --- /dev/null +++ b/alloca.h @@ -0,0 +1 @@ +#include <stdlib/alloca.h> diff --git a/ansidecl.h b/ansidecl.h new file mode 100644 index 0000000000..c351653b62 --- /dev/null +++ b/ansidecl.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* ANSI and traditional C compatibility macros + + ANSI C is assumed if __STDC__ is #defined. + + Macro ANSI C definition Traditional C definition + ----- ---- - ---------- ----------- - ---------- + PTR `void *' `char *' + LONG_DOUBLE `long double' `double' + CONST `const' `' + VOLATILE `volatile' `' + SIGNED `signed' `' + PTRCONST `void *const' `char *' + + DEFUN(name, arglist, args) + + Defines function NAME. + + ARGLIST lists the arguments, separated by commas and enclosed in + parentheses. ARGLIST becomes the argument list in traditional C. + + ARGS list the arguments with their types. It becomes a prototype in + ANSI C, and the type declarations in traditional C. Arguments should + be separated with `AND'. For functions with a variable number of + arguments, the last thing listed should be `DOTS'. + + DEFUN_VOID(name) + + Defines a function NAME, which takes no arguments. + + EXFUN(name, prototype) + + Is used in an external function declaration. + In ANSI C it is `NAMEPROTOTYPE' (so PROTOTYPE should be enclosed in + parentheses). In traditional C it is `NAME()'. + For a function that takes no arguments, PROTOTYPE should be `(NOARGS)'. + + For example: + extern int EXFUN(printf, (CONST char *format DOTS)); + int DEFUN(fprintf, (stream, format), + FILE *stream AND CONST char *format DOTS) { ... } + void DEFUN_VOID(abort) { ... } +*/ + +#ifndef _ANSIDECL_H + +#define _ANSIDECL_H 1 + + +/* Every source file includes this file, + so they will all get the switch for lint. */ +/* LINTLIBRARY */ + + +#ifdef __STDC__ + +#define PTR void * +#define PTRCONST void *CONST +#define LONG_DOUBLE long double + +#define AND , +#define NOARGS void +#define CONST const +#define VOLATILE volatile +#define SIGNED signed +#define DOTS , ... + +#define EXFUN(name, proto) name proto +#define DEFUN(name, arglist, args) name(args) +#define DEFUN_VOID(name) name(NOARGS) + +#else /* Not ANSI C. */ + +#define PTR char * +#define PTRCONST PTR +#define LONG_DOUBLE double + +#define AND ; +#define NOARGS +#define CONST +#define VOLATILE +#define SIGNED +#define DOTS + +#define EXFUN(name, proto) name() +#define DEFUN(name, arglist, args) name arglist args; +#define DEFUN_VOID(name) name() + +#endif /* ANSI C. */ + + +#endif /* ansidecl.h */ diff --git a/arpa/ftp.h b/arpa/ftp.h new file mode 100644 index 0000000000..c716d68156 --- /dev/null +++ b/arpa/ftp.h @@ -0,0 +1 @@ +#include <inet/arpa/ftp.h> diff --git a/arpa/inet.h b/arpa/inet.h new file mode 100644 index 0000000000..65733b618c --- /dev/null +++ b/arpa/inet.h @@ -0,0 +1 @@ +#include <inet/arpa/inet.h> diff --git a/arpa/nameser.h b/arpa/nameser.h new file mode 100644 index 0000000000..944fe732a6 --- /dev/null +++ b/arpa/nameser.h @@ -0,0 +1 @@ +#include <resolv/arpa/nameser.h> diff --git a/arpa/telnet.h b/arpa/telnet.h new file mode 100644 index 0000000000..742c04cfe3 --- /dev/null +++ b/arpa/telnet.h @@ -0,0 +1 @@ +#include <inet/arpa/telnet.h> diff --git a/arpa/tftp.h b/arpa/tftp.h new file mode 100644 index 0000000000..21d5197f24 --- /dev/null +++ b/arpa/tftp.h @@ -0,0 +1 @@ +#include <inet/arpa/tftp.h> diff --git a/assert.h b/assert.h new file mode 100644 index 0000000000..e2fa7020c1 --- /dev/null +++ b/assert.h @@ -0,0 +1 @@ +#include <assert/assert.h> diff --git a/assert/Makefile b/assert/Makefile new file mode 100644 index 0000000000..76b75bb2f8 --- /dev/null +++ b/assert/Makefile @@ -0,0 +1,26 @@ +# Copyright (C) 1991, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for assert portion of the library. +# +subdir := assert + +routines := assert assert-perr + +include ../Rules diff --git a/assert/assert-perr.c b/assert/assert-perr.c new file mode 100644 index 0000000000..b0436ad575 --- /dev/null +++ b/assert/assert-perr.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <sysdep.h> + + +extern const char *__assert_program_name; /* In assert.c. */ + +/* This function, when passed an error number, a filename, and a line + number, prints a message on the standard error stream of the form: + a.c:10: foobar: Unexpected error: Computer bought the farm + It then aborts program execution via a call to `abort'. */ + +#ifdef FATAL_PREPARE_INCLUDE +#include FATAL_PREPARE_INCLUDE +#endif + +void +__assert_perror_fail (int errnum, + const char *file, unsigned int line, + const char *function) +{ +#ifdef FATAL_PREPARE + FATAL_PREPARE; +#endif + + /* Print the message. */ + (void) fprintf (stderr, "%s%s%s:%u: %s%sUnexpected error: %s.\n", + __assert_program_name ? __assert_program_name : "", + __assert_program_name ? ": " : "", + file, line, + function ? function : "", function ? ": " : "", + strerror (errnum)); + (void) fflush (stderr); + + abort (); +} diff --git a/assert/assert.c b/assert/assert.c new file mode 100644 index 0000000000..9da9e22be4 --- /dev/null +++ b/assert/assert.c @@ -0,0 +1,83 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <sysdep.h> + + +CONST char *__assert_program_name; + +/* This function, when passed a string containing an asserted + expression, a filename, and a line number, prints a message + on the standard error stream of the form: + a.c:10: foobar: Assertion `a == b' failed. + It then aborts program execution via a call to `abort'. */ + +#ifdef FATAL_PREPARE_INCLUDE +#include FATAL_PREPARE_INCLUDE +#endif + +void +DEFUN(__assert_fail, (assertion, file, line, function), + CONST char *assertion AND + CONST char *file AND unsigned int line AND CONST char *function) +{ +#ifdef FATAL_PREPARE + FATAL_PREPARE; +#endif + + /* Print the message. */ + (void) fprintf (stderr, "%s%s%s:%u: %s%sAssertion `%s' failed.\n", + __assert_program_name ? __assert_program_name : "", + __assert_program_name ? ": " : "", + file, line, + function ? function : "", function ? ": " : "", + assertion); + (void) fflush (stderr); + + abort (); +} + +#ifdef HAVE_GNU_LD + +#include <string.h> + +static void +DEFUN(set_progname, (argc, argv, envp), + int argc AND char **argv AND char **envp) +{ + char *p; + + if (argv && argv[0]) + { + p = strrchr (argv[0], '/'); + if (p == NULL) + __assert_program_name = argv[0]; + else + __assert_program_name = p + 1; + } + + (void) &set_progname; /* Avoid "defined but not used" warning. */ +} + +text_set_element (__libc_subinit, set_progname); + +#endif diff --git a/assert/assert.h b/assert/assert.h new file mode 100644 index 0000000000..7f7fc7f733 --- /dev/null +++ b/assert/assert.h @@ -0,0 +1,98 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.2 DIAGNOSTICS <assert.h> + */ + +#ifdef _ASSERT_H + +#undef _ASSERT_H +#undef assert + +#endif /* assert.h */ + +#define _ASSERT_H 1 +#include <features.h> + +/* void assert (int expression); + + If NDEBUG is defined, do nothing. + If not, and EXPRESSION is zero, print an error message and abort. */ + +#ifdef NDEBUG + +#define assert(expr) ((void) 0) + +/* void assert_perror (int errnum); + + If NDEBUG is defined, do nothing. If not, and ERRNUM is not zero, print an + error message with the error text for ERRNUM and abort. + (This is a GNU extension.) */ + +#ifdef __USE_GNU +#define assert_perror(errnum) ((void) 0) +#endif + +#else /* Not NDEBUG. */ + +#include <sys/cdefs.h> + +__BEGIN_DECLS + +/* This prints an "Assertion failed" message and aborts. */ +extern void __assert_fail __P ((__const char *__assertion, + __const char *__file, + unsigned int __line, + __const char *__function)) + __attribute__ ((__noreturn__)); + +/* Likewise, but prints the error text for ERRNUM. */ +extern void __assert_perror_fail __P ((int __errnum, + __const char *__file, + unsigned int __line, + __const char *__function)) + __attribute__ ((__noreturn__)); + +__END_DECLS + +#define assert(expr) \ + ((void) ((expr) || \ + (__assert_fail (__STRING(expr), \ + __FILE__, __LINE__, __ASSERT_FUNCTION), 0))) + +#ifdef __USE_GNU +#define assert_perror(errnum) \ + ((void) ((errnum) && (__assert_perror_fail ((errnum), \ + __FILE__, __LINE__, \ + __ASSERT_FUNCTION), 0))) +#endif + +/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__' + which contains the name of the function currently being defined. + This is broken in G++ before version 2.6. */ +#if (!defined (__GNUC__) || __GNUC__ < 2 || \ + __GNUC_MINOR__ < (defined (__cplusplus) ? 6 : 4)) +#define __ASSERT_FUNCTION ((__const char *) 0) +#else +#define __ASSERT_FUNCTION __PRETTY_FUNCTION__ +#endif + + +#endif /* NDEBUG. */ + diff --git a/bare/Makefile b/bare/Makefile new file mode 100644 index 0000000000..588a713c83 --- /dev/null +++ b/bare/Makefile @@ -0,0 +1,55 @@ +# Copyright (C) 1994 Free Software Foundation, Inc. +# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), +# On-Line Applications Research Corporation. +# +# This file is part of the GNU C Library. +# +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := bare + +bare-routines := brdinit console strtsupp +routines = $(bare-routines) +elided-routines = $(bare-routines) +extra-objs = $(bare-routines:%=%.o) + +install-lib = lib$(config-vendor).a + +include ../Rules + +# +# For bare targets, the $(config-vendor) is the name of the board. +# We will place the board dependent code ONLY in a library which +# is board dependent. This way many target boards can share a +# single libc.a. To resolve all symbols and successfully link +# a program, the application must link against libc.a and libMY_TARGET.a. +# For example, the target specific library for the Motorola MVME135 +# board will be named libmvme135.a. To link a program for the +# MVME135, one must link against -lc and -lmvme135. +# + +lib: $(objpfx)lib$(config-vendor).a + +$(objpfx)lib$(config-vendor).a: $(bare-routines:%=$(objpfx)%.o) +# This library is small enough that it's simplest to recreate the archive +# from scratch each time. + rm -f $@ +ifdef objdir + cd $(objdir); $(AR) cq$(verbose) $@ $(^:$(objpfx)%=%) +else + $(AR) cq$(verbose) $@ $^ +endif + $(RANLIB) $@ diff --git a/conf/portability.h b/conf/portability.h new file mode 100644 index 0000000000..ab41b5d977 --- /dev/null +++ b/conf/portability.h @@ -0,0 +1,20 @@ +/* This file is used by some of the resolver code in inet/ that + comes from BIND 4.9. I have written this file instead of modifying + those things not to use it so that I can later drop in replacement + files from future BIND distributions without change. */ + +#include <unistd.h> +#include <string.h> +#include <stdlib.h> + +/* Some BIND code decides it can omit the definitions of some functions + if BSD is defined to some value. That might make sense when the BIND + code is augmenting or replacing an existing system library, but we can + never omit a function here, since we are defining the system library. */ + +#undef BSD + +/* Some code does stupid compatibility kludges for SunOS braindeath + #ifdef sun. */ + +#undef sun diff --git a/config-name.in b/config-name.in new file mode 100644 index 0000000000..6380b09254 --- /dev/null +++ b/config-name.in @@ -0,0 +1,10 @@ +/* @configure_input@ -*- C -*- + Generated from $Id$. + + This is used only by the generic `uname' function for systems with no real + `uname' call. If this data is not correct, it does not matter much. */ + +#define UNAME_SYSNAME "@uname_sysname@" +#define UNAME_RELEASE "@uname_release@" +#define UNAME_VERSION "@uname_version@" +#define UNAME_MACHINE "@host_cpu@-@host_vendor@" diff --git a/config.guess b/config.guess new file mode 100755 index 0000000000..4d4e6944a8 --- /dev/null +++ b/config.guess @@ -0,0 +1,494 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner <bothner@cygnus.com>. +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:V*:*) + # After 1.2, OSF1 uses "V1.3" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` + exit 0 ;; + alpha:OSF1:*:*) + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + sun4*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:5*:RISCos) + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i[34]86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then + IBM_REV=4.1 + elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then + IBM_REV=4.1.1 + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?7:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:UNICOS:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:UNICOS:*:*) + echo ymp-cray-unicos + exit 0 ;; + CRAY-2:UNICOS:*:*) + echo cray2-cray-unicos + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + i[34]86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i[34]86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i[34]86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-unknown-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-unknown-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M680[234]0:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3 && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m680[234]0:LynxOS:2.2*:*) + echo m68k-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i[34]86:LynxOS:2.2*:*) + echo i386-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.2*:*) + echo sparc-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.2*:*) + echo rs6000-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c <<EOF +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-unknown-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000000..5761db2c5c --- /dev/null +++ b/config.h.in @@ -0,0 +1,30 @@ +/* Define if using GNU ld, with support for weak symbols in a.out, + and for symbol set and warning messages extensions in a.out and ELF. + This implies HAVE_WEAK_SYMBOLS; set by --with-gnu-ld. */ +#undef HAVE_GNU_LD + +/* Define if using ELF, which supports weak symbols. + This implies HAVE_WEAK_SYMBOLS; set by --with-elf. */ +#undef HAVE_ELF + +/* Define if weak symbols are available in the assembler and + linker being used. Set by --with-weak-symbols. */ +#undef HAVE_WEAK_SYMBOLS + +/* Define if using the GNU assembler, gas. */ +#undef HAVE_GNU_AS + +/* These symbols might be defined by some sysdeps configures. */ + +/* sysdeps/generic/configure.in */ +#undef HAVE_PSIGNAL + +/* sysdeps/unix/common/configure.in */ +#undef HAVE_SYS_SIGLIST +#undef HAVE__SYS_SIGLIST +#undef HAVE__CTYPE_ +#undef HAVE___CTYPE_ +#undef HAVE___CTYPE +#undef HAVE__CTYPE__ +#undef HAVE__CTYPE +#undef HAVE__LOCP diff --git a/config.make.in b/config.make.in new file mode 100644 index 0000000000..b2105e01af --- /dev/null +++ b/config.make.in @@ -0,0 +1,26 @@ +# @configure_input@ +# From $Id$. +# Don't edit this file. Put configuration parameters in configparms instead. + +config-machine = @host_cpu@ +config-vendor = @host_vendor@ +config-os = @host_os@ +config-sysdirs = @sysnames@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +config-defines = @DEFS@ +gnu-as = @gnu_as@ +gnu-ld = @gnu_ld@ +elf = @elf@ +weak-symbols = @weak@ + +CC = @CC@ +AR = @AR@ +RANLIB = @RANLIB@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +# More variables may be inserted below by configure. diff --git a/config.sub b/config.sub new file mode 100755 index 0000000000..667d3d23be --- /dev/null +++ b/config.sub @@ -0,0 +1,816 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS (if any). +basic_machine=`echo $1 | sed 's/-[^-]*$//'` +if [ $basic_machine != $1 ] +then os=`echo $1 | sed 's/.*-/-/'` +else os=; fi + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -lynx) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ + | powerpc | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel \ + | sparc) + basic_machine=$basic_machine-unknown + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[345]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv32 + ;; + i[345]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv4 + ;; + i[345]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv + ;; + i[345]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium-*) + # We will change tis to say i586 once there has been + # time for various packages to start to recognize that. + basic_machine=i486-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + ps2) + basic_machine=i386-ibm + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware* | svr4*) + os=-sysv4 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative must end in a *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \ + | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ + | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi | -eabi) + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-masscomp) + os=-rtu + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxworks*) + vendor=wrs + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 0000000000..9a36433099 --- /dev/null +++ b/configure @@ -0,0 +1,1503 @@ +#! /bin/sh + +# From configure.in Id: configure.in,v 1.72 1995/01/30 07:26:57 roland Exp roland +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.1.1 +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-gmp=DIRECTORY find GMP source code in DIRECTORY (not needed)" +ac_help="$ac_help + --with-gnu-binutils if using GNU binutils (as and ld)" +ac_help="$ac_help + --with-gnu-ld if using GNU ld (in the binutils package)" +ac_help="$ac_help + --with-gnu-as if using GNU as (in the binutils package)" +ac_help="$ac_help + --with-elf if using the ELF object format" +ac_help="$ac_help + --with-weak-symbols if weak symbols are available in as and ld" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE + +# Initialize some other variables. +subdirs= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=PREFIX install architecture-dependent files in PREFIX + [same as prefix] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +--enable and --with options recognized:$ac_help +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.1.1" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 4 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 4>/dev/null +else + exec 4>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=features.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} conftest.$ac_ext $CFLAGS $CPPFLAGS -c 1>&5 2>&5' +ac_link='${CC-cc} conftest.$ac_ext $CFLAGS $CPPFLAGS $LDFLAGS -o conftest $LIBS 1>&5 2>&5' + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + if test -r /vmunix; then + kernel_id=`strings /vmunix | grep UNIX` + elif test -r /dynix; then + kernel_id=`strings /dynix | grep DYNIX` + else + kernel_id= + fi + + + + +# This will get text that should go into config.make. +config_vars= + +# Check for a --with-gmp argument and set gmp-srcdir in config.make. +# Check whether --with-gmp or --without-gmp was given. +withval="$with_gmp" +if test -n "$withval"; then + case "$with_gmp" in +yes) { echo "configure: error: --with-gmp requires an argument; use --with-gmp=DIRECTORY" 1>&2; exit 1; } ;; +''|no) ;; +*) config_vars="$config_vars +gmp-srcdir = $withval" ;; +esac + +fi + + +# Check whether --with-gnu-binutils or --without-gnu-binutils was given. +withval="$with_gnu_binutils" +if test -n "$withval"; then + gnu_binutils=yes +else + gnu_binutils=no +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +withval="$with_gnu_ld" +if test -n "$withval"; then + gnu_ld=yes +else + gnu_ld=no +fi + +# Check whether --with-gnu-as or --without-gnu-as was given. +withval="$with_gnu_as" +if test -n "$withval"; then + gnu_as=yes +else + gnu_as=no +fi + +test $gnu_binutils = yes && gnu_as=yes gnu_ld=yes +# Check whether --with-elf or --without-elf was given. +withval="$with_elf" +if test -n "$withval"; then + elf=yes +else + elf=no +fi + +# Check whether --with-weak-symbols or --without-weak-symbols was given. +withval="$with_weak_symbols" +if test -n "$withval"; then + weak=yes +else + weak=no +fi + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Make sure we can run config.sub. +if $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&4 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`$ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`$ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&4 + +# We keep the original values in `$config_*' and never modify them, so we +# can write them unchanged into config.make. Everything else uses +# $machine, $vendor, and $os, and changes them whenever convenient. +config_machine=$host_cpu config_vendor=$host_vendor config_os=$host_os + +sysdep_dir=$srcdir/sysdeps +echo $ac_n "checking sysdep dirs""... $ac_c" 1>&4 +if eval "test \"`echo '${'libc_cv_sysdirs'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + machine=$config_machine +vendor=$config_vendor +os=$config_os + +# Expand the configuration machine name into a subdirectory by architecture +# type and particular chip. +case "$machine" in +i[345]86) + machine=i386/$machine ;; +sparc[6789]) + machine=sparc/$machine ;; +m68k) + machine=m68k/m68020 ;; +m680?0) + machine=m68k/$machine ;; +m88k) + machine=m88k/m88100 ;; +m88???) + machine=m88k/$machine ;; +mips64*) + machine=mips/mips64/$machine ;; +mips*) + machine=mips/$machine ;; +esac + +# Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1. +os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`" + +case "$os" in +gnu*) + base_os=mach/hurd ;; +netbsd* | 386bsd*) + base_os=unix/bsd/bsd4.4 ;; +osf1* | sunos* | ultrix* | newsos* | dynix* | *bsd*) + base_os=unix/bsd ;; +linux* | sysv* | isc* | esix* | sco* | minix* | irix4*) + base_os=unix/sysv ;; +solaris[2-9]*) + base_os=unix/sysv/sysv4 ;; +none) + base_os=standalone ;; +*) + base_os='' ;; +esac + +# For sunos4.1.1, try sunos4.1.1, then sunos4.1, then sunos4, then sunos. +tail=$os +ostry=$os +while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do + ostry="$ostry /$o" + tail=$o +done +o=`echo $tail | sed 's/[0-9]*$//'` +if test $o != $tail; then + ostry="$ostry /$o" +fi + +# For unix/sysv/sysv4, try unix/sysv/sysv4, then unix/sysv, then unix. +base= +tail=$base_os +while b=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$b"; do + set $b + base="$base /$1" + tail="$2" +done + +# For sparc/sparc9, try sparc/sparc9 and then sparc. +mach= +tail=$machine +while m=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$m"; do + set $m + mach="$mach /$1" + tail="$2" +done + + +# Find what sysdep directories exist. +sysnames= +for b in $base ''; do + for m0 in $mach ''; do + for v in /$vendor ''; do + for o in /$ostry ''; do + for m in $mach ''; do + try="$m0$b$v$o$m" + if test -d $sysdep_dir$try; then + sysnames="$sysnames $try" + { test -n "$o" || test -n "$b"; } && os_used=t + { test -n "$m" || test -n "$m0"; } && machine_used=t + fi + done + done + done + done +done + +if test -z "$os_used" && test "$os" != none; then + { echo "configure: error: Operating system $os is not supported." 1>&2; exit 1; } +fi +if test -z "$machine_used" && test "$machine" != none; then + { echo "configure: error: The $machine is not supported." 1>&2; exit 1; } +fi + +# We have now validated the configuration. + +# Remove the leading slashes. +sysnames="`echo $sysnames | sed -e 's@^/@@' -e 's@ /@ @g'`" + +# Prepend the machine's FPU directory unless --without-fp. +if test "$with_fp" = no; then + fpu_dirs= + for m in $mach; do + if test -d $sysdep_dir$m/fpu; then + fpu_dirs="$fpu_dirs $m/fpu" + fi + done + sysnames="`echo $fpu_dirs | sed -e 's,^/,,' -e 's, /,,g'` $sysnames" +fi + +# Expand the list of system names into a full list of directories +# from each element's parent name and Implies file (if present). +set $sysnames +while test $# -gt 0; do + name=$1 + shift + + if test -f $sysdep_dir/$name/Implies; then + # Collect more names from the `Implies' file (removing comments). + implied="`sed 's/#.*$//' < $sysdep_dir/$name/Implies`" + for x in $implied; do + test -d $sysdep_dir/$x || echo "Warning: $name implies nonexistent $x">&2 + done + else + implied= + fi + + # Add NAME to the list of names. + names="$names $name" + + # Find the parent of NAME, using the empty string if it has none. + parent="`echo $name | sed -n -e '/\//!q' -e 's=/[^/]*$==p'`" + + # Add the names implied by NAME, and NAME's parent (if it has one), to + # the list of names to be processed (the argument list). We prepend the + # implied names to the list and append the parent. We want implied + # directories to come before further directories inferred from the + # configuration components; this ensures that for sysv4, unix/common + # (implied by unix/sysv/sysv4) comes before unix/sysv (in ostry (here $*) + # after sysv4). + sysnames="`echo $implied $* $parent`" + test -n "$sysnames" && set $sysnames +done + +# Add the default directories. +names="$names generic stub" + +# Now uniquize the list. +seen= +sysnames= +for name in $names; do + if echo "$seen" | fgrep -x $name >/dev/null; then + # Already in the list. + true; + else + # A new one. + if test -z "$seen"; then + seen="$name" sysnames="$name" + else + seen="$seen +$name" + sysnames="$sysnames $name" + fi + fi +done +libc_cv_sysdirs="$sysnames" +fi + + sysnames="$libc_cv_sysdirs" +echo "$ac_t""${sysnames}" 1>&4 + +case "$host_os" in +gnu* | linux* | bsd4.4* | netbsd* | freebsd*) + gnu_ld=yes gnu_as=yes +esac +case "$host_os" in +gnu*elf* | linux*elf* | sysv4* | solaris2*) + elf=yes +esac + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&4 +if test -z "$INSTALL"; then +if eval "test \"`echo '${'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use the slow shell script. + test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh" +fi + INSTALL="$ac_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&4 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test "$INSTALL" = "${srcdir}/install-sh"; then + # The makefiles need to use a different form to find it in $srcdir. + INSTALL='$(..)./install-sh' +fi + +echo $ac_n "checking build system type""... $ac_c" 1>&4 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`$ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&4 + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="gcc" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + + + +# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + + + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + +else + RANLIB=":" +fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&4 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '${'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 945 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 959 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi +fi +CPP="$ac_cv_prog_CPP" +echo "$ac_t""$CPP" 1>&4 + + +echo $ac_n "checking signed size_t type""... $ac_c" 1>&4 +if eval "test \"`echo '${'libc_cv_signed_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + echo '#include <stddef.h> +FOOBAR __SIZE_TYPE__ FOOBAR' > conftest.c +if eval "$ac_cpp conftest.c 2>/dev/null" \ +| grep '^FOOBAR.*unsigned.*FOOBAR$' >/dev/null; then + libc_cv_signed_size_t=no +else + libc_cv_signed_size_t=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$libc_cv_signed_size_t" 1>&4 +if test $libc_cv_signed_size_t = yes; then + cat >> confdefs.h <<\EOF +#undef __SIZE_TYPE__ +#define __SIZE_TYPE__ unsigned +EOF +fi + +echo $ac_n "checking libc-friendly stddef.h""... $ac_c" 1>&4 +if eval "test \"`echo '${'libc_cv_friendly_stddef'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext <<EOF +#line 1011 "configure" +#include "confdefs.h" +#define __need_size_t +#define __need_wchar_t +#include <stddef.h> +#define __need_NULL +#include <stddef.h> +int main() { return 0; } +int t() { +size_t size; wchar_t wchar; +#ifdef offsetof +#error stddef.h ignored __need_* +#endif +if (&size == NULL || &wchar == NULL) abort (); +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + libc_cv_friendly_stddef=yes +else + rm -rf conftest* + libc_cv_friendly_stddef=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$libc_cv_friendly_stddef" 1>&4 +if test $libc_cv_friendly_stddef = yes; then + config_vars="$config_vars +override stddef.h = # The installed <stddef.h> seems to be libc-friendly." +fi + +echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&4 +if eval "test \"`echo '${'libc_cv_need_minus_P'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.S <<EOF +#include "confdefs.h" +/* Nothing whatsoever. */ +EOF +if ${CC-cc} $CFLAGS -c conftest.S 2>/dev/null; then + libc_cv_need_minus_P=no +else + libc_cv_need_minus_P=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$libc_cv_need_minus_P" 1>&4 +if test $libc_cv_need_minus_P = yes; then + config_vars="$config_vars +asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives." +fi + +# sysdeps configure fragments may set these with files to be linked below. +libc_link_dests= +libc_link_sources= + +# Iterate over all the sysdep directories we will use, running their +# configure fragments, and looking for a uname implementation. +uname= +for dir in $sysnames; do + if test -r $sysdep_dir/$dir/configure; then + echo "$ac_t""running configure fragment for $dir" 1>&4 + . $sysdep_dir/$dir/configure + fi + if test -z "$uname"; then + { test -r $sysdep_dir/$dir/uname.c || test -r $sysdep_dir/$dir/uname.S; } \ + && uname=$dir + fi +done + + + +# If we will use the generic uname implementation, we must figure out what +# it will say by examining the system, and write the results in config-name.h. +if test "$uname" = generic; then + + uname_sysname=`echo $config_os | sed 's/[0-9.]*$//'` + if test $uname_sysname != $config_os; then + config_release=`echo $config_os | sed s/$uname_sysname//` + fi + + echo $ac_n "checking OS release for uname""... $ac_c" 1>&4 + if eval "test \"`echo '${'libc_cv_uname_release'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + kernel_release=`echo "$kernel_id" | sed 's/^[^0-9.]*\([0-9.]*\).*$/\1/'` + if test x`echo "$config_release" | sed "s/^$kernel_release//"` \ + != x$config_release; then + # The configuration release is a substring of the kernel release. + libc_cv_uname_release=$kernel_release + elif test x$config_release != x; then + libc_cv_uname_release=$config_release + elif test x$kernel_release != x; then + libc_cv_uname_release=$kernel_release + else + libc_cv_uname_release=unknown + fi +fi + + echo "$ac_t""$libc_cv_uname_release" 1>&4 + uname_release="$libc_cv_uname_release" + + echo $ac_n "checking OS version for uname""... $ac_c" 1>&4 + if eval "test \"`echo '${'libc_cv_uname_version'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + kernel_version=`echo "$kernel_id" | sed 's/^[^#]*#\([0-9]*\).*$/\1/'` + if test -n "$kernel_version"; then + libc_cv_uname_version="$kernel_version" + else + libc_cv_uname_version=unknown + fi +fi + + echo "$ac_t""$libc_cv_uname_version" 1>&4 + uname_version="$libc_cv_uname_version" + + config_uname=config-name.h:config-name.in +else + # For non-generic uname, we don't need to create config-name.h at all. + config_uname= +fi + + +if test $gnu_ld = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_GNU_LD 1 +EOF + +fi +if test $gnu_as = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_GNU_AS 1 +EOF + +fi +if test $elf = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ELF 1 +EOF + +fi +if test $weak = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_WEAK_SYMBOLS 1 +EOF + +fi + + +if test "`(cd $srcdir; pwd)`" = "`pwd`"; then + config_makefile= +else + config_makefile=Makefile +fi + +trap '' 1 2 15 +if test -w $cache_file; then +echo "updating cache $cache_file" +cat > $cache_file <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ + >> $cache_file +else +echo "not updating unwritable cache $cache_file" +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.1.1" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo config.make ${config_makefile} ${config_uname} config.h | tr : " "` conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@sysnames@%$sysnames%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@CPP@%$CPP%g +s%@uname_sysname@%$uname_sysname%g +s%@uname_release@%$uname_release%g +s%@uname_version@%$uname_version%g +s%@gnu_ld@%$gnu_ld%g +s%@gnu_as@%$gnu_as%g +s%@elf@%$elf%g +s%@weak@%$weak%g + +CEOF +EOF +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"config.make ${config_makefile} ${config_uname}"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file +fi; done +rm -f conftest.subs + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"} +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + cp $ac_given_srcdir/$ac_file_in conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. +# Maximum number of lines to put in a single here document. +ac_max_here_lines=12 + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF + +cat >> $CONFIG_STATUS <<EOF +ac_sources="`echo $libc_link_sources`" +ac_dests="`echo $libc_link_dests`" +EOF + +cat >> $CONFIG_STATUS <<\EOF +srcdir=$ac_given_srcdir +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + + echo "linking $srcdir/$ac_source to $ac_dest" + + if test ! -r $srcdir/$ac_source; then + { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } + fi + rm -f $ac_dest + + # Make relative symlinks. + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` + if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then + # The dest file is in a subdirectory. + test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" + ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dest_dir_suffix. + ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dest_dir_suffix= ac_dots= + fi + + case "$srcdir" in + [/$]*) ac_rel_source="$srcdir/$ac_source" ;; + *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; + esac + + # Make a symlink if possible; otherwise try a hard link. + if ln -s $ac_rel_source $ac_dest 2>/dev/null || + ln $srcdir/$ac_source $ac_dest; then : + else + { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } + fi +done +EOF +cat >> $CONFIG_STATUS <<EOF +echo '$config_vars' >> config.make +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000000..4d03b808cd --- /dev/null +++ b/configure.in @@ -0,0 +1,413 @@ +dnl Process this file with autoconf to produce a configure script. +AC_REVISION([$Id$]) +AC_PREREQ(2.1)dnl dnl Minimum Autoconf version required. +AC_INIT(features.h) +AC_CONFIG_HEADER(config.h) + +# This will get text that should go into config.make. +config_vars= + +# Check for a --with-gmp argument and set gmp-srcdir in config.make. +AC_ARG_WITH(gmp, dnl + --with-gmp=DIRECTORY find GMP source code in DIRECTORY (not needed), + [dnl +case "$with_gmp" in +yes) AC_MSG_ERROR(--with-gmp requires an argument; use --with-gmp=DIRECTORY) ;; +''|no) ;; +*) config_vars="$config_vars +gmp-srcdir = $withval" ;; +esac +]) + +AC_ARG_WITH(gnu-binutils, dnl + --with-gnu-binutils if using GNU binutils (as and ld), + gnu_binutils=yes, gnu_binutils=no) +AC_ARG_WITH(gnu-ld, dnl + --with-gnu-ld if using GNU ld (in the binutils package), + gnu_ld=yes, gnu_ld=no) +AC_ARG_WITH(gnu-as, dnl + --with-gnu-as if using GNU as (in the binutils package), + gnu_as=yes, gnu_as=no) +test $gnu_binutils = yes && gnu_as=yes gnu_ld=yes +AC_ARG_WITH(elf, dnl + --with-elf if using the ELF object format, + elf=yes, elf=no) +AC_ARG_WITH(weak-symbols, dnl + --with-weak-symbols if weak symbols are available in as and ld, + weak=yes, weak=no) + +AC_CANONICAL_HOST +# We keep the original values in `$config_*' and never modify them, so we +# can write them unchanged into config.make. Everything else uses +# $machine, $vendor, and $os, and changes them whenever convenient. +config_machine=$host_cpu config_vendor=$host_vendor config_os=$host_os + +sysdep_dir=$srcdir/sysdeps +AC_MSG_CHECKING(sysdep dirs) +AC_CACHE_VAL(libc_cv_sysdirs, [dnl +machine=$config_machine +vendor=$config_vendor +os=$config_os + +dnl We need to use [ and ] for other purposes for a while now. +changequote(,)dnl +# Expand the configuration machine name into a subdirectory by architecture +# type and particular chip. +case "$machine" in +i[345]86) + machine=i386/$machine ;; +sparc[6789]) + machine=sparc/$machine ;; +m68k) + machine=m68k/m68020 ;; +m680?0) + machine=m68k/$machine ;; +m88k) + machine=m88k/m88100 ;; +m88???) + machine=m88k/$machine ;; +mips64*) + machine=mips/mips64/$machine ;; +mips*) + machine=mips/$machine ;; +esac + +# Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1. +os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`" + +case "$os" in +gnu*) + base_os=mach/hurd ;; +netbsd* | 386bsd*) + base_os=unix/bsd/bsd4.4 ;; +osf1* | sunos* | ultrix* | newsos* | dynix* | *bsd*) + base_os=unix/bsd ;; +linux* | sysv* | isc* | esix* | sco* | minix* | irix4*) + base_os=unix/sysv ;; +solaris[2-9]*) + base_os=unix/sysv/sysv4 ;; +none) + base_os=standalone ;; +*) + base_os='' ;; +esac + +# For sunos4.1.1, try sunos4.1.1, then sunos4.1, then sunos4, then sunos. +tail=$os +ostry=$os +while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do + ostry="$ostry /$o" + tail=$o +done +o=`echo $tail | sed 's/[0-9]*$//'` +if test $o != $tail; then + ostry="$ostry /$o" +fi + +# For unix/sysv/sysv4, try unix/sysv/sysv4, then unix/sysv, then unix. +base= +tail=$base_os +while b=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$b"; do + set $b + base="$base /$1" + tail="$2" +done + +# For sparc/sparc9, try sparc/sparc9 and then sparc. +mach= +tail=$machine +while m=`echo $tail | sed 's@^\(.*\)/\([^/]*\)$@& \1@'`; test -n "$m"; do + set $m + mach="$mach /$1" + tail="$2" +done + +dnl We are done with glob and regexp uses of [ and ]; return to autoconf. +changequote([,])dnl + +# Find what sysdep directories exist. +sysnames= +for b in $base ''; do + for m0 in $mach ''; do + for v in /$vendor ''; do + for o in /$ostry ''; do + for m in $mach ''; do + try="$m0$b$v$o$m" + if test -d $sysdep_dir$try; then + sysnames="$sysnames $try" + { test -n "$o" || test -n "$b"; } && os_used=t + { test -n "$m" || test -n "$m0"; } && machine_used=t + fi + done + done + done + done +done + +if test -z "$os_used" && test "$os" != none; then + AC_MSG_ERROR(Operating system $os is not supported.) +fi +if test -z "$machine_used" && test "$machine" != none; then + AC_MSG_ERROR(The $machine is not supported.) +fi + +# We have now validated the configuration. + +# Remove the leading slashes. +sysnames="`echo $sysnames | sed -e 's@^/@@' -e 's@ /@ @g'`" + +# Prepend the machine's FPU directory unless --without-fp. +if test "$with_fp" = no; then + fpu_dirs= + for m in $mach; do + if test -d $sysdep_dir$m/fpu; then + fpu_dirs="$fpu_dirs $m/fpu" + fi + done + sysnames="`echo $fpu_dirs | sed -e 's,^/,,' -e 's, /,,g'` $sysnames" +fi + +# Expand the list of system names into a full list of directories +# from each element's parent name and Implies file (if present). +set $sysnames +while test $# -gt 0; do + name=$1 + shift + + if test -f $sysdep_dir/$name/Implies; then + # Collect more names from the `Implies' file (removing comments). + implied="`sed 's/#.*$//' < $sysdep_dir/$name/Implies`" + for x in $implied; do + test -d $sysdep_dir/$x || echo "Warning: $name implies nonexistent $x">&2 + done + else + implied= + fi + + # Add NAME to the list of names. + names="$names $name" + + # Find the parent of NAME, using the empty string if it has none. +changequote(,)dnl + parent="`echo $name | sed -n -e '/\//!q' -e 's=/[^/]*$==p'`" +changequote([,])dnl + + # Add the names implied by NAME, and NAME's parent (if it has one), to + # the list of names to be processed (the argument list). We prepend the + # implied names to the list and append the parent. We want implied + # directories to come before further directories inferred from the + # configuration components; this ensures that for sysv4, unix/common + # (implied by unix/sysv/sysv4) comes before unix/sysv (in ostry (here $*) + # after sysv4). + sysnames="`echo $implied $* $parent`" + test -n "$sysnames" && set $sysnames +done + +# Add the default directories. +names="$names generic stub" + +# Now uniquize the list. +seen= +sysnames= +for name in $names; do + if echo "$seen" | fgrep -x $name >/dev/null; then + # Already in the list. + true; + else + # A new one. + if test -z "$seen"; then + seen="$name" sysnames="$name" + else + seen="$seen +$name" + sysnames="$sysnames $name" + fi + fi +done +libc_cv_sysdirs="$sysnames"]) +AC_SUBST(sysnames) sysnames="$libc_cv_sysdirs" +AC_MSG_RESULT(${sysnames}) + +case "$host_os" in +gnu* | linux* | bsd4.4* | netbsd* | freebsd*) + gnu_ld=yes gnu_as=yes +esac +case "$host_os" in +gnu*elf* | linux*elf* | sysv4* | solaris2*) + elf=yes +esac + +AC_PROG_INSTALL +if test "$INSTALL" = "${srcdir}/install-sh"; then + # The makefiles need to use a different form to find it in $srcdir. + INSTALL='$(..)./install-sh' +fi + +AC_PROG_CC +AC_PROG_CPP +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB + +AC_MSG_CHECKING(signed size_t type) +AC_CACHE_VAL(libc_cv_signed_size_t, [dnl +echo '#include <stddef.h> +FOOBAR __SIZE_TYPE__ FOOBAR' > conftest.c +if eval "$ac_cpp conftest.c 2>/dev/null" \ +| grep '^FOOBAR.*unsigned.*FOOBAR$' >/dev/null; then + libc_cv_signed_size_t=no +else + libc_cv_signed_size_t=yes +fi +rm -f conftest*]) +AC_MSG_RESULT($libc_cv_signed_size_t) +if test $libc_cv_signed_size_t = yes; then + dnl Do this by hand instead of AC_DEFINE so can add #undef to avoid warnings. + cat >> confdefs.h <<\EOF +#undef __SIZE_TYPE__ +#define __SIZE_TYPE__ unsigned +EOF +fi + +AC_MSG_CHECKING(libc-friendly stddef.h) +AC_CACHE_VAL(libc_cv_friendly_stddef, [dnl +AC_TRY_COMPILE(dnl +[#define __need_size_t +#define __need_wchar_t +#include <stddef.h> +#define __need_NULL +#include <stddef.h>], [size_t size; wchar_t wchar; +#ifdef offsetof +#error stddef.h ignored __need_* +#endif +if (&size == NULL || &wchar == NULL) abort ();], + libc_cv_friendly_stddef=yes, + libc_cv_friendly_stddef=no)]) +AC_MSG_RESULT($libc_cv_friendly_stddef) +if test $libc_cv_friendly_stddef = yes; then + config_vars="$config_vars +override stddef.h = # The installed <stddef.h> seems to be libc-friendly." +fi + +AC_MSG_CHECKING(whether we need to use -P to assemble .S files) +AC_CACHE_VAL(libc_cv_need_minus_P, [dnl +cat > conftest.S <<EOF +#include "confdefs.h" +/* Nothing whatsoever. */ +EOF +if ${CC-cc} $CFLAGS -c conftest.S 2>/dev/null; then + libc_cv_need_minus_P=no +else + libc_cv_need_minus_P=yes +fi +rm -f conftest*]) +AC_MSG_RESULT($libc_cv_need_minus_P) +if test $libc_cv_need_minus_P = yes; then + config_vars="$config_vars +asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives." +fi + +# sysdeps configure fragments may set these with files to be linked below. +libc_link_dests= +libc_link_sources= + +# Iterate over all the sysdep directories we will use, running their +# configure fragments, and looking for a uname implementation. +uname= +for dir in $sysnames; do + if test -r $sysdep_dir/$dir/configure; then + AC_MSG_RESULT(running configure fragment for $dir) + . $sysdep_dir/$dir/configure + fi + if test -z "$uname"; then + { test -r $sysdep_dir/$dir/uname.c || test -r $sysdep_dir/$dir/uname.S; } \ + && uname=$dir + fi +done + +AC_LINK_FILES(`echo $libc_link_sources`, `echo $libc_link_dests`) + +# If we will use the generic uname implementation, we must figure out what +# it will say by examining the system, and write the results in config-name.h. +if test "$uname" = generic; then + +changequote(,)dnl + uname_sysname=`echo $config_os | sed 's/[0-9.]*$//'` +changequote([,])dnl + if test $uname_sysname != $config_os; then + config_release=`echo $config_os | sed s/$uname_sysname//` + fi +dnl +AC_DEFUN(LIBC_KERNEL_ID, [dnl + if test -r /vmunix; then + kernel_id=`strings /vmunix | grep UNIX` + elif test -r /dynix; then + kernel_id=`strings /dynix | grep DYNIX` + else + kernel_id= + fi +])dnl + + AC_MSG_CHECKING(OS release for uname) + AC_CACHE_VAL(libc_cv_uname_release, [dnl +AC_REQUIRE([LIBC_KERNEL_ID])dnl +changequote(,)dnl + kernel_release=`echo "$kernel_id" | sed 's/^[^0-9.]*\([0-9.]*\).*$/\1/'` +changequote([,])dnl + if test x`echo "$config_release" | sed "s/^$kernel_release//"` \ + != x$config_release; then + # The configuration release is a substring of the kernel release. + libc_cv_uname_release=$kernel_release + elif test x$config_release != x; then + libc_cv_uname_release=$config_release + elif test x$kernel_release != x; then + libc_cv_uname_release=$kernel_release + else + libc_cv_uname_release=unknown + fi]) + AC_MSG_RESULT($libc_cv_uname_release) + uname_release="$libc_cv_uname_release" + + AC_MSG_CHECKING(OS version for uname) + AC_CACHE_VAL(libc_cv_uname_version, [dnl +AC_REQUIRE([LIBC_KERNEL_ID])dnl +changequote(,)dnl + kernel_version=`echo "$kernel_id" | sed 's/^[^#]*#\([0-9]*\).*$/\1/'` +changequote([,])dnl + if test -n "$kernel_version"; then + libc_cv_uname_version="$kernel_version" + else + libc_cv_uname_version=unknown + fi]) + AC_MSG_RESULT($libc_cv_uname_version) + uname_version="$libc_cv_uname_version" + +AC_SUBST(uname_sysname) AC_SUBST(uname_release) AC_SUBST(uname_version)dnl + config_uname=config-name.h:config-name.in +else + # For non-generic uname, we don't need to create config-name.h at all. + config_uname= +fi + +AC_SUBST(gnu_ld) AC_SUBST(gnu_as) AC_SUBST(elf) AC_SUBST(weak) +if test $gnu_ld = yes; then + AC_DEFINE(HAVE_GNU_LD) +fi +if test $gnu_as = yes; then + AC_DEFINE(HAVE_GNU_AS) +fi +if test $elf = yes; then + AC_DEFINE(HAVE_ELF) +fi +if test $weak = yes; then + AC_DEFINE(HAVE_WEAK_SYMBOLS) +fi + + +if test "`(cd $srcdir; pwd)`" = "`pwd`"; then + config_makefile= +else + config_makefile=Makefile +fi + +AC_OUTPUT(config.make ${config_makefile} ${config_uname}, , + [echo '$config_vars' >> config.make]) diff --git a/crypt-README b/crypt-README new file mode 100644 index 0000000000..c80ddf5c15 --- /dev/null +++ b/crypt-README @@ -0,0 +1,14 @@ +The GNU C library now includes Michael Glad's Ultra Fast Crypt, which +provides the Unix `crypt' function, plus some other entry points. Because +of the United States export restriction on DES implementations, we are +distributing this code separately from the rest of the C library. There is +an extra distribution tar file just for crypt; it is called +`glibc-1.07-crypt.tar.gz'. You can just unpack the crypt distribution +along with the rest of the C library and build; you can also build the +library without getting crypt. Users outside the USA can get the crypt +distribution via anonymous FTP from ftp.uni-c.dk [129.142.6.74], or another +archive site outside the USA. Archive maintainers are encouraged to copy +this distribution to their archives outside the USA. Please get it from +ftp.uni-c.dk; transferring this distribution from prep.ai.mit.edu (or any +other site in the USA) to a site outside the USA is in violation of US +export laws. diff --git a/csu/Makefile b/csu/Makefile new file mode 100644 index 0000000000..6de77b768c --- /dev/null +++ b/csu/Makefile @@ -0,0 +1,84 @@ +# Makefile for csu code for GNU C library. + +# Copyright (C) 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# This directory contains the C startup code (that which calls main). This +# consists of the startfile, built from start.c and installed as crt0.o +# (traditionally) or crt1.o (for ELF); and some initialization code which +# is in the C library itself. In ELF we also install crti.o and crtn.o, +# special "initializer" and "finalizer" files in used in the link to make +# the .init and .fini sections work right; both these files are built (in +# an arcane manner) from initfini.c. + +subdir := csu + +csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o) +extra-objs = start.o $(start-installed-name) $(csu-dummies) +omit-deps = $(patsubst %.o,%,$(start-installed-name) $(csu-dummies)) +install-lib = $(start-installed-name) $(csu-dummies) +distribute = initfini.c + +all: # Make this the default target; it will be defined in Rules. + +include ../Makeconfig + +ifneq ($(elf),yes) +# When not using ELF, there is just one startfile, called crt0.o. +start-installed-name = crt0.o +else +# In the ELF universe, crt0.o is called crt1.o, and there are +# some additional bizarre files. +start-installed-name = crt1.o +install-lib += crti.o crtn.o +extra-objs += crti.o crtn.o +generated += crti.s crtn.s +omit-deps += crti crtn + +# Compile initfini.c to assembly code, which contains embedded shell +# commands that prodice crti.s-new and crtn.s-new when run. We need to +# disable emission of .size directives and debugging information, since +# they will get confused by the splitting of the output we do. +$(objpfx)cr%i.s $(objpfx)cr%n.s: initfini.c + -rm -f $(objpfx)crtcommon.tmp + (echo 'cat > crtcommon.tmp <<\EOF_common'; \ + $(CC) $< $(CPPFLAGS) $(CFLAGS) -finhibit-size-directive -g0 -S -o -; \ + echo 'EOF_common') | (cd $(@D); $(SHELL)) + cat $(objpfx)crtcommon.tmp >> $(objpfx)crti.s-new + cat $(objpfx)crtcommon.tmp >> $(objpfx)crtn.s-new + rm -f $(objpfx)crtcommon.tmp + mv -f $(objpfx)crti.s-new $(objpfx)crti.s + mv -f $(objpfx)crtn.s-new $(objpfx)crtn.s +endif + + +include ../Rules + +# The startfile is installed under different names, so we just call our +# source file `start.c' and copy to the installed name after compiling. +$(objpfx)$(start-installed-name): $(objpfx)start.o + -rm -f $@ + ln $< $@ + +# These extra files are sometimes expected by system standard linking +# procedures, but we have nothing for them to do. So compile empty files. +$(addprefix $(objpfx),$(filter-out $(start-installed-name),$(csu-dummies))): + cp /dev/null $(@:.o=.c) + $(COMPILE.c) $(@:.o=.c) $(OUTPUT_OPTION) + rm -f $(@:.o=.c) + diff --git a/csu/initfini.c b/csu/initfini.c new file mode 100644 index 0000000000..ea16e62ffe --- /dev/null +++ b/csu/initfini.c @@ -0,0 +1,85 @@ +/* Special .init and .fini section support. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file is compiled into assembly code which is then surrounded by the + lines `cat > crtcommon.tmp <<\EOF_common' and `EOF_common' and thus + becomes a shell script which creates three files of assembly code. + + * The first file is crti.s-new; this puts a function prologue at the + beginning of the .init and .fini sections and defines global symbols for + those addresses, so they can be called as functions. + + * The second file is crtn.s-new; this puts the corresponding function + epilogues in the .init and .fini sections. + + * The third file is crtcommon.tmp, which is whatever miscellaneous cruft + the compiler generated at the end; it should be appended to both crti.s-new + and crtn.s-new. */ + +#include <stdlib.h> + +/* These declarations make the functions go in the right sections when + we define them below. GCC syntax does not allow the attribute + specifications to be in the function definitions themselves. */ +void _init (void) __attribute__ ((section (".init"))); +void _fini (void) __attribute__ ((section (".fini"))); + +/* End the here document containing the initial common code. + Then move the output file crtcommon.tmp to crti.s-new and crtn.s-new. */ +asm ("\nEOF_common\n\ +mv -f crtcommon.tmp crti.s-new\n\ +cp -f crti.s-new crtn.s-new"); + +/* Append the .init prologue to crti.s-new. */ +asm ("cat >> crti.s-new <<\\EOF.crti.init"); +void +_init (void) +{ + /* End the here document containing the .init prologue code. + Then fetch the .section directive just written and append that + to crtn.s-new, followed by the function epilogue. */ + asm ("\nEOF.crti.init +\n\ + fgrep .init crti.s-new >>crtn.s-new\n\ + cat >> crtn.s-new <<\\EOF.crtn.init"); +} + +/* End the here document containing the .init epilogue code. + Then append the .fini prologue to crti.s-new. */ +asm ("\nEOF.crtn.init\ +\n\ +cat >> crti.s-new <<\\EOF.crti.fini"); + +void +_fini (void) +{ + /* End the here document containing the .fini prologue code. + Then fetch the .section directive just written and append that + to crtn.s-new, followed by the function epilogue. */ + asm ("\nEOF.crti.fini\ +\n\ + fgrep .fini crti.s-new >>crtn.s-new\n\ + cat >> crtn.s-new <<\\EOF.crtn.fini"); +} + +/* End the here document containing the .fini epilogue code. + Finally, put the remainder of the generated assembly into crtcommon.tmp. */ +asm ("\nEOF.crtn.fini\ +\n\ +cat > crtcommon.tmp <<\\EOF_common"); diff --git a/ctype.h b/ctype.h new file mode 100644 index 0000000000..7b51e1f5eb --- /dev/null +++ b/ctype.h @@ -0,0 +1 @@ +#include <ctype/ctype.h> diff --git a/ctype/Makefile b/ctype/Makefile new file mode 100644 index 0000000000..21dfc8e3b1 --- /dev/null +++ b/ctype/Makefile @@ -0,0 +1,29 @@ +# Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for ctype portion of the library. +# +subdir := ctype + +routines := ctype ctype-extn +aux := ctype-info + +tests := test_ctype + +include ../Rules diff --git a/ctype/ctype-extn.c b/ctype/ctype-extn.c new file mode 100644 index 0000000000..ccf5552c85 --- /dev/null +++ b/ctype/ctype-extn.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#define __NO_CTYPE +#include <ctype.h> + +/* Real function versions of the non-ANSI ctype functions. */ + +int DEFUN(isblank, (c), int c) { return __isctype ((c), _ISblank); } + +int DEFUN(_tolower, (c), int c) { return __tolower(c); } +int DEFUN(_toupper, (c), int c) { return __toupper(c); } + +int DEFUN(toascii, (c), int c) { return __toascii(c); } +int DEFUN(isascii, (c), int c) { return __isascii(c); } diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c new file mode 100644 index 0000000000..2a1e596223 --- /dev/null +++ b/ctype/ctype-info.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <ctype.h> +#include <localeinfo.h> + +/* Defined in locale/locale-C-ct.c. */ +extern CONST unsigned short int __ctype_b_C[]; +extern CONST short int __ctype_tolower_C[]; +extern CONST short int __ctype_toupper_C[]; + +CONST unsigned short int *__ctype_b = __ctype_b_C + 1; +CONST short int *__ctype_tolower = __ctype_tolower_C + 1; +CONST short int *__ctype_toupper = __ctype_toupper_C + 1; diff --git a/ctype/ctype.c b/ctype/ctype.c new file mode 100644 index 0000000000..ee874de057 --- /dev/null +++ b/ctype/ctype.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#define __NO_CTYPE +#include <ctype.h> + +/* Provide real-function versions of all the ctype macros. */ + +#define func(name, type) \ + int DEFUN(name, (c), int c) { return __isctype(c, type); } + +func(isalnum, _ISalnum) +func(isalpha, _ISalpha) +func(iscntrl, _IScntrl) +func(isdigit, _ISdigit) +func(islower, _ISlower) +func(isgraph, _ISgraph) +func(isprint, _ISprint) +func(ispunct, _ISpunct) +func(isspace, _ISspace) +func(isupper, _ISupper) +func(isxdigit, _ISxdigit) + +int +DEFUN(tolower, (c), int c) +{ + return __tolower (c); +} + +int +DEFUN(toupper, (c), int c) +{ + return __toupper (c); +} diff --git a/ctype/ctype.h b/ctype/ctype.h new file mode 100644 index 0000000000..0f35d2a1d7 --- /dev/null +++ b/ctype/ctype.h @@ -0,0 +1,152 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard 4.3: CHARACTER HANDLING <ctype.h> + */ + +#ifndef _CTYPE_H + +#define _CTYPE_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* These are all the characteristics of characters. All the + interdependencies (such as that an alphabetic is an uppercase or a + lowercase) are here. If there get to be more than + (sizeof (unsigned short int) * CHAR_BIT) distinct characteristics, + many things must be changed that use `unsigned short int's. */ +enum +{ + _ISupper = 1 << 0, /* UPPERCASE. */ + _ISlower = 1 << 1, /* lowercase. */ + _IScntrl = 1 << 2, /* Control character. */ + _ISdigit = 1 << 3, /* Numeric. */ + _ISspace = 1 << 4, /* Whitespace. */ + _IShex = 1 << 5, /* A - F, a - f. */ + _ISpunct = 1 << 6, /* Punctuation. */ + _NOgraph = 1 << 7, /* Printing but nongraphical. */ + _ISblank = 1 << 8, /* Blank (usually SPC and TAB). */ + _ISalpha = 1 << 9, /* Alphabetic. */ + _ISalnum = _ISalpha | _ISdigit, /* Alphanumeric. */ + _ISxdigit = _ISdigit | _IShex, /* Hexadecimal numeric. */ + _ISgraph = _ISalnum | _ISpunct, /* Graphical. */ + _ISprint = _ISgraph | _NOgraph /* Printing. */ +}; + +/* These are defined in localeinfo.c. + The declarations here must match those in localeinfo.h. + + These point to the second element ([1]) of arrays of size (UCHAR_MAX + 1). + EOF is -1, so [EOF] is the first element of the original array. + ANSI requires that the ctype functions work for `unsigned char' values + and for EOF. The case conversion arrays are of `short int's rather than + `unsigned char's because tolower (EOF) must be EOF, which doesn't fit + into an `unsigned char'. */ +extern __const unsigned short int *__ctype_b; /* Characteristics. */ +extern __const short int *__ctype_tolower; /* Case conversions. */ +extern __const short int *__ctype_toupper; /* Case conversions. */ + +#define __isctype(c, type) \ + (__ctype_b[(int) (c)] & (unsigned short int) type) + +#define __isascii(c) (((c) & (1 << 7)) == 0) /* If high bit is set. */ +#define __toascii(c) ((c) & 0x7f) /* Mask off high bit. */ + +#define __tolower(c) ((int) __ctype_tolower[(int) (c)]) +#define __toupper(c) ((int) __ctype_toupper[(int) (c)]) + +#define __exctype(name) extern int name __P ((int)) + +/* The following names are all functions: + int isCHARACTERISTIC(int c); + which return nonzero iff C has CHARACTERISTIC. + For the meaning of the characteristic names, see the `enum' above. */ +__exctype (isalnum); +__exctype (isalpha); +__exctype (iscntrl); +__exctype (isdigit); +__exctype (islower); +__exctype (isgraph); +__exctype (isprint); +__exctype (ispunct); +__exctype (isspace); +__exctype (isupper); +__exctype (isxdigit); + +#ifdef __USE_GNU +__exctype (isblank); +#endif + + +/* Return the lowercase version of C. */ +extern int tolower __P ((int __c)); + +/* Return the uppercase version of C. */ +extern int toupper __P ((int __c)); + + +#if defined(__USE_SVID) || defined(__USE_MISC) + +/* Return nonzero iff C is in the ASCII set + (i.e., is no more than 7 bits wide). */ +extern int isascii __P ((int __c)); + +/* Return the part of C that is in the ASCII set + (i.e., the low-order 7 bits of C). */ +extern int toascii __P ((int __c)); + +#endif /* Use SVID or use misc. */ + +#ifdef __USE_SVID +/* These are the same as `toupper' and and `tolower'. */ +__exctype (_toupper); +__exctype (_tolower); +#endif + +#ifndef __NO_CTYPE +#define isalnum(c) __isctype((c), _ISalnum) +#define isalpha(c) __isctype((c), _ISalpha) +#define iscntrl(c) __isctype((c), _IScntrl) +#define isdigit(c) __isctype((c), _ISdigit) +#define islower(c) __isctype((c), _ISlower) +#define isgraph(c) __isctype((c), _ISgraph) +#define isprint(c) __isctype((c), _ISprint) +#define ispunct(c) __isctype((c), _ISpunct) +#define isspace(c) __isctype((c), _ISspace) +#define isupper(c) __isctype((c), _ISupper) +#define isxdigit(c) __isctype((c), _ISxdigit) + +#ifdef __USE_GNU +#define isblank(c) __isctype((c), _ISblank) +#endif + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) + +#if defined(__USE_SVID) || defined(__USE_MISC) +#define isascii(c) __isascii(c) +#define toascii(c) __toascii(c) +#endif + +#endif /* Not __NO_CTYPE. */ + +__END_DECLS + +#endif /* ctype.h */ diff --git a/ctype/test_ctype.c b/ctype/test_ctype.c new file mode 100644 index 0000000000..622e5bf762 --- /dev/null +++ b/ctype/test_ctype.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <limits.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> + +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) + +#ifdef __GNUC__ +__inline +#endif +static void +DEFUN(print_char, (c), unsigned char c) +{ + printf("%d/", (int) c); + if (isgraph(c)) + printf("'%c'", c); + else + printf("'\\%.3o'", c); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + register unsigned short int c; + int lose = 0; + + for (c = 0; c <= UCHAR_MAX; ++c) + { + print_char (c); + + if (XOR (islower (c), ISLOWER (c)) || toupper (c) != TOUPPER (c)) + { + fputs (" BOGUS", stdout); + ++lose; + } + + if (isascii(c)) + fputs(" isascii", stdout); + if (isalnum(c)) + fputs(" isalnum", stdout); + if (isalpha(c)) + fputs(" isalpha", stdout); + if (iscntrl(c)) + fputs(" iscntrl", stdout); + if (isdigit(c)) + fputs(" isdigit", stdout); + if (isgraph(c)) + fputs(" isgraph", stdout); + if (islower(c)) + fputs(" islower", stdout); + if (isprint(c)) + fputs(" isprint", stdout); + if (ispunct(c)) + fputs(" ispunct", stdout); + if (isspace(c)) + fputs(" isspace", stdout); + if (isupper(c)) + fputs(" isupper", stdout); + if (isxdigit(c)) + fputs(" isxdigit", stdout); + if (isblank(c)) + fputs(" isblank", stdout); + fputs("; lower = ", stdout); + print_char(tolower(c)); + fputs("; upper = ", stdout); + print_char(toupper(c)); + putchar('\n'); + } + + exit (lose ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/dirent.h b/dirent.h new file mode 100644 index 0000000000..f59a6b778b --- /dev/null +++ b/dirent.h @@ -0,0 +1 @@ +#include <dirent/dirent.h> diff --git a/dirent/Makefile b/dirent/Makefile new file mode 100644 index 0000000000..ed3335ce1b --- /dev/null +++ b/dirent/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for dirent portion of the library. +# +subdir := dirent + +headers := dirent.h dirstream.h +routines := opendir closedir readdir rewinddir \ + seekdir telldir scandir alphasort \ + getdents +distribute := direct.h + +tests := list tst-seekdir + +include ../Rules diff --git a/dirent/alphasort.c b/dirent/alphasort.c new file mode 100644 index 0000000000..a7bdf3820e --- /dev/null +++ b/dirent/alphasort.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <dirent.h> +#include <string.h> + +int +DEFUN(alphasort, (a, b), + CONST PTR a AND CONST PTR b) +{ + return strcmp (((struct dirent *) a)->d_name, + ((struct dirent *) b)->d_name); +} diff --git a/dirent/dirent.h b/dirent/dirent.h new file mode 100644 index 0000000000..b102a4786c --- /dev/null +++ b/dirent/dirent.h @@ -0,0 +1,149 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 5.1.2 Directory Operations <dirent.h> + */ + +#ifndef _DIRENT_H + +#define _DIRENT_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + + +/* Directory entry structure. + + This structure is laid out identically to the `struct direct' that + represents directory entries in the GNU Hurd and in BSD 4.4 (and + incidentally, on disk in the Berkeley fast file system). The `readdir' + implementations for GNU and BSD know this; you must change them if you + change this structure. */ + +struct dirent + { + __ino_t d_fileno; /* File serial number. */ + unsigned short int d_reclen; /* Length of the whole `struct dirent'. */ + unsigned char d_type; /* File type, possibly unknown. */ + unsigned char d_namlen; /* Length of the file name. */ + + /* Only this member is in the POSIX standard. */ + char d_name[1]; /* File name (actually longer). */ + }; + +#if defined(__USE_BSD) || defined(__USE_MISC) +#define d_ino d_fileno /* Backward compatibility. */ +#endif + +#ifdef __USE_BSD +/* File types for `d_type'. */ +enum + { + DT_UNKNOWN = 0, + DT_FIFO = 1, + DT_CHR = 2, + DT_DIR = 4, + DT_BLK = 6, + DT_REG = 8, + DT_LNK = 10, + DT_SOCK = 12 + }; + +/* Convert between stat structure types and directory types. */ +#define IFTODT(mode) (((mode) & 0170000) >> 12) +#define DTTOIF(dirtype) ((dirtype) << 12) +#endif + + +/* Get the system-dependent definition of `DIR', + the data type of directory stream objects. */ +#include <dirstream.h> + +/* Open a directory stream on NAME. + Return a DIR stream on the directory, or NULL if it could not be opened. */ +extern DIR *opendir __P ((__const char *__name)); + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +extern int closedir __P ((DIR * __dirp)); + +/* Read a directory entry from DIRP. + Return a pointer to a `struct dirent' describing the entry, + or NULL for EOF or error. The storage returned may be overwritten + by a later readdir call on the same DIR stream. */ +extern struct dirent *readdir __P ((DIR * __dirp)); + +/* Rewind DIRP to the beginning of the directory. */ +extern void rewinddir __P ((DIR * __dirp)); + +#if defined(__USE_BSD) || defined(__USE_MISC) + +#ifndef MAXNAMLEN +/* Get the definitions of the POSIX.1 limits. */ +#include <posix1_lim.h> + +/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */ +#ifdef NAME_MAX +#define MAXNAMLEN NAME_MAX +#else +#define MAXNAMLEN 255 +#endif +#endif + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + +/* Seek to position POS on DIRP. */ +extern void seekdir __P ((DIR * __dirp, __off_t __pos)); + +/* Return the current position of DIRP. */ +extern __off_t telldir __P ((DIR * __dirp)); + +/* Scan the directory DIR, calling SELECT on each directory entry. + Entries for which SELECT returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. */ +extern int scandir __P ((__const char *__dir, + struct dirent ***__namelist, + int (*__select) __P ((struct dirent *)), + int (*__cmp) __P ((__const __ptr_t, + __const __ptr_t)))); + +/* Function to compare two `struct dirent's alphabetically. */ +extern int alphasort __P ((__const __ptr_t, __const __ptr_t)); + + +/* Read directory entries from FD into BUF, reading at most NBYTES. + Reading starts at offset *BASEP, and *BASEP is updated with the new + position after reading. Returns the number of bytes read; zero when at + end of directory; or -1 for errors. */ +extern __ssize_t __getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); +extern __ssize_t getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); + + +#endif /* Use BSD or misc. */ + +__END_DECLS + +#endif /* dirent.h */ diff --git a/dirent/list.c b/dirent/list.c new file mode 100644 index 0000000000..606bd42591 --- /dev/null +++ b/dirent/list.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> + + +void +DEFUN(test, (name), CONST char *name) +{ + DIR *dirp; + struct dirent *entp; + + puts(name); + + dirp = opendir(name); + if (dirp == NULL) + { + perror("opendir"); + return; + } + + errno = 0; + while ((entp = readdir(dirp)) != NULL) + printf("%s\tfile number %lu\n", + entp->d_name, (unsigned long int) entp->d_fileno); + + if (errno) + perror ("readdir"); + + if (closedir(dirp) < 0) + perror("closedir"); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + --argc; + ++argv; + + if (argc == 0) + test("."); + else + while (argc-- > 0) + test(*argv++); + + exit(0); + return(0); +} diff --git a/dirent/scandir.c b/dirent/scandir.c new file mode 100644 index 0000000000..6794eadf0d --- /dev/null +++ b/dirent/scandir.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <dirent.h> +#include <stdlib.h> + +int +DEFUN(scandir, (dir, namelist, select, cmp), + CONST char *dir AND + struct dirent ***namelist AND + int EXFUN((*select), (struct dirent *)) AND + int EXFUN((*cmp), (CONST PTR, CONST PTR))) +{ + DIR *dp = opendir (dir); + struct dirent **v = NULL; + size_t vsize = 0, i; + struct dirent *d; + int save; + + if (dp == NULL) + return -1; + + save = errno; + errno = 0; + + i = 0; + while ((d = readdir (dp)) != NULL) + if (select == NULL || (*select) (d)) + { + if (i == vsize) + { + struct dirent **new; + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + new = (struct dirent **) realloc (v, vsize * sizeof (*v)); + if (new == NULL) + { + lose: + errno = ENOMEM; + break; + } + v = new; + } + + v[i] = (struct dirent *) malloc (sizeof (**v)); + if (v[i] == NULL) + goto lose; + + *v[i++] = *d; + } + + if (errno != 0) + { + save = errno; + (void) closedir (dp); + while (i > 0) + free (v[--i]); + free (v); + errno = save; + return -1; + } + + (void) closedir (dp); + errno = save; + + /* Sort the list if we have a comparison function to sort with. */ + if (cmp != NULL) + qsort (v, i, sizeof (*v), cmp); + *namelist = v; + return i; +} diff --git a/dirent/tst-seekdir.c b/dirent/tst-seekdir.c new file mode 100644 index 0000000000..fc282468fe --- /dev/null +++ b/dirent/tst-seekdir.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <dirent.h> +#include <stdlib.h> + +int +main () +{ + + DIR * dirp; + long save3; + int i = 0; + struct dirent *dp; + + dirp = opendir("."); + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + { + /* save position 3 (fourth entry) */ + if (i++ == 3) + save3 = telldir(dirp); + + printf("%s\n", dp->d_name); + + /* stop at 400 (just to make sure dirp->__offset and dirp->__size are + scrambled */ + if (i == 400) + break; + } + + /* go back to saved entry */ + seekdir (dirp, save3); + + + /* print remaining files (3-last) */ + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) + printf("%s\n", dp->d_name); + + + closedir (dirp); + exit(0); +} diff --git a/elf/elf.h b/elf/elf.h new file mode 100644 index 0000000000..452b5c92d9 --- /dev/null +++ b/elf/elf.h @@ -0,0 +1,587 @@ +/* This file defines standard ELF types, structures, and macros. +Copyright (C) 1995 Free Software Foundation, Inc. +Contributed by Ian Lance Taylor (ian@cygnus.com). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _ELF_H +#define _ELF_H 1 + + +/* Standard ELF types. + + Using __attribute__ mode ensures that gcc will choose the right for + these types. */ + +typedef unsigned int Elf32_Addr __attribute__ ((mode (SI))); +typedef unsigned int Elf32_Half __attribute__ ((mode (HI))); +typedef unsigned int Elf32_Off __attribute__ ((mode (SI))); +typedef int Elf32_Sword __attribute__ ((mode (SI))); +typedef unsigned int Elf32_Word __attribute__ ((mode (SI))); + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_PAD 7 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_LOPROC 0xff00 /* Processor-specific */ +#define ET_HIPROC 0xffff /* Processor-specific */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_486 6 /* Intel 80486 */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* Amdhal */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ + +#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ + +#define EM_PARISC 15 /* HPPA */ + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf32_Half st_shndx; /* Section index */ +} Elf32_Sym; + +/* Special symbol index. */ + +#define STN_UNDEF 0 /* Undefined symbol */ + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +/* Program segment header. */ + +typedef struct { + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Standard 64 bit ELF types. */ + +typedef unsigned int Elf64_Addr __attribute__ ((mode (DI))); +typedef unsigned int Elf64_Half __attribute__ ((mode (HI))); +typedef unsigned int Elf64_Off __attribute__ ((mode (DI))); +typedef int Elf64_Sword __attribute__ ((mode (SI))); +typedef int Elf64_Sxword __attribute__ ((mode (DI))); +typedef unsigned int Elf64_Word __attribute__ ((mode (SI))); +typedef unsigned int Elf64_Xword __attribute__ ((mode (DI))); +typedef unsigned int Elf64_Byte __attribute__ ((mode (QI))); +typedef unsigned int Elf64_Section __attribute__ ((mode (HI))); + +/* 64 bit ELF file header. */ + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* 64 bit section header. */ + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* 64 bit symbol table entry. */ + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + Elf64_Byte st_info; /* Symbol type and binding */ + Elf64_Byte st_other; /* No defined meaning, 0 */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The 64 bit st_info field is the same as the 32 bit one. */ + +#define ELF64_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF64_ST_TYPE(val) ((val) & 0xf) +#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard <elf.h> file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + int a_type; /* Entry type */ + union + { + long a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (); /* Function pointer value */ + } a_un; +} Elf32_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Read gid */ +#define AT_EGID 14 /* Effective gid */ + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ + +/* SUN SPARC specific definitions. */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information */ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Regiser usage information */ + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ + +/* Legal values for DT_MIPS_FLAG Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +/* Legal values for l_flags. */ + +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +#endif /* elf.h */ diff --git a/endian.h b/endian.h new file mode 100644 index 0000000000..cacf2fe9b7 --- /dev/null +++ b/endian.h @@ -0,0 +1 @@ +#include <string/endian.h> diff --git a/errno.h b/errno.h new file mode 100644 index 0000000000..08fc6802e8 --- /dev/null +++ b/errno.h @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.1.3 Errors <errno.h> + */ + +#ifndef _ERRNO_H + +#define _ERRNO_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get the error number constants. */ +#include <errnos.h> + +/* Declare the `errno' variable. */ +extern int errno; + +#ifdef __USE_GNU +/* The full and simple forms of the name with which the program was + invoked. These variables are set up automatically at startup based on + the value of ARGV[0] (this works only if you use GNU ld). */ +extern char *program_invocation_name, *program_invocation_short_name; +#endif + +__END_DECLS + +#endif /* errno.h */ diff --git a/fcntl.h b/fcntl.h new file mode 100644 index 0000000000..bac1e8685d --- /dev/null +++ b/fcntl.h @@ -0,0 +1 @@ +#include <io/fcntl.h> diff --git a/features.h b/features.h new file mode 100644 index 0000000000..0778092ed9 --- /dev/null +++ b/features.h @@ -0,0 +1,157 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FEATURES_H + +#define _FEATURES_H 1 + +/* These are defined by the user (or the compiler) + to specify the desired environment: + + __STRICT_ANSI__ ANSI Standard C. + _POSIX_SOURCE IEEE Std 1003.1. + _POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if ==2 add IEEE Std 1003.2. + _BSD_SOURCE ANSI, POSIX, and 4.3BSD things. + _SVID_SOURCE ANSI, POSIX, and SVID things. + _GNU_SOURCE All of the above, plus GNU extensions. + + The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__. + If none of these are defined, the default is _GNU_SOURCE. + If more than one of these are defined, they accumulate. + For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE + together give you ANSI C, 1003.1, and 1003.2, but nothing else. + + These are defined by this file and are used by the + header files to decide what to declare or define: + + __USE_POSIX Define IEEE Std 1003.1 things. + __USE_POSIX2 Define IEEE Std 1003.2 things. + __USE_BSD Define 4.3BSD things. + __USE_SVID Define SVID things. + __USE_MISC Define things common to BSD and System V Unix. + __USE_GNU Define GNU extensions. + __FAVOR_BSD Favor 4.3BSD things in cases of conflict. + + The macro `__GNU_LIBRARY__' is defined by this file unconditionally. + + All macros defined by this file are defined as 1. + All macros listed above as possibly being defined by this file are + explicitly undefined if they are not explicitly defined. + Feature-test macros that are not defined by the user or compiler + but are implied by the other feature-test macros defined (or by the + lack of any definitions) are defined by the file. */ + + +/* Undefine everything, so we get a clean slate. */ +#undef __USE_POSIX +#undef __USE_POSIX2 +#undef __USE_BSD +#undef __USE_SVID +#undef __USE_MISC +#undef __USE_GNU +#undef __FAVOR_BSD + + +/* If nothing is defined, define _GNU_SOURCE. */ +#if (!defined(_GNU_SOURCE) && !defined(__STRICT_ANSI__) && \ + !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && \ + !defined(_BSD_SOURCE) && !defined(_SVID_SOURCE)) +#define _GNU_SOURCE 1 +#endif + + +/* Always use ANSI things. */ +#define __USE_ANSI 1 + + +/* If _BSD_SOURCE was defined by the user, favor BSD over POSIX. */ +#ifdef _BSD_SOURCE +#define __FAVOR_BSD 1 +#endif + + +/* If nothing (other than _GNU_SOURCE) is defined, + define _BSD_SOURCE and _SVID_SOURCE. */ +#if (!defined(__STRICT_ANSI__) && !defined(_POSIX_SOURCE) && \ + !defined(_POSIX_C_SOURCE) && !defined(_BSD_SOURCE) && \ + !defined(_SVID_SOURCE)) +#define _BSD_SOURCE 1 +#define _SVID_SOURCE 1 +#endif + +/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2. */ +#if (!defined(__STRICT_ANSI__) && !defined(_POSIX_SOURCE) && \ + !defined(_POSIX_C_SOURCE)) +#define _POSIX_SOURCE 1 +#define _POSIX_C_SOURCE 2 +#endif + +#if defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1 +#define __USE_POSIX 1 +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2 +#define __USE_POSIX2 1 +#endif + +#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) +#define __USE_MISC 1 +#endif + +#ifdef _BSD_SOURCE +#define __USE_BSD 1 +#endif + +#ifdef _SVID_SOURCE +#define __USE_SVID 1 +#endif + +#ifdef _GNU_SOURCE +#define __USE_GNU 1 +#endif + + +#undef __GNU_LIBRARY__ +#define __GNU_LIBRARY__ 1 + + +#if !defined(__GNUC__) || __GNUC__ < 2 +/* In GCC version 2, (__extension__ EXPR) will not complain + about GCC extensions used in EXPR under -ansi or -pedantic. */ +#define __extension__ +#endif + + +/* This is here only because every header file already includes this one. */ +#include <sys/cdefs.h> + +/* This is here only because every header file already includes this one. */ +#ifndef _LIBC +/* Get the definitions of all the appropriate `__stub_FUNCTION' symbols. + <stubs.h> contains `#define __stub_FUNCTION' when FUNCTION is a stub + which will always return failure (and set errno to ENOSYS). + + We avoid including <stubs.h> when compiling the C library itself to + avoid a dependency loop. stubs.h depends on every object file. If + this #include were done for the library source code, then every object + file would depend on stubs.h. */ + +#include <stubs.h> +#endif + +#endif /* __features.h */ diff --git a/fnmatch.h b/fnmatch.h new file mode 100644 index 0000000000..b12b786df0 --- /dev/null +++ b/fnmatch.h @@ -0,0 +1 @@ +#include <posix/fnmatch.h> @@ -0,0 +1 @@ +#include <io/ftw.h> diff --git a/getopt.h b/getopt.h new file mode 100644 index 0000000000..74ca6d453a --- /dev/null +++ b/getopt.h @@ -0,0 +1 @@ +#include <posix/getopt.h> diff --git a/glob.h b/glob.h new file mode 100644 index 0000000000..ce047bb177 --- /dev/null +++ b/glob.h @@ -0,0 +1 @@ +#include <posix/glob.h> diff --git a/gnu-stabs.h b/gnu-stabs.h new file mode 100644 index 0000000000..3cdc91def8 --- /dev/null +++ b/gnu-stabs.h @@ -0,0 +1,75 @@ +#error This file is obsolete. + +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef __GNU_STABS_H + +#define __GNU_STABS_H 1 + +#ifdef HAVE_GNU_LD + +/* Alias a function: + function_alias(creat, _creat, int, (file, mode), + DEFUN(creat, (file, mode), + CONST char *file AND int mode)) + Yes, this is very repetitive. Nothing you can do about it, so shut up. */ +#define function_alias(name, _name, type, args, defun) \ + symbol_alias (_name, name); + +#define function_alias_void(name, _name, args, defun) \ + symbol_alias (_name, name); + +#ifdef NO_UNDERSCORES +#define __SYMBOL_PREFIX +#else +#define __SYMBOL_PREFIX "_" +#endif + +/* Make references to ALIAS refer to SYMBOL. */ +#define symbol_alias(symbol, alias) \ + asm(".stabs \"" __SYMBOL_PREFIX #alias "\",11,0,0,0\n"\ + ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0") + +/* Issue a warning message from the linker whenever SYMBOL is referenced. */ +#define warn_references(symbol, msg) \ + asm(".stabs \"" msg "\",30,0,0,0\n" \ + ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0") + +#define stub_warning(name) \ + warn_references(name, \ + "warning: " #name " is not implemented and will always fail") + +#define text_set_element(set, symbol) \ + asm(".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) +#define data_set_element(set, symbol) \ + asm(".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) +#define bss_set_element(set, symbol) \ + asm(".stabs \"" __SYMBOL_PREFIX #set "\",27,0,0," __SYMBOL_PREFIX #symbol) + +#else /* No GNU stabs. */ + +#define function_alias(name, _name, type, args, defun) \ + type defun { return _name args; } + +#define function_alias_void(name, _name, args, defun) \ + void defun { _name args; } + +#endif /* GNU stabs. */ + +#endif /* gnu-stabs.h */ diff --git a/gnu/signal.h b/gnu/signal.h new file mode 100644 index 0000000000..3c1dfa2baf --- /dev/null +++ b/gnu/signal.h @@ -0,0 +1 @@ +#include <signal/gnu/signal.h> diff --git a/gnu/time.h b/gnu/time.h new file mode 100644 index 0000000000..9f90588546 --- /dev/null +++ b/gnu/time.h @@ -0,0 +1 @@ +#include <time/gnu/time.h> diff --git a/gnu/types.h b/gnu/types.h new file mode 100644 index 0000000000..0d1fb31d06 --- /dev/null +++ b/gnu/types.h @@ -0,0 +1 @@ +#include <posix/gnu/types.h> diff --git a/gnu/wait.h b/gnu/wait.h new file mode 100644 index 0000000000..a47b5e8754 --- /dev/null +++ b/gnu/wait.h @@ -0,0 +1 @@ +#include <posix/gnu/wait.h> diff --git a/gnulib/.cvsignore b/gnulib/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/gnulib/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/gnulib/Makefile b/gnulib/Makefile new file mode 100644 index 0000000000..84ebc2e6bc --- /dev/null +++ b/gnulib/Makefile @@ -0,0 +1,23 @@ +# Copyright (C) 1991 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := gnulib + +# Which routines are required is machine-dependent. + +include ../Rules @@ -0,0 +1 @@ +#include <grp/grp.h> diff --git a/grp/Makefile b/grp/Makefile new file mode 100644 index 0000000000..6444aab5ff --- /dev/null +++ b/grp/Makefile @@ -0,0 +1,29 @@ +# Copyright (C) 1991, 1992 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for grp portion of the library. +# +subdir := grp + +routines := grpopen grpread fgetgrent getgrent getgrgid getgrnam \ + initgroups setgroups + +tests := testgrp + +include ../Rules diff --git a/grp/fgetgrent.c b/grp/fgetgrent.c new file mode 100644 index 0000000000..bef3e3f745 --- /dev/null +++ b/grp/fgetgrent.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <grp.h> + + +/* Read a group entry from STREAM. */ +struct group * +DEFUN(fgetgrent, (stream), FILE *stream) +{ + static PTR info = NULL; + if (info == NULL) + { + info = __grpalloc(); + if (info == NULL) + return NULL; + } + + return __grpread(stream, info); +} diff --git a/grp/getgrent.c b/grp/getgrent.c new file mode 100644 index 0000000000..105572f9a0 --- /dev/null +++ b/grp/getgrent.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <grp.h> + +static FILE *stream = NULL; + +/* Rewind the stream. */ +void +DEFUN_VOID(setgrent) +{ + if (stream != NULL) + rewind(stream); +} + + +/* Close the stream. */ +void +DEFUN_VOID(endgrent) +{ + if (stream != NULL) + { + (void) fclose(stream); + stream = NULL; + } +} + + +/* Read an entry from the stream. */ +struct group * +DEFUN_VOID(getgrent) +{ + static PTR info = NULL; + if (info == NULL) + { + info = __grpalloc(); + if (info == NULL) + return(NULL); + } + + if (stream == NULL) + { + stream = __grpopen(); + if (stream == NULL) + return(NULL); + } + + return(__grpread(stream, info)); +} diff --git a/grp/getgrgid.c b/grp/getgrgid.c new file mode 100644 index 0000000000..1375f5ff56 --- /dev/null +++ b/grp/getgrgid.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <sys/types.h> +#include <grp.h> + +/* Search for an entry with a matching group ID. */ +struct group * +DEFUN(getgrgid, (gid), register gid_t gid) +{ + static PTR info = NULL; + register FILE *stream; + register struct group *g; + + if (info == NULL) + { + info = __grpalloc(); + if (info == NULL) + return NULL; + } + + stream = __grpopen(); + if (stream == NULL) + return NULL; + + while ((g = __grpread(stream, info)) != NULL) + if (g->gr_gid == (gid_t) gid) + break; + + (void) fclose(stream); + return g; +} diff --git a/grp/getgrnam.c b/grp/getgrnam.c new file mode 100644 index 0000000000..1f88ea3ff3 --- /dev/null +++ b/grp/getgrnam.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <grp.h> + +/* Search for an entry with a matching name. */ +struct group * +DEFUN(getgrnam, (name), register CONST char *name) +{ + static PTR info = NULL; + register FILE *stream; + register struct group *g; + + if (info == NULL) + { + info = __grpalloc(); + if (info == NULL) + return NULL; + } + + stream = __grpopen(); + if (stream == NULL) + return NULL; + + while ((g = __grpread(stream, info)) != NULL) + if (!strcmp(g->gr_name, name)) + break; + + (void) fclose(stream); + return g; +} diff --git a/grp/grp.h b/grp/grp.h new file mode 100644 index 0000000000..2562671885 --- /dev/null +++ b/grp/grp.h @@ -0,0 +1,101 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 9.2.1 Group Database Access <grp.h> + */ + +#ifndef _GRP_H + +#define _GRP_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + + +/* The group structure. */ +struct group + { + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + __gid_t gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ + }; + + +#if defined(__USE_SVID) || defined(__USE_GNU) +#define __need_FILE +#include <stdio.h> +#endif + +#ifdef __USE_GNU +/* Return a new stream open on the group file. */ +extern FILE *__grpopen __P ((void)); + +/* Read a group entry from STREAM, filling in G. + Return the `struct group' of G if successful, NULL on failure. */ +extern struct group *__grpread __P ((FILE * __stream, __ptr_t __g)); + +/* Return a chunk of memory containing pre-initialized data for __grpread. */ +extern __ptr_t __grpalloc __P ((void)); +#endif + + +#if defined(__USE_SVID) || defined(__USE_MISC) || defined (__USE_BSD) +/* Rewind the group-file stream. */ +extern void setgrent __P ((void)); + +/* Close the group-file stream. */ +extern void endgrent __P ((void)); + +/* Read an entry from the group-file stream, opening it if necessary. */ +extern struct group *getgrent __P ((void)); +#endif + +#ifdef __USE_SVID +/* Read a group entry from STREAM. */ +extern struct group *fgetgrent __P ((FILE * __stream)); +#endif + +/* Search for an entry with a matching group ID. */ +extern struct group *getgrgid __P ((__gid_t __gid)); + +/* Search for an entry with a matching group name. */ +extern struct group *getgrnam __P ((__const char *__name)); + + +#ifdef __USE_BSD + +#define __need_size_t +#include <stddef.h> + +/* Set the group set for the current user to GROUPS (N of them). */ +extern int setgroups __P ((size_t __n, __const __gid_t * groups)); + +/* Initialize the group set for the current user + by reading the group database and using all groups + of which USER is a member. Also include GROUP. */ +extern int initgroups __P ((__const char *user, __gid_t group)); + +#endif /* Use BSD. */ + +__END_DECLS + +#endif /* grp.h */ diff --git a/grp/grpopen.c b/grp/grpopen.c new file mode 100644 index 0000000000..77d15979f1 --- /dev/null +++ b/grp/grpopen.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <grp.h> + +/* Return a new stream open on the group file. */ +FILE * +DEFUN_VOID(__grpopen) +{ + return fopen("/etc/group", "r"); +} diff --git a/grp/grpread.c b/grp/grpread.c new file mode 100644 index 0000000000..b7bac4c192 --- /dev/null +++ b/grp/grpread.c @@ -0,0 +1,135 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <grp.h> + +/* This is the function that all the others are based on. + The format of the group file is known only here. */ + +/* Structure containing info kept by each __grpread caller. */ +typedef struct + { + char *buf; + size_t buflen; + size_t max_members; + char **members; + struct group g; + } grpread_info; + + +/* Return a chunk of memory containing a pre-initialized `grpread_info'. */ +PTR +DEFUN_VOID(__grpalloc) +{ + grpread_info *info = (PTR) malloc (sizeof(grpread_info)); + if (info == NULL) + return NULL; + + info->buf = NULL; + info->buflen = 0; + + info->max_members = 5; + info->members = (char **) malloc (5 * sizeof(char *)); + if (info->members == NULL) + { + free ((PTR) info); + return NULL; + } + + return info; +} + +/* Read a group entry from STREAM, filling in G. */ +struct group * +DEFUN(__grpread, (stream, g), FILE *stream AND PTR CONST g) +{ + register grpread_info *CONST info = (grpread_info *) g; + char *start, *end; + register size_t i; + + /* Idiocy checks. */ + if (stream == NULL) + { + errno = EINVAL; + return NULL; + } + + do + if (__getline (&info->buf, &info->buflen, stream) == -1) + return NULL; + while (info->buf[0] == '#'); + + start = info->buf; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->g.gr_name = start; + + start = end + 1; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->g.gr_passwd = start; + + info->g.gr_gid = (gid_t) strtol (end + 1, &end, 10); + if (*end != ':') + return NULL; + + i = 0; + do + { + start = end + 1; + end = strchr (start, ','); + if (end == NULL) + { + end = strchr (start, '\n'); + if (end == start) + break; + if (end == NULL) + return NULL; + *end = '\0'; + end = NULL; + } + else + *end = '\0'; + + if (i == info->max_members - 2) + { + info->max_members += 5; + info->members = (char **) + realloc ((PTR) info->members, info->max_members * sizeof (char *)); + if (info->members == NULL) + return NULL; + } + + info->members[i++] = start; + } while (end != NULL); + info->members[i] = NULL; + info->g.gr_mem = info->members; + + return &info->g; +} diff --git a/grp/initgroups.c b/grp/initgroups.c new file mode 100644 index 0000000000..5af1926742 --- /dev/null +++ b/grp/initgroups.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1989, 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <string.h> +#include <grp.h> +#include <limits.h> +#include <sys/types.h> + + +/* Initialize the group set for the current user + by reading the group database and using all groups + of which USER is a member. Also include GROUP. */ +int +DEFUN(initgroups, (user, group), + CONST char *user AND gid_t group) +{ +#ifdef NGROUPS_MAX +#if NGROUPS_MAX == 0 + return 0; +#else + static PTR info = NULL; + register FILE *stream; + register struct group *g; + gid_t groups[NGROUPS_MAX]; + register size_t n; + + if (info == NULL) + { + info = __grpalloc(); + if (info == NULL) + return -1; + } + + stream = __grpopen(); + if (stream == NULL) + return -1; + + n = 0; + groups[n++] = group; + + while (n < NGROUPS_MAX && (g = __grpread(stream, info)) != NULL) + if (g->gr_gid != group) + { + register char **m; + + for (m = g->gr_mem; *m != NULL; ++m) + if (!strcmp(*m, user)) + groups[n++] = g->gr_gid; + } + + return setgroups(n, groups); +#endif +#else + return 0; +#endif +} diff --git a/grp/testgrp.c b/grp/testgrp.c new file mode 100644 index 0000000000..109d1a46d3 --- /dev/null +++ b/grp/testgrp.c @@ -0,0 +1,45 @@ +#include <ansidecl.h> +#include <grp.h> +#include <pwd.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + uid_t me; + struct passwd *my_passwd; + struct group *my_group; + char **members; + + me = getuid (); + my_passwd = getpwuid (me); + if (my_passwd == NULL) + perror ("getpwuid"); + else + { + printf ("My login name is %s.\n", my_passwd->pw_name); + printf ("My uid is %d.\n", (int)(my_passwd->pw_uid)); + printf ("My home directory is %s.\n", my_passwd->pw_dir); + printf ("My default shell is %s.\n", my_passwd->pw_shell); + + my_group = getgrgid (my_passwd->pw_gid); + if (my_group == NULL) + perror ("getgrgid"); + else + { + printf ("My default group is %s (%d).\n", + my_group->gr_name, (int)(my_passwd->pw_gid)); + printf ("The members of this group are:\n"); + for (members = my_group->gr_mem; *members != NULL; ++members) + printf (" %s\n", *members); + } + } + + exit (my_passwd && my_group ? EXIT_SUCCESS : EXIT_FAILURE); +} + + + diff --git a/hurd/.cvsignore b/hurd/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/hurd/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/hurd/Makefile b/hurd/Makefile new file mode 100644 index 0000000000..7a5a1ba995 --- /dev/null +++ b/hurd/Makefile @@ -0,0 +1,117 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := hurd + +all: + +# Some things below (but before including Rules) use configuration variables. +include ../Makeconfig + + +headers = hurd.h $(interface-headers) \ + $(addprefix hurd/,fd.h id.h port.h signal.h userlink.h \ + resource.h threadvar.h) + +distribute := hurdfault.h intr-rpc.awk intr-rpc.defs STATUS + +# The RPC interfaces go in a separate library. +interface-library := libhurduser.a +user-interfaces := $(addprefix hurd/,\ + auth process startup \ + msg msg_reply msg_request \ + exec core interrupt \ + fs fsys io term socket ifsock) +server-interfaces := hurd/msg + +routines = hurdinit hurdid hurdlookup hurdpid hurdrlimit hurdprio hurdexec \ + setauth \ + pid2task task2pid \ + getuids setuids getumask fchroot \ + hurdsock hurdauth invoke-trans \ + privports \ + msgportdemux \ + fopenport \ + vpprintf \ + ports-get ports-set hurdports hurdmsg \ + $(sig) $(dtable) hurdinline +sig = hurdsig hurdfault faultexc siginfo hurd-raise preempt-sig \ + trampoline longjmp-ts catch-exc exc2signal hurdkill +dtable = dtable port2fd new-fd alloc-fd intern-fd \ + getdport openport \ + fd-close fd-read fd-write hurdioctl ctty-input ctty-output + +# XXX this is a temporary hack; see hurdmalloc.h +routines += hurdmalloc +distribute += hurdmalloc.h + +# Get the proper definition of `hurd-srcdir'. +include ../sysdeps/mach/hurd/Makefile + +# Use and install the Hurd header files directly out of the Hurd source. + +# Find the MiG defs files in the Hurd source. +vpath %.defs $(hurd-srcdir) + +# Install all .h and .defs files we find in the Hurd's hurd/ directory. +hurd-headers := $(patsubst $(hurd-srcdir)/%,%,\ + $(wildcard $(addprefix $(hurd-srcdir)/hurd/,\ + *.defs *.h))) + + +# Don't distribute the Hurd headers; they are in the Hurd distribution. +dont_distribute = $(hurd-headers) + +# DO NOT try to remake these in any way!!! +$(addprefix $(hurd-srcdir)/,$(hurd-headers)) : ; +install-others += $(addprefix $(includedir)/,$(hurd-headers)) +$(includedir)/hurd/%: $(hurd-srcdir)/hurd/%; $(do-install) + +include ../mach/Machrules +include ../Rules + +# intr-rpc.defs defines the INTR_INTERFACE macro to make the generated RPC +# stubs send-interruptible, and to prefix them with `hurd_intr_rpc_'. +user-MIGFLAGS += -imacros intr-rpc.defs + +# Run each generated user stub through intr-rpc.awk, which will detect +# stubs __hurd_intr_rpc_% and generate the user-callable function for the +# stub: this is a wrapper which calls __hurd_intr_rpc_% inside +# HURD_EINTR_RPC. +define transform-user-stub +gawk -v call=$${call} -f $(word 2,$^) \ + $(objpfx)tmp_$${call}.c > $(objpfx)tmpi_$${call}.c; \ +rm -f $(objpfx)tmp_$${call}.c; +endef +transform-user-stub-output = tmpi + +$(foreach if,$(user-interfaces),$($(if)-calls:%=$(objpfx)RPC_%.o))): \ + hurd/signal.h + +$(user-interfaces:%=$(objpfx)%.ustamp): intr-rpc.awk + +$(objpfx)fault%.c $(objpfx)fault%.h: $(mach-srcdir)/mach/%.defs + $(MIG) $(MIGFLAGS) -prefix _hurdsig_fault_ \ + -server $(@:.h=.c) -sheader $(@:.c=.h) \ + -user /dev/null -header /dev/null \ + $< +generated += faultexc.c faultexc.h + +# We need this static dependency to get faultexc.h generated the first time. +$(objpfx)hurdfault.o $(objpfx)hurdfault.d: \ + $(objpfx)faultexc.h $(objpfx)faultexc.c diff --git a/hurd/Notes b/hurd/Notes new file mode 100644 index 0000000000..9052f29096 --- /dev/null +++ b/hurd/Notes @@ -0,0 +1,37 @@ +The library pays attention to some envariables: + +CORESERVER -- Name of core server naming point; falls back to /servers/core +COREFILE -- Name of file to write core dump in; falls back to core +GNUTARGET -- Passed to core server to specify flavor of core dump format + +New functions: + +int openport (io_t port); +FILE *fopenport (mach_port_t, const char *mode); +file_t getdport (int fd); + +task_t pid2task (pid_t); +pid_t task2pid (task_t); + +int fchroot (int fd); +mode_t getumask (void); + +int getuids (int n, uid_t *uidset); + +error_t hurd_path_lookup (file_t root, file_t cwd, + const char *path, int flags, mode_t mode, + file_t *port); +error_t hurd_path_split (file_t root, file_t cwd, + const char *path, + file_t *dir, char **name); +file_t path_lookup (const char *path, int flags, mode_t mode); +file_t path_split (const char *path, char **name); + +process_t getproc (void); +int setproc (process_t); +file_t getcrdir (void); +int setcrdir (file_t); +file_t getcwdir (void); +int setcwdir (file_t); +auth_t getauth (void); +int setauth (auth_t); /* Reauthenticates all library ports. */ diff --git a/hurd/STATUS b/hurd/STATUS new file mode 100644 index 0000000000..ceb0a865d0 --- /dev/null +++ b/hurd/STATUS @@ -0,0 +1,72 @@ +Status of Hurd support in libc. Last updated 22 Nov 1994. +Roland McGrath <roland@gnu.ai.mit.edu> + +Everything not noted below is implemented, most of it tested. There are +various very small things unfinished or thought to be perhaps wrong +throughout the code, marked by comments containing `XXX'. + + +* Signals and job control work, but are a very hairy area. + There are various ways the signal thread can block and fail + to respond when the program is losing badly. + +* We are not sure about possible races between setpgrp (A, pgrp) from + process B vs process A receiving proc_newids. + +* The rest of libc (stdio et al) is not safe for multithreaded programs. + mutex locks should be added to various things. + +* Recovery from faults in the signal thread is not implemented yet. + +* longjmp needs to clean up reply port, intr_port; needs thought about. + +* Cooperation with cthreads is not finished. If you link with cthreads, + libc internal code still does not use real condition variables. + sigsuspend currently does a busy wait where it should use a condition. + Signal state is per kernel thread; for unwired cthreads it should be per + cthread instead. + +* sigaltstack/sigstack do not really work: the signal stack needs thread + variables and cthread data set up, which is not done. + +* malloc is a kludge. + +* Nothing uses mapped io. Eventually stdio and read/write/seek should. I + have written a little code for this, but it is far from finished. + +* Resource limits do not really work; current implementation is patchy and + inconsistent. + +* libc implicitly uses some environment variables. This is a security + problem for setuid exec. Probably crt0 should remove the variables from + the environment if setuid. + +* The miscellaneous msg.defs calls are only partially implemented. + +* The default SIGINFO handler needs to be written. + +* File locking is not implemented; the RPC interface is not there yet. + +* The current getitimer/setitimer implementation is a kludge. + +* mmap cannot do MAP_NOEXTEND. + +* Unimplemented calls (from the 4.4 system call list): +acct +fstatfs +getfh +getfsstat +getrusage +madvise +mincore +mount +msync +profil +recvmsg +revoke +sendmsg +setpriority +sstk +statfs +swapon +unmount diff --git a/hurd/alloc-fd.c b/hurd/alloc-fd.c new file mode 100644 index 0000000000..02a1bdfd52 --- /dev/null +++ b/hurd/alloc-fd.c @@ -0,0 +1,127 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/resource.h> +#include <stdlib.h> +#include "hurdmalloc.h" /* XXX */ + +/* Allocate a new file descriptor and return it, locked. The new + descriptor number will be no less than FIRST_FD. If the table is full, + set errno to EMFILE and return NULL. If FIRST_FD is negative or bigger + than the size of the table, set errno to EINVAL and return NULL. */ + +struct hurd_fd * +_hurd_alloc_fd (int *fd, int first_fd) +{ + int i; + void *crit; + long int rlimit; + + if (first_fd < 0) + { + errno = EINVAL; + return NULL; + } + + crit = _hurd_critical_section_lock (); + + __mutex_lock (&_hurd_dtable_lock); + + search: + for (i = first_fd; i < _hurd_dtablesize; ++i) + { + struct hurd_fd *d = _hurd_dtable[i]; + if (d == NULL) + { + /* Allocate a new descriptor structure for this slot, + initializing its port cells to nil. The test below will catch + and return this descriptor cell after locking it. */ + d = _hurd_new_fd (MACH_PORT_NULL, MACH_PORT_NULL); + if (d == NULL) + { + __mutex_unlock (&_hurd_dtable_lock); + _hurd_critical_section_unlock (crit); + return NULL; + } + _hurd_dtable[i] = d; + } + + __spin_lock (&d->port.lock); + if (d->port.port == MACH_PORT_NULL) + { + __mutex_unlock (&_hurd_dtable_lock); + _hurd_critical_section_unlock (crit); + if (fd != NULL) + *fd = i; + return d; + } + else + __spin_unlock (&d->port.lock); + } + + __mutex_lock (&_hurd_rlimit_lock); + rlimit = _hurd_rlimits[RLIMIT_OFILE].rlim_cur; + __mutex_unlock (&_hurd_rlimit_lock); + + if (first_fd < rlimit) + { + /* The descriptor table is full. Check if we have reached the + resource limit, or only the allocated size. */ + if (_hurd_dtablesize < rlimit) + { + /* Enlarge the table. */ + int save = errno; + struct hurd_fd **new; + /* Try to double the table size (but don't exceed the limit). + If there isn't any at all, give it three slots (because + stdio will take that many anyway). */ + int size = _hurd_dtablesize ? _hurd_dtablesize * 2 : 3; + if (size > rlimit) + size = rlimit; + /* If we fail to allocate that, decrement the desired size + until we succeed in allocating it. */ + do + new = realloc (_hurd_dtable, size * sizeof (*_hurd_dtable)); + while (new == NULL && size-- > _hurd_dtablesize); + if (new != NULL) + { + /* We managed to allocate a new table. Now install it. */ + errno = save; + first_fd = _hurd_dtablesize; + /* Initialize the new slots. */ + for (i = first_fd; i < size; ++i) + new[i] = NULL; + _hurd_dtablesize = size; + _hurd_dtable = new; + /* Go back to the loop to initialize the first new slot. */ + goto search; + } + } + else + errno = EMFILE; + } + else + errno = EINVAL; /* Bogus FIRST_FD value. */ + + __mutex_unlock (&_hurd_dtable_lock); + _hurd_critical_section_unlock (crit); + + return NULL; +} diff --git a/hurd/catch-exc.c b/hurd/catch-exc.c new file mode 100644 index 0000000000..72e06db1d3 --- /dev/null +++ b/hurd/catch-exc.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach/exc_server.h> +#include <hurd/signal.h> + +/* Called by the microkernel when a thread gets an exception. */ + +kern_return_t +_S_catch_exception_raise (mach_port_t port, + thread_t thread, + task_t task, + int exception, + int code, + int subcode) +{ + int signo, error; + long int sigcode; + struct hurd_sigstate *ss; + + if (task != __mach_task_self ()) + /* The sender wasn't the kernel. */ + return EPERM; + + /* Call the machine-dependent function to translate the Mach exception + codes into a signal number and subcode. */ + _hurd_exception2signal (exception, code, subcode, + &signo, &sigcode, &error); + + /* Find the sigstate structure for the faulting thread. */ + __mutex_lock (&_hurd_siglock); + for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) + if (ss->thread == thread) + break; + __mutex_unlock (&_hurd_siglock); + if (ss == NULL) + ss = _hurd_thread_sigstate (thread); /* Allocate a fresh one. */ + + if (__spin_lock_locked (&ss->lock)) + { + /* Loser. The thread faulted with its sigstate lock held. Its + sigstate data is now suspect. So we reset the parts of it which + could cause trouble for the signal thread. Anything else + clobbered therein will just hose this user thread, but it's + faulting already. + + This is almost certainly a library bug: unless random memory + clobberation caused the sigstate lock to gratuitously appear held, + no code should do anything that can fault while holding the + sigstate lock. */ + + ss->critical_section = 0; + ss->context = NULL; + __spin_unlock (&ss->lock); + } + + /* Post the signal. */ + _hurd_internal_post_signal (ss, signo, sigcode, error, + MACH_PORT_NULL, MACH_MSG_TYPE_PORT_SEND, + 0); + + return KERN_SUCCESS; +} diff --git a/hurd/ctty-input.c b/hurd/ctty-input.c new file mode 100644 index 0000000000..71aef1b6cf --- /dev/null +++ b/hurd/ctty-input.c @@ -0,0 +1,77 @@ +/* _hurd_ctty_input -- Do an input RPC and generate SIGTTIN if necessary. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> + +/* Call *RPC on PORT and/or CTTY. If a call on CTTY returns EBACKGROUND, + generate SIGTTIN or EIO as appropriate. */ + +error_t +_hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t)) +{ + error_t err; + + do + { + err = (*rpc) (ctty != MACH_PORT_NULL ? ctty : port); + if (ctty != MACH_PORT_NULL && err == EBACKGROUND) + { + /* We are a background job and tried to read from the tty. + We should probably get a SIGTTIN signal. */ + struct hurd_sigstate *ss; + if (_hurd_orphaned) + /* Our process group is orphaned. Don't stop; just fail. */ + err = EIO; + else + { + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + if (__sigismember (&ss->blocked, SIGTTIN) || + ss->actions[SIGTTIN].sa_handler == SIG_IGN) + /* We are blocking or ignoring SIGTTIN. Just fail. */ + err = EIO; + __spin_unlock (&ss->lock); + } + if (err == EBACKGROUND) + { + /* Send a SIGTTIN signal to our process group. + + We must remember here not to clobber ERR, since + the loop condition below uses it to recall that + we should retry after a stop. */ + + __USEPORT (CTTYID, _hurd_sig_post (0, SIGTTIN, port)); + /* XXX what to do if error here? */ + + /* At this point we should have just run the handler for + SIGTTIN or resumed after being stopped. Now this is + still a "system call", so check to see if we should + restart it. */ + __spin_lock (&ss->lock); + if (!(ss->actions[SIGTTIN].sa_flags & SA_RESTART)) + err = EINTR; + __spin_unlock (&ss->lock); + } + } + /* If the last RPC generated a SIGTTIN, loop to try it again. */ + } while (err == EBACKGROUND); + + return err; +} diff --git a/hurd/ctty-output.c b/hurd/ctty-output.c new file mode 100644 index 0000000000..0d9c54383d --- /dev/null +++ b/hurd/ctty-output.c @@ -0,0 +1,82 @@ +/* _hurd_ctty_output -- Do an output RPC and generate SIGTTOU if necessary. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> + +/* Call *RPC on PORT and/or CTTY. If a call on CTTY returns EBACKGROUND, + generate SIGTTOU if appropriate. */ + +error_t +_hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t)) +{ + error_t err; + struct hurd_sigstate *ss; + io_t ioport; + + /* Don't use the ctty io port if we are blocking or ignoring SIGTTOU. */ + if (ctty == MACH_PORT_NULL) + ioport = port; + else + { + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + if (__sigismember (&ss->blocked, SIGTTOU) || + ss->actions[SIGTTOU].sa_handler == SIG_IGN) + ioport = port; + else + ioport = ctty; + __spin_unlock (&ss->lock); + } + + do + { + err = (*rpc) (ioport); + if (ioport == ctty && err == EBACKGROUND) + { + if (_hurd_orphaned) + /* Our process group is orphaned, so we never generate a + signal; we just fail. */ + err = EIO; + else + { + /* Send a SIGTTOU signal to our process group. + + We must remember here not to clobber ERR, since + the loop condition below uses it to recall that + we should retry after a stop. */ + + __USEPORT (CTTYID, _hurd_sig_post (0, SIGTTOU, port)); + /* XXX what to do if error here? */ + + /* At this point we should have just run the handler for + SIGTTOU or resumed after being stopped. Now this is + still a "system call", so check to see if we should + restart it. */ + __spin_lock (&ss->lock); + if (!(ss->actions[SIGTTOU].sa_flags & SA_RESTART)) + err = EINTR; + __spin_unlock (&ss->lock); + } + } + /* If the last RPC generated a SIGTTOU, loop to try it again. */ + } while (err == EBACKGROUND); + + return err; +} diff --git a/hurd/dtable.c b/hurd/dtable.c new file mode 100644 index 0000000000..3e785a9710 --- /dev/null +++ b/hurd/dtable.c @@ -0,0 +1,277 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <hurd.h> +#include <hurd/term.h> +#include <hurd/fd.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <limits.h> +#include <cthreads.h> /* For `struct mutex'. */ +#include "set-hooks.h" +#include "hurdmalloc.h" /* XXX */ + + +struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER; /* XXX ld bug; must init */ +struct hurd_fd **_hurd_dtable; +int _hurd_dtablesize; + + +DEFINE_HOOK (_hurd_fd_subinit, (void)); + +/* Initialize the file descriptor table at startup. */ + +static void +init_dtable (void) +{ + register size_t i; + + __mutex_init (&_hurd_dtable_lock); + + /* The initial size of the descriptor table is that of the passed-in + table. It will be expanded as necessary up to _hurd_dtable_rlimit. */ + _hurd_dtablesize = _hurd_init_dtablesize; + + /* Allocate the vector of pointers. */ + _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable)); + if (_hurd_dtablesize != 0 && _hurd_dtable == NULL) + __libc_fatal ("hurd: Can't allocate file descriptor table\n"); + + /* Initialize the descriptor table. */ + for (i = 0; i < _hurd_init_dtablesize; ++i) + { + if (_hurd_init_dtable[i] == MACH_PORT_NULL) + /* An unused descriptor is marked by a null pointer. */ + _hurd_dtable[i] = NULL; + else + { + /* Allocate a new file descriptor structure. */ + struct hurd_fd *new = malloc (sizeof (struct hurd_fd)); + if (new == NULL) + __libc_fatal ("hurd: Can't allocate initial file descriptors\n"); + + /* Initialize the port cells. */ + _hurd_port_init (&new->port, MACH_PORT_NULL); + _hurd_port_init (&new->ctty, MACH_PORT_NULL); + + /* Install the port in the descriptor. + This sets up all the ctty magic. */ + _hurd_port2fd (new, _hurd_init_dtable[i], 0); + + _hurd_dtable[i] = new; + } + } + + /* Clear out the initial descriptor table. + Everything must use _hurd_dtable now. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) _hurd_init_dtable, + _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0])); + _hurd_init_dtable = NULL; + _hurd_init_dtablesize = 0; + + /* Initialize the remaining empty slots in the table. */ + for (; i < _hurd_dtablesize; ++i) + _hurd_dtable[i] = NULL; + + /* Run things that want to run after the file descriptor table + is initialized. */ + RUN_HOOK (_hurd_fd_subinit, ()); + + (void) &init_dtable; /* Avoid "defined but not used" warning. */ +} + +text_set_element (_hurd_subinit, init_dtable); + +/* XXX when the linker supports it, the following functions should all be + elsewhere and just have text_set_elements here. */ + +/* Called by `getdport' to do its work. */ + +static file_t +get_dtable_port (int fd) +{ + file_t dport; + int err = HURD_DPORT_USE (fd, __mach_port_mod_refs (__mach_task_self (), + (dport = port), + MACH_PORT_RIGHT_SEND, + 1)); + if (err) + { + errno = err; + return MACH_PORT_NULL; + } + else + return dport; +} + +file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port; + +#include <hurd/signal.h> + +/* We are in the child fork; the dtable lock is still held. + The parent has inserted send rights for all the normal io ports, + but we must recover ctty-special ports for ourselves. */ +static error_t +fork_child_dtable (void) +{ + error_t err; + int i; + + err = 0; + + for (i = 0; !err && i < _hurd_dtablesize; ++i) + { + struct hurd_fd *d = _hurd_dtable[i]; + if (d == NULL) + continue; + + /* No other thread is using the send rights in the child task. */ + d->port.users = d->ctty.users = NULL; + + if (d->ctty.port != MACH_PORT_NULL) + { + /* There was a ctty-special port in the parent. + We need to get one for ourselves too. */ + __mach_port_deallocate (__mach_task_self (), d->ctty.port); + err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp, + &d->ctty.port); + if (err) + d->ctty.port = MACH_PORT_NULL; + } + + /* XXX for each fd with a cntlmap, reauth and re-map_cntl. */ + } + return err; + + (void) &fork_child_dtable; /* Avoid "defined but not used" warning. */ +} + +data_set_element (_hurd_fork_locks, _hurd_dtable_lock); /* XXX ld bug: bss */ +text_set_element (_hurd_fork_child_hook, fork_child_dtable); + +/* Called when our process group has changed. */ + +static void +ctty_new_pgrp (void) +{ + int i; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + + for (i = 0; i < _hurd_dtablesize; ++i) + { + struct hurd_fd *const d = _hurd_dtable[i]; + struct hurd_userlink ulink, ctty_ulink; + io_t port, ctty; + + if (d == NULL) + /* Nothing to do for an unused descriptor cell. */ + continue; + + port = _hurd_port_get (&d->port, &ulink); + ctty = _hurd_port_get (&d->ctty, &ctty_ulink); + + if (ctty != MACH_PORT_NULL) + { + /* This fd has a ctty-special port. We need a new one, to tell + the io server of our different process group. */ + io_t new; + if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new)) + new = MACH_PORT_NULL; + _hurd_port_set (&d->ctty, new); + } + + _hurd_port_free (&d->port, &ulink, port); + _hurd_port_free (&d->ctty, &ctty_ulink, ctty); + } + + __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; + + (void) &ctty_new_pgrp; /* Avoid "defined but not used" warning. */ +} + +text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp); + +/* Called to reauthenticate the dtable when the auth port changes. */ + +static void +reauth_dtable (void) +{ + int i; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + + for (i = 0; i < _hurd_dtablesize; ++i) + { + struct hurd_fd *const d = _hurd_dtable[i]; + mach_port_t new, newctty, ref; + + if (d == NULL) + /* Nothing to do for an unused descriptor cell. */ + continue; + + ref = __mach_reply_port (); + + /* Take the descriptor cell's lock. */ + __spin_lock (&d->port.lock); + + /* Reauthenticate the descriptor's port. */ + if (d->port.port != MACH_PORT_NULL && + ! __io_reauthenticate (d->port.port, + ref, MACH_MSG_TYPE_MAKE_SEND) && + ! __USEPORT (AUTH, __auth_user_authenticate + (port, + d->port.port, + ref, MACH_MSG_TYPE_MAKE_SEND, + &new))) + { + /* Replace the port in the descriptor cell + with the newly reauthenticated port. */ + + if (d->ctty.port != MACH_PORT_NULL && + ! __io_reauthenticate (d->ctty.port, + ref, MACH_MSG_TYPE_MAKE_SEND) && + ! __USEPORT (AUTH, __auth_user_authenticate + (port, + d->ctty.port, + ref, MACH_MSG_TYPE_MAKE_SEND, + &newctty))) + _hurd_port_set (&d->ctty, newctty); + + _hurd_port_locked_set (&d->port, new); + } + else + /* Lost. Leave this descriptor cell alone. */ + __spin_unlock (&d->port.lock); + + __mach_port_destroy (__mach_task_self (), ref); + } + + __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; + + (void) &reauth_dtable; /* Avoid "defined but not used" warning. */ +} + +text_set_element (_hurd_reauth_hook, reauth_dtable); diff --git a/hurd/fchroot.c b/hurd/fchroot.c new file mode 100644 index 0000000000..cccf1391be --- /dev/null +++ b/hurd/fchroot.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Change the current root directory to FD. */ +int +DEFUN(fchroot, (fd), int fd) +{ + error_t err; + file_t dir; + + err = __USEPORT (CRDIR, + ({ file_t crdir = port; + HURD_DPORT_USE (fd, + __hurd_file_name_lookup (crdir, port, "", + 0, 0, &dir)); + })); + + if (err) + return __hurd_fail (err); + + _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir); + return 0; +} diff --git a/hurd/fd-close.c b/hurd/fd-close.c new file mode 100644 index 0000000000..54beb2a09a --- /dev/null +++ b/hurd/fd-close.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/fd.h> + +error_t +_hurd_fd_close (struct hurd_fd *fd) +{ + error_t err; + + HURD_CRITICAL_BEGIN; + + __spin_lock (&fd->port.lock); + if (fd->port.port == MACH_PORT_NULL) + { + __spin_unlock (&fd->port.lock); + err = EBADF; + } + else + { + /* Clear the descriptor's port cells. + This deallocates the ports if noone else is still using them. */ + _hurd_port_set (&fd->ctty, MACH_PORT_NULL); + _hurd_port_locked_set (&fd->port, MACH_PORT_NULL); + err = 0; + } + + HURD_CRITICAL_END; + + return err; +} diff --git a/hurd/fd-read.c b/hurd/fd-read.c new file mode 100644 index 0000000000..842066c150 --- /dev/null +++ b/hurd/fd-read.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <string.h> + +error_t +_hurd_fd_read (struct hurd_fd *fd, void *buf, size_t *nbytes) +{ + error_t err; + char *data; + mach_msg_type_number_t nread; + + error_t readfd (io_t port) + { + return __io_read (port, &data, &nread, -1, *nbytes); + } + + data = buf; + if (err = HURD_FD_PORT_USE (fd, _hurd_ctty_input (port, ctty, readfd))) + return err; + + if (data != buf) + { + memcpy (buf, data, nread); + __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); + } + + *nbytes = nread; + return 0; +} diff --git a/hurd/fd-write.c b/hurd/fd-write.c new file mode 100644 index 0000000000..f228d5e47c --- /dev/null +++ b/hurd/fd-write.c @@ -0,0 +1,42 @@ +/* _hurd_fd_write -- write to a file descriptor; handles job control et al. +Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +error_t +_hurd_fd_write (struct hurd_fd *fd, const void *buf, size_t *nbytes) +{ + error_t err; + mach_msg_type_number_t wrote; + + error_t writefd (io_t port) + { + return __io_write (port, buf, *nbytes, -1, &wrote); + } + + err = HURD_FD_PORT_USE (fd, _hurd_ctty_output (port, ctty, writefd)); + + if (! err) + *nbytes = wrote; + + return err; +} diff --git a/hurd/fopenport.c b/hurd/fopenport.c new file mode 100644 index 0000000000..5792b3e26e --- /dev/null +++ b/hurd/fopenport.c @@ -0,0 +1,131 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <hurd.h> +#include <stdio.h> +#include <fcntl.h> +#include <string.h> + +/* Read up to N chars into BUF from COOKIE. + Return how many chars were read, 0 for EOF or -1 for error. */ +static ssize_t +readio (void *cookie, char *buf, size_t n) +{ + mach_msg_type_number_t nread; + error_t err; + char *bufp = buf; + + nread = n; + if (err = __io_read ((io_t) cookie, &bufp, &nread, -1, n)) + return __hurd_fail (err); + + if (bufp != buf) + { + memcpy (buf, bufp, nread); + __vm_deallocate (__mach_task_self (), + (vm_address_t) bufp, (vm_size_t) nread); + } + + return nread; +} + +/* Write up to N chars from BUF to COOKIE. + Return how many chars were written or -1 for error. */ +static ssize_t +writeio (void *cookie, const char *buf, size_t n) +{ + mach_msg_type_number_t wrote; + error_t err; + + if (err = __io_write ((io_t) cookie, buf, n, -1, &wrote)) + return __hurd_fail (err); + + return wrote; +} + +/* Move COOKIE's file position *POS bytes, according to WHENCE. + The current file position is stored in *POS. + Returns zero if successful, nonzero if not. */ +static int +seekio (void *cookie, fpos_t *pos, int whence) +{ + error_t error = __io_seek ((file_t) cookie, *pos, whence, pos); + if (error) + return __hurd_fail (error); + return 0; +} + +/* Close the file associated with COOKIE. + Return 0 for success or -1 for failure. */ +static int +closeio (void *cookie) +{ + error_t error = __mach_port_deallocate (__mach_task_self (), + (mach_port_t) cookie); + if (error) + return __hurd_fail (error); + return 0; +} + +static const __io_functions funcsio = { readio, writeio, seekio, closeio }; + + +/* Defined in fopen.c. */ +extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr)); + + +/* Open a stream on PORT. MODE is as for fopen. */ + +FILE * +__fopenport (mach_port_t port, const char *mode) +{ + register FILE *stream; + __io_mode m; + int pflags; + error_t err; + + if (!__getmode (mode, &m)) + return NULL; + + /* Verify the PORT is valid allows the access MODE specifies. */ + + if (err = __io_get_openmodes (port, &pflags)) + return __hurd_fail (err), NULL; + + /* Check the access mode. */ + if ((m.__read && !(pflags & O_READ)) || (m.__write && !(pflags & O_WRITE))) + { + errno = EBADF; + return NULL; + } + + stream = __newstream (); + if (stream == NULL) + return NULL; + + stream->__cookie = (PTR) port; + stream->__mode = m; + stream->__io_funcs = funcsio; + stream->__room_funcs = __default_room_functions; + stream->__seen = 1; + + return stream; +} + +weak_alias (__fopenport, fopenport) diff --git a/hurd/getdport.c b/hurd/getdport.c new file mode 100644 index 0000000000..884deaa868 --- /dev/null +++ b/hurd/getdport.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +/* This is initialized in dtable.c when that gets linked in. + If dtable.c is not linked in, it will be zero. */ +file_t (*_hurd_getdport_fn) (int fd); + +file_t +__getdport (int fd) +{ + if (_hurd_getdport_fn) + /* dtable.c has defined the function to fetch a port from the real file + descriptor table. */ + return (*_hurd_getdport_fn) (fd); + + /* getdport is the only use of file descriptors, + so we don't bother allocating a real table. */ + + if (_hurd_init_dtable == NULL) + /* Never had a descriptor table. */ + return EBADF; + + if (fd < 0 || fd > _hurd_init_dtablesize || + _hurd_init_dtable[fd] == MACH_PORT_NULL) + { + errno = EBADF; + return MACH_PORT_NULL; + } + else + { + __mach_port_mod_refs (__mach_task_self (), _hurd_init_dtable[fd], + MACH_PORT_RIGHT_SEND, 1); + return _hurd_init_dtable[fd]; + } +} + +weak_alias (__getdport, getdport) diff --git a/hurd/getuids.c b/hurd/getuids.c new file mode 100644 index 0000000000..9a62f65611 --- /dev/null +++ b/hurd/getuids.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +int +__getuids (int n, uid_t *uidset) +{ + error_t err; + int nuids; + void *crit; + + crit = _hurd_critical_section_lock (); + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + return __hurd_fail (err); + } + + nuids = _hurd_id.gen.nuids; + + if (n != 0) + { + /* Copy the uids onto stack storage and then release the idlock. */ + uid_t uids[nuids]; + memcpy (uids, _hurd_id.gen.uids, sizeof (uids)); + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + + /* Now that the lock is released, we can safely copy the + uid set into the user's array, which might fault. */ + if (nuids > n) + nuids = n; + memcpy (uidset, uids, nuids * sizeof (uid_t)); + } + else + { + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + } + + return nuids; +} diff --git a/hurd/getumask.c b/hurd/getumask.c new file mode 100644 index 0000000000..80a8bf4590 --- /dev/null +++ b/hurd/getumask.c @@ -0,0 +1,25 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +mode_t +getumask (void) +{ + return _hurd_umask; +} diff --git a/hurd/hurd-raise.c b/hurd/hurd-raise.c new file mode 100644 index 0000000000..ad01ab9f89 --- /dev/null +++ b/hurd/hurd-raise.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/msg.h> +#include <setjmp.h> + +/* Handle signal SIGNO in the calling thread. + If SS is not NULL it is the sigstate for the calling thread; + SS->lock is held on entry and released before return. */ + +void +_hurd_raise_signal (struct hurd_sigstate *ss, + int signo, long int sigcode, int sigerror) +{ + if (ss == NULL) + { + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + } + + /* Mark SIGNO as pending to be delivered. */ + __sigaddset (&ss->pending, signo); + ss->pending_data[signo].code = sigcode; + ss->pending_data[signo].error = sigerror; + + __spin_unlock (&ss->lock); + + /* Send a message to the signal thread so it + will wake up and check for pending signals. */ + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); +} diff --git a/hurd/hurd.h b/hurd/hurd.h new file mode 100644 index 0000000000..472fb9173b --- /dev/null +++ b/hurd/hurd.h @@ -0,0 +1,292 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_H + +#define _HURD_H 1 +#include <features.h> + + +/* Get types, macros, constants and function declarations + for all Mach microkernel interaction. */ +#include <mach.h> +#include <mach/mig_errors.h> + +/* Get types and constants necessary for Hurd interfaces. */ +#include <hurd/hurd_types.h> + +/* Get MiG stub declarations for commonly used Hurd interfaces. */ +#include <hurd/auth.h> +#include <hurd/process.h> +#include <hurd/fs.h> +#include <hurd/io.h> + +/* Get `struct hurd_port' and related definitions implementing lightweight + user references for ports. These are used pervasively throughout the C + library; this is here to avoid putting it in nearly every source file. */ +#include <hurd/port.h> + +#include <errno.h> +#define __hurd_fail(err) (errno = (err), -1) + +/* Basic ports and info, initialized by startup. */ + +extern int _hurd_exec_flags; /* Flags word passed in exec_startup. */ +extern struct hurd_port *_hurd_ports; +extern unsigned int _hurd_nports; +extern volatile mode_t _hurd_umask; + +/* Shorthand macro for referencing _hurd_ports (see <hurd/port.h>). */ + +#define __USEPORT(which, expr) \ + HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr)) + + +/* Base address and size of the initial stack set up by the exec server. + If using cthreads, this stack is deallocated in startup. + Not locked. */ + +extern vm_address_t _hurd_stack_base; +extern vm_size_t _hurd_stack_size; + +/* Initial file descriptor table we were passed at startup. If we are + using a real dtable, these are turned into that and then cleared at + startup. If not, these are never changed after startup. Not locked. */ + +extern mach_port_t *_hurd_init_dtable; +extern mach_msg_type_number_t _hurd_init_dtablesize; + +/* Current process IDs. */ + +extern pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp; +extern int _hurd_orphaned; + +/* This variable is incremented every time the process IDs change. */ + +unsigned int _hurd_pids_changed_stamp; + +/* This condition is broadcast every time the process IDs change. */ +struct condition _hurd_pids_changed_sync; + +/* Unix `data break', for brk and sbrk. + If brk and sbrk are not used, this info will not be initialized or used. */ + + +/* Data break. This is what `sbrk (0)' returns. */ + +extern vm_address_t _hurd_brk; + +/* End of allocated space. This is generally `round_page (_hurd_brk)'. */ + +extern vm_address_t _hurd_data_end; + +/* This mutex locks _hurd_brk and _hurd_data_end. */ + +extern struct mutex _hurd_brk_lock; + +/* Set the data break to NEWBRK; _hurd_brk_lock must + be held, and is released on return. */ + +extern int _hurd_set_brk (vm_address_t newbrk); + +#define __need_FILE +#include <stdio.h> + +/* Calls to get and set basic ports. */ + +extern error_t _hurd_ports_get (int which, mach_port_t *result); +extern error_t _hurd_ports_set (int which, mach_port_t newport); + +extern process_t getproc (void); +extern file_t getcwdir (void), getcrdir (void); +extern auth_t getauth (void); +extern mach_port_t getcttyid (); +extern int setproc (process_t); +extern int setcwdir (file_t), setcrdir (file_t); +extern int setcttyid (mach_port_t); + +/* Does reauth with the proc server and fd io servers. */ +extern int __setauth (auth_t), setauth (auth_t); + + +/* Split FILE into a directory and a name within the directory. Look up a + port for the directory and store it in *DIR; store in *NAME a pointer + into FILE where the name within directory begins. The directory lookup + uses CRDIR for the root directory and CWDIR for the current directory. + Returns zero on success or an error code. */ + +extern error_t __hurd_file_name_split (file_t crdir, file_t cwdir, + const char *file, + file_t *dir, char **name); +extern error_t hurd_file_name_split (file_t crdir, file_t cwdir, + const char *file, + file_t *dir, char **name); + +/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>). + The file lookup uses CRDIR for the root directory and CWDIR for the + current directory. If successful, returns zero and store the port + to FILE in *PORT; otherwise returns an error code. */ + +extern error_t __hurd_file_name_lookup (file_t crdir, file_t cwdir, + const char *file, + int flags, mode_t mode, + file_t *port); +extern error_t hurd_file_name_lookup (file_t crdir, file_t cwdir, + const char *filename, + int flags, mode_t mode, + file_t *port); + +/* Process the values returned by `dir_lookup' et al, and loop doing + `dir_lookup' calls until one returns FS_RETRY_NONE. CRDIR is the + root directory used for things like symlinks to absolute file names; the + other arguments should be those just passed to and/or returned from + `dir_lookup', `fsys_getroot', or `file_invoke_translator'. This + function consumes the reference in *RESULT even if it returns an error. */ + +extern error_t __hurd_file_name_lookup_retry (file_t crdir, + enum retry_type doretry, + char retryname[1024], + int flags, mode_t mode, + file_t *result); +extern error_t hurd_file_name_lookup_retry (file_t crdir, + enum retry_type doretry, + char retryname[1024], + int flags, mode_t mode, + file_t *result); + + +/* Split FILE into a directory and a name within the directory. The + directory lookup uses the current root and working directory. If + successful, stores in *NAME a pointer into FILE where the name + within directory begins and returns a port to the directory; + otherwise sets `errno' and returns MACH_PORT_NULL. */ + +extern file_t __file_name_split (const char *file, char **name); +extern file_t file_name_split (const char *file, char **name); + +/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>). + The file lookup uses the current root and working directory. + Returns a port to the file if successful; otherwise sets `errno' + and returns MACH_PORT_NULL. */ + +extern file_t __file_name_lookup (const char *file, int flags, mode_t mode); +extern file_t file_name_lookup (const char *file, int flags, mode_t mode); + +/* Invoke any translator set on the node FILE represents, and return in + *TRANSLATED a port to the translated node. FLAGS are as for + `dir_lookup' et al, but the returned port will not necessarily have + any more access rights than FILE does. */ + +extern error_t __hurd_invoke_translator (file_t file, int flags, + file_t *translated); +extern error_t hurd_invoke_translator (file_t file, int flags, + file_t *translated); + + +/* Open a file descriptor on a port. FLAGS are as for `open'; flags + affected by io_set_openmodes are not changed by this. If successful, + this consumes a user reference for PORT (which will be deallocated on + close). */ + +extern int openport (io_t port, int flags); + +/* Open a stream on a port. MODE is as for `fopen'. + If successful, this consumes a user reference for PORT + (which will be deallocated on fclose). */ + +extern FILE *fopenport (io_t port, const char *mode); +extern FILE *__fopenport (io_t port, const char *mode); + + +/* Execute a file, replacing TASK's current program image. */ + +extern error_t _hurd_exec (task_t task, + file_t file, + char *const argv[], + char *const envp[]); + + +/* Inform the proc server we have exitted with STATUS, and kill the + task thoroughly. This function never returns, no matter what. */ + +extern void _hurd_exit (int status) __attribute__ ((noreturn)); + + +/* Initialize the library data structures from the + ints and ports passed to us by the exec server. + Then vm_deallocate PORTARRAY and INTARRAY. */ + +extern void _hurd_init (int flags, char **argv, + mach_port_t *portarray, size_t portarraysize, + int *intarray, size_t intarraysize); + +/* Do startup handshaking with the proc server. */ + +extern void _hurd_proc_init (char **argv); + + +/* Return the socket server for sockaddr domain DOMAIN. If DEAD is + nonzero, remove the old cached port and always do a fresh lookup. + + It is assumed that a socket server will stay alive during a complex socket + operation involving several RPCs. But a socket server may die during + long idle periods between socket operations. Callers should first pass + zero for DEAD; if the first socket RPC tried on the returned port fails + with MACH_SEND_INVALID_DEST or MIG_SERVER_DIED (indicating the server + went away), the caller should call _hurd_socket_server again with DEAD + nonzero and retry the RPC on the new socket server port. */ + +extern socket_t _hurd_socket_server (int domain, int dead); + +/* Send a `sig_post' RPC to process number PID. If PID is zero, + send the message to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. + SIG and REFPORT are passed along in the request message. */ + +extern error_t _hurd_sig_post (pid_t pid, int sig, mach_port_t refport); +extern error_t hurd_sig_post (pid_t pid, int sig, mach_port_t refport); + +/* Fetch the host privileged port and device master port from the proc + server. They are fetched only once and then cached in the + variables below. A special program that gets them from somewhere + other than the proc server (such as a bootstrap filesystem) can set + these variables to install the ports. */ + +extern kern_return_t get_privileged_ports (host_priv_t *host_priv_ptr, + device_t *device_master_ptr); +extern mach_port_t _hurd_host_priv, _hurd_device_master; + +/* Return the PID of the task whose control port is TASK. + On error, sets `errno' and returns -1. */ + +extern pid_t __task2pid (task_t task), task2pid (task_t task); + +/* Return the task control port of process PID. + On error, sets `errno' and returns MACH_PORT_NULL. */ + +extern task_t __pid2task (pid_t pid), pid2task (pid_t pid); + + +/* Return the io server port for file descriptor FD. + This adds a Mach user reference to the returned port. + On error, sets `errno' and returns MACH_PORT_NULL. */ + +extern io_t __getdport (int fd), getdport (int fd); + + +#endif /* hurd.h */ diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h new file mode 100644 index 0000000000..4747c785a5 --- /dev/null +++ b/hurd/hurd/fd.h @@ -0,0 +1,222 @@ +/* File descriptors. +Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_FD_H + +#define _HURD_FD_H 1 +#include <features.h> + +#include <hurd/hurd_types.h> +#include <hurd/port.h> + + +/* Structure representing a file descriptor. */ + +struct hurd_fd + { + struct hurd_port port; /* io server port. */ + int flags; /* fcntl flags; locked by port.lock. */ + + /* Normal port to the ctty. When `port' is our ctty, this is a port to + the same io object but which never returns EBACKGROUND; when not, + this is nil. */ + struct hurd_port ctty; + }; + + +/* Current file descriptor table. */ + +extern int _hurd_dtablesize; +extern struct hurd_fd **_hurd_dtable; +extern struct mutex _hurd_dtable_lock; /* Locks those two variables. */ + +#include <hurd/signal.h> +#include <lock-intern.h> + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Returns the descriptor cell for FD. If FD is invalid or unused, return + NULL. The cell is unlocked; when ready to use it, lock it and check for + it being unused. */ + +_EXTERN_INLINE struct hurd_fd * +_hurd_fd_get (int fd) +{ + struct hurd_fd *descriptor; + + __mutex_lock (&_hurd_dtable_lock); + if (fd < 0 || fd >= _hurd_dtablesize) + descriptor = NULL; + else + { + struct hurd_fd *cell = _hurd_dtable[fd]; + if (cell == NULL) + /* No descriptor allocated at this index. */ + descriptor = NULL; + else + { + __spin_lock (&cell->port.lock); + if (cell->port.port == MACH_PORT_NULL) + /* The descriptor at this index has no port in it. + This happens if it existed before but was closed. */ + descriptor = NULL; + else + descriptor = cell; + __spin_unlock (&cell->port.lock); + } + } + __mutex_unlock (&_hurd_dtable_lock); + + return descriptor; +} + + +/* Evaluate EXPR with the variable `descriptor' bound to a pointer to the + file descriptor structure for FD. */ + +#define HURD_FD_USE(fd, expr) \ + ({ struct hurd_fd *descriptor = _hurd_fd_get (fd); \ + descriptor == NULL ? EBADF : (expr); }) + +/* Evaluate EXPR with the variable `port' bound to the port to FD, and + `ctty' bound to the ctty port. */ + +#define HURD_DPORT_USE(fd, expr) \ + HURD_FD_USE ((fd), HURD_FD_PORT_USE (descriptor, (expr))) + +/* Likewise, but FD is a pointer to the file descriptor structure. */ + +#define HURD_FD_PORT_USE(fd, expr) \ + ({ error_t __result; \ + struct hurd_fd *const __d = (fd); \ + struct hurd_userlink __ulink, __ctty_ulink; \ + io_t port, ctty; \ + void *crit = _hurd_critical_section_lock (); \ + __spin_lock (&__d->port.lock); \ + if (__d->port.port == MACH_PORT_NULL) \ + { \ + __spin_unlock (&__d->port.lock); \ + _hurd_critical_section_unlock (crit); \ + __result = EBADF; \ + } \ + else \ + { \ + ctty = _hurd_port_get (&__d->ctty, &__ctty_ulink); \ + port = _hurd_port_locked_get (&__d->port, &__ulink); \ + _hurd_critical_section_unlock (crit); \ + __result = (expr); \ + _hurd_port_free (&__d->port, &__ulink, port); \ + if (ctty != MACH_PORT_NULL) \ + _hurd_port_free (&__d->ctty, &__ctty_ulink, ctty); \ + } \ + __result; }) + +#include <errno.h> + +/* Check if ERR should generate a signal. + Returns the signal to take, or zero if none. */ + +_EXTERN_INLINE error_t +_hurd_fd_error_signal (error_t err) +{ + switch (err) + { + case EMACH_SEND_INVALID_DEST: + case EMIG_SERVER_DIED: + /* The server has disappeared! */ + return SIGLOST; + case EPIPE: + return SIGPIPE; + default: + /* Having a default case avoids -Wenum-switch warnings. */ + return 0; + } +} + +/* Handle an error from an RPC on a file descriptor's port. You should + always use this function to handle errors from RPCs made on file + descriptor ports. Some errors are translated into signals. */ + +_EXTERN_INLINE error_t +_hurd_fd_error (int fd, error_t err) +{ + int signo = _hurd_fd_error_signal (err); + if (signo) + _hurd_raise_signal (NULL, signo, fd, err); + return err; +} + +/* Handle error code ERR from an RPC on file descriptor FD's port. + Set `errno' to the appropriate error code, and always return -1. */ + +_EXTERN_INLINE int +__hurd_dfail (int fd, error_t err) +{ + errno = _hurd_fd_error (fd, err); + return -1; +} + +/* Set up *FD to have PORT its server port, doing appropriate ctty magic. + Does no locking or unlocking. */ + +extern void _hurd_port2fd (struct hurd_fd *fd, io_t port, int flags); + +/* Allocate a new file descriptor and install PORT in it (doing any + appropriate ctty magic); consumes a user reference on PORT. FLAGS are + as for `open'; only O_IGNORE_CTTY is meaningful, but all are saved. + + If the descriptor table is full, set errno, and return -1. + If DEALLOC is nonzero, deallocate PORT first. */ + +extern int _hurd_intern_fd (io_t port, int flags, int dealloc); + +/* Allocate a new file descriptor in the table and return it, locked. The + new descriptor number will be no less than FIRST_FD. If the table is + full, set errno to EMFILE and return NULL. If FIRST_FD is negative or + bigger than the size of the table, set errno to EINVAL and return NULL. */ + +extern struct hurd_fd *_hurd_alloc_fd (int *fd_ptr, int first_fd); + +/* Allocate a new file descriptor structure and initialize its port cells + with PORT and CTTY. (This does not affect the descriptor table.) */ + +extern struct hurd_fd *_hurd_new_fd (io_t port, io_t ctty); + +/* Close a file descriptor, making it available for future reallocation. */ + +extern error_t _hurd_fd_close (struct hurd_fd *fd); + +/* Read and write data from a file descriptor; just like `read' and `write'. + If successful, stores the amount actually read or written in *NBYTES. */ + +extern error_t _hurd_fd_read (struct hurd_fd *fd, void *buf, size_t *nbytes); +extern error_t _hurd_fd_write (struct hurd_fd *fd, + const void *buf, size_t *nbytes); + + +/* Call *RPC on PORT and/or CTTY; if a call on CTTY returns EBACKGROUND, + generate SIGTTIN/SIGTTOU or EIO as appropriate. */ + +extern error_t _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t)); +extern error_t _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t)); + + +#endif /* hurd/fd.h */ diff --git a/hurd/hurd/id.h b/hurd/hurd/id.h new file mode 100644 index 0000000000..7a50081038 --- /dev/null +++ b/hurd/hurd/id.h @@ -0,0 +1,55 @@ +/* User and group IDs. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_ID_H + +#define _HURD_ID_H 1 +#include <features.h> + +#include <cthreads.h> /* For `struct mutex'. */ + +/* Structure describing authorization data for the process. */ + +struct hurd_id_data + { + struct mutex lock; + + int valid; /* If following data are up to date. */ + + struct + { + uid_t *uids; + gid_t *gids; + mach_msg_type_number_t nuids, ngids; + } gen, aux; + + auth_t rid_auth; /* Cache used by access. */ + }; + +/* Current data. */ + +extern struct hurd_id_data _hurd_id; + + +/* Update _hurd_id (caller should be holding the lock). */ + +extern error_t _hurd_check_ids (void); + + +#endif /* hurd/id.h */ diff --git a/hurd/hurd/ioctl.h b/hurd/hurd/ioctl.h new file mode 100644 index 0000000000..cc83433c17 --- /dev/null +++ b/hurd/hurd/ioctl.h @@ -0,0 +1,71 @@ +/* User-registered handlers for specific `ioctl' requests. +Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_IOCTL_H +#define _HURD_IOCTL_H 1 + +#define __need___va_list +#include <stdarg.h> + + +/* Type of handler function, called like ioctl to do its entire job. */ +typedef int (*ioctl_handler_t) (int fd, int request, void *arg); + +/* Structure that records an ioctl handler. */ +struct ioctl_handler + { + int first_request, last_request; /* Range of handled request values. */ + + /* Handler function, called like ioctl to do its entire job. */ + ioctl_handler_t handler; + + struct ioctl_handler *next; /* Next handler. */ + }; + + +/* Register HANDLER to handle ioctls with REQUEST values between + FIRST_REQUEST and LAST_REQUEST inclusive. Returns zero if successful. + Return nonzero and sets `errno' for an error. */ + +extern int hurd_register_ioctl_handler (int first_request, int last_request, + ioctl_handler_t handler); + + +/* Define a library-internal handler for ioctl commands between FIRST and + LAST inclusive. The last element gratuitously references HANDLER to + avoid `defined but not used' warnings. */ + +#define _HURD_HANDLE_IOCTLS(handler, first, last) \ + static const struct ioctl_handler handler##_ioctl_handler = \ + { (first), (last), (int (*) (int, int, void *)) (handler), \ + (&(handler), &(handler##_ioctl_handler), NULL) }; \ + text_set_element (_hurd_ioctl_handler_lists, ##handler##_ioctl_handler) + +/* Define a library-internal handler for a single ioctl command. */ + +#define _HURD_HANDLE_IOCTL(handler, ioctl) \ + _HURD_HANDLE_IOCTLS (handler, (ioctl), (ioctl)) + + +/* Lookup the handler for the given ioctl request. */ + +ioctl_handler_t _hurd_lookup_ioctl_handler (int request); + + +#endif /* hurd/ioctl.h */ diff --git a/hurd/hurd/port.h b/hurd/hurd/port.h new file mode 100644 index 0000000000..a057503d4a --- /dev/null +++ b/hurd/hurd/port.h @@ -0,0 +1,152 @@ +/* Lightweight user references for ports. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_PORT_H + +#define _HURD_PORT_H 1 +#include <features.h> + +#include <mach.h> +#include <hurd/userlink.h> +#include <spin-lock.h> +#include <hurd/signal.h> + + +/* Structure describing a cell containing a port. With the lock held, a + user extracts PORT, and attaches his own link (in local storage) to the + USERS chain. PORT can then safely be used. When PORT is no longer + needed, with the lock held, the user removes his link from the chain. + If his link is the last, and PORT has changed since he fetched it, the + user deallocates the port he used. See <hurd/userlink.h>. */ + +struct hurd_port + { + spin_lock_t lock; /* Locks rest. */ + struct hurd_userlink *users; /* Chain of users; see below. */ + mach_port_t port; /* Port. */ + }; + + +/* Evaluate EXPR with the variable `port' bound to the port in PORTCELL. */ + +#define HURD_PORT_USE(portcell, expr) \ + ({ struct hurd_port *const __p = (portcell); \ + struct hurd_userlink __link; \ + const mach_port_t port = _hurd_port_get (__p, &__link); \ + __typeof(expr) __result = (expr); \ + _hurd_port_free (__p, &__link, port); \ + __result; }) + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + + +/* Initialize *PORT to INIT. */ + +_EXTERN_INLINE void +_hurd_port_init (struct hurd_port *port, mach_port_t init) +{ + __spin_lock_init (&port->lock); + port->users = NULL; + port->port = init; +} + + +/* Get a reference to *PORT, which is locked. + Pass return value and LINK to _hurd_port_free when done. */ + +_EXTERN_INLINE mach_port_t +_hurd_port_locked_get (struct hurd_port *port, + struct hurd_userlink *link) +{ + mach_port_t result; + result = port->port; + if (result != MACH_PORT_NULL) + _hurd_userlink_link (&port->users, link); + __spin_unlock (&port->lock); + return result; +} + +/* Same, but locks PORT first. */ + +_EXTERN_INLINE mach_port_t +_hurd_port_get (struct hurd_port *port, + struct hurd_userlink *link) +{ + mach_port_t result; + HURD_CRITICAL_BEGIN; + __spin_lock (&port->lock); + result = _hurd_port_locked_get (port, link); + HURD_CRITICAL_END; + return result; +} + + +/* Free a reference gotten with `USED_PORT = _hurd_port_get (PORT, LINK);' */ + +_EXTERN_INLINE void +_hurd_port_free (struct hurd_port *port, + struct hurd_userlink *link, + mach_port_t used_port) +{ + int dealloc; + if (used_port == MACH_PORT_NULL) + /* When we fetch an empty port cell with _hurd_port_get, + it does not link us on the users chain, since there is + no shared resource. */ + return; + HURD_CRITICAL_BEGIN; + __spin_lock (&port->lock); + dealloc = _hurd_userlink_unlink (link); + __spin_unlock (&port->lock); + HURD_CRITICAL_END; + if (dealloc) + __mach_port_deallocate (__mach_task_self (), used_port); +} + + +/* Set *PORT's port to NEWPORT. NEWPORT's reference is consumed by PORT->port. + PORT->lock is locked. */ + +_EXTERN_INLINE void +_hurd_port_locked_set (struct hurd_port *port, mach_port_t newport) +{ + mach_port_t old; + old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL; + port->port = newport; + __spin_unlock (&port->lock); + if (old != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), old); +} + +/* Same, but locks PORT first. */ + +_EXTERN_INLINE void +_hurd_port_set (struct hurd_port *port, mach_port_t newport) +{ + HURD_CRITICAL_BEGIN; + __spin_lock (&port->lock); + _hurd_port_locked_set (port, newport); + HURD_CRITICAL_END; +} + + +#endif /* hurd/port.h */ diff --git a/hurd/hurd/resource.h b/hurd/hurd/resource.h new file mode 100644 index 0000000000..ad2a61ab42 --- /dev/null +++ b/hurd/hurd/resource.h @@ -0,0 +1,50 @@ +/* Resource limits for the Hurd. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_RESOURCE_H +#define _HURD_RESOURCE_H + +#include <sys/types.h> +#include <sys/resource.h> +#include <errno.h> +#include <hurd/process.h> + +/* This array contains the current resource limits for the process. */ +extern struct rlimit _hurd_rlimits[RLIM_NLIMITS]; +extern struct mutex _hurd_rlimit_lock; /* Locks _hurd_rlimits. */ + + +/* Helper function for getpriority and setpriority. Maps FN over all the + processes specified by WHICH and WHO. PI is non-null if a + proc_getprocinfo was already done; FN may use *PI arbitrarily, it is + reset on the next call. Returns FN's result the first time it returns + nonzero. If FN never returns nonzero, this returns zero. */ +extern error_t _hurd_priority_which_map (enum __priority_which which, int who, + error_t (*fn) (pid_t pid, + struct procinfo *pi)); + +/* Convert between Mach priority values and the priority + values used by getpriority, setpriority, and nice. */ +#define MACH_PRIORITY_TO_NICE(prio) (2 * ((prio) - 12)) +#define NICE_TO_MACH_PRIORITY(nice) (12 + ((nice) / 2)) + + + + +#endif diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h new file mode 100644 index 0000000000..76007d5037 --- /dev/null +++ b/hurd/hurd/signal.h @@ -0,0 +1,391 @@ +/* Implementing POSIX.1 signals under the Hurd. +Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_SIGNAL_H + +#define _HURD_SIGNAL_H 1 +#include <features.h> +/* Make sure <signal.h> is going to define NSIG. */ +#ifndef __USE_GNU +#error "Must have `_GNU_SOURCE' feature test macro to use this file" +#endif + +#define __need_NULL +#include <stddef.h> + +#include <mach/mach_types.h> +#include <mach/port.h> +#include <mach/message.h> +#include <hurd/hurd_types.h> +#include <signal.h> +#include <errno.h> +#include <hurd/msg.h> + +#include <cthreads.h> /* For `struct mutex'. */ +#include <spin-lock.h> +#include <hurd/threadvar.h> /* We cache sigstate in a threadvar. */ + + +/* Per-thread signal state. */ + +struct hurd_sigstate + { + spin_lock_t lock; /* Locks most of the rest of the structure. */ + + int critical_section; /* Nonzero if in critical section. */ + + thread_t thread; + struct hurd_sigstate *next; /* Linked-list of thread sigstates. */ + + sigset_t blocked; /* What signals are blocked. */ + sigset_t pending; /* Pending signals, possibly blocked. */ + struct sigaction actions[NSIG]; + struct sigaltstack sigaltstack; + struct + { + /* For each signal that may be pending, the + sigcode and error code to deliver it with. */ + long int code; + error_t error; + } pending_data[NSIG]; + + /* If `suspended' is set when this thread gets a signal, + the signal thread sends an empty message to it. */ + mach_port_t suspended; + + /* The following members are not locked. They are used only by this + thread, or by the signal thread with this thread suspended. */ + + volatile mach_port_t intr_port; /* Port interruptible RPC was sent on. */ + + /* If this is not null, the thread is in sigreturn awaiting delivery of + pending signals. This context (the machine-dependent portions only) + will be passed to sigreturn after running the handler for a pending + signal, instead of examining the thread state. */ + struct sigcontext *context; + }; + +/* Linked list of states of all threads whose state has been asked for. */ + +extern struct hurd_sigstate *_hurd_sigstates; + +extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates. */ + +/* Get the sigstate of a given thread, taking its lock. */ + +extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t); + +/* Get the sigstate of the current thread. + This uses a per-thread variable to optimize the lookup. */ +_EXTERN_INLINE struct hurd_sigstate * +_hurd_self_sigstate (void) +{ + struct hurd_sigstate **location = + (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); + if (*location == NULL) + *location = _hurd_thread_sigstate (__mach_thread_self ()); + return *location; +} + +/* Thread listening on our message port; also called the "signal thread". */ + +extern thread_t _hurd_msgport_thread; + +/* Our message port. We hold the receive right and _hurd_msgport_thread + listens for messages on it. We also hold a send right, for convenience. */ + +extern mach_port_t _hurd_msgport; + + +/* Thread to receive process-global signals. */ + +extern thread_t _hurd_sigthread; + + +/* Resource limit on core file size. Enforced by hurdsig.c. */ +extern int _hurd_core_limit; + +/* Critical sections. + + A critical section is a section of code which cannot safely be interrupted + to run a signal handler; for example, code that holds any lock cannot be + interrupted lest the signal handler try to take the same lock and + deadlock result. */ + +_EXTERN_INLINE void * +_hurd_critical_section_lock (void) +{ + struct hurd_sigstate **location = + (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); + struct hurd_sigstate *ss = *location; + if (ss == NULL) + /* The thread variable is unset; this must be the first time we've + asked for it. In this case, the critical section flag cannot + possible already be set. Look up our sigstate structure the slow + way; this locks the sigstate lock. */ + ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); + else + __spin_lock (&ss->lock); + + if (ss->critical_section) + { + /* We are already in a critical section, so do nothing. */ + __spin_unlock (&ss->lock); + return NULL; + } + + /* Set the critical section flag so no signal handler will run. */ + ss->critical_section = 1; + __spin_unlock (&ss->lock); + + /* Return our sigstate pointer; this will be passed to + _hurd_critical_section_unlock to clear the critical section flag. */ + return ss; +} + +_EXTERN_INLINE void +_hurd_critical_section_unlock (void *our_lock) +{ + if (our_lock == NULL) + /* The critical section lock was held when we began. Do nothing. */ + return; + else + { + /* It was us who acquired the critical section lock. Clear the + critical section flag. */ + struct hurd_sigstate *ss = our_lock; + sigset_t pending; + __spin_lock (&ss->lock); + ss->critical_section = 0; + pending = ss->pending & ~ss->blocked; + __spin_unlock (&ss->lock); + if (pending) + /* There are unblocked signals pending, which weren't + delivered because we were in the critical section. + Tell the signal thread to deliver them now. */ + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + } +} + +/* Convenient macros for simple uses of critical sections. + These two must be used as a pair at the same C scoping level. */ + +#define HURD_CRITICAL_BEGIN \ + { void *__hurd_critical__ = _hurd_critical_section_lock () +#define HURD_CRITICAL_END \ + _hurd_critical_section_unlock (__hurd_critical__); } while (0) + +/* Initialize the signal code, and start the signal thread. */ + +extern void _hurdsig_init (void); + +/* Initialize proc server-assisted fault recovery for the signal thread. */ + +extern void _hurdsig_fault_init (void); + +/* Raise a signal as described by SIGNO, SIGCODE and SIGERROR, on the + thread whose sigstate SS points to. If SS is a null pointer, this + instead affects the calling thread. */ + +extern void _hurd_raise_signal (struct hurd_sigstate *ss, + int signo, long int sigcode, int sigerror); + +/* Translate a Mach exception into a signal (machine-dependent). */ + +extern void _hurd_exception2signal (int exception, int code, int subcode, + int *signo, long int *sigcode, int *error); + + +/* Make the thread described by SS take the signal described by SIGNO and + SIGCODE. If the process is traced, this will in fact stop with a SIGNO + as the stop signal unless UNTRACED is nonzero. When the signal can be + considered delivered, sends a sig_post reply message on REPLY_PORT + indicating success. SS is not locked. */ + +extern void _hurd_internal_post_signal (struct hurd_sigstate *ss, + int signo, long int sigcode, int error, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + int untraced); + +/* Set up STATE and SS to handle signal SIGNO by running HANDLER. If + RPC_WAIT is nonzero, the thread needs to wait for a pending RPC to + finish before running the signal handler. The handler is passed SIGNO, + SIGCODE, and the returned `struct sigcontext' (which resides on the + stack the handler will use, and which describes the state of the thread + encoded in STATE before running the handler). */ + +struct machine_thread_all_state; +extern struct sigcontext * +_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, + int signo, long int sigcode, + int rpc_wait, struct machine_thread_all_state *state); + +/* Function run by the signal thread to receive from the signal port. */ + +extern void _hurd_msgport_receive (void); + +/* STATE describes a thread that had intr_port set (meaning it was inside + HURD_EINTR_RPC), after it has been thread_abort'd. It it looks to have + just completed a mach_msg_trap system call that returned + MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right + being waited on. */ + +extern int _hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, + mach_port_t *port); + +/* Set up STATE with a thread state that, when resumed, is + like `longjmp (_hurd_sigthread_fault_env, 1)'. */ + +extern void _hurd_initialize_fault_recovery_state (void *state); + + +/* Function run for SIGINFO when its action is SIG_DFL and the current + process is the session leader. */ + +extern void _hurd_siginfo_handler (int); + + +/* Perform interruptible RPC CALL on PORT. + The call should use + The args in CALL should be constant or local variable refs. + They may be evaluated many times, and must not change. + PORT must not be deallocated before this RPC is finished. */ +#define HURD_EINTR_RPC(port, call) \ + ({ \ + __label__ __do_call; /* Give this label block scope. */ \ + error_t __err; \ + struct hurd_sigstate *__ss = _hurd_self_sigstate (); \ + __do_call: \ + /* Tell the signal thread that we are doing an interruptible RPC on \ + this port. If we get a signal and should return EINTR, the signal \ + thread will set this variable to MACH_PORT_NULL. The RPC might \ + return EINTR when some other thread gets a signal, in which case we \ + want to restart our call. */ \ + __ss->intr_port = (port); \ + /* A signal may arrive here, after intr_port is set, but before the \ + mach_msg system call. The signal handler might do an interruptible \ + RPC, and clobber intr_port; then it would not be set properly when \ + we actually did send the RPC, and a later signal wouldn't interrupt \ + that RPC. So, _hurd_setup_sighandler saves intr_port in the \ + sigcontext, and sigreturn restores it. */ \ + switch (__err = (call)) \ + { \ + case EINTR: /* RPC went out and was interrupted. */ \ + case MACH_SEND_INTERRUPTED: /* RPC didn't get out. */ \ + if (__ss->intr_port != MACH_PORT_NULL) \ + /* If this signal was for us and it should interrupt calls, the \ + signal thread will have cleared SS->intr_port. Since it's not \ + cleared, the signal was for another thread, or SA_RESTART is \ + set. Restart the interrupted call. */ \ + goto __do_call; \ + /* FALLTHROUGH */ \ + case MACH_RCV_PORT_DIED: \ + /* Server didn't respond to interrupt_operation, \ + so the signal thread destroyed the reply port. */ \ + __err = EINTR; \ + break; \ + default: /* Quiet -Wswitch-enum. */ \ + } \ + __ss->intr_port = MACH_PORT_NULL; \ + __err; \ + }) \ + + +/* Mask of signals that cannot be caught, blocked, or ignored. */ +#define _SIG_CANT_MASK (__sigmask (SIGSTOP) | __sigmask (SIGKILL)) + +/* Do an RPC to a process's message port. + + Each argument is an expression which returns an error code; each + expression may be evaluated several times. FETCH_MSGPORT_EXPR should + fetch the appropriate message port and store it in the local variable + `msgport'; it will be deallocated after use. FETCH_REFPORT_EXPR should + fetch the appropriate message port and store it in the local variable + `refport' (if no reference port is needed in the call, then + FETCH_REFPORT_EXPR should be simply KERN_SUCCESS or 0); if + DEALLOC_REFPORT evaluates to nonzero it will be deallocated after use, + otherwise the FETCH_REFPORT_EXPR must take care of user references to + `refport'. RPC_EXPR should perform the desired RPC operation using + `msgport' and `refport'. + + The reason for the complexity is that a process's message port and + reference port may change between fetching those ports and completing an + RPC using them (usually they change only when a process execs). The RPC + will fail with MACH_SEND_INVALID_DEST if the msgport dies before we can + send the RPC request; or with MIG_SERVER_DIED if the msgport was + destroyed after we sent the RPC request but before it was serviced. In + either of these cases, we retry the entire operation, discarding the old + message and reference ports and fetch them anew. */ + +#define HURD_MSGPORT_RPC(fetch_msgport_expr, \ + fetch_refport_expr, dealloc_refport, \ + rpc_expr) \ +({ \ + error_t __err; \ + mach_port_t msgport, refport = MACH_PORT_NULL; \ + do \ + { \ + /* Get the message port. */ \ + if (__err = (fetch_msgport_expr)) \ + break; \ + /* Get the reference port. */ \ + if (__err = (fetch_refport_expr)) \ + { \ + /* Couldn't get it; deallocate MSGPORT and fail. */ \ + __mach_port_deallocate (__mach_task_self (), msgport); \ + break; \ + } \ + __err = (rpc_expr); \ + __mach_port_deallocate (__mach_task_self (), msgport); \ + if ((dealloc_refport) && refport != MACH_PORT_NULL) \ + __mach_port_deallocate (__mach_task_self (), refport); \ + } while (__err == MACH_SEND_INVALID_DEST || \ + __err == MIG_SERVER_DIED); \ + __err; \ +}) + +/* Some other parts of the library need to preempt signals, to detect + errors that should not result in a POSIX signal. For example, when + some mapped region of memory is used, an extraneous SIGSEGV might be + generated when the mapping server returns an error for a page fault. */ + +struct hurd_signal_preempt + { + /* Function to examine a thread receiving a given signal. The handler + is called even for blocked signals. This function is run in the + signal thread, with THREAD's sigstate locked; it should be as simple + and robust as possible. THREAD is the thread which is about to + receive the signal. SIGNO and SIGCODE would be passed to the normal + handler. + + If the return value is SIG_DFL, normal signal processing continues. + If it is SIG_IGN, the signal is ignored. + Any other value is used in place of the normal handler. */ + sighandler_t (*handler) (thread_t thread, + int signo, long int sigcode, int sigerror); + long int first, last; /* Range of sigcodes this handler wants. */ + struct hurd_signal_preempt *next; /* Next handler on the chain. */ + }; + +extern struct hurd_signal_preempt *_hurd_signal_preempt[NSIG]; +extern struct mutex _hurd_signal_preempt_lock; + + +#endif /* hurd/signal.h */ diff --git a/hurd/hurd/threadvar.h b/hurd/hurd/threadvar.h new file mode 100644 index 0000000000..eab133a2f6 --- /dev/null +++ b/hurd/hurd/threadvar.h @@ -0,0 +1,107 @@ +/* Internal per-thread variables for the Hurd. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_THREADVAR_H +#define _HURD_THREADVAR_H + +/* The per-thread variables are found by ANDing this mask + with the value of the stack pointer and then adding this offset. + + In the multi-threaded case, cthreads initialization sets + __hurd_threadvar_stack_mask to ~(cthread_stack_size - 1), a mask which + finds the base of the fixed-size cthreads stack; and + __hurd_threadvar_stack_offset to a small offset that skips the data + cthreads itself maintains at the base of each thread's stack. + + In the single-threaded case, __hurd_threadvar_stack_mask is zero, so the + stack pointer is ignored; and __hurd_threadvar_stack_offset gives the + address of a small allocated region which contains the variables for the + single thread. */ + +extern unsigned long int __hurd_threadvar_stack_mask; +extern unsigned long int __hurd_threadvar_stack_offset; + +/* A special case must always be made for the signal thread. Even when there + is only one user thread and an allocated region can be used for the user + thread's variables, the signal thread needs to have its own location for + per-thread variables. The variables __hurd_sigthread_stack_base and + __hurd_sigthread_stack_end define the bounds of the stack used by the + signal thread, so that thread can always be specifically identified. */ + +extern unsigned long int __hurd_sigthread_stack_base; +extern unsigned long int __hurd_sigthread_stack_end; +extern unsigned long int *__hurd_sigthread_variables; + + +/* At the location described by the two variables above, + there are __hurd_threadvar_max `unsigned long int's of per-thread data. */ +extern unsigned int __hurd_threadvar_max; + +/* These values are the indices for the standard per-thread variables. */ +enum __hurd_threadvar_index + { + _HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */ + _HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */ + _HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */ + _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */ + _HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */ + }; + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Return the location of the value for the per-thread variable with index + INDEX used by the thread whose stack pointer is SP. */ + +_EXTERN_INLINE unsigned long int * +__hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index, + void *__sp) +{ + unsigned long int __stack = (unsigned long int) __sp; + return &((__stack >= __hurd_sigthread_stack_base && + __stack < __hurd_sigthread_stack_end) + ? __hurd_sigthread_variables + : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) + + __hurd_threadvar_stack_offset))[__index]; +} + +#include <machine-sp.h> /* Define __thread_stack_pointer. */ + +/* Return the location of the current thread's value for the + per-thread variable with index INDEX. */ + +_EXTERN_INLINE unsigned long int * +__hurd_threadvar_location (enum __hurd_threadvar_index __index) +{ + return __hurd_threadvar_location_from_sp (__index, + __thread_stack_pointer ()); +} + +/* Return the current thread's location for `errno'. + The syntax of this function allows redeclarations like `int errno'. */ +_EXTERN_INLINE int * +__hurd_errno_location (void) +{ + return (int *) __hurd_threadvar_location (_HURD_THREADVAR_ERRNO); +} + + +#endif /* hurd/threadvar.h */ diff --git a/hurd/hurd/userlink.h b/hurd/hurd/userlink.h new file mode 100644 index 0000000000..337d46aef6 --- /dev/null +++ b/hurd/hurd/userlink.h @@ -0,0 +1,105 @@ +/* Support for chains recording users of a resource; `struct hurd_userlink'. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_USERLINK_H + +#define _HURD_USERLINK_H 1 +#include <features.h> + +#define __need_NULL +#include <stddef.h> + + +/* This structure is simply a doubly-linked list. Users of a given + resource are recorded by their presence in a list associated with that + resource. A user attaches his own link (in local storage) to a shared + chain at the time he begins using some resource. When finished with + that resource, the user removes his link from the chain. If his link is + the last (there are no other users of the resource), and his chain has + been detached from the shared cell (the resource in the cell has been + replaced), then the user deallocates the resource that he used. */ + +struct hurd_userlink + { + struct hurd_userlink *next, **prevp; + }; + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + + +/* Attach LINK to the chain of users at *CHAINP. */ + +_EXTERN_INLINE void +_hurd_userlink_link (struct hurd_userlink **chainp, + struct hurd_userlink *link) +{ + link->next = *chainp; + if (link->next) + link->next->prevp = &link->next; + link->prevp = chainp; + *chainp = link; +} + + +/* Detach LINK from its chain. If the return value is nonzero, the caller + should deallocate the resource he started using after attaching LINK to + the chain it's on. If the return value is zero, then someone else is + still using the resource. */ + +_EXTERN_INLINE int +_hurd_userlink_unlink (struct hurd_userlink *link) +{ + /* The caller should deallocate the resource he used if his chain has + been detached from the cell (and thus has a nil `prevp'), and there is + no next link representing another user reference to the same resource. */ + int dealloc = ! link->next && ! link->prevp; + + /* Remove our link from the chain of current users. */ + if (link->prevp) + *link->prevp = link->next; + if (link->next) + link->next->prevp = link->prevp; + + return dealloc; +} + + +/* Clear all users from *CHAINP. Call this when the resource *CHAINP + protects is changing. If the return value is nonzero, no users are on + the chain and the caller should deallocate the resource. If the return + value is zero, someone is still using the resource and they will + deallocate it when they are finished. */ + +_EXTERN_INLINE int +_hurd_userlink_clear (struct hurd_userlink **chainp) +{ + if (*chainp == NULL) + return 1; + + /* Detach the chain of current users from the cell. The last user to + remove his link from that chain will deallocate the old resource. */ + (*chainp)->prevp = NULL; + *chainp = NULL; + return 0; +} + +#endif /* hurd/userlink.h */ diff --git a/hurd/hurdauth.c b/hurd/hurdauth.c new file mode 100644 index 0000000000..db93fd6ec3 --- /dev/null +++ b/hurd/hurdauth.c @@ -0,0 +1,130 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/msg_server.h> +#include <hurd/id.h> +#include <string.h> + +int +_hurd_refport_secure_p (mach_port_t ref) +{ + if (ref == __mach_task_self ()) + return 1; + if (__USEPORT (AUTH, ref == port)) + return 1; + return 0; +} + +kern_return_t +_S_msg_add_auth (mach_port_t me, + auth_t addauth) +{ + error_t err; + auth_t newauth; + + if (err = __USEPORT (AUTH, + __auth_makeauth (port, + &addauth, 1, MACH_MSG_TYPE_MOVE_SEND, + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0, + &newauth))) + return err; + + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + if (err) + return errno; + + return 0; +} + +kern_return_t +_S_msg_del_auth (mach_port_t me, + task_t task, + intarray_t uids, mach_msg_type_number_t nuids, + intarray_t gids, mach_msg_type_number_t ngids) +{ + error_t err; + auth_t newauth; + + if (!_hurd_refport_secure_p (task)) + return EPERM; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + size_t i, j; + size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids; + uid_t newu[nu]; + gid_t newg[ng]; + + memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t)); + memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t)); + + for (j = 0; j < nuids; ++j) + { + const uid_t uid = uids[j]; + for (i = 0; i < nu; ++i) + if (newu[i] == uid) + /* Move the last uid into this slot, and decrease the + number of uids so the last slot is no longer used. */ + newu[i] = newu[--nu]; + } + __vm_deallocate (__mach_task_self (), + (vm_address_t) uids, nuids * sizeof (uid_t)); + + for (j = 0; j < ngids; ++j) + { + const gid_t gid = gids[j]; + for (i = 0; i < nu; ++i) + if (newu[i] == gid) + /* Move the last gid into this slot, and decrease the + number of gids so the last slot is no longer used. */ + newu[i] = newu[--nu]; + } + __vm_deallocate (__mach_task_self (), + (vm_address_t) gids, ngids * sizeof (gid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, + NULL, 0, MACH_MSG_TYPE_COPY_SEND, + newu, nu, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + newg, ng, + _hurd_id.aux.uids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return err; + + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + if (err) + return errno; + + return 0; +} diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c new file mode 100644 index 0000000000..d5d2d080e4 --- /dev/null +++ b/hurd/hurdexec.c @@ -0,0 +1,259 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/signal.h> + +/* Overlay TASK, executing FILE with arguments ARGV and environment ENVP. + If TASK == mach_task_self (), some ports are dealloc'd by the exec server. + ARGV and ENVP are terminated by NULL pointers. */ +error_t +_hurd_exec (task_t task, file_t file, + char *const argv[], char *const envp[]) +{ + error_t err; + char *args, *env, *ap; + size_t argslen, envlen; + int ints[INIT_INT_MAX]; + mach_port_t ports[_hurd_nports]; + struct hurd_userlink ulink_ports[_hurd_nports]; + file_t *dtable; + int dtablesize; + struct hurd_port **dtable_cells; + struct hurd_userlink *ulink_dtable; + int i; + char *const *p; + struct hurd_sigstate *ss; + mach_port_t *please_dealloc, *pdp; + + + /* Pack the arguments into an array with nulls separating the elements. */ + argslen = 0; + if (argv != NULL) + { + p = argv; + while (*p != NULL) + argslen += strlen (*p++) + 1; + args = __alloca (argslen); + ap = args; + for (p = argv; *p != NULL; ++p) + ap = __memccpy (ap, *p, '\0', ULONG_MAX); + } + else + args = NULL; + + /* Pack the environment into an array with nulls separating elements. */ + envlen = 0; + if (envp != NULL) + { + p = envp; + while (*p != NULL) + envlen += strlen (*p++) + 1; + env = __alloca (envlen); + ap = env; + for (p = envp; *p != NULL; ++p) + ap = __memccpy (ap, *p, '\0', ULONG_MAX); + } + else + env = NULL; + + /* Load up the ports to give to the new program. */ + for (i = 0; i < _hurd_nports; ++i) + if (i == INIT_PORT_PROC && task != __mach_task_self ()) + { + /* This is another task, so we need to ask the proc server + for the right proc server port for it. */ + if (err = __USEPORT (PROC, __proc_task2proc (port, task, &ports[i]))) + { + while (--i > 0) + _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]); + return err; + } + } + else + ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]); + + + /* Load up the ints to give the new program. */ + for (i = 0; i < INIT_INT_MAX; ++i) + switch (i) + { + case INIT_UMASK: + ints[i] = _hurd_umask; + break; + + case INIT_SIGMASK: + case INIT_SIGIGN: + case INIT_SIGPENDING: + /* We will set these all below. */ + break; + + default: + ints[i] = 0; + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + ints[INIT_SIGMASK] = ss->blocked; + ints[INIT_SIGPENDING] = ss->pending; + ints[INIT_SIGIGN] = 0; + for (i = 1; i < NSIG; ++i) + if (ss->actions[i].sa_handler == SIG_IGN) + ints[INIT_SIGIGN] |= __sigmask (i); + + /* We hold the sigstate lock until the exec has failed so that no signal + can arrive between when we pack the blocked and ignored signals, and + when the exec actually happens. A signal handler could change what + signals are blocked and ignored. Either the change will be reflected + in the exec, or the signal will never be delivered. Setting the + critical section flag avoids anything we call trying to acquire the + sigstate lock. */ + + ss->critical_section = 1; + __spin_unlock (&ss->lock); + + /* Pack up the descriptor table to give the new program. */ + __mutex_lock (&_hurd_dtable_lock); + + dtablesize = _hurd_dtable ? _hurd_dtablesize : _hurd_init_dtablesize; + + if (task == __mach_task_self ()) + /* Request the exec server to deallocate some ports from us if the exec + succeeds. The init ports and descriptor ports will arrive in the + new program's exec_startup message. If we failed to deallocate + them, the new program would have duplicate user references for them. + But we cannot deallocate them ourselves, because we must still have + them after a failed exec call. */ + please_dealloc = __alloca ((_hurd_nports + (2 * dtablesize)) + * sizeof (mach_port_t)); + else + please_dealloc = NULL; + pdp = please_dealloc; + + if (_hurd_dtable != NULL) + { + dtable = __alloca (dtablesize * sizeof (dtable[0])); + ulink_dtable = __alloca (dtablesize * sizeof (ulink_dtable[0])); + dtable_cells = __alloca (dtablesize * sizeof (dtable_cells[0])); + for (i = 0; i < dtablesize; ++i) + { + struct hurd_fd *const d = _hurd_dtable[i]; + if (d == NULL) + { + dtable[i] = MACH_PORT_NULL; + continue; + } + __spin_lock (&d->port.lock); + if (d->flags & FD_CLOEXEC) + { + /* This descriptor is marked to be closed on exec. + So don't pass it to the new program. */ + dtable[i] = MACH_PORT_NULL; + if (pdp && d->port.port != MACH_PORT_NULL) + { + /* We still need to deallocate the ports. */ + *pdp++ = d->port.port; + if (d->ctty.port != MACH_PORT_NULL) + *pdp++ = d->ctty.port; + } + __spin_unlock (&d->port.lock); + } + else + { + if (pdp && d->ctty.port != MACH_PORT_NULL) + /* All the elements of DTABLE are added to PLEASE_DEALLOC + below, so we needn't add the port itself. + But we must deallocate the ctty port as well as + the normal port that got installed in DTABLE[I]. */ + *pdp++ = d->ctty.port; + dtable[i] = _hurd_port_locked_get (&d->port, &ulink_dtable[i]); + dtable_cells[i] = &d->port; + } + } + } + else + { + dtable = _hurd_init_dtable; + ulink_dtable = NULL; + dtable_cells = NULL; + } + + /* The information is all set up now. Try to exec the file. */ + + { + if (pdp) + { + /* Request the exec server to deallocate some ports from us if the exec + succeeds. The init ports and descriptor ports will arrive in the + new program's exec_startup message. If we failed to deallocate + them, the new program would have duplicate user references for them. + But we cannot deallocate them ourselves, because we must still have + them after a failed exec call. */ + + for (i = 0; i < _hurd_nports; ++i) + *pdp++ = ports[i]; + for (i = 0; i < dtablesize; ++i) + *pdp++ = dtable[i]; + } + + err = __file_exec (file, task, + _hurd_exec_flags & EXEC_INHERITED, + args, argslen, env, envlen, + dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize, + ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports, + ints, INIT_INT_MAX, + please_dealloc, pdp - please_dealloc, + NULL, 0); + } + + /* Release references to the standard ports. */ + for (i = 0; i < _hurd_nports; ++i) + if (i == INIT_PORT_PROC && task != __mach_task_self ()) + __mach_port_deallocate (__mach_task_self (), ports[i]); + else + _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]); + + if (ulink_dtable != NULL) + /* Release references to the file descriptor ports. */ + for (i = 0; i < dtablesize; ++i) + if (dtable[i] != MACH_PORT_NULL) + _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]); + + /* Release lock on the file descriptor table. */ + __mutex_unlock (&_hurd_dtable_lock); + + /* Safe to let signals happen now. */ + { + sigset_t pending; + __spin_lock (&ss->lock); + ss->critical_section = 0; + pending = ss->pending & ~ss->blocked; + __spin_unlock (&ss->lock); + if (pending) + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + } + + return err; +} diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c new file mode 100644 index 0000000000..e8b54660b9 --- /dev/null +++ b/hurd/hurdfault.c @@ -0,0 +1,143 @@ +/* Handle faults in the signal thread. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include "hurdfault.h" +#include <errno.h> +#include <string.h> +#include <setjmp.h> +#include <stdio.h> +#include "thread_state.h" +#include "faultexc.h" /* mig-generated header for our exc server. */ + +jmp_buf _hurdsig_fault_env; + +static mach_port_t forward_sigexc; + +int _hurdsig_fault_expect_signo; +long int _hurdsig_fault_sigcode; +int _hurdsig_fault_sigerror; + +kern_return_t +_hurdsig_fault_catch_exception_raise (mach_port_t port, + thread_t thread, + task_t task, + int exception, + int code, + int subcode) +{ + int signo; + + if (port != forward_sigexc || + thread != _hurd_msgport_thread || task != __mach_task_self ()) + return EPERM; /* Strange bogosity. */ + + /* Call the machine-dependent function to translate the Mach exception + codes into a signal number and subcode. */ + _hurd_exception2signal (exception, code, subcode, &signo, + &_hurdsig_fault_sigcode, &_hurdsig_fault_sigerror); + + return signo == _hurdsig_fault_expect_signo ? 0 : EGREGIOUS; +} + +static void +faulted (void) +{ + struct + { + mach_msg_header_t head; + char buf[64]; + } request; + struct + { + mach_msg_header_t head; + mach_msg_type_t type; + int result; + } reply; + extern int _hurdsig_fault_exc_server (mach_msg_header_t *, + mach_msg_header_t *); + + /* Wait for the exception_raise message forwarded by the proc server. */ + + if (__mach_msg (&request.head, MACH_RCV_MSG, 0, + sizeof request, forward_sigexc, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL) + != MACH_MSG_SUCCESS) + __libc_fatal ("msg receive failed on signal thread exc\n"); + + /* Run the exc demuxer which should call the server function above. + That function returns 0 if the exception was expected. */ + switch (_hurdsig_fault_exc_server (&request.head, &reply.head)) + { + case KERN_SUCCESS: + if (reply.head.msgh_remote_port != MACH_PORT_NULL) + __mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size, + 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + break; + default: + __mach_msg_destroy (&request.head); + case MIG_NO_REPLY: + } + + _hurdsig_fault_expect_signo = 0; + longjmp (_hurdsig_fault_env, 1); +} + +static char faultstack[1024]; + +/* Send exceptions for the signal thread to the proc server. + It will forward the message on to our message port, + and then restore the thread's state to code which + does `longjmp (_hurd_sigthread_fault_env, 1)'. */ + +void +_hurdsig_fault_init (void) +{ + error_t err; + struct machine_thread_state state; + mach_port_t sigexc; + + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &sigexc)) + __libc_fatal ("hurd: Can't create receive right for signal thread exc\n"); + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &forward_sigexc)) + __libc_fatal ("hurd: Can't create receive right for signal thread exc\n"); + + memset (&state, 0, sizeof state); + MACHINE_THREAD_STATE_SET_PC (&state, faulted); + MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack); + +#if 0 /* Don't confuse gdb. */ + __thread_set_special_port (_hurd_msgport_thread, + THREAD_EXCEPTION_PORT, sigexc); +#endif + + if (err = __USEPORT + (PROC, + __proc_handle_exceptions (port, + sigexc, + forward_sigexc, MACH_MSG_TYPE_MAKE_SEND, + MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, + MACHINE_THREAD_STATE_COUNT))) + __libc_fatal ("hurd: proc won't handle signal thread exceptions\n"); +} + diff --git a/hurd/hurdfault.h b/hurd/hurdfault.h new file mode 100644 index 0000000000..00ec905925 --- /dev/null +++ b/hurd/hurdfault.h @@ -0,0 +1,49 @@ +/* Declarations for handling faults in the signal thread. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HURD_FAULT_H +#define _HURD_FAULT_H + +#include <setjmp.h> + +/* Call this before code that might fault in the signal thread; SIGNO is + the signal expected to possibly arrive. This behaves like setjmp: it + returns zero the first time, and returns again nonzero if the signal + does arrive. */ + +#define _hurdsig_catch_fault(signo) \ + (_hurdsig_fault_expect_signo = (signo), setjmp (_hurdsig_fault_env)) + +/* Call this at the end of a section protected by _hurdsig_catch_fault. */ + +#define _hurdsig_end_catch_fault() \ + (_hurdsig_fault_expect_signo = 0) + +extern jmp_buf _hurdsig_fault_env; +extern int _hurdsig_fault_expect_signo; + +/* If _hurdsig_catch_fault returns nonzero, these variables + contain information about the signal that arrived. */ + + + +extern long int _hurdsig_fault_sigcode; +extern int _hurdsig_fault_sigerror; + +#endif /* hurd/fault.h */ diff --git a/hurd/hurdid.c b/hurd/hurdid.c new file mode 100644 index 0000000000..6f1c977cc8 --- /dev/null +++ b/hurd/hurdid.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/id.h> + +struct hurd_id_data _hurd_id; + + +/* Check that _hurd_id.{gen,aux} are valid and update them if not. + Expects _hurd_id.lock to be held and does not release it. */ + +error_t +_hurd_check_ids (void) +{ + if (! _hurd_id.valid) + { + inline void dealloc (__typeof (_hurd_id.gen) *p) + { + if (p->uids) + { + __vm_deallocate (__mach_task_self (), + (vm_address_t) p->uids, + p->nuids * sizeof (uid_t)); + p->uids = NULL; + } + p->nuids = 0; + if (p->gids) + { + __vm_deallocate (__mach_task_self (), + (vm_address_t) p->gids, + p->ngids * sizeof (gid_t)); + p->gids = NULL; + } + p->ngids = 0; + } + + error_t err; + + dealloc (&_hurd_id.gen); + dealloc (&_hurd_id.aux); + + if (_hurd_id.rid_auth != MACH_PORT_NULL) + { + __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); + _hurd_id.rid_auth = MACH_PORT_NULL; + } + + if (err = __USEPORT (AUTH, __auth_getids + (port, + &_hurd_id.gen.uids, &_hurd_id.gen.nuids, + &_hurd_id.aux.uids, &_hurd_id.aux.nuids, + &_hurd_id.gen.gids, &_hurd_id.gen.ngids, + &_hurd_id.aux.gids, &_hurd_id.aux.ngids))) + return err; + + _hurd_id.valid = 1; + } + + return 0; +} + +static void +init_id (void) +{ + __mutex_init (&_hurd_id.lock); + _hurd_id.valid = 0; + _hurd_id.rid_auth = MACH_PORT_NULL; + _hurd_id.gen.uids = _hurd_id.aux.uids = NULL; + _hurd_id.gen.nuids = _hurd_id.aux.nuids = 0; + _hurd_id.gen.gids = _hurd_id.aux.gids = NULL; + _hurd_id.gen.ngids = _hurd_id.aux.ngids = 0; + + (void) &init_id; /* Avoid "defined but not used" warning. */ +} +text_set_element (_hurd_preinit_hook, init_id); diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c new file mode 100644 index 0000000000..4469a17339 --- /dev/null +++ b/hurd/hurdinit.c @@ -0,0 +1,193 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/stat.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> +#include "set-hooks.h" +#include "hurdmalloc.h" /* XXX */ + + +int _hurd_exec_flags; +struct hurd_port *_hurd_ports; +unsigned int _hurd_nports; +mode_t _hurd_umask; + +void _hurd_proc_init (char **argv); + +DEFINE_HOOK (_hurd_subinit, (void)); + +/* Initialize the library data structures from the + ints and ports passed to us by the exec server. + + PORTARRAY and INTARRAY are vm_deallocate'd. */ + +void +_hurd_init (int flags, char **argv, + mach_port_t *portarray, size_t portarraysize, + int *intarray, size_t intarraysize) +{ + int i; + + _hurd_exec_flags = flags; + + _hurd_ports = malloc (portarraysize * sizeof (*_hurd_ports)); + if (_hurd_ports == NULL) + __libc_fatal ("Can't allocate _hurd_ports\n"); + _hurd_nports = portarraysize; + + /* See what ports we were passed. */ + for (i = 0; i < portarraysize; ++i) + _hurd_port_init (&_hurd_ports[i], portarray[i]); + + /* When the user asks for the bootstrap port, + he will get the one the exec server passed us. */ + __task_set_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, + portarray[INIT_PORT_BOOTSTRAP]); + + /* Tell the proc server we exist, if it does. */ + if (portarray[INIT_PORT_PROC] != MACH_PORT_NULL) + _hurd_proc_init (argv); + + if (intarraysize > INIT_UMASK) + _hurd_umask = intarray[INIT_UMASK] & 0777; + else + _hurd_umask = CMASK; + + /* All done with init ints and ports. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) intarray, + intarraysize * sizeof (int)); + __vm_deallocate (__mach_task_self (), + (vm_address_t) portarray, + portarraysize * sizeof (mach_port_t)); + + if (flags & EXEC_SECURE) + /* XXX if secure exec, elide environment variables + which the library uses and could be security holes. + CORESERVER, COREFILE + */ ; + + /* Call other things which want to do some initialization. These are not + on the __libc_subinit hook because things there like to be able to + assume the availability of the POSIX.1 services we provide. */ + RUN_HOOK (_hurd_subinit, ()); +} + +#include <hurd/signal.h> + +/* The user can do "int _hide_arguments = 1;" to make + sure the arguments are never visible with `ps'. */ +int _hide_arguments, _hide_environment; + +/* Hook for things which should be initialized as soon as the proc + server is available. */ +DEFINE_HOOK (_hurd_proc_subinit, (void)); + +/* Do startup handshaking with the proc server just installed in _hurd_ports. + Call _hurdsig_init to set up signal processing. */ + +void +_hurd_proc_init (char **argv) +{ + mach_port_t oldmsg; + struct hurd_userlink ulink; + process_t procserver; + + /* Initialize the signal code; Mach exceptions will become signals. */ + _hurdsig_init (); + + /* The signal thread is now prepared to receive messages. + It is safe to give the port to the proc server. */ + + procserver = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); + + /* Give the proc server our message port. */ + __proc_setmsgport (procserver, _hurd_msgport, &oldmsg); + if (oldmsg != MACH_PORT_NULL) + /* Deallocate the old msg port we replaced. */ + __mach_port_deallocate (__mach_task_self (), oldmsg); + + /* Tell the proc server where our args and environment are. */ + __proc_set_arg_locations (procserver, + _hide_arguments ? 0 : (vm_address_t) argv, + _hide_environment ? 0 : (vm_address_t) __environ); + + _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, procserver); + + /* Initialize proc server-assisted fault recovery for the signal thread. */ + _hurdsig_fault_init (); + + /* Call other things which want to do some initialization. These are not + on the _hurd_subinit hook because things there assume that things done + here, like _hurd_pid, are already initialized. */ + RUN_HOOK (_hurd_proc_subinit, ()); + + if (_hurd_exec_flags & EXEC_TRACED) + /* This process is "traced", meaning it should stop on signals or exec. + We are all set up now to handle signals. Stop ourselves, to inform + our parent (presumably a debugger) that the exec has completed. */ + _hurd_raise_signal (NULL, SIGTRAP, 0, 0); +} + +/* Called when we get a message telling us to change our proc server port. */ + +error_t +_hurd_setproc (process_t procserver) +{ + error_t err; + mach_port_t oldmsg; + + /* Give the proc server our message port. */ + if (err = __proc_setmsgport (procserver, _hurd_msgport, &oldmsg)) + return err; + if (oldmsg != MACH_PORT_NULL) + /* Deallocate the old msg port we replaced. */ + __mach_port_deallocate (__mach_task_self (), oldmsg); + + /* Tell the proc server where our args and environment are. */ + if (err = __proc_set_arg_locations (procserver, + /* We don't know the ARGV location. */ + (vm_address_t) 0, + _hide_environment ? 0 : + (vm_address_t) __environ)) + return err; + + /* Those calls worked, so the port looks good. */ + _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver); + + { + pid_t oldpgrp = _hurd_pgrp; + + /* Call these functions again so they can fetch the + new information from the new proc server. */ + RUN_HOOK (_hurd_proc_subinit, ()); + + if (_hurd_pgrp != oldpgrp) + { + /* Run things that want notification of a pgrp change. */ + DECLARE_HOOK (_hurd_pgrp_changed_hook, (pid_t)); + RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp)); + } + } + + return 0; +} diff --git a/hurd/hurdinline.c b/hurd/hurdinline.c new file mode 100644 index 0000000000..12a5be6508 --- /dev/null +++ b/hurd/hurdinline.c @@ -0,0 +1,11 @@ +/* Include this first to avoid defining its inline functions. */ +#include <lock-intern.h> + +#undef _EXTERN_INLINE +#define _EXTERN_INLINE /* Define the real function. */ + +#include "hurd/fd.h" +#include "hurd/signal.h" +#include "hurd/userlink.h" +#include "hurd/threadvar.h" +#include "hurd/port.h" diff --git a/hurd/hurdintr.awk b/hurd/hurdintr.awk new file mode 100644 index 0000000000..d03940985c --- /dev/null +++ b/hurd/hurdintr.awk @@ -0,0 +1,25 @@ +BEGIN { intr=0; wantcall=0; calls=""; } + +$1 == "/*" && $2 == "INTR" && $3 == "*/" { intr=1; } + +NF == 1 && $1 == "routine" { wantcall=1; next; } + +intr != 0 && wantcall == 0 && NF >= 2 && $1 == "routine" \ + { + if (substr($2, length($2)-2, 1) == "(") + calls = calls " " substr($2, 0, length($2)-1); + else calls = calls " " $2; + intr=0; + } + +wantcall != 0 && NF >= 1 \ + { + if (substr($1, length($1)-2, 1) == "(") + calls = calls " " substr($1, 0, length($1)-1); + else calls = calls " " $1; + intr=0; + } + +{ wantcall=0; } + +END { print varname " :=" calls; } diff --git a/hurd/hurdioctl.c b/hurd/hurdioctl.c new file mode 100644 index 0000000000..5a41eb10f7 --- /dev/null +++ b/hurd/hurdioctl.c @@ -0,0 +1,264 @@ +/* ioctl commands which must be done in the C library. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fd.h> +#include <sys/ioctl.h> +#include <hurd/ioctl.h> + + + +/* Symbol set of ioctl handler lists. If there are user-registered + handlers, one of these lists will contain them. The other lists are + handlers built into the library. */ +symbol_set_define (_hurd_ioctl_handler_lists) + +/* Look up REQUEST in the set of handlers. */ +ioctl_handler_t +_hurd_lookup_ioctl_handler (int request) +{ + void *const *ptr; + const struct ioctl_handler *h; + + for (ptr = symbol_set_first_element (_hurd_ioctl_handler_lists); + !symbol_set_end_p (_hurd_ioctl_handler_lists, ptr); + ++ptr) + for (h = *ptr; h != NULL; h = h->next) + if (request >= h->first_request && request <= h->last_request) + return h->handler; + + return NULL; +} + +#include <fcntl.h> + +/* Find out how many bytes may be read from FD without blocking. */ + +static int +fioctl (int fd, + int request, + int *arg) +{ + error_t err; + + *(volatile int *) arg = *arg; + + switch (request) + { + default: + err = EGRATUITOUS; + break; + + case FIONREAD: + { + mach_msg_type_number_t navail; + err = HURD_DPORT_USE (fd, __io_readable (port, &navail)); + if (!err) + *arg = (int) navail; + } + break; + + case FIONBIO: + err = HURD_DPORT_USE (fd, (*arg ? + __io_set_some_openmodes : + __io_clear_some_openmodes) + (port, O_NONBLOCK)); + break; + + case FIOASYNC: + err = HURD_DPORT_USE (fd, (*arg ? + __io_set_some_openmodes : + __io_clear_some_openmodes) + (port, O_ASYNC)); + break; + + case FIOSETOWN: + err = HURD_DPORT_USE (fd, __io_mod_owner (port, *arg)); + break; + + case FIOGETOWN: + err = HURD_DPORT_USE (fd, __io_get_owner (port, arg)); + break; + } + + return err ? __hurd_fail (err) : 0; +} + +_HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD); + + +static int +fioclex (int fd, + int request) +{ + int flag; + + switch (request) + { + default: + return __hurd_fail (EGRATUITOUS); + case FIOCLEX: + flag = FD_CLOEXEC; + break; + case FIONCLEX: + flag = 0; + break; + } + + return __fcntl (fd, F_SETFD, flag); +} +_HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX); + +#include <hurd/term.h> + +static void +rectty_dtable (mach_port_t cttyid) +{ + int i; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + + for (i = 0; i < _hurd_dtablesize; ++i) + { + struct hurd_fd *const d = _hurd_dtable[i]; + mach_port_t newctty; + + if (d == NULL) + /* Nothing to do for an unused descriptor cell. */ + continue; + + if (cttyid == MACH_PORT_NULL) + /* We now have no controlling tty at all. */ + newctty = MACH_PORT_NULL; + else + HURD_PORT_USE (&d->port, + ({ mach_port_t id; + /* Get the io object's cttyid port. */ + if (! __term_getctty (port, &id)) + { + if (id == cttyid && /* Is it ours? */ + /* Get the ctty io port. */ + __term_open_ctty (port, + _hurd_pid, _hurd_pgrp, + &newctty)) + /* XXX it is our ctty but the call failed? */ + newctty = MACH_PORT_NULL; + __mach_port_deallocate + (__mach_task_self (), (mach_port_t) id); + } + else + newctty = MACH_PORT_NULL; + 0; + })); + + /* Install the new ctty port. */ + _hurd_port_set (&d->ctty, newctty); + } + + __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; +} + + +/* Called when we have received a message saying to use a new ctty ID port. */ + +error_t +_hurd_setcttyid (mach_port_t cttyid) +{ + error_t err; + + if (cttyid != MACH_PORT_NULL) + { + /* Give the new send right a user reference. + This is a good way to check that it is valid. */ + if (err = __mach_port_mod_refs (__mach_task_self (), cttyid, + MACH_PORT_RIGHT_SEND, 1)) + return err; + } + + /* Install the port, consuming the reference we just created. */ + _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid); + + /* Reset all the ctty ports in all the descriptors. */ + __USEPORT (CTTYID, (rectty_dtable (cttyid), 0)); + + return 0; +} + + +/* Make FD be the controlling terminal. + This function is called for `ioctl (fd, TCIOSCTTY)'. */ + +static int +tiocsctty (int fd, + int request) /* Always TIOCSCTTY. */ +{ + mach_port_t cttyid; + error_t err; + + /* Get FD's cttyid port, unless it is already ours. */ + err = HURD_DPORT_USE (fd, ctty != MACH_PORT_NULL ? EADDRINUSE : + __term_getctty (port, &cttyid)); + if (err == EADDRINUSE) + /* FD is already the ctty. Nothing to do. */ + return 0; + else if (err) + return __hurd_fail (err); + + /* Make it our own. */ + _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid); + + /* Reset all the ctty ports in all the descriptors. */ + __USEPORT (CTTYID, (rectty_dtable (cttyid), 0)); + + return 0; +} +_HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY); + +/* Dissociate from the controlling terminal. */ + +static int +tiocnotty (int fd, + int request) /* Always TIOCNOTTY. */ +{ + mach_port_t fd_cttyid; + error_t err; + + if (err = HURD_DPORT_USE (fd, __term_getctty (port, &fd_cttyid))) + return __hurd_fail (err); + + if (__USEPORT (CTTYID, port != fd_cttyid)) + err = EINVAL; + + __mach_port_deallocate (__mach_task_self (), fd_cttyid); + + if (err) + return __hurd_fail (err); + + /* Clear our cttyid port cell. */ + _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], MACH_PORT_NULL); + + /* Reset all the ctty ports in all the descriptors. */ + + __USEPORT (CTTYID, (rectty_dtable (MACH_PORT_NULL), 0)); + + return 0; +} +_HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY); diff --git a/hurd/hurdkill.c b/hurd/hurdkill.c new file mode 100644 index 0000000000..364b6ed692 --- /dev/null +++ b/hurd/hurdkill.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <sys/types.h> +#include <signal.h> +#include <hurd.h> +#include <hurd/port.h> +#include <hurd/signal.h> +#include <hurd/msg.h> + +/* Send a `sig_post' RPC to process number PID. If PID is zero, + send the message to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. + SIG and REFPORT are passed along in the request message. */ +error_t +_hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport) +{ + int delivered = 0; /* Set when we deliver any signal. */ + error_t err; + mach_port_t proc; + struct hurd_userlink ulink; + + inline void kill_pid (pid_t pid) /* Kill one PID. */ + { + err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport), + (refport = arg_refport, 0), 0, + /* If no message port we cannot send signals. */ + msgport == MACH_PORT_NULL ? EPERM : + __msg_sig_post (msgport, sig, refport)); + if (! err) + delivered = 1; + } + + proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); + + if (pid <= 0) + { + /* Send SIG to each process in pgrp (- PID). */ + mach_msg_type_number_t npids = 10, i; + pid_t pidsbuf[10], *pids = pidsbuf; + + err = __proc_getpgrppids (proc, - pid, &pids, &npids); + if (!err) + { + for (i = 0; i < npids; ++i) + { + kill_pid (pids[i]); + if (err == ESRCH) + /* The process died already. Ignore it. */ + err = 0; + } + if (pids != pidsbuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pids, npids * sizeof (pids[0])); + } + } + else + kill_pid (pid); + + _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc); + + /* If we delivered no signals, but ERR is clear, this must mean that + every kill_pid call failed with ESRCH, meaning all the processes in + the pgrp died between proc_getpgrppids and kill_pid; in that case we + fail with ESRCH. */ + return delivered ? 0 : err ?: ESRCH; +} +weak_alias (_hurd_sig_post, hurd_sig_post) diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c new file mode 100644 index 0000000000..b467404840 --- /dev/null +++ b/hurd/hurdlookup.c @@ -0,0 +1,381 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <string.h> +#include <limits.h> +#include <fcntl.h> +#include "stdio/_itoa.h" +#include <hurd/term.h> + + +/* Translate the error from dir_lookup into the error the user sees. */ +static inline error_t +lookup_error (error_t error) +{ + switch (error) + { + case EOPNOTSUPP: + case MIG_BAD_ID: + /* These indicate that the server does not understand dir_lookup + at all. If it were a directory, it would, by definition. */ + return ENOTDIR; + default: + return error; + } +} + +error_t +__hurd_file_name_lookup (file_t crdir, file_t cwdir, + const char *file_name, int flags, mode_t mode, + file_t *result) +{ + error_t err; + enum retry_type doretry; + char retryname[1024]; /* XXX string_t LOSES! */ + file_t startdir; + + startdir = file_name[0] == '/' ? crdir : cwdir; + + while (file_name[0] == '/') + file_name++; + + if (err = __dir_lookup (startdir, file_name, flags, mode, + &doretry, retryname, result)) + return lookup_error (err); + + return __hurd_file_name_lookup_retry (crdir, doretry, retryname, flags, mode, + result); +} +weak_alias (__hurd_file_name_lookup, hurd_file_name_lookup) + +error_t +__hurd_file_name_lookup_retry (file_t crdir, + enum retry_type doretry, + char retryname[1024], + int flags, mode_t mode, + file_t *result) +{ + error_t err; + file_t startdir; + file_t newpt; + char *file_name; + int dealloc_dir; + int nloops; + + dealloc_dir = 0; + nloops = 0; + err = 0; + + while (1) + { + if (dealloc_dir) + __mach_port_deallocate (__mach_task_self (), startdir); + if (err) + return lookup_error (err); + + switch (doretry) + { + case FS_RETRY_REAUTH: + { + mach_port_t ref = __mach_reply_port (); + err = __io_reauthenticate (*result, + ref, MACH_MSG_TYPE_MAKE_SEND); + if (! err) + err = __USEPORT + (AUTH, __auth_user_authenticate (port, *result, + ref, + MACH_MSG_TYPE_MAKE_SEND, + &newpt)); + __mach_port_destroy (__mach_task_self (), ref); + } + __mach_port_deallocate (__mach_task_self (), *result); + if (err) + return err; + *result = newpt; + /* Fall through. */ + + case FS_RETRY_NORMAL: +#ifdef SYMLOOP_MAX + if (nloops++ >= SYMLOOP_MAX) + return ELOOP; +#endif + + /* An empty RETRYNAME indicates we have the final port. */ + if (retryname[0] == '\0') + { + /* We got a successful translation. Now apply any open-time + action flags we were passed. */ + if (flags & O_EXLOCK) + ; /* XXX */ + if (!err && (flags & O_SHLOCK)) + ; /* XXX */ + if (!err && (flags & O_TRUNC)) + err = __file_truncate (*result, 0); + + if (err) + __mach_port_deallocate (__mach_task_self (), *result); + return err; + } + + startdir = *result; + dealloc_dir = 1; + file_name = retryname; + break; + + case FS_RETRY_MAGICAL: + switch (retryname[0]) + { + case '/': + startdir = crdir; + dealloc_dir = 0; + if (*result != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), *result); + file_name = &retryname[1]; + break; + + case 'f': + if (retryname[1] == 'd' && retryname[2] == '/') + { + int fd; + char *end; + int save = errno; + errno = 0; + fd = (int) strtol (retryname, &end, 10); + if (end == NULL || errno || /* Malformed number. */ + /* Check for excess text after the number. A slash + is valid; it ends the component. Anything else + does not name a numeric file descriptor. */ + (*end != '/' && *end != '\0')) + { + errno = save; + return ENOENT; + } + *result = __getdport (fd); + if (*result == MACH_PORT_NULL) + { + /* If the name was a proper number, but the file + descriptor does not exist, we return EBADF instead + of ENOENT. */ + error_t err = errno; + errno = save; + return err; + } + errno = save; + if (*end == '\0') + return 0; + else + { + /* Do a normal retry on the remaining components. */ + startdir = *result; + dealloc_dir = 1; + file_name = end + 1; /* Skip the slash. */ + break; + } + } + else + goto bad_magic; + break; + + case 'm': + if (retryname[1] == 'a' && retryname[2] == 'c' && + retryname[3] == 'h' && retryname[4] == 't' && + retryname[5] == 'y' && retryname[6] == 'p' && + retryname[7] == 'e') + { + error_t err; + struct host_basic_info hostinfo; + mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT; + char *p; + if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, + (natural_t *) &hostinfo, + &hostinfocnt)) + return err; + if (hostinfocnt != HOST_BASIC_INFO_COUNT) + return EGRATUITOUS; + p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0); + *--p = '/'; + p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0); + if (p < retryname) + abort (); /* XXX write this right if this ever happens */ + if (p > retryname) + strcpy (retryname, p); + startdir = *result; + dealloc_dir = 1; + } + else + goto bad_magic; + break; + + case 't': + if (retryname[1] == 't' && retryname[2] == 'y') + switch (retryname[3]) + { + error_t opentty (file_t *result) + { + error_t err; + file_t unauth; + err = __USEPORT (CTTYID, + __termctty_open_terminal (port, + flags, + &unauth)); + if (! err) + { + mach_port_t ref = __mach_reply_port (); + err = __io_reauthenticate + (unauth, + ref, + MACH_MSG_TYPE_MAKE_SEND); + if (! err) + err = __USEPORT + (AUTH, __auth_user_authenticate + (port, + unauth, + ref, MACH_MSG_TYPE_MAKE_SEND, + result)); + __mach_port_deallocate (__mach_task_self (), + unauth); + __mach_port_destroy (__mach_task_self (), ref); + } + return err; + } + + case '\0': + return opentty (result); + case '/': + if (err = opentty (&startdir)) + return err; + dealloc_dir = 1; + strcpy (retryname, &retryname[4]); + break; + default: + goto bad_magic; + } + else + goto bad_magic; + break; + + default: + bad_magic: + return EGRATUITOUS; + } + break; + + default: + return EGRATUITOUS; + } + + err = __dir_lookup (startdir, file_name, flags, mode, + &doretry, retryname, result); + } +} +weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) + +error_t +__hurd_file_name_split (file_t crdir, file_t cwdir, + const char *file_name, + file_t *dir, char **name) +{ + const char *lastslash; + error_t err; + + lastslash = strrchr (file_name, '/'); + if (lastslash != NULL) + { + if (lastslash == file_name) + { + /* "/foobar" => crdir + "foobar". */ + *name = (char *) file_name + 1; + if (err = __mach_port_mod_refs (__mach_task_self (), + crdir, MACH_PORT_RIGHT_SEND, +1)) + return err; + *dir = crdir; + return 0; + } + else + { + /* "/dir1/dir2/.../file". */ + char dirname[lastslash - file_name + 1]; + memcpy (dirname, file_name, lastslash - file_name); + dirname[lastslash - file_name] = '\0'; + *name = (char *) lastslash + 1; + return __hurd_file_name_lookup (crdir, cwdir, dirname, 0, 0, dir); + } + } + else + { + /* "foobar" => cwdir + "foobar". */ + *name = (char *) file_name; + if (err = __mach_port_mod_refs (__mach_task_self (), + cwdir, MACH_PORT_RIGHT_SEND, +1)) + return err; + *dir = cwdir; + return 0; + } +} +weak_alias (__hurd_file_name_split, hurd_file_name_split) + + +file_t +__file_name_lookup (const char *file_name, int flags, mode_t mode) +{ + error_t err; + file_t result, crdir, cwdir; + struct hurd_userlink crdir_ulink, cwdir_ulink; + + crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); + cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink); + + err = __hurd_file_name_lookup (crdir, cwdir, file_name, flags, mode, + &result); + + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir); + + if (err) + return __hurd_fail (err), MACH_PORT_NULL; + else + return result; +} +weak_alias (__file_name_lookup, file_name_lookup) + + +file_t +__file_name_split (const char *file_name, char **name) +{ + error_t err; + file_t dir, crdir, cwdir; + struct hurd_userlink crdir_ulink, cwdir_ulink; + + crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); + cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink); + + err = __hurd_file_name_split (crdir, cwdir, file_name, &dir, name); + + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir); + + if (err) + { + errno = err; + return MACH_PORT_NULL; + } + else + return dir; +} +weak_alias (__file_name_split, file_name_split) diff --git a/hurd/hurdmalloc.c b/hurd/hurdmalloc.c new file mode 100644 index 0000000000..1de887bb80 --- /dev/null +++ b/hurd/hurdmalloc.c @@ -0,0 +1,411 @@ +#include <stdlib.h> +#include <string.h> + +#define bcopy(s,d,n) memcpy ((d), (s), (n)) /* No overlap handling. */ + +#include "hurdmalloc.h" /* XXX see that file */ + +#include <mach.h> +#define vm_allocate __vm_allocate +#define vm_page_size __vm_page_size + +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.10 1995/02/13 22:04:34 roland + * (malloc_init): Add self reference to avoid not only the `defined but not + * used' warning, but also to avoid GCC optimizing out the entire function + * (!). + * + * Revision 1.9 1995/02/13 16:36:08 roland + * Include string.h; #define bcopy using memcpy. + * + * Revision 1.8 1995/02/03 01:54:21 roland + * Remove bogus bcopy decl. + * + * Revision 1.7 1995/01/26 04:22:02 roland + * Don't include gnu-stabs.h. + * + * Revision 1.6 1994/12/07 19:41:26 roland + * (vm_allocate, vm_page_size): #define these to __ names at top. + * + * Revision 1.5 1994/06/04 01:48:44 roland + * entered into RCS + * + * Revision 2.7 91/05/14 17:57:34 mrt + * Correcting copyright + * + * Revision 2.6 91/02/14 14:20:26 mrt + * Added new Mach copyright + * [91/02/13 12:41:21 mrt] + * + * Revision 2.5 90/11/05 14:37:33 rpd + * Added malloc_fork* code. + * [90/11/02 rwd] + * + * Add spin_lock_t. + * [90/10/31 rwd] + * + * Revision 2.4 90/08/07 14:31:28 rpd + * Removed RCS keyword nonsense. + * + * Revision 2.3 90/06/02 15:14:00 rpd + * Converted to new IPC. + * [90/03/20 20:56:57 rpd] + * + * Revision 2.2 89/12/08 19:53:59 rwd + * Removed conditionals. + * [89/10/23 rwd] + * + * Revision 2.1 89/08/03 17:09:46 rwd + * Created. + * + * + * 13-Sep-88 Eric Cooper (ecc) at Carnegie Mellon University + * Changed realloc() to copy min(old size, new size) bytes. + * Bug found by Mike Kupfer at Olivetti. + */ +/* + * File: malloc.c + * Author: Eric Cooper, Carnegie Mellon University + * Date: July, 1988 + * + * Memory allocator for use with multiple threads. + */ + + +#include <cthreads.h> +#include "cthread_internals.h" + + +/* + * Structure of memory block header. + * When free, next points to next block on free list. + * When allocated, fl points to free list. + * Size of header is 4 bytes, so minimum usable block size is 8 bytes. + */ +typedef union header { + union header *next; + struct free_list *fl; +} *header_t; + +#define MIN_SIZE 8 /* minimum block size */ + +typedef struct free_list { + spin_lock_t lock; /* spin lock for mutual exclusion */ + header_t head; /* head of free list for this size */ +#ifdef DEBUG + int in_use; /* # mallocs - # frees */ +#endif DEBUG +} *free_list_t; + +/* + * Free list with index i contains blocks of size 2^(i+3) including header. + * Smallest block size is 8, with 4 bytes available to user. + * Size argument to malloc is a signed integer for sanity checking, + * so largest block size is 2^31. + */ +#define NBUCKETS 29 + +static struct free_list malloc_free_list[NBUCKETS]; + +/* Initialization just sets everything to zero, but might be necessary on a + machine where spin_lock_init does otherwise, and is necessary when + running an executable that was written by something like Emacs's unexec. + It preserves the values of data variables like malloc_free_list, but + does not save the vm_allocate'd space allocated by this malloc. */ + +static void +malloc_init (void) +{ + int i; + for (i = 0; i < NBUCKETS; ++i) + { + spin_lock_init (&malloc_free_list[i].lock); + malloc_free_list[i].head = NULL; +#ifdef DEBUG + malloc_free_list[i].in_use = 0; +#endif + } + + /* This not only suppresses a `defined but not used' warning, + but it is ABSOLUTELY NECESSARY to avoid the hyperclever + compiler from "optimizing out" the entire function! */ + (void) &malloc_init; +} + +static void +more_memory(size, fl) + int size; + register free_list_t fl; +{ + register int amount; + register int n; + vm_address_t where; + register header_t h; + kern_return_t r; + + if (size <= vm_page_size) { + amount = vm_page_size; + n = vm_page_size / size; + /* + * We lose vm_page_size - n*size bytes here. */ + } else { + amount = size; + n = 1; + } + MACH_CALL(vm_allocate(mach_task_self(), &where, (vm_size_t) amount, TRUE), r); + h = (header_t) where; + do { + h->next = fl->head; + fl->head = h; + h = (header_t) ((char *) h + size); + } while (--n != 0); +} + +/* Declaration changed to standard one for GNU. */ +void * +malloc(size) + register size_t size; +{ + register int i, n; + register free_list_t fl; + register header_t h; + + if ((int) size < 0) /* sanity check */ + return 0; + size += sizeof(union header); + /* + * Find smallest power-of-two block size + * big enough to hold requested size plus header. + */ + i = 0; + n = MIN_SIZE; + while (n < size) { + i += 1; + n <<= 1; + } + ASSERT(i < NBUCKETS); + fl = &malloc_free_list[i]; + spin_lock(&fl->lock); + h = fl->head; + if (h == 0) { + /* + * Free list is empty; + * allocate more blocks. + */ + more_memory(n, fl); + h = fl->head; + if (h == 0) { + /* + * Allocation failed. + */ + spin_unlock(&fl->lock); + return 0; + } + } + /* + * Pop block from free list. + */ + fl->head = h->next; +#ifdef DEBUG + fl->in_use += 1; +#endif DEBUG + spin_unlock(&fl->lock); + /* + * Store free list pointer in block header + * so we can figure out where it goes + * at free() time. + */ + h->fl = fl; + /* + * Return pointer past the block header. + */ + return ((char *) h) + sizeof(union header); +} + +/* Declaration changed to standard one for GNU. */ +void +free(base) + void *base; +{ + register header_t h; + register free_list_t fl; + register int i; + + if (base == 0) + return; + /* + * Find free list for block. + */ + h = (header_t) (base - sizeof(union header)); + fl = h->fl; + i = fl - malloc_free_list; + /* + * Sanity checks. + */ + if (i < 0 || i >= NBUCKETS) { + ASSERT(0 <= i && i < NBUCKETS); + return; + } + if (fl != &malloc_free_list[i]) { + ASSERT(fl == &malloc_free_list[i]); + return; + } + /* + * Push block on free list. + */ + spin_lock(&fl->lock); + h->next = fl->head; + fl->head = h; +#ifdef DEBUG + fl->in_use -= 1; +#endif DEBUG + spin_unlock(&fl->lock); + return; +} + +/* Declaration changed to standard one for GNU. */ +void * +realloc(old_base, new_size) + void *old_base; + size_t new_size; +{ + register header_t h; + register free_list_t fl; + register int i; + unsigned int old_size; + char *new_base; + + if (old_base == 0) + return malloc (new_size); + + /* + * Find size of old block. + */ + h = (header_t) (old_base - sizeof(union header)); + fl = h->fl; + i = fl - malloc_free_list; + /* + * Sanity checks. + */ + if (i < 0 || i >= NBUCKETS) { + ASSERT(0 <= i && i < NBUCKETS); + return 0; + } + if (fl != &malloc_free_list[i]) { + ASSERT(fl == &malloc_free_list[i]); + return 0; + } + /* + * Free list with index i contains blocks of size 2^(i+3) including header. + */ + old_size = (1 << (i+3)) - sizeof(union header); + /* + * Allocate new block, copy old bytes, and free old block. + */ + new_base = malloc(new_size); + if (new_base != 0) + bcopy(old_base, new_base, (int) (old_size < new_size ? old_size : new_size)); + free(old_base); + return new_base; +} + +#ifdef DEBUG +void +print_malloc_free_list() +{ + register int i, size; + register free_list_t fl; + register int n; + register header_t h; + int total_used = 0; + int total_free = 0; + + fprintf(stderr, " Size In Use Free Total\n"); + for (i = 0, size = MIN_SIZE, fl = malloc_free_list; + i < NBUCKETS; + i += 1, size <<= 1, fl += 1) { + spin_lock(&fl->lock); + if (fl->in_use != 0 || fl->head != 0) { + total_used += fl->in_use * size; + for (n = 0, h = fl->head; h != 0; h = h->next, n += 1) + ; + total_free += n * size; + fprintf(stderr, "%10d %10d %10d %10d\n", + size, fl->in_use, n, fl->in_use + n); + } + spin_unlock(&fl->lock); + } + fprintf(stderr, " all sizes %10d %10d %10d\n", + total_used, total_free, total_used + total_free); +} +#endif DEBUG + +static void malloc_fork_prepare() +/* + * Prepare the malloc module for a fork by insuring that no thread is in a + * malloc critical section. + */ +{ + register int i; + + for (i = 0; i < NBUCKETS; i++) { + spin_lock(&malloc_free_list[i].lock); + } +} + +static void malloc_fork_parent() +/* + * Called in the parent process after a fork() to resume normal operation. + */ +{ + register int i; + + for (i = NBUCKETS-1; i >= 0; i--) { + spin_unlock(&malloc_free_list[i].lock); + } +} + +static void malloc_fork_child() +/* + * Called in the child process after a fork() to resume normal operation. + */ +{ + register int i; + + for (i = NBUCKETS-1; i >= 0; i--) { + spin_unlock(&malloc_free_list[i].lock); + } +} + + +text_set_element (_hurd_fork_prepare_hook, malloc_fork_prepare); +text_set_element (_hurd_fork_parent_hook, malloc_fork_parent); +text_set_element (_hurd_fork_child_hook, malloc_fork_child); +text_set_element (_hurd_preinit_hook, malloc_init); diff --git a/hurd/hurdmalloc.h b/hurd/hurdmalloc.h new file mode 100644 index 0000000000..91286093c4 --- /dev/null +++ b/hurd/hurdmalloc.h @@ -0,0 +1,17 @@ +/* XXX this file is a tempoary hack. + + All hurd-internal code which uses malloc et al includes this file so it + will use the internal malloc routines _hurd_{malloc,realloc,free} + instead. The "hurd-internal" functions are the cthreads version, + which uses vm_allocate and is thread-safe. The normal user version + of malloc et al is the unixoid one using sbrk. + + */ + +extern void *_hurd_malloc (size_t); +extern void *_hurd_realloc (void *, size_t); +extern void _hurd_free (void *); + +#define malloc _hurd_malloc +#define realloc _hurd_realloc +#define free _hurd_free diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c new file mode 100644 index 0000000000..57b6b8dd67 --- /dev/null +++ b/hurd/hurdmsg.c @@ -0,0 +1,451 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/msg_server.h> +#include <hurd/fd.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> + + +#define AUTHCHECK \ + if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \ + return EPERM + + +/* Snarfing and frobbing the init ports. */ + +kern_return_t +_S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which, + mach_port_t *result, mach_msg_type_name_t *result_type) +{ + AUTHCHECK; + *result_type = MACH_MSG_TYPE_MOVE_SEND; + /* This function adds a new user reference for the *RESULT it gives back. + Our reply message uses a move-send right that consumes this reference. */ + return _hurd_ports_get (which, result); +} + +kern_return_t +_S_msg_set_init_port (mach_port_t msgport, mach_port_t auth, + int which, mach_port_t port) +{ + error_t err; + + AUTHCHECK; + + err = _hurd_ports_set (which, port); + if (err == 0) + __mach_port_deallocate (__mach_task_self (), port); + + return 0; +} + +kern_return_t +_S_msg_get_init_ports (mach_port_t msgport, mach_port_t auth, + mach_port_t **ports, + mach_msg_type_name_t *ports_type, + mach_msg_type_number_t *nports) +{ + mach_msg_type_number_t i; + error_t err; + + AUTHCHECK; + + if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) ports, + _hurd_nports * sizeof (mach_port_t), 1)) + return err; + *nports = _hurd_nports; + + for (i = 0; i < _hurd_nports; ++i) + /* This function adds a new user ref for the *RESULT it gives back. + Our reply message uses move-send rights that consumes this ref. */ + if (err = _hurd_ports_get (i, &(*ports)[i])) + { + /* Died part way through. Deallocate the ports already fetched. */ + while (i-- > 0) + __mach_port_deallocate (__mach_task_self (), (*ports)[i]); + __vm_deallocate (__mach_task_self (), + (vm_address_t) *ports, + *nports * sizeof (mach_port_t)); + return err; + } + + *ports_type = MACH_MSG_TYPE_MOVE_SEND; + return 0; +} + +kern_return_t +_S_msg_set_init_ports (mach_port_t msgport, mach_port_t auth, + mach_port_t *ports, mach_msg_type_number_t nports) +{ + mach_msg_type_number_t i; + error_t err; + + AUTHCHECK; + + for (i = 0; i < _hurd_nports; ++i) + { + if (err = _hurd_ports_set (i, ports[i])) + return err; + else + __mach_port_deallocate (__mach_task_self (), ports[i]); + } + + return 0; +} + +/* Snarfing and frobbing the init ints. */ + +static kern_return_t +get_int (int which, int *value) +{ + switch (which) + { + case INIT_UMASK: + *value = _hurd_umask; + return 0; + case INIT_SIGMASK: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + __spin_lock (&ss->lock); + *value = ss->blocked; + __spin_unlock (&ss->lock); + return 0; + } + case INIT_SIGPENDING: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + __spin_lock (&ss->lock); + *value = ss->pending; + __spin_unlock (&ss->lock); + return 0; + } + case INIT_SIGIGN: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + sigset_t ign; + int sig; + __spin_lock (&ss->lock); + __sigemptyset (&ign); + for (sig = 1; sig < NSIG; ++sig) + if (ss->actions[sig].sa_handler == SIG_IGN) + __sigaddset (&ign, sig); + __spin_unlock (&ss->lock); + *value = ign; + return 0; + } + default: + return EINVAL; + } +} + +kern_return_t +_S_msg_get_init_int (mach_port_t msgport, mach_port_t auth, + int which, int *value) +{ + AUTHCHECK; + + return get_int (which, value); +} + +kern_return_t +_S_msg_get_init_ints (mach_port_t msgport, mach_port_t auth, + int **values, mach_msg_type_number_t *nvalues) +{ + error_t err; + mach_msg_type_number_t i; + + AUTHCHECK; + + if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) values, + INIT_INT_MAX * sizeof (int), 1)) + return err; + *nvalues = INIT_INT_MAX; + + for (i = 0; i < INIT_INT_MAX; ++i) + switch (err = get_int (i, &(*values)[i])) + { + case 0: /* Success. */ + break; + case EINVAL: /* Unknown index. */ + (*values)[i] = 0; + break; + default: /* Lossage. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) *values, INIT_INT_MAX * sizeof (int)); + return err; + } + + return 0; +} + + +static kern_return_t +set_int (int which, int value) +{ + switch (which) + { + case INIT_UMASK: + _hurd_umask = value; + return 0; + + /* These are pretty odd things to do. But you asked for it. */ + case INIT_SIGMASK: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + __spin_lock (&ss->lock); + ss->blocked = value; + __spin_unlock (&ss->lock); + return 0; + } + case INIT_SIGPENDING: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + __spin_lock (&ss->lock); + ss->pending = value; + __spin_unlock (&ss->lock); + return 0; + } + case INIT_SIGIGN: + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); + int sig; + const sigset_t ign = value; + __spin_lock (&ss->lock); + for (sig = 1; sig < NSIG; ++sig) + { + if (__sigismember (&ign, sig)) + ss->actions[sig].sa_handler = SIG_IGN; + else if (ss->actions[sig].sa_handler == SIG_IGN) + ss->actions[sig].sa_handler = SIG_DFL; + } + __spin_unlock (&ss->lock); + return 0; + } + default: + return EINVAL; + } +} + +kern_return_t +_S_msg_set_init_int (mach_port_t msgport, mach_port_t auth, + int which, int value) +{ + AUTHCHECK; + + return set_int (which, value); +} + +kern_return_t +_S_msg_set_init_ints (mach_port_t msgport, mach_port_t auth, + int *values, mach_msg_type_number_t nvalues) +{ + error_t err; + mach_msg_type_number_t i; + + AUTHCHECK; + + for (i = 0; i < INIT_INT_MAX; ++i) + switch (err = set_int (i, values[i])) + { + case 0: /* Success. */ + break; + case EINVAL: /* Unknown index. */ + break; + default: /* Lossage. */ + return err; + } + + return 0; +} + + +kern_return_t +_S_msg_get_fd (mach_port_t msgport, mach_port_t auth, + int which, mach_port_t *result, mach_msg_type_name_t *result_type) +{ + AUTHCHECK; + + /* This creates a new user reference for the send right. + Our reply message will move that reference to the caller. */ + *result = __getdport (which); + if (*result == MACH_PORT_NULL) + return errno; + *result_type = MACH_MSG_TYPE_MOVE_SEND; + + return 0; +} + +kern_return_t +_S_msg_set_fd (mach_port_t msgport, mach_port_t auth, + int which, mach_port_t port) +{ + AUTHCHECK; + + /* We consume the reference if successful. */ + return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0)); +} + +/* Snarfing and frobbing environment variables. */ + +kern_return_t +_S_msg_get_env_variable (mach_port_t msgport, + char *variable, + char **data, mach_msg_type_number_t *datalen) +{ + const char *value = getenv (variable); + + if (value == NULL) + return ENOENT; + + /* XXX this pointer might become invalid */ + *data = value; + *datalen = strlen (value); + return 0; +} + + +kern_return_t +_S_msg_set_env_variable (mach_port_t msgport, mach_port_t auth, + char *variable, + char *value, + int replace) +{ + AUTHCHECK; + + if (setenv (variable, value, replace)) /* XXX name space */ + return errno; + return 0; +} + +kern_return_t +_S_msg_get_environment (mach_port_t msgport, + char **data, mach_msg_type_number_t *datalen) +{ + /* Pack the environment into an array with nulls separating elements. */ + if (__environ != NULL) + { + char *ap, **p; + size_t envlen = 0; + + for (p = __environ; *p != NULL; ++p) + envlen += strlen (*p) + 1; + + if (envlen > *datalen) + { + if (__vm_allocate (__mach_task_self (), + (vm_address_t *) data, envlen, 1)) + return ENOMEM; + } + + ap = *data; + for (p = __environ; *p != NULL; ++p) + ap = __memccpy (ap, *p, '\0', ULONG_MAX); + + *datalen = envlen; + } + else + *datalen = 0; + + return 0; +} + +kern_return_t +_S_msg_set_environment (mach_port_t msgport, mach_port_t auth, + char *data, mach_msg_type_number_t datalen) +{ + int _hurd_split_args (char *, mach_msg_type_number_t, char **); + int envc; + char **envp; + + AUTHCHECK; + + envc = _hurd_split_args (data, datalen, NULL); + envp = malloc ((envc + 1) * sizeof (char *)); + if (envp == NULL) + return errno; + _hurd_split_args (data, datalen, envp); + __environ = envp; /* XXX cooperate with loadenv et al */ + return 0; +} + +/* Get and frob the exec flags. */ + +kern_return_t +_S_msg_get_exec_flags (mach_port_t process, mach_port_t auth, + int *flags) +{ + AUTHCHECK; + + *flags = _hurd_exec_flags; + return 0; +} + +kern_return_t +_S_msg_set_all_exec_flags (mach_port_t process, mach_port_t auth, + int flags) +{ + AUTHCHECK; + + _hurd_exec_flags = flags; + return 0; +} + +kern_return_t +_S_msg_set_some_exec_flags (mach_port_t process, mach_port_t auth, + int flags) +{ + AUTHCHECK; + + _hurd_exec_flags |= flags; + return 0; +} + +kern_return_t +_S_msg_clear_some_exec_flags (mach_port_t process, mach_port_t auth, + int flags) +{ + AUTHCHECK; + + _hurd_exec_flags &= ~flags; + return 0; +} + + +/* XXX */ + +kern_return_t +_S_msg_get_dtable (mach_port_t process, + mach_port_t refport, + portarray_t *dtable, + mach_msg_type_name_t *dtablePoly, + mach_msg_type_number_t *dtableCnt) +{ return EOPNOTSUPP; } + +kern_return_t +_S_msg_set_dtable (mach_port_t process, + mach_port_t refport, + portarray_t dtable, + mach_msg_type_number_t dtableCnt) +{ return EOPNOTSUPP; } + +kern_return_t +_S_msg_startup_dosync (mach_port_t process) +{ return EOPNOTSUPP; } diff --git a/hurd/hurdpid.c b/hurd/hurdpid.c new file mode 100644 index 0000000000..23594d9a10 --- /dev/null +++ b/hurd/hurdpid.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp; +int _hurd_orphaned; + +static void +init_pids (void) +{ + __USEPORT (PROC, + ({ + __proc_getpids (port, &_hurd_pid, &_hurd_ppid, &_hurd_orphaned); + __proc_getpgrp (port, _hurd_pid, &_hurd_pgrp); + })); + + (void) &init_pids; /* Avoid "defined but not used" warning. */ +} + +text_set_element (_hurd_proc_subinit, init_pids); + +#include <hurd/msg_server.h> +#include "set-hooks.h" +#include <cthreads.h> + +DEFINE_HOOK (_hurd_pgrp_changed_hook, (pid_t)); + +/* These let user threads synchronize with an operation which changes ids. */ +unsigned int _hurd_pids_changed_stamp; +struct condition _hurd_pids_changed_sync; + +kern_return_t +_S_msg_proc_newids (mach_port_t me, + task_t task, + pid_t ppid, pid_t pgrp, int orphaned) +{ + if (task != __mach_task_self ()) + return EPERM; + + __mach_port_deallocate (__mach_task_self (), task); + + _hurd_ppid = ppid; + _hurd_pgrp = pgrp; + _hurd_orphaned = orphaned; + + /* Run things that want notification of a pgrp change. */ + RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp)); + + /* Notify any waiting user threads that the id change as been completed. */ + ++_hurd_pids_changed_stamp; +#ifdef noteven + __condition_broadcast (&_hurd_pids_changed_sync); +#endif + + return 0; +} diff --git a/hurd/hurdports.c b/hurd/hurdports.c new file mode 100644 index 0000000000..5b7dfd883f --- /dev/null +++ b/hurd/hurdports.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/port.h> + + +static inline mach_port_t +get (const int idx) +{ + mach_port_t result; + error_t err = _hurd_ports_get (idx, &result); + + if (err) + return __hurd_fail (err), MACH_PORT_NULL; + return result; +} +#define GET(type, what, idx) \ + type get##what (void) { return get (INIT_PORT_##idx); } + +static inline int +set (const int idx, mach_port_t new) +{ + error_t err = _hurd_ports_set (idx, new); + return err ? __hurd_fail (err) : 0; +} +#define SET(type, what, idx) \ + int set##what (type new) { return set (INIT_PORT_##idx, new); } + +#define GETSET(type, what, idx) \ + GET (type, what, idx) SET (type, what, idx) + +GETSET (process_t, proc, PROC) +GETSET (mach_port_t, cttyid, CTTYID) +GETSET (file_t, cwdir, CWDIR) +GETSET (file_t, crdir, CRDIR) +GETSET (auth_t, auth, AUTH) diff --git a/hurd/hurdprio.c b/hurd/hurdprio.c new file mode 100644 index 0000000000..d7beb3c97a --- /dev/null +++ b/hurd/hurdprio.c @@ -0,0 +1,87 @@ +/* Support code for dealing with priorities in the Hurd. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/resource.h> +#include <hurd.h> + +error_t +_hurd_priority_which_map (enum __priority_which which, int who, + error_t (*function) (pid_t, struct procinfo *)) +{ + mach_msg_type_number_t npids = 64, i; + pid_t pidbuf[npids], *pids; + error_t err; + struct procinfo *pip; + int pibuf[sizeof *pip + 5 * sizeof (pip->threadinfos[0])], *pi = pibuf; + mach_msg_type_number_t pisize = sizeof (pibuf) / sizeof (int); + + switch (which) + { + case PRIO_PROCESS: + npids = 1; + pids[0] = who; + err = 0; + break; + + case PRIO_PGRP: + err = __USEPORT (PROC, __proc_getpgrppids (port, who, &pids, &npids)); + break; + + case PRIO_USER: + err = __USEPORT (PROC, __proc_getallpids (port, &pids, &npids)); + break; + + default: + return EINVAL; + } + + for (i = 0; !err && i < npids; ++i) + { + if (which == PRIO_USER) + { + /* Get procinfo to check the owner. */ + int *oldpi = pi; + mach_msg_type_number_t oldpisize = pisize; + if (err = __USEPORT (PROC, __proc_getprocinfo (port, pids[i], + &pi, &pisize))) + continue; + if (pi != oldpi && oldpi != pibuf) + /* Old buffer from last call was not reused; free it. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) oldpi, oldpisize * sizeof pi[0]); + + pip = (struct procinfo *) pi; + if (pip->owner != who) + continue; + } + else + pip = NULL; + + err = (*function) (pids[i], pip); + } + + if (pids != pidbuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pids, npids * sizeof pids[0]); + if (pi != pibuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pi, pisize * sizeof pi[0]); + + return err; +} diff --git a/hurd/hurdrlimit.c b/hurd/hurdrlimit.c new file mode 100644 index 0000000000..2cc33682a5 --- /dev/null +++ b/hurd/hurdrlimit.c @@ -0,0 +1,50 @@ +/* Resource limits. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <cthreads.h> +#include <hurd/resource.h> + +/* This must be given an initializer, or the a.out linking rules will + not include the entire file when this symbol is referenced. */ +struct rlimit _hurd_rlimits[RLIM_NLIMITS] = { { 0, }, }; + +/* This must be initialized data for the same reason as above, but this is + intentionally initialized to a bogus value to emphasize the point that + mutex_init is still required below just in case of unexec. */ +struct mutex _hurd_rlimit_lock = { SPIN_LOCK_INITIALIZER, }; + +static void +init_rlimit (void) +{ + int i; + + __mutex_init (&_hurd_rlimit_lock); + + for (i = 0; i < RLIM_NLIMITS; ++i) + { + if (_hurd_rlimits[i].rlim_max == 0) + _hurd_rlimits[i].rlim_max = RLIM_INFINITY; + if (_hurd_rlimits[i].rlim_cur == 0) + _hurd_rlimits[i].rlim_cur = _hurd_rlimits[i].rlim_max; + } + + (void) &init_rlimit; +} +text_set_element (_hurd_preinit_hook, init_rlimit); diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c new file mode 100644 index 0000000000..2c6f6a17d2 --- /dev/null +++ b/hurd/hurdsig.c @@ -0,0 +1,1080 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <cthreads.h> /* For `struct mutex'. */ +#include <string.h> +#include "hurdfault.h" +#include "hurdmalloc.h" /* XXX */ + +const char *_hurdsig_getenv (const char *); + +struct mutex _hurd_siglock; +int _hurd_stopped; + +/* Port that receives signals and other miscellaneous messages. */ +mach_port_t _hurd_msgport; + +/* Thread listening on it. */ +thread_t _hurd_msgport_thread; + +/* Thread which receives task-global signals. */ +thread_t _hurd_sigthread; + +/* Linked-list of per-thread signal state. */ +struct hurd_sigstate *_hurd_sigstates; + +static void +default_sigaction (struct sigaction actions[NSIG]) +{ + int signo; + + __sigemptyset (&actions[0].sa_mask); + actions[0].sa_flags = SA_RESTART; + actions[0].sa_handler = SIG_DFL; + + for (signo = 1; signo < NSIG; ++signo) + actions[signo] = actions[0]; +} + +struct hurd_sigstate * +_hurd_thread_sigstate (thread_t thread) +{ + struct hurd_sigstate *ss; + __mutex_lock (&_hurd_siglock); + for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) + if (ss->thread == thread) + break; + if (ss == NULL) + { + ss = malloc (sizeof (*ss)); + if (ss == NULL) + __libc_fatal ("hurd: Can't allocate thread sigstate\n"); + ss->thread = thread; + __spin_lock_init (&ss->lock); + + /* Initialze default state. */ + __sigemptyset (&ss->blocked); + __sigemptyset (&ss->pending); + memset (&ss->sigaltstack, 0, sizeof (ss->sigaltstack)); + ss->suspended = 0; +#ifdef noteven + __condition_init (&ss->arrived); +#endif + ss->intr_port = MACH_PORT_NULL; + ss->context = NULL; + + /* Initialize the sigaction vector from the default signal receiving + thread's state, and its from the system defaults. */ + if (thread == _hurd_sigthread) + default_sigaction (ss->actions); + else + { + struct hurd_sigstate *s; + for (s = _hurd_sigstates; s != NULL; s = s->next) + if (s->thread == _hurd_sigthread) + break; + if (s) + { + __spin_lock (&s->lock); + memcpy (ss->actions, s->actions, sizeof (s->actions)); + __spin_unlock (&s->lock); + } + else + default_sigaction (ss->actions); + } + + ss->next = _hurd_sigstates; + _hurd_sigstates = ss; + } + __mutex_unlock (&_hurd_siglock); + return ss; +} + +/* Signal delivery itself is on this page. */ + +#include <hurd/fd.h> +#include <hurd/core.h> +#include <hurd/paths.h> +#include <setjmp.h> +#include <fcntl.h> +#include <sys/wait.h> +#include "thread_state.h" +#include <hurd/msg_server.h> +#include <hurd/msg_reply.h> /* For __msg_sig_post_reply. */ +#include <assert.h> +#include <hurd/interrupt.h> + +int _hurd_core_limit; /* XXX */ + +/* Call the core server to mummify us before we die. + Returns nonzero if a core file was written. */ +static int +write_corefile (int signo, long int sigcode, int sigerror) +{ + error_t err; + mach_port_t coreserver; + file_t file, coredir; + const char *name; + + /* XXX RLIMIT_CORE: + When we have a protocol to make the server return an error + for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE + value in place of the RLIMIT_FSIZE value. */ + + /* First get a port to the core dumping server. */ + coreserver = MACH_PORT_NULL; + name = _hurdsig_getenv ("CORESERVER"); + if (name != NULL) + coreserver = __file_name_lookup (name, 0, 0); + if (coreserver == MACH_PORT_NULL) + coreserver = __file_name_lookup (_SERVERS_CORE, 0, 0); + if (coreserver == MACH_PORT_NULL) + return 0; + + /* Get a port to the directory where the new core file will reside. */ + name = _hurdsig_getenv ("COREFILE"); + if (name == NULL) + name = "core"; + coredir = __file_name_split (name, (char **) &name); + if (coredir == MACH_PORT_NULL) + return 0; + /* Create the new file, but don't link it into the directory yet. */ + if (err = __dir_mkfile (coredir, O_WRONLY|O_CREAT, + 0600 & ~_hurd_umask, /* XXX ? */ + &file)) + return 0; + + /* Call the core dumping server to write the core file. */ + err = __core_dump_task (coreserver, + __mach_task_self (), + file, _hurdsig_getenv ("GNUTARGET"), + signo, sigcode, sigerror); + __mach_port_deallocate (__mach_task_self (), coreserver); + if (! err) + /* The core dump into FILE succeeded, so now link it into the + directory. */ + err = __dir_link (file, coredir, name); + __mach_port_deallocate (__mach_task_self (), file); + __mach_port_deallocate (__mach_task_self (), coredir); + return !err; +} + + +/* Send a sig_post reply message if it hasn't already been sent. */ +static inline void +post_reply (mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, + int untraced, + error_t result) +{ + if (reply_port == NULL || *reply_port == MACH_PORT_NULL) + return; + (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply) + (*reply_port, reply_port_type, result); + *reply_port = MACH_PORT_NULL; +} + + +/* The lowest-numbered thread state flavor value is 1, + so we use bit 0 in machine_thread_all_state.set to + record whether we have done thread_abort. */ +#define THREAD_ABORTED 1 + +/* SS->thread is suspended. Abort the thread and get its basic state. If + REPLY_PORT is not NULL, send a reply on *REPLY_PORT after aborting the + thread. */ +static void +abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state, + mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, + int untraced) +{ + if (!(state->set & THREAD_ABORTED)) + { + __thread_abort (ss->thread); + /* Clear all thread state flavor set bits, because thread_abort may + have changed the state. */ + state->set = THREAD_ABORTED; + } + + if (reply_port) + post_reply (reply_port, reply_port_type, untraced, 0); + + machine_get_basic_state (ss->thread, state); +} + +/* Find the location of the MiG reply port cell in use by the thread whose + state is described by THREAD_STATE. Make sure that this location can be + set without faulting, or else return NULL. */ + +static mach_port_t * +interrupted_reply_port_location (struct machine_thread_all_state *thread_state) +{ + mach_port_t *portloc = (mach_port_t *) __hurd_threadvar_location_from_sp + (_HURD_THREADVAR_MIG_REPLY, (void *) thread_state->basic.SP); + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode == (long int) portloc); + /* Faulted trying to read the stack. */ + return NULL; + } + + /* Fault now if this pointer is bogus. */ + *(volatile mach_port_t *) portloc = *portloc; + + _hurdsig_end_catch_fault (); + + return portloc; +} + + +/* SS->thread is suspended. + + Abort any interruptible RPC operation the thread is doing. + + This uses only the constant member SS->thread and the unlocked, atomically + set member SS->intr_port, so no locking is needed. + + If successfully sent an interrupt_operation and therefore the thread should + wait for its pending RPC to return (possibly EINTR) before taking the + incoming signal, returns the reply port to be received on. Otherwise + returns MACH_PORT_NULL. + + *STATE_CHANGE is set nonzero if STATE->basic was modified and should + be applied back to the thread if it might ever run again, else zero. */ + +static mach_port_t +abort_rpcs (struct hurd_sigstate *ss, int signo, + struct machine_thread_all_state *state, int *state_change, + mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, + int untraced) +{ + mach_port_t msging_port; + mach_port_t intr_port; + + *state_change = 0; + + intr_port = ss->intr_port; + if (intr_port == MACH_PORT_NULL) + /* No interruption needs done. */ + return MACH_PORT_NULL; + + /* Abort the thread's kernel context, so any pending message send or + receive completes immediately or aborts. */ + abort_thread (ss, state, reply_port, reply_port_type, untraced); + + if (_hurdsig_rcv_interrupted_p (state, &msging_port)) + { + error_t err; + + /* The RPC request message was sent and the thread was waiting for + the reply message; now the message receive has been aborted, so + the mach_msg_call will return MACH_RCV_INTERRUPTED. We must tell + the server to interrupt the pending operation. The thread must + wait for the reply message before running the signal handler (to + guarantee that the operation has finished being interrupted), so + our nonzero return tells the trampoline code to finish the message + receive operation before running the handler. */ + + err = __interrupt_operation (intr_port); + + if (err) + { + mach_port_t *reply; + + /* The interrupt didn't work. + Destroy the receive right the thread is blocked on. */ + __mach_port_destroy (__mach_task_self (), msging_port); + + /* The system call return value register now contains + MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the + call. Since we have just destroyed the receive right, the + retry will fail with MACH_RCV_INVALID_NAME. Instead, just + change the return value here to EINTR so mach_msg will not + retry and the EINTR error code will propagate up. */ + state->basic.SYSRETURN = EINTR; + *state_change = 1; + + /* If that was the thread's MiG reply port (which I think should + always be the case), clear the reply port cell so it won't be + reused. */ + reply = interrupted_reply_port_location (state); + if (reply != NULL && *reply == msging_port) + *reply = MACH_PORT_NULL; + } + + /* All threads whose RPCs were interrupted by the interrupt_operation + call above will retry their RPCs unless we clear SS->intr_port. + So we clear it for the thread taking a signal when SA_RESTART is + clear, so that its call returns EINTR. */ + if (!(ss->actions[signo].sa_flags & SA_RESTART)) + ss->intr_port = MACH_PORT_NULL; + + return err ? MACH_PORT_NULL : msging_port; + } + + /* One of the following is true: + + 1. The RPC has not yet been sent. The thread will start its operation + after the signal has been handled. + + 2. The RPC has finished, but not yet cleared SS->intr_port. + The thread will clear SS->intr_port after running the handler. + + 3. The RPC request message was being sent was aborted. The mach_msg + system call will return MACH_SEND_INTERRUPTED, and HURD_EINTR_RPC will + notice the interruption (either retrying the RPC or returning EINTR). */ + + return MACH_PORT_NULL; +} + +/* Abort the RPCs being run by all threads but this one; + all other threads should be suspended. If LIVE is nonzero, those + threads may run again, so they should be adjusted as necessary to be + happy when resumed. STATE is clobbered as a scratch area; its initial + contents are ignored, and its contents on return are not useful. */ + +static void +abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live) +{ + /* We can just loop over the sigstates. Any thread doing something + interruptible must have one. We needn't bother locking because all + other threads are stopped. */ + + struct hurd_sigstate *ss; + size_t nthreads; + mach_port_t *reply_ports; + + /* First loop over the sigstates to count them. + We need to know how big a vector we will need for REPLY_PORTS. */ + nthreads = 0; + for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) + ++nthreads; + + reply_ports = alloca (nthreads * sizeof *reply_ports); + + nthreads = 0; + for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) + if (ss->thread == _hurd_msgport_thread) + reply_ports[nthreads++] = MACH_PORT_NULL; + else + { + int state_changed; + state->set = 0; /* Reset scratch area. */ + + /* Abort any operation in progress with interrupt_operation. + Record the reply port the thread is waiting on. + We will wait for all the replies below. */ + reply_ports[nthreads++] = abort_rpcs (ss, signo, state, &state_changed, + NULL, 0, 0); + if (state_changed && live) + /* Aborting the RPC needed to change this thread's state, + and it might ever run again. So write back its state. */ + __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state->basic, + MACHINE_THREAD_STATE_COUNT); + } + + /* Wait for replies from all the successfully interrupted RPCs. */ + while (nthreads-- > 0) + if (reply_ports[nthreads] != MACH_PORT_NULL) + { + error_t err; + mach_msg_header_t head; + err = __mach_msg (&head, MACH_RCV_MSG, 0, sizeof head, + reply_ports[nthreads], + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (err != MACH_RCV_TOO_LARGE) + assert_perror (err); + } +} + + +struct hurd_signal_preempt *_hurd_signal_preempt[NSIG]; +struct mutex _hurd_signal_preempt_lock; + +/* Mask of stop signals. */ +#define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \ + sigmask (SIGSTOP) | sigmask (SIGTSTP)) + +/* Deliver a signal. SS is not locked. */ +void +_hurd_internal_post_signal (struct hurd_sigstate *ss, + int signo, long int sigcode, int sigerror, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + int untraced) +{ + struct machine_thread_all_state thread_state; + enum { stop, ignore, core, term, handle } act; + sighandler_t handler; + struct hurd_signal_preempt *pe; + sighandler_t (*preempt) (thread_t, int, long int, int) = NULL; + sigset_t pending; + int ss_suspended; + + /* Reply to this sig_post message. */ + inline void reply (void) + { + post_reply (&reply_port, reply_port_type, untraced, 0); + } + + /* Mark the signal as pending. */ + void mark_pending (void) + { + __sigaddset (&ss->pending, signo); + /* Save the code to be given to the handler when SIGNO is + unblocked. */ + ss->pending_data[signo].code = sigcode; + ss->pending_data[signo].error = sigerror; + } + + /* Suspend the process with SIGNO. */ + void suspend (void) + { + /* Stop all other threads and mark ourselves stopped. */ + __USEPORT (PROC, + ({ + /* Hold the siglock while stopping other threads to be + sure it is not held by another thread afterwards. */ + __mutex_lock (&_hurd_siglock); + __proc_dostop (port, _hurd_msgport_thread); + __mutex_unlock (&_hurd_siglock); + abort_all_rpcs (signo, &thread_state, 1); + __proc_mark_stop (port, signo); + })); + _hurd_stopped = 1; + } + + post_signal: + + thread_state.set = 0; /* We know nothing. */ + + /* Check for a preempted signal. Preempted signals + can arrive during critical sections. */ + __mutex_lock (&_hurd_signal_preempt_lock); + for (pe = _hurd_signal_preempt[signo]; pe != NULL; pe = pe->next) + if (sigcode >= pe->first && sigcode <= pe->last) + { + preempt = pe->handler; + break; + } + __mutex_unlock (&_hurd_signal_preempt_lock); + + handler = SIG_DFL; + if (preempt) + /* Let the preempting handler examine the thread. + If it returns SIG_DFL, we run the normal handler; + otherwise we use the handler it returns. */ + handler = (*preempt) (ss->thread, signo, sigcode, sigerror); + + ss_suspended = 0; + + if (handler != SIG_DFL) + /* Run the preemption-provided handler. */ + act = handle; + else + { + /* No preemption. Do normal handling. */ + + __spin_lock (&ss->lock); + + handler = ss->actions[signo].sa_handler; + + if (!untraced && (_hurd_exec_flags & EXEC_TRACED)) + { + /* We are being traced. Stop to tell the debugger of the signal. */ + if (_hurd_stopped) + /* Already stopped. Mark the signal as pending; + when resumed, we will notice it and stop again. */ + mark_pending (); + else + suspend (); + __spin_unlock (&ss->lock); + reply (); + return; + } + + if (handler == SIG_DFL) + /* Figure out the default action for this signal. */ + switch (signo) + { + case 0: + /* A sig_post msg with SIGNO==0 is sent to + tell us to check for pending signals. */ + act = ignore; + break; + + case SIGTTIN: + case SIGTTOU: + case SIGSTOP: + case SIGTSTP: + act = stop; + break; + + case SIGCONT: + case SIGIO: + case SIGURG: + case SIGCHLD: + case SIGWINCH: + act = ignore; + break; + + case SIGQUIT: + case SIGILL: + case SIGTRAP: + case SIGIOT: + case SIGEMT: + case SIGFPE: + case SIGBUS: + case SIGSEGV: + case SIGSYS: + act = core; + break; + + case SIGINFO: + if (_hurd_pgrp == _hurd_pid) + { + /* We are the process group leader. Since there is no + user-specified handler for SIGINFO, we use a default one + which prints something interesting. We use the normal + handler mechanism instead of just doing it here to avoid + the signal thread faulting or blocking in this + potentially hairy operation. */ + act = handle; + handler = _hurd_siginfo_handler; + } + else + act = ignore; + break; + + default: + act = term; + break; + } + else if (handler == SIG_IGN) + act = ignore; + else + act = handle; + + if (__sigmask (signo) & STOPSIGS) + /* Stop signals clear a pending SIGCONT even if they + are handled or ignored (but not if preempted). */ + ss->pending &= ~sigmask (SIGCONT); + else + { + if (signo == SIGCONT) + /* Even if handled or ignored (but not preempted), SIGCONT clears + stop signals and resumes the process. */ + ss->pending &= ~STOPSIGS; + + if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT)) + { + /* Resume the process from being stopped. */ + thread_t *threads; + mach_msg_type_number_t nthreads, i; + error_t err; + /* Tell the proc server we are continuing. */ + __USEPORT (PROC, __proc_mark_cont (port)); + /* Fetch ports to all our threads and resume them. */ + err = __task_threads (__mach_task_self (), &threads, &nthreads); + assert_perror (err); + for (i = 0; i < nthreads; ++i) + { + if (threads[i] != _hurd_msgport_thread && + (act != handle || threads[i] != ss->thread)) + __thread_resume (threads[i]); + __mach_port_deallocate (__mach_task_self (), threads[i]); + } + __vm_deallocate (__mach_task_self (), + (vm_address_t) threads, + nthreads * sizeof *threads); + _hurd_stopped = 0; + /* The thread that will run the handler is already suspended. */ + ss_suspended = 1; + } + } + } + + if (_hurd_orphaned && act == stop && + (__sigmask (signo) & (__sigmask (SIGTTIN) | __sigmask (SIGTTOU) | + __sigmask (SIGTSTP)))) + { + /* If we would ordinarily stop for a job control signal, but we are + orphaned so noone would ever notice and continue us again, we just + quietly die, alone and in the dark. */ + sigcode = signo; + signo = SIGKILL; + act = term; + } + + /* Handle receipt of a blocked signal, or any signal while stopped. + It matters that we test ACT first here, because we must never pass + SIGNO==0 to __sigismember. */ + if ((act != ignore && __sigismember (&ss->blocked, signo)) || + (signo != SIGKILL && _hurd_stopped)) + { + mark_pending (); + act = ignore; + } + + /* Perform the chosen action for the signal. */ + switch (act) + { + case stop: + if (_hurd_stopped) + /* We are already stopped, but receiving an untraced stop + signal. Instead of resuming and suspending again, just + notify the proc server of the new stop signal. */ + __USEPORT (PROC, __proc_mark_stop (port, signo)); + else + /* Suspend the process. */ + suspend (); + break; + + case ignore: + /* Nobody cares about this signal. */ + break; + + case term: /* Time to die. */ + case core: /* And leave a rotting corpse. */ + nirvana: + /* Have the proc server stop all other threads in our task. */ + __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread)); + /* No more user instructions will be executed. + The signal can now be considered delivered. */ + reply (); + /* Abort all server operations now in progress. */ + abort_all_rpcs (signo, &thread_state, 0); + + { + int status = W_EXITCODE (0, signo); + /* Do a core dump if desired. Only set the wait status bit saying we + in fact dumped core if the operation was actually successful. */ + if (act == core && write_corefile (signo, sigcode, sigerror)) + status |= WCOREFLAG; + /* Tell proc how we died and then stick the saber in the gut. */ + _hurd_exit (status); + /* NOTREACHED */ + } + + case handle: + /* Call a handler for this signal. */ + { + struct sigcontext *scp; + int wait_for_reply, state_changed; + + /* Stop the thread and abort its pending RPC operations. */ + if (! ss_suspended) + __thread_suspend (ss->thread); + + /* Abort the thread's kernel context, so any pending message send + or receive completes immediately or aborts. If an interruptible + RPC is in progress, abort_rpcs will do this. But we must always + do it before fetching the thread's state, because + thread_get_state is never kosher before thread_abort. */ + abort_thread (ss, &thread_state, NULL, 0, 0); + + wait_for_reply = (abort_rpcs (ss, signo, &thread_state, &state_changed, + &reply_port, reply_port_type, untraced) + != MACH_PORT_NULL); + + if (ss->critical_section) + { + /* The thread is in a critical section. Mark the signal as + pending. When it finishes the critical section, it will + check for pending signals. */ + mark_pending (); + assert (! state_changed); + __thread_resume (ss->thread); + break; + } + + /* Call the machine-dependent function to set the thread up + to run the signal handler, and preserve its old context. */ + scp = _hurd_setup_sighandler (ss, handler, + signo, sigcode, + wait_for_reply, &thread_state); + if (scp == NULL) + { + /* We got a fault setting up the stack frame for the handler. + Nothing to do but die; BSD gets SIGILL in this case. */ + sigcode = signo; /* XXX ? */ + signo = SIGILL; + act = core; + goto nirvana; + } + + /* Set the machine-independent parts of the signal context. */ + + scp->sc_error = sigerror; + { + /* Fetch the thread variable for the MiG reply port, + and set it to MACH_PORT_NULL. */ + mach_port_t *loc = interrupted_reply_port_location (&thread_state); + if (loc) + { + scp->sc_reply_port = *loc; + *loc = MACH_PORT_NULL; + } + else + scp->sc_reply_port = MACH_PORT_NULL; + } + + /* Block SIGNO and requested signals while running the handler. */ + scp->sc_mask = ss->blocked; + ss->blocked |= __sigmask (signo) | ss->actions[signo].sa_mask; + + /* Save the intr_port in use by the interrupted code, + and clear the cell before running the trampoline. */ + scp->sc_intr_port = ss->intr_port; + ss->intr_port = MACH_PORT_NULL; + + /* Start the thread running the handler (or possibly waiting for an + RPC reply before running the handler). */ + __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &thread_state.basic, + MACHINE_THREAD_STATE_COUNT); + __thread_resume (ss->thread); + thread_state.set = 0; /* Everything we know is now wrong. */ + break; + } + } + + /* The signal has either been ignored or is now being handled. We can + consider it delivered and reply to the killer. The exception is + signal 0, which can be sent by a user thread to make us check for + pending signals. In that case we want to deliver the pending signals + before replying. */ + if (signo != 0) + reply (); + + /* We get here unless the signal was fatal. We still hold SS->lock. + Check for pending signals, and loop to post them. */ +#define PENDING (!_hurd_stopped && (pending = ss->pending & ~ss->blocked)) + if (PENDING) + { + pending: + for (signo = 1; signo < NSIG; ++signo) + if (__sigismember (&pending, signo)) + { + __sigdelset (&ss->pending, signo); + sigcode = ss->pending_data[signo].code; + sigerror = ss->pending_data[signo].error; + __spin_unlock (&ss->lock); + goto post_signal; + } + } + + /* No pending signals left undelivered for this thread. + If we were sent signal 0, we need to check for pending + signals for all threads. */ + if (signo == 0) + { + __spin_unlock (&ss->lock); + __mutex_lock (&_hurd_siglock); + for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) + { + __spin_lock (&ss->lock); + if (PENDING) + goto pending; + __spin_unlock (&ss->lock); + } + __mutex_unlock (&_hurd_siglock); + } + else + { + /* No more signals pending; SS->lock is still locked. + Wake up any sigsuspend call that is blocking SS->thread. */ + if (ss->suspended != MACH_PORT_NULL) + { + /* There is a sigsuspend waiting. Tell it to wake up. */ + error_t err; + mach_msg_header_t msg; + err = __mach_port_insert_right (__mach_task_self (), + ss->suspended, ss->suspended, + MACH_MSG_TYPE_MAKE_SEND); + assert_perror (err); + msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MOVE_SEND, 0); + msg.msgh_remote_port = ss->suspended; + msg.msgh_local_port = MACH_PORT_NULL; + /* These values do not matter. */ + msg.msgh_id = 8675309; /* Jenny, Jenny. */ + msg.msgh_seqno = 17; /* Random. */ + ss->suspended = MACH_PORT_NULL; + err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0, + MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); + assert_perror (err); + } + __spin_unlock (&ss->lock); + } + + /* All pending signals delivered to all threads. + Now we can send the reply message even for signal 0. */ + reply (); +} + +/* Decide whether REFPORT enables the sender to send us a SIGNO signal. + Returns zero if so, otherwise the error code to return to the sender. */ + +static error_t +signal_allowed (int signo, mach_port_t refport) +{ + if (signo < 0 || signo >= NSIG) + return EINVAL; + + if (refport == __mach_task_self ()) + /* Can send any signal. */ + goto win; + + /* Avoid needing to check for this below. */ + if (refport == MACH_PORT_NULL) + return EPERM; + + switch (signo) + { + case SIGINT: + case SIGQUIT: + case SIGTSTP: + case SIGHUP: + case SIGINFO: + case SIGTTIN: + case SIGTTOU: + /* Job control signals can be sent by the controlling terminal. */ + if (__USEPORT (CTTYID, port == refport)) + goto win; + break; + + case SIGCONT: + { + /* A continue signal can be sent by anyone in the session. */ + mach_port_t sessport; + if (! __USEPORT (PROC, __proc_getsidport (port, &sessport))) + { + __mach_port_deallocate (__mach_task_self (), sessport); + if (refport == sessport) + goto win; + } + } + break; + + case SIGIO: + case SIGURG: + { + /* Any io object a file descriptor refers to might send us + one of these signals using its async ID port for REFPORT. + + This is pretty wide open; it is not unlikely that some random + process can at least open for reading something we have open, + get its async ID port, and send us a spurious SIGIO or SIGURG + signal. But BSD is actually wider open than that!--you can set + the owner of an io object to any process or process group + whatsoever and send them gratuitous signals. + + Someday we could implement some reasonable scheme for + authorizing SIGIO and SIGURG signals properly. */ + + int d; + __mutex_lock (&_hurd_dtable_lock); + for (d = 0; (unsigned int) d < (unsigned int) _hurd_dtablesize; ++d) + { + struct hurd_userlink ulink; + io_t port; + mach_port_t asyncid; + if (_hurd_dtable[d] == NULL) + continue; + port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink); + if (! __io_get_icky_async_id (port, &asyncid)) + { + if (refport == asyncid) + /* Break out of the loop on the next iteration. */ + d = -1; + __mach_port_deallocate (__mach_task_self (), asyncid); + } + _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port); + } + /* If we found a lucky winner, we've set D to -1 in the loop. */ + if (d < 0) + goto win; + } + } + + /* If this signal is legit, we have done `goto win' by now. + When we return the error, mig deallocates REFPORT. */ + return EPERM; + + win: + /* Deallocate the REFPORT send right; we are done with it. */ + __mach_port_deallocate (__mach_task_self (), refport); + + return 0; +} + +/* Implement the sig_post RPC from <hurd/msg.defs>; + sent when someone wants us to get a signal. */ +kern_return_t +_S_msg_sig_post (mach_port_t me, + mach_port_t reply_port, mach_msg_type_name_t reply_port_type, + int signo, + mach_port_t refport) +{ + error_t err; + + if (err = signal_allowed (signo, refport)) + return err; + + /* Post the signal to the designated signal-receiving thread. This will + reply when the signal can be considered delivered. */ + _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), + signo, 0, 0, reply_port, reply_port_type, + 0); /* Stop if traced. */ + + return MIG_NO_REPLY; /* Already replied. */ +} + +/* Implement the sig_post_untraced RPC from <hurd/msg.defs>; + sent when the debugger wants us to really get a signal + even if we are traced. */ +kern_return_t +_S_msg_sig_post_untraced (mach_port_t me, + mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, + int signo, + mach_port_t refport) +{ + error_t err; + + if (err = signal_allowed (signo, refport)) + return err; + + /* Post the signal to the designated signal-receiving thread. This will + reply when the signal can be considered delivered. */ + _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), + signo, 0, 0, reply_port, reply_port_type, + 1); /* Untraced flag. */ + + return MIG_NO_REPLY; /* Already replied. */ +} + +extern void __mig_init (void *); + +#include <mach/task_special_ports.h> + +/* Initialize the message port and _hurd_sigthread and start the signal + thread. */ + +void +_hurdsig_init (void) +{ + error_t err; + vm_size_t stacksize; + + __mutex_init (&_hurd_siglock); + + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, + &_hurd_msgport)) + __libc_fatal ("hurd: Can't create message port receive right\n"); + + /* Make a send right to the signal port. */ + if (err = __mach_port_insert_right (__mach_task_self (), + _hurd_msgport, + _hurd_msgport, + MACH_MSG_TYPE_MAKE_SEND)) + __libc_fatal ("hurd: Can't create send right to message port\n"); + + /* Set the default thread to receive task-global signals + to this one, the main (first) user thread. */ + _hurd_sigthread = __mach_thread_self (); + + /* Start the signal thread listening on the message port. */ + + if (err = __thread_create (__mach_task_self (), &_hurd_msgport_thread)) + __libc_fatal ("hurd: Can't create signal thread\n"); + + stacksize = __vm_page_size * 4; /* Small stack for signal thread. */ + if (err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread, + _hurd_msgport_receive, + (vm_address_t *) &__hurd_sigthread_stack_base, + &stacksize)) + __libc_fatal ("hurd: Can't setup signal thread\n"); + + __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize; + __hurd_sigthread_variables = + malloc (__hurd_threadvar_max * sizeof (unsigned long int)); + if (__hurd_sigthread_variables == NULL) + __libc_fatal ("hurd: Can't allocate thread variables for signal thread\n"); + + /* Reinitialize the MiG support routines so they will use a per-thread + variable for the cached reply port. */ + __mig_init ((void *) __hurd_sigthread_stack_base); + + if (err = __thread_resume (_hurd_msgport_thread)) + __libc_fatal ("hurd: Can't resume signal thread\n"); + +#if 0 /* Don't confuse poor gdb. */ + /* Receive exceptions on the signal port. */ + __task_set_special_port (__mach_task_self (), + TASK_EXCEPTION_PORT, _hurd_msgport); +#endif +} + /* XXXX */ +/* Reauthenticate with the proc server. */ + +static void +reauth_proc (mach_port_t new) +{ + mach_port_t ref, ignore; + + ref = __mach_reply_port (); + if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC], + __proc_reauthenticate (port, ref, + MACH_MSG_TYPE_MAKE_SEND) || + __auth_user_authenticate (new, port, ref, + MACH_MSG_TYPE_MAKE_SEND, + &ignore)) + && ignore != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), ignore); + __mach_port_destroy (__mach_task_self (), ref); + + (void) &reauth_proc; /* Silence compiler warning. */ +} +text_set_element (_hurd_reauth_hook, reauth_proc); + +/* Like `getenv', but safe for the signal thread to run. + If the environment is trashed, this will just return NULL. */ + +const char * +_hurdsig_getenv (const char *variable) +{ + if (_hurdsig_catch_fault (SIGSEGV)) + /* We bombed in getenv. */ + return NULL; + else + { + const char *value = getenv (variable); + /* Fault now if VALUE is a bogus string. */ + (void) strlen (value); + _hurdsig_end_catch_fault (); + return value; + } +} diff --git a/hurd/hurdsock.c b/hurd/hurdsock.c new file mode 100644 index 0000000000..266fd40d31 --- /dev/null +++ b/hurd/hurdsock.c @@ -0,0 +1,115 @@ +/* _hurd_socket_server - Find the server for a socket domain. + +Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <sys/socket.h> +#include <stdlib.h> +#include <string.h> +#include <hurd/paths.h> +#include <stdio.h> +#include "stdio/_itoa.h" +#include <cthreads.h> /* For `struct mutex'. */ +#include "hurdmalloc.h" /* XXX */ + +static struct mutex lock; + +static file_t *servers; +static int max_domain; + +/* Return a port to the socket server for DOMAIN. + Socket servers translate nodes in the directory _SERVERS_SOCKET + (canonically /servers/socket). These naming point nodes are named + by the simplest decimal representation of the socket domain number, + for example "/servers/socket/3". + + Socket servers are assumed not to change very often. + The library keeps all the server socket ports it has ever looked up, + and does not look them up in /servers/socket more than once. */ + +socket_t +_hurd_socket_server (int domain, int dead) +{ + socket_t server; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&lock); + + if (domain > max_domain) + { + error_t save = errno; + file_t *new = realloc (servers, (domain + 1) * sizeof (file_t)); + if (new != NULL) + { + while (max_domain <= domain) + new[max_domain++] = MACH_PORT_NULL; + servers = new; + } + else + /* No space to cache the port; we will just fetch it anew below. */ + errno = save; + } + + if (dead && domain <= max_domain) + { + /* The user says the port we returned earlier (now in SERVERS[DOMAIN]) + was dead. Clear the cache and fetch a new one below. */ + __mach_port_deallocate (__mach_task_self (), servers[domain]); + servers[domain] = MACH_PORT_NULL; + } + + if (domain > max_domain || servers[domain] == MACH_PORT_NULL) + { + char name[sizeof (_SERVERS_SOCKET) + 100]; + char *np = &name[sizeof (name)]; + *--np = '\0'; + np = _itoa (domain, np, 10, 0); + *--np = '/'; + np -= sizeof (_SERVERS_SOCKET) - 1; + memcpy (np, _SERVERS_SOCKET, sizeof (_SERVERS_SOCKET) - 1); + server = __file_name_lookup (np, 0, 0); + if (domain <= max_domain) + servers[domain] = server; + } + else + server = servers[domain]; + + if (server == MACH_PORT_NULL && errno == ENOENT) + /* If the server node is absent, we don't support that protocol. */ + errno = EPFNOSUPPORT; + + __mutex_unlock (&lock); + HURD_CRITICAL_END; + + return server; +} + +static void +init (void) +{ + size_t i; + + __mutex_init (&lock); + + for (i = 0; i < max_domain; ++i) + servers[i] = MACH_PORT_NULL; + + (void) &init; /* Avoid "defined but not used" warning. */ +} +text_set_element (_hurd_preinit_hook, init); diff --git a/hurd/intern-fd.c b/hurd/intern-fd.c new file mode 100644 index 0000000000..fe7424b9bc --- /dev/null +++ b/hurd/intern-fd.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fd.h> + +/* Allocate a new file descriptor and install PORT in it. FLAGS are as for + `open'; only O_IGNORE_CTTY is meaningful. + + If the descriptor table is full, set errno, and return -1. + If DEALLOC is nonzero, deallocate PORT first. */ +int +_hurd_intern_fd (io_t port, int flags, int dealloc) +{ + int fd; + struct hurd_fd *d; + + HURD_CRITICAL_BEGIN; + d = _hurd_alloc_fd (&fd, 0); + if (d != NULL) + { + _hurd_port2fd (d, port, flags); + __spin_unlock (&d->port.lock); + } + HURD_CRITICAL_END; + + if (d == NULL) + { + if (dealloc) + __mach_port_deallocate (__mach_task_self (), port); + return -1; + } + + return fd; +} diff --git a/hurd/intr-rpc.awk b/hurd/intr-rpc.awk new file mode 100644 index 0000000000..9dbcd6f8e2 --- /dev/null +++ b/hurd/intr-rpc.awk @@ -0,0 +1,45 @@ +# Icky intimate knowledge of MiG output. + +BEGIN \ + { + nprotolines=0; proto=0; + args=""; echo=1; isintr=0; + intrcall = "__hurd_intr_rpc_" call; + print "#include <hurd/signal.h>"; + } + +$NF == intrcall { isintr=1; } + +NF == 1 && $1 == ")" { proto=0; } +proto \ + { + protolines[nprotolines++] = $0; + arg = $NF; + if (substr(arg, 1, 1) == "*") + arg = substr(arg, 2, length(arg)-1); + args = args arg; + } +NF == 1 && $1 == "(" { proto=1; } + +NF == 3 && $1 == "InP->Head.msgh_request_port" \ + { portarg = substr($3, 1, length($3)-1); } + +{ print $0; } + +END \ + { + if (isintr) + { + print "\n\n/* User-callable interrupt-handling stub. */"; + print "kern_return_t __" call; + print "("; + for (i = 0; i < nprotolines; ++i) + print protolines[i]; + print ")"; + print "{"; + print " return HURD_EINTR_RPC (" portarg ", " \ + intrcall "(" args "));"; + print "}"; + } + print "weak_alias (__" call ", " call ")" + } diff --git a/hurd/intr-rpc.defs b/hurd/intr-rpc.defs new file mode 100644 index 0000000000..a2e7b060c9 --- /dev/null +++ b/hurd/intr-rpc.defs @@ -0,0 +1,27 @@ +/* Special MiG definitions for interruptible RPC stubs. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Set the MiG options for an interruptible RPC interface. + We rename each MiG-generated function to hurd_intr_rpc_CALL and + give it the option to return on an interrupted message send. */ + +#define INTR_INTERFACE \ +msgoption MACH_SEND_INTERRUPT;\ +userprefix hurd_intr_rpc_; + diff --git a/hurd/invoke-trans.c b/hurd/invoke-trans.c new file mode 100644 index 0000000000..e11bff5dc3 --- /dev/null +++ b/hurd/invoke-trans.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fs.h> + +error_t +__hurd_invoke_translator (file_t file, int flags, file_t *newport) +{ + error_t err; + enum retry_type doretry; + char retryname[1024]; /* XXX string_t LOSES! */ + + err = __file_invoke_translator (file, flags, &doretry, retryname, newport); + + if (! err) + err = __USEPORT (CRDIR, __hurd_file_name_lookup_retry (port, + doretry, retryname, + flags, 0, newport)); + + return err; +} diff --git a/hurd/msgportdemux.c b/hurd/msgportdemux.c new file mode 100644 index 0000000000..ae783ef270 --- /dev/null +++ b/hurd/msgportdemux.c @@ -0,0 +1,66 @@ +/* Demux messages sent on the signal port. + +Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <stddef.h> + +struct demux + { + struct demux *next; + boolean_t (*demux) (mach_msg_header_t *inp, + mach_msg_header_t *outp); + }; + +struct demux *_hurd_msgport_demuxers = NULL; + +extern boolean_t __msg_server (mach_msg_header_t *inp, + mach_msg_header_t *outp); + +static boolean_t +msgport_server (mach_msg_header_t *inp, + mach_msg_header_t *outp) +{ + extern boolean_t _S_msg_server (mach_msg_header_t *inp, + mach_msg_header_t *outp); + extern boolean_t _S_exc_server (mach_msg_header_t *inp, + mach_msg_header_t *outp); + struct demux *d; + + for (d = _hurd_msgport_demuxers; d != NULL; d = d->next) + if ((*d->demux) (inp, outp)) + return 1; + + return (_S_exc_server (inp, outp) || + _S_msg_server (inp, outp)); +} + +/* This is the code that the signal thread runs. */ +void +_hurd_msgport_receive (void) +{ + /* Get our own sigstate cached so we never again have to take a lock to + fetch it. There is much code in hurdsig.c that operates with some + sigstate lock held, which will deadlock with _hurd_thread_sigstate. */ + (void) _hurd_self_sigstate (); + + while (1) + (void) __mach_msg_server (msgport_server, __vm_page_size, _hurd_msgport); +} diff --git a/hurd/msgstub.c b/hurd/msgstub.c new file mode 100644 index 0000000000..d4b59ed635 --- /dev/null +++ b/hurd/msgstub.c @@ -0,0 +1,26 @@ +#include <hurd.h> + +/* XXX */ +#define STUB(fn) error_t fn (mach_port_t port) { return EOPNOTSUPP; } + +STUB(_S_get_init_ports) +STUB(_S_set_init_ports) +STUB(_S_get_init_port) +STUB(_S_set_init_port) +STUB(_S_get_init_ints) +STUB(_S_set_init_ints) +STUB(_S_get_init_int) +STUB(_S_set_init_int) +STUB(_S_get_dtable) +STUB(_S_set_dtable) +STUB(_S_get_fd) +STUB(_S_set_fd) +STUB(_S_get_environment) +STUB(_S_set_environment) +STUB(_S_get_env_variable) +STUB(_S_set_env_variable) +STUB(_S_io_select_done) +STUB(_S_startup_dosync) + +STUB(_S_dir_changed) +STUB(_S_file_changed) diff --git a/hurd/new-fd.c b/hurd/new-fd.c new file mode 100644 index 0000000000..de9a3933f4 --- /dev/null +++ b/hurd/new-fd.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/fd.h> +#include <stdlib.h> +#include "hurdmalloc.h" /* XXX */ + +/* Allocate a new file descriptor structure + and initialize it with PORT and CTTY. */ + +struct hurd_fd * +_hurd_new_fd (io_t port, io_t ctty) +{ + struct hurd_fd *d = malloc (sizeof (struct hurd_fd)); + + if (d != NULL) + { + /* Initialize the port cells. */ + _hurd_port_init (&d->port, port); + _hurd_port_init (&d->ctty, ctty); + } + + return d; +} diff --git a/hurd/openport.c b/hurd/openport.c new file mode 100644 index 0000000000..244368acaa --- /dev/null +++ b/hurd/openport.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fd.h> + +/* User entry point for interning a port as a new FD. + Just like _hurd_intern_fd, but don't dealloc PORT on error. */ + +int +openport (io_t port, int flags) +{ + return _hurd_intern_fd (port, flags, 0); +} diff --git a/hurd/pid2task.c b/hurd/pid2task.c new file mode 100644 index 0000000000..6b8182bd02 --- /dev/null +++ b/hurd/pid2task.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +task_t +__pid2task (pid_t pid) +{ + error_t err; + task_t task; + + err = __USEPORT (PROC, __proc_pid2task (port, pid, &task)); + + return err ? (__hurd_fail (err), MACH_PORT_NULL) : task; +} + +weak_alias (__pid2task, pid2task) diff --git a/hurd/port2fd.c b/hurd/port2fd.c new file mode 100644 index 0000000000..cad89e770f --- /dev/null +++ b/hurd/port2fd.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/signal.h> +#include <hurd/term.h> +#include <fcntl.h> + +/* Store PORT in file descriptor D, doing appropriate ctty magic. + FLAGS are as for `open'; only O_IGNORE_CTTY is meaningful. + D should be locked, and will not be unlocked. */ + +void +_hurd_port2fd (struct hurd_fd *d, io_t port, int flags) +{ + io_t ctty; + mach_port_t cttyid; + int is_ctty = !(flags & O_IGNORE_CTTY) && ! __term_getctty (port, &cttyid); + + if (is_ctty) + { + /* This port is capable of being a controlling tty. + Is it ours? */ + struct hurd_port *const id = &_hurd_ports[INIT_PORT_CTTYID]; + __spin_lock (&id->lock); + if (id->port == MACH_PORT_NULL) + /* We have no controlling tty, so make this one it. */ + _hurd_port_locked_set (id, cttyid); + else + { + if (cttyid != id->port) + /* We have a controlling tty and this is not it. */ + is_ctty = 0; + /* Either we don't want CTTYID, or ID->port already is it. + So we don't need to change ID->port, and we can release + the reference to CTTYID. */ + __spin_unlock (&id->lock); + __mach_port_deallocate (__mach_task_self (), cttyid); + } + } + + if (!is_ctty || __term_open_ctty (port, _hurd_pid, _hurd_pgrp, &ctty) != 0) + /* XXX if IS_CTTY, then this port is our ctty, but we are + not doing ctty style i/o because term_become_ctty barfed. + What to do? */ + /* No ctty magic happening here. */ + ctty = MACH_PORT_NULL; + + /* Install PORT in the descriptor cell, leaving it locked. */ + { + mach_port_t old + = _hurd_userlink_clear (&d->port.users) ? d->port.port : MACH_PORT_NULL; + d->port.port = port; + if (old != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), old); + } + + _hurd_port_set (&d->ctty, ctty); +} diff --git a/hurd/ports-get.c b/hurd/ports-get.c new file mode 100644 index 0000000000..def59731c5 --- /dev/null +++ b/hurd/ports-get.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +static error_t +getbootstrap (mach_port_t *result) +{ + return __task_get_special_port (__mach_task_self (), + TASK_BOOTSTRAP_PORT, + result); +} + +error_t (*_hurd_ports_getters[INIT_PORT_MAX]) (mach_port_t *result) = + { + [INIT_PORT_BOOTSTRAP] = getbootstrap, + }; + +error_t +_hurd_ports_get (int which, mach_port_t *result) +{ + if (which < 0 || which >= _hurd_nports) + return EINVAL; + if (which >= INIT_PORT_MAX || _hurd_ports_getters[which] == NULL) + return HURD_PORT_USE (&_hurd_ports[which], + __mach_port_mod_refs (__mach_task_self (), + (*result = port), + MACH_PORT_RIGHT_SEND, + +1)); + return (*_hurd_ports_getters[which]) (result); +} diff --git a/hurd/ports-set.c b/hurd/ports-set.c new file mode 100644 index 0000000000..fbc2940217 --- /dev/null +++ b/hurd/ports-set.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +static error_t +setbootstrap (mach_port_t newport) +{ + return __task_set_special_port (__mach_task_self (), + TASK_BOOTSTRAP_PORT, + newport); +} + +extern error_t _hurd_setauth (auth_t); +extern error_t _hurd_setproc (process_t); +extern error_t _hurd_setcttyid (mach_port_t); + +error_t (*_hurd_ports_setters[INIT_PORT_MAX]) (mach_port_t newport) = + { + [INIT_PORT_BOOTSTRAP] = setbootstrap, + [INIT_PORT_AUTH] = _hurd_setauth, + [INIT_PORT_PROC] = _hurd_setproc, + [INIT_PORT_CTTYID] = _hurd_setcttyid, + }; + + +error_t +_hurd_ports_set (int which, mach_port_t newport) +{ + error_t err; + if (which < 0 || which >= _hurd_nports) + return EINVAL; + if (err = __mach_port_mod_refs (__mach_task_self (), newport, + MACH_PORT_RIGHT_SEND, 1)) + return err; + if (which >= INIT_PORT_MAX || _hurd_ports_setters[which] == NULL) + { + _hurd_port_set (&_hurd_ports[which], newport); + return 0; + } + return (*_hurd_ports_setters[which]) (newport); +} diff --git a/hurd/preempt-sig.c b/hurd/preempt-sig.c new file mode 100644 index 0000000000..86761967cc --- /dev/null +++ b/hurd/preempt-sig.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> + +/* Initialize PREEMPTER with the information given and stick it in the + chain of preempters for SIGNO. */ + +int +hurd_preempt_signals (struct hurd_signal_preempt *preempter, + int signo, int first_code, int last_code, + sighandler_t (*handler) (thread_t, int, long int, int)) +{ + if (signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + preempter->first = first_code; + preempter->last = last_code; + preempter->handler = handler; + __mutex_lock (&_hurd_signal_preempt_lock); + preempter->next = _hurd_signal_preempt[signo]; + _hurd_signal_preempt[signo] = preempter; + __mutex_unlock (&_hurd_signal_preempt_lock); + return 0; +} + +/* Remove PREEMPTER from the chain for SIGNO. */ + +int +hurd_unpreempt_signals (struct hurd_signal_preempt *preempter, int signo) +{ + struct hurd_signal_preempt *p, *lastp; + if (signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + __mutex_lock (&_hurd_signal_preempt_lock); + for (p = _hurd_signal_preempt[signo], lastp = NULL; + p != NULL; lastp = p, p = p->next) + if (p == preempter) + { + (lastp == NULL ? _hurd_signal_preempt[signo] : lastp->next) = p->next; + __mutex_unlock (&_hurd_signal_preempt_lock); + return 0; + } + _hurd_signal_preempt[signo] = preempter; + __mutex_unlock (&_hurd_signal_preempt_lock); + errno = ENOENT; + return -1; +} diff --git a/hurd/privports.c b/hurd/privports.c new file mode 100644 index 0000000000..f760e37e6e --- /dev/null +++ b/hurd/privports.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +/* The program might set these if it is the initial task + bootstrapped by the microkernel. */ + +mach_port_t _hurd_host_priv, _hurd_device_master; + + +kern_return_t +get_privileged_ports (host_priv_t *host_priv_ptr, device_t *device_master_ptr) +{ + if (! _hurd_host_priv) + { + error_t err; + + if (_hurd_ports) + /* We have gotten some initial ports, so perhaps + we have a proc server to talk to. */ + err = __USEPORT (PROC, __proc_getprivports (port, + &_hurd_host_priv, + &_hurd_device_master)); + else + return MACH_SEND_INVALID_DEST; + + if (err) + return err; + } + + if (host_priv_ptr) + { + mach_port_mod_refs (mach_task_self (), + _hurd_host_priv, MACH_PORT_RIGHT_SEND, 1); + *host_priv_ptr = _hurd_host_priv; + } + if (device_master_ptr) + { + mach_port_mod_refs (mach_task_self (), + _hurd_device_master, MACH_PORT_RIGHT_SEND, 1); + *device_master_ptr = _hurd_device_master; + } + return KERN_SUCCESS; +} diff --git a/hurd/setauth.c b/hurd/setauth.c new file mode 100644 index 0000000000..7378e4f070 --- /dev/null +++ b/hurd/setauth.c @@ -0,0 +1,124 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/port.h> +#include <hurd/id.h> +#include "set-hooks.h" + +/* Things in the library which want to be run when the auth port changes. */ +DEFINE_HOOK (_hurd_reauth_hook, (auth_t new_auth)); + +#include <cthreads.h> +static struct mutex reauth_lock = MUTEX_INITIALIZER; + + +/* Set the auth port to NEW, and reauthenticate + everything used by the library. */ +error_t +_hurd_setauth (auth_t new) +{ + error_t err; + int d; + mach_port_t newport, ref; + + /* Give the new send right a user reference. + This is a good way to check that it is valid. */ + if (err = __mach_port_mod_refs (__mach_task_self (), new, + MACH_PORT_RIGHT_SEND, 1)) + return err; + + HURD_CRITICAL_BEGIN; + + /* We lock against another thread doing setauth. Anyone who sets + _hurd_ports[INIT_PORT_AUTH] some other way is asking to lose. */ + __mutex_lock (&reauth_lock); + + /* Install the new port in the cell. */ + __mutex_lock (&_hurd_id.lock); + _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], new); + _hurd_id.valid = 0; + if (_hurd_id.rid_auth) + { + __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); + _hurd_id.rid_auth = MACH_PORT_NULL; + } + __mutex_unlock (&_hurd_id.lock); + + if (_hurd_init_dtable != NULL) + /* We just have the simple table we got at startup. + Otherwise, a reauth_hook in dtable.c takes care of this. */ + for (d = 0; d < _hurd_init_dtablesize; ++d) + if (_hurd_init_dtable[d] != MACH_PORT_NULL) + { + mach_port_t new; + ref = __mach_reply_port (); + if (! __io_reauthenticate (_hurd_init_dtable[d], + ref, MACH_MSG_TYPE_MAKE_SEND) && + ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH], + __auth_user_authenticate + (port, + _hurd_init_dtable[d], + ref, MACH_MSG_TYPE_MAKE_SEND, + &new))) + { + __mach_port_deallocate (__mach_task_self (), + _hurd_init_dtable[d]); + _hurd_init_dtable[d] = new; + } + __mach_port_destroy (__mach_task_self (), ref); + } + + ref = __mach_reply_port (); + if (__USEPORT (CRDIR, + ! __io_reauthenticate (port, + ref, MACH_MSG_TYPE_MAKE_SEND) && + ! __auth_user_authenticate (new, port, + ref, MACH_MSG_TYPE_MAKE_SEND, + &newport))) + _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport); + __mach_port_destroy (__mach_task_self (), ref); + + ref = __mach_reply_port (); + if (__USEPORT (CWDIR, + ! __io_reauthenticate (port, + ref, MACH_MSG_TYPE_MAKE_SEND) && + ! __auth_user_authenticate (new, port, + ref, MACH_MSG_TYPE_MAKE_SEND, + &newport))) + _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport); + __mach_port_destroy (__mach_task_self (), ref); + + /* Run things which want to do reauthorization stuff. */ + RUN_HOOK (_hurd_reauth_hook, (new)); + + __mutex_unlock (&reauth_lock); + + HURD_CRITICAL_END; + + return 0; +} + +int +__setauth (auth_t new) +{ + error_t err = _hurd_setauth (new); + return err ? __hurd_fail (err) : 0; +} + +weak_alias (__setauth, setauth) diff --git a/hurd/setuids.c b/hurd/setuids.c new file mode 100644 index 0000000000..3b049b0100 --- /dev/null +++ b/hurd/setuids.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/id.h> + +/* Set the uid set for the current user to UIDS (N of them). */ +int +setuids (int n, const uid_t *uids) +{ + error_t err; + auth_t newauth; + size_t i; + gid_t new[n]; + + /* Fault before taking locks. */ + for (i = 0; i < n; ++i) + new[i] = uids[i]; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + if (! err) + { + /* Get a new auth port using those IDs. */ + err = __USEPORT (AUTH, + __auth_makeauth (port, NULL, 0, 0, + new, n, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + _hurd_id.gen.gids, _hurd_id.gen.ngids, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new auth port and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} diff --git a/hurd/siginfo.c b/hurd/siginfo.c new file mode 100644 index 0000000000..eb61fec973 --- /dev/null +++ b/hurd/siginfo.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <stdio.h> + +void +_hurd_siginfo_handler (int signo) +{ + /* XXX */ + puts ("got a SIGINFO"); +} diff --git a/hurd/task2pid.c b/hurd/task2pid.c new file mode 100644 index 0000000000..707753c104 --- /dev/null +++ b/hurd/task2pid.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +pid_t +__task2pid (task_t task) +{ + error_t err; + pid_t pid; + err = __USEPORT (PROC, __proc_task2pid (port, task, &pid)); + return err ? (pid_t) __hurd_fail (err) : pid; +} + +weak_alias (__task2pid, task2pid) diff --git a/hurd/vpprintf.c b/hurd/vpprintf.c new file mode 100644 index 0000000000..dcdcd5a13d --- /dev/null +++ b/hurd/vpprintf.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <hurd.h> + +static ssize_t +DEFUN(pwrite, (cookie, buf, n), + PTR cookie AND CONST char *buf AND size_t n) +{ + error_t error = __io_write ((io_t) cookie, buf, n, -1, + (mach_msg_type_number_t *) &n); + if (error) + return __hurd_fail (error); + return n; +} + + +/* Write formatted output to PORT, a Mach port supporting the i/o protocol, + according to the format string FORMAT, using the argument list in ARG. */ +int +DEFUN(vpprintf, (port, format, arg), + io_t port AND CONST char *format AND va_list arg) +{ + int done; + FILE f; + + /* Create an unbuffered stream talking to PORT on the stack. */ + memset((PTR) &f, 0, sizeof(f)); + f.__magic = _IOMAGIC; + f.__mode.__write = 1; + f.__cookie = (PTR) port; + f.__room_funcs = __default_room_functions; + f.__io_funcs.__write = pwrite; + f.__seen = 1; + f.__userbuf = 1; + + /* vfprintf will use a buffer on the stack for the life of the call. */ + done = vfprintf(&f, format, arg); + + return done; +} diff --git a/inet/Makefile b/inet/Makefile new file mode 100644 index 0000000000..aaa9880c1e --- /dev/null +++ b/inet/Makefile @@ -0,0 +1,36 @@ +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for inet portion of the library. +# +subdir := inet + +headers := netinet/in.h $(wildcard arpa/*.h protocols/*.h) netdb.h + +routines := ntohl ntohs htonl htons \ + inet_addr inet_lnaof inet_mkadr \ + inet_netof inet_ntoa inet_net \ + getproto getprtent getprtname \ + getsrvbynm getsrvbypt getservent \ + rcmd rexec + +# No warnings about losing BSD code. +override +gccwarn := -w + +include ../Rules diff --git a/inet/arpa/ftp.h b/inet/arpa/ftp.h new file mode 100644 index 0000000000..64532b9e25 --- /dev/null +++ b/inet/arpa/ftp.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)ftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _FTP_H_ +#define _FTP_H_ + +/* Definitions for FTP; see RFC-765. */ + +/* + * Reply codes. + */ +#define PRELIM 1 /* positive preliminary */ +#define COMPLETE 2 /* positive completion */ +#define CONTINUE 3 /* positive intermediate */ +#define TRANSIENT 4 /* transient negative completion */ +#define ERROR 5 /* permanent negative completion */ + +/* + * Type codes + */ +#define TYPE_A 1 /* ASCII */ +#define TYPE_E 2 /* EBCDIC */ +#define TYPE_I 3 /* image */ +#define TYPE_L 4 /* local byte size */ + +#ifdef FTP_NAMES +char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" }; +#endif + +/* + * Form codes + */ +#define FORM_N 1 /* non-print */ +#define FORM_T 2 /* telnet format effectors */ +#define FORM_C 3 /* carriage control (ASA) */ +#ifdef FTP_NAMES +char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" }; +#endif + +/* + * Structure codes + */ +#define STRU_F 1 /* file (no record structure) */ +#define STRU_R 2 /* record structure */ +#define STRU_P 3 /* page structure */ +#ifdef FTP_NAMES +char *strunames[] = {"0", "File", "Record", "Page" }; +#endif + +/* + * Mode types + */ +#define MODE_S 1 /* stream */ +#define MODE_B 2 /* block */ +#define MODE_C 3 /* compressed */ +#ifdef FTP_NAMES +char *modenames[] = {"0", "Stream", "Block", "Compressed" }; +#endif + +/* + * Record Tokens + */ +#define REC_ESC '\377' /* Record-mode Escape */ +#define REC_EOR '\001' /* Record-mode End-of-Record */ +#define REC_EOF '\002' /* Record-mode End-of-File */ + +/* + * Block Header + */ +#define BLK_EOR 0x80 /* Block is End-of-Record */ +#define BLK_EOF 0x40 /* Block is End-of-File */ +#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */ +#define BLK_RESTART 0x10 /* Block is Restart Marker */ + +#define BLK_BYTECOUNT 2 /* Bytes in this block */ + +#endif /* !_FTP_H_ */ diff --git a/inet/arpa/inet.h b/inet/arpa/inet.h new file mode 100644 index 0000000000..a231484642 --- /dev/null +++ b/inet/arpa/inet.h @@ -0,0 +1,53 @@ +/* + * 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. + * + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _INET_H_ +#define _INET_H_ + +/* External definitions for functions in inet(3) */ + +#include <sys/cdefs.h> + +__BEGIN_DECLS +unsigned long inet_addr __P((const char *)); +int inet_aton __P((const char *, struct in_addr *)); +unsigned long inet_lnaof __P((struct in_addr)); +struct in_addr inet_makeaddr __P((u_long , u_long)); +unsigned long inet_netof __P((struct in_addr)); +unsigned long inet_network __P((const char *)); +char *inet_ntoa __P((struct in_addr)); +__END_DECLS + +#endif /* !_INET_H_ */ diff --git a/inet/arpa/telnet.h b/inet/arpa/telnet.h new file mode 100644 index 0000000000..10155a84a8 --- /dev/null +++ b/inet/arpa/telnet.h @@ -0,0 +1,320 @@ +/* + * 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. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + */ + +#ifndef _TELNET_H_ +#define _TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 + +#define NSLC 18 + +/* + * For backwards compatability, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, +#ifdef SLC_NAMES +char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* !_TELNET_H_ */ diff --git a/inet/arpa/tftp.h b/inet/arpa/tftp.h new file mode 100644 index 0000000000..036720011f --- /dev/null +++ b/inet/arpa/tftp.h @@ -0,0 +1,80 @@ +/* + * 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. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TFTP_H_ +#define _TFTP_H_ + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define ERROR 05 /* error code */ + +struct tftphdr { + short th_opcode; /* packet type */ + union { + short tu_block; /* block # */ + short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ + +#endif /* !_TFTP_H_ */ diff --git a/inet/getproto.c b/inet/getproto.c new file mode 100644 index 0000000000..92f562bebf --- /dev/null +++ b/inet/getproto.c @@ -0,0 +1,55 @@ +/* + * 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[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> + +extern int _proto_stayopen; + +struct protoent * +getprotobynumber(proto) + register int proto; +{ + register struct protoent *p; + + setprotoent(_proto_stayopen); + while (p = getprotoent()) + if (p->p_proto == proto) + break; + if (!_proto_stayopen) + endprotoent(); + return (p); +} diff --git a/inet/getprtent.c b/inet/getprtent.c new file mode 100644 index 0000000000..c10ae330e4 --- /dev/null +++ b/inet/getprtent.c @@ -0,0 +1,119 @@ +/* + * 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[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define MAXALIASES 35 + +static FILE *protof = NULL; +static char line[BUFSIZ+1]; +static struct protoent proto; +static char *proto_aliases[MAXALIASES]; +int _proto_stayopen; + +void +setprotoent(f) + int f; +{ + if (protof == NULL) + protof = fopen(_PATH_PROTOCOLS, "r" ); + else + rewind(protof); + _proto_stayopen |= f; +} + +void +endprotoent() +{ + if (protof) { + fclose(protof); + protof = NULL; + } + _proto_stayopen = 0; +} + +struct protoent * +getprotoent() +{ + char *p; + register char *cp, **q; + + if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) + return (NULL); +again: + if ((p = fgets(line, BUFSIZ, protof)) == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + proto.p_name = p; + cp = strpbrk(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = strpbrk(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + proto.p_proto = atoi(cp); + q = proto.p_aliases = proto_aliases; + if (p != NULL) { + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &proto_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&proto); +} diff --git a/inet/getprtname.c b/inet/getprtname.c new file mode 100644 index 0000000000..3ee6754bb3 --- /dev/null +++ b/inet/getprtname.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> + +extern int _proto_stayopen; + +struct protoent * +getprotobyname(name) + register const char *name; +{ + register struct protoent *p; + register char **cp; + + setprotoent(_proto_stayopen); + while (p = getprotoent()) { + if (strcmp(p->p_name, name) == 0) + break; + for (cp = p->p_aliases; *cp != 0; cp++) + if (strcmp(*cp, name) == 0) + goto found; + } +found: + if (!_proto_stayopen) + endprotoent(); + return (p); +} diff --git a/inet/getservent.c b/inet/getservent.c new file mode 100644 index 0000000000..6bee5d3a8b --- /dev/null +++ b/inet/getservent.c @@ -0,0 +1,121 @@ +/* + * 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[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#define MAXALIASES 35 + +static FILE *servf = NULL; +static char line[BUFSIZ+1]; +static struct servent serv; +static char *serv_aliases[MAXALIASES]; +int _serv_stayopen; + +void +setservent(f) + int f; +{ + if (servf == NULL) + servf = fopen(_PATH_SERVICES, "r" ); + else + rewind(servf); + _serv_stayopen |= f; +} + +void +endservent() +{ + if (servf) { + fclose(servf); + servf = NULL; + } + _serv_stayopen = 0; +} + +struct servent * +getservent() +{ + char *p; + register char *cp, **q; + + if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) + return (NULL); +again: + if ((p = fgets(line, BUFSIZ, servf)) == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + serv.s_name = p; + p = strpbrk(p, " \t"); + if (p == NULL) + goto again; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + cp = strpbrk(p, ",/"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + serv.s_port = htons((u_short)atoi(p)); + serv.s_proto = cp; + q = serv.s_aliases = serv_aliases; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &serv_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&serv); +} diff --git a/inet/getsrvbynm.c b/inet/getsrvbynm.c new file mode 100644 index 0000000000..77bf813777 --- /dev/null +++ b/inet/getsrvbynm.c @@ -0,0 +1,65 @@ +/* + * 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[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> + +extern int _serv_stayopen; + +struct servent * +getservbyname(name, proto) + const char *name, *proto; +{ + register struct servent *p; + register char **cp; + + setservent(_serv_stayopen); + while (p = getservent()) { + if (strcmp(name, p->s_name) == 0) + goto gotname; + for (cp = p->s_aliases; *cp; cp++) + if (strcmp(name, *cp) == 0) + goto gotname; + continue; +gotname: + if (proto == 0 || strcmp(p->s_proto, proto) == 0) + break; + } + if (!_serv_stayopen) + endservent(); + return (p); +} diff --git a/inet/getsrvbypt.c b/inet/getsrvbypt.c new file mode 100644 index 0000000000..0acb31bb08 --- /dev/null +++ b/inet/getsrvbypt.c @@ -0,0 +1,60 @@ +/* + * 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[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> + +extern int _serv_stayopen; + +struct servent * +getservbyport(port, proto) + int port; + const char *proto; +{ + register struct servent *p; + + setservent(_serv_stayopen); + while (p = getservent()) { + if (p->s_port != port) + continue; + if (proto == 0 || strcmp(p->s_proto, proto) == 0) + break; + } + if (!_serv_stayopen) + endservent(); + return (p); +} diff --git a/inet/inet_addr.c b/inet/inet_addr.c new file mode 100644 index 0000000000..246a418a95 --- /dev/null +++ b/inet/inet_addr.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#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 <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> + +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +u_long +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + register const char *cp; + struct in_addr *addr; +{ + register u_long val; + register int base, n; + register char c; + u_int parts[4]; + register u_int *pp = parts; + + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, other=decimal. + */ + val = 0; base = 10; + if (*cp == '0') { + if (*++cp == 'x' || *cp == 'X') + base = 16, cp++; + else + base = 8; + } + while ((c = *cp) != '\0') { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) + + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16-bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3 || val > 0xff) + return (0); + *pp++ = val, cp++; + } else + break; + } + /* + * Check for trailing characters. + */ + if (*cp && (!isascii(*cp) || !isspace(*cp))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} diff --git a/inet/inet_lnaof.c b/inet/inet_lnaof.c new file mode 100644 index 0000000000..406be30034 --- /dev/null +++ b/inet/inet_lnaof.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Return the local network address portion of an + * internet address; handles class a/b/c network + * number formats. + */ +u_long +inet_lnaof(in) + struct in_addr in; +{ + register u_long i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return ((i)&IN_CLASSA_HOST); + else if (IN_CLASSB(i)) + return ((i)&IN_CLASSB_HOST); + else + return ((i)&IN_CLASSC_HOST); +} diff --git a/inet/inet_mkadr.c b/inet/inet_mkadr.c new file mode 100644 index 0000000000..7976188ea5 --- /dev/null +++ b/inet/inet_mkadr.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Formulate an Internet address from network + host. Used in + * building addresses stored in the ifnet structure. + */ +struct in_addr +inet_makeaddr(net, host) + u_long net, host; +{ + u_long addr; + + if (net < 128) + addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); + else if (net < 65536) + addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST); + else if (net < 16777216L) + addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST); + else + addr = net | host; + addr = htonl(addr); + return (*(struct in_addr *)&addr); +} diff --git a/inet/inet_net.c b/inet/inet_net.c new file mode 100644 index 0000000000..fda53b6ecc --- /dev/null +++ b/inet/inet_net.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> + +/* + * Internet network address interpretation routine. + * The library routines call this routine to interpret + * network numbers. + */ +u_long +inet_network(cp) + register const char *cp; +{ + register u_long val, base, n; + register char c; + u_long parts[4], *pp = parts; + register int i; + +again: + val = 0; base = 10; + if (*cp == '0') + base = 8, cp++; + if (*cp == 'x' || *cp == 'X') + base = 16, cp++; + while (c = *cp) { + if (isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit(c)) { + val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + if (pp >= parts + 4) + return (INADDR_NONE); + *pp++ = val, cp++; + goto again; + } + if (*cp && !isspace(*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); +} diff --git a/inet/inet_netof.c b/inet/inet_netof.c new file mode 100644 index 0000000000..d6de694243 --- /dev/null +++ b/inet/inet_netof.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Return the network number from an internet + * address; handles class a/b/c network #'s. + */ +u_long +inet_netof(in) + struct in_addr in; +{ + register u_long i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); + else if (IN_CLASSB(i)) + return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); + else + return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); +} diff --git a/inet/inet_ntoa.c b/inet/inet_ntoa.c new file mode 100644 index 0000000000..a37b1dbeef --- /dev/null +++ b/inet/inet_ntoa.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> + +char * +inet_ntoa(in) + struct in_addr in; +{ + static char b[18]; + register char *p; + + 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); +} diff --git a/inet/netdb.h b/inet/netdb.h new file mode 100644 index 0000000000..21caa894f9 --- /dev/null +++ b/inet/netdb.h @@ -0,0 +1,147 @@ +/*- + * 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. + * + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * $Id$ + * - + * 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-- + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#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" + +/* + * 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 # */ +}; + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in extern int h_errno). + */ + +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-Authoritive 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 */ + +#include <sys/cdefs.h> + +__BEGIN_DECLS +void endhostent __P((void)); +void endnetent __P((void)); +void endprotoent __P((void)); +void endservent __P((void)); +struct hostent *gethostbyaddr __P((const char *, int, int)); +struct hostent *gethostbyname __P((const char *)); +struct hostent *gethostent __P((void)); +struct netent *getnetbyaddr __P((long, int)); /* u_long? */ +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)); +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)); +__END_DECLS + +#endif /* !_NETDB_H_ */ diff --git a/inet/netinet/in.h b/inet/netinet/in.h new file mode 100644 index 0000000000..e8bc3b075e --- /dev/null +++ b/inet/netinet/in.h @@ -0,0 +1,198 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _NETINET_IN_H + +#define _NETINET_IN_H 1 +#include <features.h> + +#include <sys/socket.h> + + +/* Standard well-defined IP protocols. */ +enum + { + IPPROTO_IP = 0, /* Dummy protocol for TCP. */ + IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */ + IPPROTO_GGP = 2, /* Gateway Protocol (deprecated). */ + IPPROTO_TCP = 6, /* Transmission Control Protocol. */ + IPPROTO_EGP = 8, /* Exterior Gateway Protocol. */ + IPPROTO_PUP = 12, /* PUP protocol. */ + IPPROTO_UDP = 17, /* User Datagram Protocol. */ + IPPROTO_IDP = 22, /* XNS IDP protocol. */ + + IPPROTO_RAW = 255, /* Raw IP packets. */ + IPPROTO_MAX, + }; + +/* Standard well-known ports. */ +enum + { + IPPORT_ECHO = 7, /* Echo service. */ + IPPORT_DISCARD = 9, /* Discard transmissions service. */ + IPPORT_SYSTAT = 11, /* System status service. */ + IPPORT_DAYTIME = 13, /* Time of day service. */ + IPPORT_NETSTAT = 15, /* Network status service. */ + IPPORT_FTP = 21, /* File Transfer Protocol. */ + IPPORT_TELNET = 23, /* Telnet protocol. */ + IPPORT_SMTP = 25, /* Simple Mail Transfer Protocol. */ + IPPORT_TIMESERVER = 37, /* Timeserver service. */ + IPPORT_NAMESERVER = 42, /* Domain Name Service. */ + IPPROT_WHOIS = 43, /* Internet Whois service. */ + IPPORT_MTP = 57, + + IPPORT_TFTP = 69, /* Trivial File Transfer Protocol. */ + IPPORT_RJE = 77, + IPPORT_FINGER = 79, /* Finger service. */ + IPPORT_TTYLINK = 87, + IPPORT_SUPDUP = 95, /* SUPDUP protocol. */ + + + IPPORT_EXECSERVER = 512, /* execd service. */ + IPPORT_LOGINSERVER = 513, /* rlogind service. */ + IPPORT_CMDSERVER = 514, + IPPORT_EFSSERVER = 520, + + /* UDP ports. */ + IPPORT_BIFFUDP = 512, + IPPORT_WHOSERVER = 513, + IPPORT_ROUTESERVER = 520, + + /* Ports less than this value are reserved for privileged processes. */ + IPPORT_RESERVED = 1024, + + /* Ports greater this value are reserved for (non-privileged) servers. */ + IPPORT_USERRESERVED = 5000, + }; + + +/* Link numbers. */ +#define IMPLINK_IP 155 +#define IMPLINK_LOWEXPER 156 +#define IMPLINK_HIGHEXPER 158 + + +/* Internet address. */ +struct in_addr + { + unsigned long int s_addr; + }; + + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ + +#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSA_NSHIFT 24 +#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) +#define IN_CLASSA_MAX 128 + +#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSB_NSHIFT 16 +#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) +#define IN_CLASSB_MAX 65536 + +#define IN_CLASSC(a) ((((long int) (a)) & 0xc0000000) == 0xc0000000) +#define IN_CLASSC_NET 0xffffff00 +#define IN_CLASSC_NSHIFT 8 +#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) + +#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) = 0xe0000000) +#define IN_MULTICAST(a) IN_CLASSD(a) + +#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) = 0xe0000000) +#define IN_BADCLASS(a) ((((long int) (a)) & 0xf0000000) = 0xf0000000) + +/* Address to accept any incoming messages. */ +#define INADDR_ANY ((unsigned long int) 0x00000000) +/* Address to send to all hosts. */ +#define INADDR_BROADCAST ((unsigned long int) 0xffffffff) +/* Address indicating an error return. */ +#define INADDR_NONE 0xffffffff + +/* Network number for local host loopback. */ +#define IN_LOOPBACKNET 127 +/* Address to loopback in software to local host. */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ +#endif + + +/* Get the definition of the macro to define the common sockaddr members. */ +#include <sockaddrcom.h> + + +/* Structure describing an Internet socket address. */ +struct sockaddr_in + { + __SOCKADDR_COMMON (sin_); + unsigned short int sin_port; /* Port number. */ + struct in_addr sin_addr; /* Internet address. */ + + /* Pad to size of `struct sockaddr'. */ + unsigned char sin_zero[sizeof(struct sockaddr) - + __SOCKADDR_COMMON_SIZE - + sizeof(unsigned short int) - + sizeof(struct in_addr)]; + }; + + +/* Options for use with `getsockopt' and `setsockopt' at the IP level. + The first word in the comment at the right is the data type used; + "bool" means a boolean value stored in an `int'. */ +#define IP_OPTIONS 1 /* ip_opts; IP per-packet options. */ +#define IP_HDRINCL 2 /* int; Header is included with data. */ +#define IP_TOS 3 /* int; IP type of service and precedence. */ +#define IP_TTL 4 /* int; IP time to live. */ +#define IP_RECVOPTS 5 /* bool; Receive all IP options w/datagram. */ +#define IP_RECVRETOPTS 6 /* bool; Receive IP options for response. */ +#define IP_RECVDSTADDR 7 /* bool; Receive IP dst addr w/datagram. */ +#define IP_RETOPTS 8 /* ip_opts; Set/get IP per-packet options. */ + +/* Structure used to describe IP options for IP_OPTIONS and IP_RETOPTS. + The `ip_dst' field is used for the first-hop gateway when using a + source route (this gets put into the header proper). */ +struct ip_opts + { + struct in_addr ip_dst; /* First hop; zero without source route. */ + char ip_opts[40]; /* Actually variable in size. */ + }; + + +/* Functions to convert between host and network byte order. */ + +extern unsigned long int ntohl __P ((unsigned long int)); +extern unsigned short int ntohs __P ((unsigned short int)); +extern unsigned long int htonl __P ((unsigned long int)); +extern unsigned short int htons __P ((unsigned short int)); + +#include <endian.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +/* The host byte order is the same as network byte order, + so these functions are all just identity. */ +#define ntohl(x) (x) +#define ntohs(x) (x) +#define htonl(x) (x) +#define htons(x) (x) +#endif + +#endif /* netinet/in.h */ diff --git a/inet/protocols/routed.h b/inet/protocols/routed.h new file mode 100644 index 0000000000..f41fc2182a --- /dev/null +++ b/inet/protocols/routed.h @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 1983, 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. + * + * @(#)routed.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ROUTED_H_ +#define _ROUTED_H_ + +/* + * Routing Information Protocol + * + * Derived from Xerox NS Routing Information Protocol + * by changing 32-bit net numbers to sockaddr's and + * padding stuff to 32-bit boundaries. + */ +#define RIPVERSION 1 + +struct netinfo { + struct sockaddr rip_dst; /* destination net/host */ + int rip_metric; /* cost of route */ +}; + +struct rip { + u_char rip_cmd; /* request/response */ + u_char rip_vers; /* protocol version # */ + u_char rip_res1[2]; /* pad to 32-bit boundary */ + union { + struct netinfo ru_nets[1]; /* variable length... */ + char ru_tracefile[1]; /* ditto ... */ + } ripun; +#define rip_nets ripun.ru_nets +#define rip_tracefile ripun.ru_tracefile +}; + +/* + * Packet types. + */ +#define RIPCMD_REQUEST 1 /* want info */ +#define RIPCMD_RESPONSE 2 /* responding to request */ +#define RIPCMD_TRACEON 3 /* turn tracing on */ +#define RIPCMD_TRACEOFF 4 /* turn it off */ + +#define RIPCMD_MAX 5 +#ifdef RIPCMDS +char *ripcmds[RIPCMD_MAX] = + { "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF" }; +#endif + +#define HOPCNT_INFINITY 16 /* per Xerox NS */ +#define MAXPACKETSIZE 512 /* max broadcast size */ + +/* + * Timer values used in managing the routing table. + * Complete tables are broadcast every SUPPLY_INTERVAL seconds. + * If changes occur between updates, dynamic updates containing only changes + * may be sent. When these are sent, a timer is set for a random value + * between MIN_WAITTIME and MAX_WAITTIME, and no additional dynamic updates + * are sent until the timer expires. + * + * Every update of a routing entry forces an entry's timer to be reset. + * After EXPIRE_TIME without updates, the entry is marked invalid, + * but held onto until GARBAGE_TIME so that others may + * see it "be deleted". + */ +#define TIMER_RATE 30 /* alarm clocks every 30 seconds */ + +#define SUPPLY_INTERVAL 30 /* time to supply tables */ +#define MIN_WAITTIME 2 /* min. interval to broadcast changes */ +#define MAX_WAITTIME 5 /* max. time to delay changes */ + +#define EXPIRE_TIME 180 /* time to mark entry invalid */ +#define GARBAGE_TIME 240 /* time to garbage collect */ + +#endif /* !_ROUTED_H_ */ diff --git a/inet/protocols/rwhod.h b/inet/protocols/rwhod.h new file mode 100644 index 0000000000..93008a4181 --- /dev/null +++ b/inet/protocols/rwhod.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)rwhod.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _RWHOD_H_ +#define _RWHOD_H_ + +/* + * rwho protocol packet format. + */ +struct outmp { + char out_line[8]; /* tty name */ + char out_name[8]; /* user id */ + long out_time; /* time on */ +}; + +struct whod { + char wd_vers; /* protocol version # */ + char wd_type; /* packet type, see below */ + char wd_pad[2]; + int wd_sendtime; /* time stamp by sender */ + int wd_recvtime; /* time stamp applied by receiver */ + char wd_hostname[32]; /* hosts's name */ + int wd_loadav[3]; /* load average as in uptime */ + int wd_boottime; /* time system booted */ + struct whoent { + struct outmp we_utmp; /* active tty info */ + int we_idle; /* tty idle time */ + } wd_we[1024 / sizeof (struct whoent)]; +}; + +#define WHODVERSION 1 +#define WHODTYPE_STATUS 1 /* host status */ + +#define _PATH_RWHODIR "/var/rwho" + +#endif /* !_RWHOD_H_ */ diff --git a/inet/protocols/talkd.h b/inet/protocols/talkd.h new file mode 100644 index 0000000000..0d30d5bfa3 --- /dev/null +++ b/inet/protocols/talkd.h @@ -0,0 +1,114 @@ +/* + * 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. + * + * @(#)talkd.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TALKD_H_ +#define _TALKD_H_ + +/* + * This describes the protocol used by the talk server and clients. + * + * The talk server acts a repository of invitations, responding to + * requests by clients wishing to rendezvous for the purpose of + * holding a conversation. In normal operation, a client, the caller, + * initiates a rendezvous by sending a CTL_MSG to the server of + * type LOOK_UP. This causes the server to search its invitation + * tables to check if an invitation currently exists for the caller + * (to speak to the callee specified in the message). If the lookup + * fails, the caller then sends an ANNOUNCE message causing the server + * to broadcast an announcement on the callee's login ports requesting + * contact. When the callee responds, the local server uses the + * recorded invitation to respond with the appropriate rendezvous + * address and the caller and callee client programs establish a + * stream connection through which the conversation takes place. + */ + +/* + * Client->server request message format. + */ +typedef struct { + u_char vers; /* protocol version */ + u_char type; /* request type, see below */ + u_char answer; /* not used */ + u_char pad; + u_long id_num; /* message id */ + struct osockaddr addr; /* old (4.3) style */ + struct osockaddr ctl_addr; /* old (4.3) style */ + long pid; /* caller's process id */ +#define NAME_SIZE 12 + char l_name[NAME_SIZE];/* caller's name */ + char r_name[NAME_SIZE];/* callee's name */ +#define TTY_SIZE 16 + char r_tty[TTY_SIZE];/* callee's tty name */ +} CTL_MSG; + +/* + * Server->client response message format. + */ +typedef struct { + u_char vers; /* protocol version */ + u_char type; /* type of request message, see below */ + u_char answer; /* respose to request message, see below */ + u_char pad; + u_long id_num; /* message id */ + struct osockaddr addr; /* address for establishing conversation */ +} CTL_RESPONSE; + +#define TALK_VERSION 1 /* protocol version */ + +/* message type values */ +#define LEAVE_INVITE 0 /* leave invitation with server */ +#define LOOK_UP 1 /* check for invitation by callee */ +#define DELETE 2 /* delete invitation by caller */ +#define ANNOUNCE 3 /* announce invitation by caller */ + +/* answer values */ +#define SUCCESS 0 /* operation completed properly */ +#define NOT_HERE 1 /* callee not logged in */ +#define FAILED 2 /* operation failed for unexplained reason */ +#define MACHINE_UNKNOWN 3 /* caller's machine name unknown */ +#define PERMISSION_DENIED 4 /* callee's tty doesn't permit announce */ +#define UNKNOWN_REQUEST 5 /* request has invalid type value */ +#define BADVERSION 6 /* request has invalid protocol version */ +#define BADADDR 7 /* request has invalid addr value */ +#define BADCTLADDR 8 /* request has invalid ctl_addr value */ + +/* + * Operational parameters. + */ +#define MAX_LIFE 60 /* max time daemon saves invitations */ +/* RING_WAIT should be 10's of seconds less than MAX_LIFE */ +#define RING_WAIT 30 /* time to wait before resending invitation */ + +#endif /* !_TALKD_H_ */ diff --git a/inet/protocols/timed.h b/inet/protocols/timed.h new file mode 100644 index 0000000000..1b569f5312 --- /dev/null +++ b/inet/protocols/timed.h @@ -0,0 +1,99 @@ +/* + * 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. + * + * @(#)timed.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TIMED_H_ +#define _TIMED_H_ + +/* + * Time Synchronization Protocol + */ + +#define TSPVERSION 1 +#define ANYADDR NULL + +struct tsp { + u_char tsp_type; + u_char tsp_vers; + u_short tsp_seq; + union { + struct timeval tspu_time; + char tspu_hopcnt; + } tsp_u; + char tsp_name[MAXHOSTNAMELEN]; +}; + +#define tsp_time tsp_u.tspu_time +#define tsp_hopcnt tsp_u.tspu_hopcnt + +/* + * Command types. + */ +#define TSP_ANY 0 /* match any types */ +#define TSP_ADJTIME 1 /* send adjtime */ +#define TSP_ACK 2 /* generic acknowledgement */ +#define TSP_MASTERREQ 3 /* ask for master's name */ +#define TSP_MASTERACK 4 /* acknowledge master request */ +#define TSP_SETTIME 5 /* send network time */ +#define TSP_MASTERUP 6 /* inform slaves that master is up */ +#define TSP_SLAVEUP 7 /* slave is up but not polled */ +#define TSP_ELECTION 8 /* advance candidature for master */ +#define TSP_ACCEPT 9 /* support candidature of master */ +#define TSP_REFUSE 10 /* reject candidature of master */ +#define TSP_CONFLICT 11 /* two or more masters present */ +#define TSP_RESOLVE 12 /* masters' conflict resolution */ +#define TSP_QUIT 13 /* reject candidature if master is up */ +#define TSP_DATE 14 /* reset the time (date command) */ +#define TSP_DATEREQ 15 /* remote request to reset the time */ +#define TSP_DATEACK 16 /* acknowledge time setting */ +#define TSP_TRACEON 17 /* turn tracing on */ +#define TSP_TRACEOFF 18 /* turn tracing off */ +#define TSP_MSITE 19 /* find out master's site */ +#define TSP_MSITEREQ 20 /* remote master's site request */ +#define TSP_TEST 21 /* for testing election algo */ +#define TSP_SETDATE 22 /* New from date command */ +#define TSP_SETDATEREQ 23 /* New remote for above */ +#define TSP_LOOP 24 /* loop detection packet */ + +#define TSPTYPENUMBER 25 + +#ifdef TSPTYPES +char *tsptype[TSPTYPENUMBER] = + { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP", + "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT", + "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ", + "TEST", "SETDATE", "SETDATEREQ", "LOOP" }; +#endif + +#endif /* !_TIMED_H_ */ diff --git a/inet/rcmd.c b/inet/rcmd.c new file mode 100644 index 0000000000..e5b28c63f8 --- /dev/null +++ b/inet/rcmd.c @@ -0,0 +1,414 @@ +/* + * 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 <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <signal.h> +#include <fcntl.h> +#include <netdb.h> +#include <unistd.h> +#include <pwd.h> +#include <errno.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +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(1 + (s > s2 ? s : s2), &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; + + 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)) { + char *pbuf; + size_t dirlen; + + first = 0; + if ((pwd = getpwnam(luser)) == NULL) + return (-1); + + dirlen = strlen (pwd->pw_dir); + pbuf = alloca (dirlen + sizeof "/.rhosts"); + memcpy (pbuf, pwd->pw_dir, dirlen); + memcpy (pbuf + dirlen, "/.rhosts", sizeof "/.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 = NULL; + size_t bufsize = 0; + ssize_t nread; + + while ((nread = getline (&buf, &bufsize, hostf)) > 0) { + buf[bufsize - 1] = '\0'; /* Make sure it's terminated. */ + p = buf; + 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) { + free (buf); + return (0); + } + } + free (buf); + 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/inet/rexec.c b/inet/rexec.c new file mode 100644 index 0000000000..297e44402d --- /dev/null +++ b/inet/rexec.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 1980, 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[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <stdio.h> +#include <netdb.h> +#include <errno.h> + +extern errno; +char *index(); +int rexecoptions; +char *getpass(), *getlogin(); + +rexec(ahost, rport, name, pass, cmd, fd2p) + char **ahost; + int rport; + char *name, *pass, *cmd; + int *fd2p; +{ + struct sockaddr_in sin, sin2, from; + struct hostent *hp; + u_short port; + int s, timo = 1, s3; + char c; + + hp = gethostbyname(*ahost); + if (hp == 0) { + herror(*ahost); + return (-1); + } + *ahost = hp->h_name; + ruserpass(hp->h_name, &name, &pass); +retry: + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) { + perror("rexec: socket"); + return (-1); + } + sin.sin_family = hp->h_addrtype; + sin.sin_port = rport; + bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + if (errno == ECONNREFUSED && timo <= 16) { + (void) close(s); + sleep(timo); + timo *= 2; + goto retry; + } + perror(hp->h_name); + return (-1); + } + if (fd2p == 0) { + (void) write(s, "", 1); + port = 0; + } else { + char num[8]; + int s2, sin2len; + + s2 = socket(AF_INET, SOCK_STREAM, 0); + if (s2 < 0) { + (void) close(s); + return (-1); + } + listen(s2, 1); + sin2len = sizeof (sin2); + if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 || + sin2len != sizeof (sin2)) { + perror("getsockname"); + (void) close(s2); + goto bad; + } + port = ntohs((u_short)sin2.sin_port); + (void) sprintf(num, "%u", port); + (void) write(s, num, strlen(num)+1); + { int len = sizeof (from); + s3 = accept(s2, (struct sockaddr *)&from, &len); + close(s2); + if (s3 < 0) { + perror("accept"); + port = 0; + goto bad; + } + } + *fd2p = s3; + } + (void) write(s, name, strlen(name) + 1); + /* should public key encypt the password here */ + (void) write(s, pass, strlen(pass) + 1); + (void) write(s, cmd, strlen(cmd) + 1); + if (read(s, &c, 1) != 1) { + perror(*ahost); + goto bad; + } + if (c != 0) { + while (read(s, &c, 1) == 1) { + (void) write(2, &c, 1); + if (c == '\n') + break; + } + goto bad; + } + return (s); +bad: + if (port) + (void) close(*fd2p); + (void) close(s); + return (-1); +} diff --git a/install-sh b/install-sh new file mode 100755 index 0000000000..89fc9b098b --- /dev/null +++ b/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/io/Makefile b/io/Makefile new file mode 100644 index 0000000000..639f6b75bb --- /dev/null +++ b/io/Makefile @@ -0,0 +1,49 @@ +# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for I/O portion of the library. +# +subdir := io + +headers := sys/stat.h statbuf.h \ + fcntl.h sys/fcntl.h fcntlbits.h \ + poll.h sys/poll.h \ + utime.h ftw.h fts.h + +routines := \ + utime \ + mkfifo \ + stat fstat lstat \ + umask chmod fchmod mkdir \ + open close read write lseek access \ + fcntl flock lockf \ + dup dup2 pipe \ + creat \ + chdir fchdir \ + getcwd getwd getdirname \ + chown fchown \ + ttyname isatty \ + link symlink readlink \ + unlink rmdir \ + ftw fts poll + +others := pwd +tests := test-utime + +include ../Rules diff --git a/io/creat.c b/io/creat.c new file mode 100644 index 0000000000..ee935c87a4 --- /dev/null +++ b/io/creat.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <fcntl.h> +#include <sys/types.h> + +#undef creat + +/* Create FILE with protections MODE. */ +int +DEFUN(creat, (file, mode), CONST char *file AND mode_t mode) +{ + return __open(file, O_WRONLY|O_CREAT|O_TRUNC, mode); +} diff --git a/io/fcntl.h b/io/fcntl.h new file mode 100644 index 0000000000..952b2b51da --- /dev/null +++ b/io/fcntl.h @@ -0,0 +1,86 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 6.5 File Control Operations <fcntl.h> + */ + +#ifndef _FCNTL_H + +#define _FCNTL_H 1 +#include <features.h> + +/* This must be early so <fcntlbits.h> can define types winningly. */ +__BEGIN_DECLS + +/* Get the definitions of O_*, F_*, FD_*: all the + numbers and flag bits for `open', `fcntl', et al. */ +#include <fcntlbits.h> + +#ifdef __USE_MISC +#ifndef R_OK /* Verbatim from <unistd.h>. Ugh. */ +/* Values for the second argument to access. + These may be OR'd together. */ +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ +#endif +#endif /* Use misc. */ + + +/* Do the file control operation described by CMD on FD. + The remaining arguments are interpreted depending on CMD. */ +extern int __fcntl __P ((int __fd, int __cmd, ...)); +extern int fcntl __P ((int __fd, int __cmd, ...)); + +/* Open FILE and return a new file descriptor for it, or -1 on error. + OFLAG determines the type of access used. If O_CREAT is on OFLAG, + the third argument is taken as a `mode_t', the mode of the created file. */ +extern int __open __P ((__const char *__file, int __oflag,...)); +extern int open __P ((__const char *__file, int __oflag,...)); + +/* Create and open FILE, with mode MODE. + This takes an `int' MODE argument because that is + what `mode_t' will be widened to. */ +extern int creat __P ((__const char *__file, __mode_t __mode)); + +#ifdef __OPTIMIZE__ +#define creat(file, m) __open((file), O_WRONLY|O_CREAT|O_TRUNC, (m)) +#endif /* Optimizing. */ + +#if defined (__USE_MISC) && !defined (F_LOCK) +/* NOTE: These declarations also appear in <unistd.h>; be sure to keep both + files consistent. Some systems have them there and some here, and some + software depends on the macros being defined without including both. */ + +/* `lockf' is a simpler interface to the locking facilities of `fcntl'. + LEN is always relative to the current file position. + The CMD argument is one of the following. */ + +#define F_ULOCK 0 /* Unlock a previously locked region. */ +#define F_LOCK 1 /* Lock a region for exclusive use. */ +#define F_TLOCK 2 /* Test and lock a region for exclusive use. */ +#define F_TEST 3 /* Test a region for other processes locks. */ + +extern int lockf __P ((int __fd, int __cmd, __off_t __len)); +#endif + +__END_DECLS + +#endif /* fcntl.h */ diff --git a/io/fts.c b/io/fts.c new file mode 100644 index 0000000000..044779d595 --- /dev/null +++ b/io/fts.c @@ -0,0 +1,981 @@ +/*- + * 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[] = "@(#)fts.c 8.2 (Berkeley) 1/2/94"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <errno.h> +#include <fts.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +/* Largest alignment size needed, minus one. + Usually long double is the worst case. */ +#ifndef ALIGNBYTES +#define ALIGNBYTES (__alignof__ (long double) - 1) +#endif +/* Align P to that size. */ +#ifndef ALIGN +#define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES) +#endif + + +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)); + +#define ISDOT(a) (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2])) + +#define ISSET(opt) (sp->fts_options & opt) +#define SET(opt) (sp->fts_options |= opt) + +#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path)) +#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) + +/* fts_build flags */ +#define BCHILD 1 /* fts_children */ +#define BNAMES 2 /* fts_children, names only */ +#define BREAD 3 /* fts_read */ + +FTS * +fts_open(argv, options, compar) + char * const *argv; + register int options; + int (*compar)(); +{ + register FTS *sp; + register FTSENT *p, *root; + register int nitems; + FTSENT *parent, *tmp; + int len; + + /* Options check. */ + if (options & ~FTS_OPTIONMASK) { + errno = EINVAL; + return (NULL); + } + + /* Allocate/initialize the stream */ + if ((sp = malloc((u_int)sizeof(FTS))) == NULL) + return (NULL); + bzero(sp, sizeof(FTS)); + sp->fts_compar = compar; + sp->fts_options = options; + + /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ + if (ISSET(FTS_LOGICAL)) + SET(FTS_NOCHDIR); + + /* + * Start out with 1K of path space, and enough, in any case, + * to hold the user's paths. + */ +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) + goto mem1; + + /* Allocate/initialize root's parent. */ + if ((parent = fts_alloc(sp, "", 0)) == NULL) + goto mem2; + parent->fts_level = FTS_ROOTPARENTLEVEL; + + /* Allocate/initialize root(s). */ + for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) { + /* Don't allow zero-length paths. */ + if ((len = strlen(*argv)) == 0) { + errno = ENOENT; + goto mem3; + } + + p = fts_alloc(sp, *argv, len); + p->fts_level = FTS_ROOTLEVEL; + p->fts_parent = parent; + p->fts_accpath = p->fts_name; + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); + + /* Command-line "." and ".." are real directories. */ + if (p->fts_info == FTS_DOT) + p->fts_info = FTS_D; + + /* + * If comparison routine supplied, traverse in sorted + * order; otherwise traverse in the order specified. + */ + if (compar) { + p->fts_link = root; + root = p; + } else { + p->fts_link = NULL; + if (root == NULL) + tmp = root = p; + else { + tmp->fts_link = p; + tmp = p; + } + } + } + if (compar && nitems > 1) + root = fts_sort(sp, root, nitems); + + /* + * Allocate a dummy pointer and make fts_read think that we've just + * finished the node before the root(s); set p->fts_info to FTS_INIT + * so that everything about the "current" node is ignored. + */ + if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) + goto mem3; + sp->fts_cur->fts_link = root; + sp->fts_cur->fts_info = FTS_INIT; + + /* + * If using chdir(2), grab a file descriptor pointing to dot to insure + * that we can get back here; this could be avoided for some paths, + * but almost certainly not worth the effort. Slashes, symbolic links, + * and ".." are all fairly nasty problems. Note, if we can't get the + * descriptor we run anyway, just more slowly. + */ + if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0) + SET(FTS_NOCHDIR); + + return (sp); + +mem3: fts_lfree(root); + free(parent); +mem2: free(sp->fts_path); +mem1: free(sp); + return (NULL); +} + +static void +fts_load(sp, p) + FTS *sp; + register FTSENT *p; +{ + register int len; + register char *cp; + + /* + * Load the stream structure for the next traversal. Since we don't + * actually enter the directory until after the preorder visit, set + * the fts_accpath field specially so the chdir gets done to the right + * place and the user can access the first node. From fts_open it's + * known that the path will fit. + */ + len = p->fts_pathlen = p->fts_namelen; + bcopy(p->fts_name, sp->fts_path, len + 1); + if ((cp = rindex(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { + len = strlen(++cp); + bcopy(cp, p->fts_name, len + 1); + p->fts_namelen = len; + } + p->fts_accpath = p->fts_path = sp->fts_path; + sp->fts_dev = p->fts_dev; +} + +int +fts_close(sp) + FTS *sp; +{ + register FTSENT *freep, *p; + int saved_errno; + + /* + * This still works if we haven't read anything -- the dummy structure + * points to the root list, so we step through to the end of the root + * list which has a valid parent pointer. + */ + if (sp->fts_cur) { + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { + freep = p; + p = p->fts_link ? p->fts_link : p->fts_parent; + free(freep); + } + free(p); + } + + /* Free up child linked list, sort array, path buffer. */ + if (sp->fts_child) + fts_lfree(sp->fts_child); + if (sp->fts_array) + free(sp->fts_array); + free(sp->fts_path); + + /* Return to original directory, save errno if necessary. */ + if (!ISSET(FTS_NOCHDIR)) { + saved_errno = fchdir(sp->fts_rfd) ? errno : 0; + (void)close(sp->fts_rfd); + } + + /* Free up the stream pointer. */ + free(sp); + + /* Set errno and return. */ + if (!ISSET(FTS_NOCHDIR) && saved_errno) { + errno = saved_errno; + return (-1); + } + return (0); +} + +/* + * Special case a root of "/" so that slashes aren't appended which would + * cause paths to be written as "//foo". + */ +#define NAPPEND(p) \ + (p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 && \ + p->fts_path[0] == '/' ? 0 : p->fts_pathlen) + +FTSENT * +fts_read(sp) + register FTS *sp; +{ + register FTSENT *p, *tmp; + register int instr; + register char *t; + int saved_errno; + + /* If finished or unrecoverable error, return NULL. */ + if (sp->fts_cur == NULL || ISSET(FTS_STOP)) + return (NULL); + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* Save and zero out user instructions. */ + instr = p->fts_instr; + p->fts_instr = FTS_NOINSTR; + + /* Any type of file may be re-visited; re-stat and re-turn. */ + if (instr == FTS_AGAIN) { + p->fts_info = fts_stat(sp, p, 0); + return (p); + } + + /* + * Following a symlink -- SLNONE test allows application to see + * SLNONE and recover. If indirecting through a symlink, have + * keep a pointer to current location. If unable to get that + * pointer, follow fails. + */ + if (instr == FTS_FOLLOW && + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { + p->fts_info = fts_stat(sp, p, 1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) + if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + return (p); + } + + /* Directory in pre-order. */ + if (p->fts_info == FTS_D) { + /* If skipped or crossed mount point, do post-order visit. */ + if (instr == FTS_SKIP || + ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) { + if (p->fts_flags & FTS_SYMFOLLOW) + (void)close(p->fts_symfd); + if (sp->fts_child) { + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + p->fts_info = FTS_DP; + return (p); + } + + /* Rebuild if only read the names and now traversing. */ + if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) { + sp->fts_options &= ~FTS_NAMEONLY; + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + + /* + * Cd to the subdirectory. + * + * If have already read and now fail to chdir, whack the list + * to make the names come out right, and set the parent errno + * so the application will eventually get an error condition. + * Set the FTS_DONTCHDIR flag so that when we logically change + * directories back to the parent we don't do a chdir. + * + * If haven't read do so. If the read fails, fts_build sets + * FTS_STOP or the fts_info field of the node. + */ + if (sp->fts_child) { + if (CHDIR(sp, p->fts_accpath)) { + p->fts_errno = errno; + p->fts_flags |= FTS_DONTCHDIR; + for (p = sp->fts_child; p; p = p->fts_link) + p->fts_accpath = + p->fts_parent->fts_accpath; + } + } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { + if (ISSET(FTS_STOP)) + return (NULL); + return (p); + } + p = sp->fts_child; + sp->fts_child = NULL; + goto name; + } + + /* Move to the next node on this level. */ +next: tmp = p; + if (p = p->fts_link) { + free(tmp); + + /* + * If reached the top, return to the original directory, and + * load the paths for the next root. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + return (NULL); + } + fts_load(sp, p); + return (sp->fts_cur = p); + } + + /* + * User may have called fts_set on the node. If skipped, + * ignore. If followed, get a file descriptor so we can + * get back if necessary. + */ + if (p->fts_instr == FTS_SKIP) + goto next; + if (p->fts_instr == FTS_FOLLOW) { + p->fts_info = fts_stat(sp, p, 1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) + if ((p->fts_symfd = + open(".", O_RDONLY, 0)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + p->fts_instr = FTS_NOINSTR; + } + +name: t = sp->fts_path + NAPPEND(p->fts_parent); + *t++ = '/'; + bcopy(p->fts_name, t, p->fts_namelen + 1); + return (sp->fts_cur = p); + } + + /* Move up to the parent node. */ + p = tmp->fts_parent; + free(tmp); + + if (p->fts_level == FTS_ROOTPARENTLEVEL) { + /* + * Done; free everything up and set errno to 0 so the user + * can distinguish between error and EOF. + */ + free(p); + errno = 0; + return (sp->fts_cur = NULL); + } + + /* Nul terminate the pathname. */ + sp->fts_path[p->fts_pathlen] = '\0'; + + /* + * Return to the parent directory. If at a root node or came through + * a symlink, go back through the file descriptor. Otherwise, cd up + * one directory. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + return (NULL); + } + } else if (p->fts_flags & FTS_SYMFOLLOW) { + if (FCHDIR(sp, p->fts_symfd)) { + saved_errno = errno; + (void)close(p->fts_symfd); + errno = saved_errno; + SET(FTS_STOP); + return (NULL); + } + (void)close(p->fts_symfd); + } else if (!(p->fts_flags & FTS_DONTCHDIR)) { + if (CHDIR(sp, "..")) { + SET(FTS_STOP); + return (NULL); + } + } + p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; + return (sp->fts_cur = p); +} + +/* + * Fts_set takes the stream as an argument although it's not used in this + * implementation; it would be necessary if anyone wanted to add global + * semantics to fts using fts_set. An error return is allowed for similar + * reasons. + */ +/* ARGSUSED */ +int +fts_set(sp, p, instr) + FTS *sp; + FTSENT *p; + int instr; +{ + if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && + instr != FTS_NOINSTR && instr != FTS_SKIP) { + errno = EINVAL; + return (1); + } + p->fts_instr = instr; + return (0); +} + +FTSENT * +fts_children(sp, instr) + register FTS *sp; + int instr; +{ + register FTSENT *p; + int fd; + + if (instr && instr != FTS_NAMEONLY) { + errno = EINVAL; + return (NULL); + } + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* + * Errno set to 0 so user can distinguish empty directory from + * an error. + */ + errno = 0; + + /* Fatal errors stop here. */ + if (ISSET(FTS_STOP)) + return (NULL); + + /* Return logical hierarchy of user's arguments. */ + if (p->fts_info == FTS_INIT) + return (p->fts_link); + + /* + * If not a directory being visited in pre-order, stop here. Could + * allow FTS_DNR, assuming the user has fixed the problem, but the + * same effect is available with FTS_AGAIN. + */ + if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) + return (NULL); + + /* Free up any previous child list. */ + if (sp->fts_child) + fts_lfree(sp->fts_child); + + if (instr == FTS_NAMEONLY) { + sp->fts_options |= FTS_NAMEONLY; + instr = BNAMES; + } else + instr = BCHILD; + + /* + * If using chdir on a relative path and called BEFORE fts_read does + * its chdir to the root of a traversal, we can lose -- we need to + * chdir into the subdirectory, and we don't know where the current + * directory is, so we can't get back so that the upcoming chdir by + * fts_read will work. + */ + if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || + ISSET(FTS_NOCHDIR)) + return (sp->fts_child = fts_build(sp, instr)); + + if ((fd = open(".", O_RDONLY, 0)) < 0) + return (NULL); + sp->fts_child = fts_build(sp, instr); + if (fchdir(fd)) + return (NULL); + (void)close(fd); + return (sp->fts_child); +} + +/* + * This is the tricky part -- do not casually change *anything* in here. The + * idea is to build the linked list of entries that are used by fts_children + * and fts_read. There are lots of special cases. + * + * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is + * set and it's a physical walk (so that symbolic links can't be directories), + * we can do things quickly. First, if it's a 4.4BSD file system, the type + * of the file is in the directory entry. Otherwise, we assume that the number + * of subdirectories in a node is equal to the number of links to the parent. + * The former skips all stat calls. The latter skips stat calls in any leaf + * directories and for any files after the subdirectories in the directory have + * been found, cutting the stat calls by about 2/3. + */ +static FTSENT * +fts_build(sp, type) + register FTS *sp; + int type; +{ + register struct dirent *dp; + register FTSENT *p, *head; + register int nitems; + FTSENT *cur, *tail; + DIR *dirp; + void *adjaddr; + int cderrno, descend, len, level, maxlen, nlinks, saved_errno; + char *cp; + + /* Set current node pointer. */ + cur = sp->fts_cur; + + /* + * Open the directory for reading. If this fails, we're done. + * If being called from fts_read, set the fts_info field. + */ + if ((dirp = opendir(cur->fts_accpath)) == NULL) { + if (type == BREAD) { + cur->fts_info = FTS_DNR; + cur->fts_errno = errno; + } + return (NULL); + } + + /* + * Nlinks is the number of possible entries of type directory in the + * directory if we're cheating on stat calls, 0 if we're not doing + * any stat calls at all, -1 if we're doing stats on everything. + */ + if (type == BNAMES) + nlinks = 0; + else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) + nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); + else + nlinks = -1; + +#ifdef notdef + (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); + (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", + ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); +#endif + /* + * If we're going to need to stat anything or we want to descend + * and stay in the directory, chdir. If this fails we keep going, + * but set a flag so we don't chdir after the post-order visit. + * We won't be able to stat anything, but we can still return the + * names themselves. Note, that since fts_read won't be able to + * chdir into the directory, it will have to return different path + * names than before, i.e. "a/b" instead of "b". Since the node + * has already been visited in pre-order, have to wait until the + * post-order visit to return the error. There is a special case + * here, if there was nothing to stat then it's not an error to + * not be able to stat. This is all fairly nasty. If a program + * needed sorted entries or stat information, they had better be + * checking FTS_NS on the returned nodes. + */ + cderrno = 0; + if (nlinks || type == BREAD) + if (FCHDIR(sp, dirfd(dirp))) { + if (nlinks && type == BREAD) + cur->fts_errno = errno; + cur->fts_flags |= FTS_DONTCHDIR; + descend = 0; + cderrno = errno; + } else + descend = 1; + else + descend = 0; + + /* + * Figure out the max file name length that can be stored in the + * current path -- the inner loop allocates more path as necessary. + * We really wouldn't have to do the maxlen calculations here, we + * could do them in fts_read before returning the path, but it's a + * lot easier here since the length is part of the dirent structure. + * + * If not changing directories set a pointer so that can just append + * each new name into the path. + */ + maxlen = sp->fts_pathlen - cur->fts_pathlen - 1; + len = NAPPEND(cur); + if (ISSET(FTS_NOCHDIR)) { + cp = sp->fts_path + len; + *cp++ = '/'; + } + + level = cur->fts_level + 1; + + /* Read the directory, attaching each entry to the `link' pointer. */ + adjaddr = NULL; + for (head = tail = NULL, nitems = 0; dp = readdir(dirp);) { + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) + continue; + + if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL) + goto mem1; + if (dp->d_namlen > maxlen) { + if (fts_palloc(sp, (size_t)dp->d_namlen)) { + /* + * No more memory for path or structures. Save + * errno, free up the current structure and the + * structures already allocated. + */ +mem1: saved_errno = errno; + if (p) + free(p); + fts_lfree(head); + (void)closedir(dirp); + errno = saved_errno; + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + return (NULL); + } + adjaddr = sp->fts_path; + maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1; + } + + p->fts_pathlen = len + dp->d_namlen + 1; + p->fts_parent = sp->fts_cur; + p->fts_level = level; + + if (cderrno) { + if (nlinks) { + p->fts_info = FTS_NS; + p->fts_errno = cderrno; + } else + p->fts_info = FTS_NSOK; + p->fts_accpath = cur->fts_accpath; + } else if (nlinks == 0 +#ifdef DT_DIR + || nlinks > 0 && + dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN +#endif + ) { + p->fts_accpath = + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; + p->fts_info = FTS_NSOK; + } else { + /* Build a file name for fts_stat to stat. */ + if (ISSET(FTS_NOCHDIR)) { + p->fts_accpath = p->fts_path; + bcopy(p->fts_name, cp, p->fts_namelen + 1); + } else + p->fts_accpath = p->fts_name; + /* Stat it. */ + p->fts_info = fts_stat(sp, p, 0); + + /* Decrement link count if applicable. */ + if (nlinks > 0 && (p->fts_info == FTS_D || + p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) + --nlinks; + } + + /* We walk in directory order so "ls -f" doesn't get upset. */ + p->fts_link = NULL; + if (head == NULL) + head = tail = p; + else { + tail->fts_link = p; + tail = p; + } + ++nitems; + } + (void)closedir(dirp); + + /* + * If had to realloc the path, adjust the addresses for the rest + * of the tree. + */ + if (adjaddr) + fts_padjust(sp, adjaddr); + + /* + * If not changing directories, reset the path back to original + * state. + */ + if (ISSET(FTS_NOCHDIR)) { + if (cp - 1 > sp->fts_path) + --cp; + *cp = '\0'; + } + + /* + * If descended after called from fts_children or called from + * fts_read and didn't find anything, get back. If can't get + * back, done. + */ + if (descend && (!nitems || type == BCHILD) && CHDIR(sp, "..")) { + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + return (NULL); + } + + /* If didn't find anything, return NULL. */ + if (!nitems) { + if (type == BREAD) + cur->fts_info = FTS_DP; + return (NULL); + } + + /* Sort the entries. */ + if (sp->fts_compar && nitems > 1) + head = fts_sort(sp, head, nitems); + return (head); +} + +static u_short +fts_stat(sp, p, follow) + FTS *sp; + register FTSENT *p; + int follow; +{ + register FTSENT *t; + register dev_t dev; + register ino_t ino; + struct stat *sbp, sb; + int saved_errno; + + /* If user needs stat info, stat buffer already allocated. */ + sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; + + /* + * If doing a logical walk, or application requested FTS_FOLLOW, do + * a stat(2). If that fails, check for a non-existent symlink. If + * fail, set the errno from the stat call. + */ + if (ISSET(FTS_LOGICAL) || follow) { + if (stat(p->fts_accpath, sbp)) { + saved_errno = errno; + if (!lstat(p->fts_accpath, sbp)) { + errno = 0; + return (FTS_SLNONE); + } + p->fts_errno = saved_errno; + goto err; + } + } else if (lstat(p->fts_accpath, sbp)) { + p->fts_errno = errno; +err: bzero(sbp, sizeof(struct stat)); + return (FTS_NS); + } + + if (S_ISDIR(sbp->st_mode)) { + /* + * Set the device/inode. Used to find cycles and check for + * crossing mount points. Also remember the link count, used + * in fts_build to limit the number of stat calls. It is + * understood that these fields are only referenced if fts_info + * is set to FTS_D. + */ + dev = p->fts_dev = sbp->st_dev; + ino = p->fts_ino = sbp->st_ino; + p->fts_nlink = sbp->st_nlink; + + if (ISDOT(p->fts_name)) + return (FTS_DOT); + + /* + * Cycle detection is done by brute force when the directory + * is first encountered. If the tree gets deep enough or the + * number of symbolic links to directories is high enough, + * something faster might be worthwhile. + */ + for (t = p->fts_parent; + t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) + if (ino == t->fts_ino && dev == t->fts_dev) { + p->fts_cycle = t; + return (FTS_DC); + } + return (FTS_D); + } + if (S_ISLNK(sbp->st_mode)) + return (FTS_SL); + if (S_ISREG(sbp->st_mode)) + return (FTS_F); + return (FTS_DEFAULT); +} + +static FTSENT * +fts_sort(sp, head, nitems) + FTS *sp; + FTSENT *head; + register int nitems; +{ + register FTSENT **ap, *p; + + /* + * Construct an array of pointers to the structures and call qsort(3). + * Reassemble the array in the order returned by qsort. If unable to + * sort for memory reasons, return the directory entries in their + * current order. Allocate enough space for the current needs plus + * 40 so don't realloc one entry at a time. + */ + if (nitems > sp->fts_nitems) { + sp->fts_nitems = nitems + 40; + if ((sp->fts_array = realloc(sp->fts_array, + (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) { + sp->fts_nitems = 0; + return (head); + } + } + for (ap = sp->fts_array, p = head; p; p = p->fts_link) + *ap++ = p; + qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); + for (head = *(ap = sp->fts_array); --nitems; ++ap) + ap[0]->fts_link = ap[1]; + ap[0]->fts_link = NULL; + return (head); +} + +static FTSENT * +fts_alloc(sp, name, namelen) + FTS *sp; + char *name; + register int namelen; +{ + register FTSENT *p; + size_t len; + + /* + * The file name is a variable length array and no stat structure is + * necessary if the user has set the nostat bit. Allocate the FTSENT + * structure, the file name and the stat structure in one chunk, but + * be careful that the stat structure is reasonably aligned. Since the + * fts_name field is declared to be of size 1, the fts_name pointer is + * namelen + 2 before the first possible address of the stat structure. + */ + len = sizeof(FTSENT) + namelen; + if (!ISSET(FTS_NOSTAT)) + len += sizeof(struct stat) + ALIGNBYTES; + if ((p = malloc(len)) == NULL) + return (NULL); + + /* Copy the name plus the trailing NULL. */ + bcopy(name, p->fts_name, namelen + 1); + + if (!ISSET(FTS_NOSTAT)) + p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); + p->fts_namelen = namelen; + p->fts_path = sp->fts_path; + p->fts_errno = 0; + p->fts_flags = 0; + p->fts_instr = FTS_NOINSTR; + p->fts_number = 0; + p->fts_pointer = NULL; + return (p); +} + +static void +fts_lfree(head) + register FTSENT *head; +{ + register FTSENT *p; + + /* Free a linked list of structures. */ + while (p = head) { + head = head->fts_link; + free(p); + } +} + +/* + * Allow essentially unlimited paths; find, rm, ls should all work on any tree. + * Most systems will allow creation of paths much longer than MAXPATHLEN, even + * though the kernel won't resolve them. Add the size (not just what's needed) + * plus 256 bytes so don't realloc the path 2 bytes at a time. + */ +static int +fts_palloc(sp, more) + FTS *sp; + size_t more; +{ + sp->fts_pathlen += more + 256; + sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen); + return (sp->fts_path == NULL); +} + +/* + * When the path is realloc'd, have to fix all of the pointers in structures + * already returned. + */ +static void +fts_padjust(sp, addr) + FTS *sp; + void *addr; +{ + FTSENT *p; + +#define ADJUST(p) { \ + (p)->fts_accpath = \ + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ + (p)->fts_path = addr; \ +} + /* Adjust the current set of children. */ + for (p = sp->fts_child; p; p = p->fts_link) + ADJUST(p); + + /* Adjust the rest of the tree. */ + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { + ADJUST(p); + p = p->fts_link ? p->fts_link : p->fts_parent; + } +} + +static size_t +fts_maxarglen(argv) + char * const *argv; +{ + size_t len, max; + + for (max = 0; *argv; ++argv) + if ((len = strlen(*argv)) > max) + max = len; + return (max); +} diff --git a/io/fts.h b/io/fts.h new file mode 100644 index 0000000000..84dbe14bc7 --- /dev/null +++ b/io/fts.h @@ -0,0 +1,125 @@ +/* + * 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. + * + * @(#)fts.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _FTS_H_ +#define _FTS_H_ + +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + int fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ + int (*fts_compar)(); /* compare function */ + +#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x002 /* logical walk */ +#define FTS_NOCHDIR 0x004 /* don't change directories */ +#define FTS_NOSTAT 0x008 /* don't get stat info */ +#define FTS_PHYSICAL 0x010 /* physical walk */ +#define FTS_SEEDOT 0x020 /* return dot and dot-dot */ +#define FTS_XDEV 0x040 /* don't cross devices */ +#define FTS_OPTIONMASK 0x07f /* valid user option mask */ + +#define FTS_NAMEONLY 0x080 /* (private) child names only */ +#define FTS_STOP 0x100 /* (private) unrecoverable error */ + int fts_options; /* fts_open options, global flags */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink */ + u_short fts_pathlen; /* strlen(fts_path) */ + u_short fts_namelen; /* strlen(fts_name) */ + + ino_t fts_ino; /* inode */ + dev_t fts_dev; /* device */ + nlink_t fts_nlink; /* link count */ + +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 + short fts_level; /* depth (-1 to N) */ + +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ + u_short fts_info; /* user flags for FTSENT structure */ + +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ + u_short fts_flags; /* private flags for FTSENT structure */ + +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + u_short fts_instr; /* fts_set() instructions */ + + struct stat *fts_statp; /* stat(2) information */ + char fts_name[1]; /* file name */ +} FTSENT; + +#include <sys/cdefs.h> + +__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)); +__END_DECLS + +#endif /* !_FTS_H_ */ diff --git a/io/ftw.c b/io/ftw.c new file mode 100644 index 0000000000..7b264e032e --- /dev/null +++ b/io/ftw.c @@ -0,0 +1,216 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <ftw.h> + + +#ifndef PATH_MAX +#define PATH_MAX 1024 /* XXX */ +#endif + + +/* Traverse one level of a directory tree. */ + +static int +DEFUN (ftw_dir, (dirs, level, descriptors, dir, len, func), + DIR **dirs AND int level AND int descriptors AND + char *dir AND size_t len AND + int EXFUN((*func), (CONST char *file, struct stat *status, + int flag))) +{ + int got; + struct dirent *entry; + + got = 0; + + errno = 0; + + while ((entry = readdir (dirs[level])) != NULL) + { + struct stat s; + int flag, retval, newlev; + + ++got; + + if (entry->d_name[0] == '.' + && (entry->d_namlen == 1 || + (entry->d_namlen == 2 && entry->d_name[1] == '.'))) + { + errno = 0; + continue; + } + + if (entry->d_namlen + len + 1 > PATH_MAX) + { +#ifdef ENAMETOOLONG + errno = ENAMETOOLONG; +#else + errno = ENOMEM; +#endif + return -1; + } + + dir[len] = '/'; + memcpy ((PTR) (dir + len + 1), (PTR) entry->d_name, + entry->d_namlen + 1); + + if (stat (dir, &s) < 0) + { + if (errno != EACCES && errno != ENOENT) + return -1; + flag = FTW_NS; + } + else if (S_ISDIR (s.st_mode)) + { + newlev = (level + 1) % descriptors; + + if (dirs[newlev] != NULL) + closedir (dirs[newlev]); + + dirs[newlev] = opendir (dir); + if (dirs[newlev] != NULL) + flag = FTW_D; + else + { + if (errno != EACCES) + return -1; + flag = FTW_DNR; + } + } + else + flag = FTW_F; + + retval = (*func) (dir, &s, flag); + + if (flag == FTW_D) + { + if (retval == 0) + retval = ftw_dir (dirs, newlev, descriptors, dir, + entry->d_namlen + len + 1, func); + if (dirs[newlev] != NULL) + { + int save; + + save = errno; + closedir (dirs[newlev]); + errno = save; + dirs[newlev] = NULL; + } + } + + if (retval != 0) + return retval; + + if (dirs[level] == NULL) + { + int skip; + + dir[len] = '\0'; + dirs[level] = opendir (dir); + if (dirs[level] == NULL) + return -1; + skip = got; + while (skip-- != 0) + { + errno = 0; + if (readdir (dirs[level]) == NULL) + return errno == 0 ? 0 : -1; + } + } + + errno = 0; + } + + return errno == 0 ? 0 : -1; +} + +/* Call a function on every element in a directory tree. */ + +int +DEFUN(ftw, (dir, func, descriptors), + CONST char *dir AND + int EXFUN((*func), (CONST char *file, struct stat *status, + int flag)) AND + int descriptors) +{ + DIR **dirs; + size_t len; + char buf[PATH_MAX + 1]; + struct stat s; + int flag, retval; + int i; + + if (descriptors <= 0) + descriptors = 1; + + dirs = (DIR **) __alloca (descriptors * sizeof (DIR *)); + i = descriptors; + while (i-- > 0) + dirs[i] = NULL; + + if (stat (dir, &s) < 0) + { + if (errno != EACCES && errno != ENOENT) + return -1; + flag = FTW_NS; + } + else if (S_ISDIR (s.st_mode)) + { + dirs[0] = opendir (dir); + if (dirs[0] != NULL) + flag = FTW_D; + else + { + if (errno != EACCES) + return -1; + flag = FTW_DNR; + } + } + else + flag = FTW_F; + + len = strlen (dir); + memcpy ((PTR) buf, (PTR) dir, len + 1); + + retval = (*func) (buf, &s, flag); + + if (flag == FTW_D) + { + if (retval == 0) + retval = ftw_dir (dirs, 0, descriptors, buf, len, func); + if (dirs[0] != NULL) + { + int save; + + save = errno; + closedir (dirs[0]); + errno = save; + } + } + + return retval; +} diff --git a/io/ftw.h b/io/ftw.h new file mode 100644 index 0000000000..c7c3a88305 --- /dev/null +++ b/io/ftw.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * SVID ftw.h + */ + +#ifndef _FTW_H + +#define _FTW_H 1 +#include <features.h> + +#include <statbuf.h> + +/* The FLAG argument to the user function passed to ftw. */ +#define FTW_F 0 /* Regular file. */ +#define FTW_D 1 /* Directory. */ +#define FTW_DNR 2 /* Unreadable directory. */ +#define FTW_NS 3 /* Unstatable file. */ + +/* Call a function on every element in a directory tree. */ +extern int ftw __P ((__const char *__dir, + int (*__func) (__const char *__file, + struct stat *__status, + int __flag), + int __descriptors)); + +#endif /* ftw.h */ diff --git a/io/getdirname.c b/io/getdirname.c new file mode 100644 index 0000000000..733745b584 --- /dev/null +++ b/io/getdirname.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <string.h> + +/* Return a malloc'd string containing the current directory name. + If the environment variable `PWD' is set, and its value is correct, + that value is used. */ + +char * +DEFUN_VOID(get_current_dir_name) +{ + char *pwd; + struct stat dotstat, pwdstat; + + pwd = getenv ("PWD"); + if (pwd != NULL && + stat (".", &dotstat) == 0 && + stat (pwd, &pwdstat) == 0 && + pwdstat.st_dev == dotstat.st_dev && + pwdstat.st_ino == dotstat.st_ino) + /* The PWD value is correct. Use it. */ + return strdup (pwd); + + return getcwd ((char *) NULL, 0); +} diff --git a/io/getwd.c b/io/getwd.c new file mode 100644 index 0000000000..fdda1cac22 --- /dev/null +++ b/io/getwd.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <string.h> +#include <unistd.h> + +/* Put the absolute pathname of the current working direction in BUF. + If successful, return BUF. If not, put an error message in + BUF and return NULL. BUF should be at least PATH_MAX bytes long. */ +char * +DEFUN(getwd, (buf), char *buf) +{ + if (buf == NULL) + { + errno = EINVAL; + return NULL; + } + +#ifndef PATH_MAX +#define PATH_MAX 1024 /* Arbitrary; this function is unreliable. */ +#endif + if (getcwd (buf, PATH_MAX) == NULL) + { + (void) strncpy (buf, strerror (errno), PATH_MAX); + return NULL; + } + + return buf; +} diff --git a/io/lockf.c b/io/lockf.c new file mode 100644 index 0000000000..91664197ae --- /dev/null +++ b/io/lockf.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +/* lockf is a simplified interface to fcntl's locking facilities. */ + +int +lockf (int fd, int cmd, off_t len) +{ + struct flock fl; + + switch (cmd) + { + case F_TEST: + /* Test the lock: return 0 if FD is unlocked or locked by this process; + return -1, set errno to EACCES, if another process holds the lock. */ + if (fcntl (fd, F_GETLK, &fl) < 0) + return -1; + if (fl.l_type == F_UNLCK || fl.l_pid == getpid ()) + return 0; + errno = EACCES; + return -1; + + case F_ULOCK: + fl.l_type = F_UNLCK; + cmd = F_SETLK; + break; + case F_LOCK: + fl.l_type = F_WRLCK; + cmd = F_SETLKW; + break; + case F_TLOCK: + fl.l_type = F_WRLCK; + cmd = F_SETLK; + break; + + default: + errno = EINVAL; + return -1; + } + + /* lockf is always relative to the current file position. */ + fl.l_whence = SEEK_CUR; + fl.l_start = 0; + + fl.l_len = len; + + return fcntl (fd, cmd, &fl); +} diff --git a/io/poll.h b/io/poll.h new file mode 100644 index 0000000000..06fb41ab89 --- /dev/null +++ b/io/poll.h @@ -0,0 +1 @@ +#include <sys/poll.h> diff --git a/io/pwd.c b/io/pwd.c new file mode 100644 index 0000000000..7ff1948c1d --- /dev/null +++ b/io/pwd.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int +DEFUN_VOID(main) +{ + char *dir = getcwd((char *) NULL, 0); + + if (dir == NULL) + perror("getcwd"); + else + { + puts(dir); + free(dir); + } + + exit(dir == NULL ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/io/sys/fcntl.h b/io/sys/fcntl.h new file mode 100644 index 0000000000..cd304557e7 --- /dev/null +++ b/io/sys/fcntl.h @@ -0,0 +1 @@ +#include <fcntl.h> diff --git a/io/sys/poll.h b/io/sys/poll.h new file mode 100644 index 0000000000..48b9afac9e --- /dev/null +++ b/io/sys/poll.h @@ -0,0 +1,65 @@ +/* Compatibility definitions for System V `poll' interface. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_POLL_H +#define _SYS_POLL_H + +#include <sys/cdefs.h> + +/* Data structure describing a polling request. */ +struct pollfd + { + int fd; /* File descriptor to poll. */ + short int events; /* Types of events poller cares about. */ + short int revents; /* Types of events that actually occurred. */ + }; + +/* Event types that can be polled for. These bits may be set in `events' + to indicate the interesting event types; they will appear in `revents' + to indicate the status of the file descriptor. */ +#define POLLIN 01 /* There is data to read. */ +#define POLLPRI 02 /* There is urgent data to read. */ +#define POLLOUT 04 /* Writing now will not block. */ + +/* Event types always implicitly polled for. These bits need not be set in + `events', but they will appear in `revents' to indicate the status of + the file descriptor. */ +#define POLLERR 010 /* Error condition. */ +#define POLLHUP 020 /* Hung up. */ +#define POLLNVAL 040 /* Invalid polling request. */ + +/* Canonical number of polling requests to read in at a time in poll. */ +#define NPOLLFILE 30 + + +__BEGIN_DECLS + +/* Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors. */ + +extern int poll __P ((struct pollfd *__fds, unsigned long int __nfds, + int __timeout)); + +__END_DECLS + +#endif /* sys/poll.h */ + diff --git a/io/sys/stat.h b/io/sys/stat.h new file mode 100644 index 0000000000..b5b9e363d7 --- /dev/null +++ b/io/sys/stat.h @@ -0,0 +1,168 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 5.6 File Characteristics <sys/stat.h> + */ + +#ifndef _SYS_STAT_H + +#define _SYS_STAT_H 1 +#include <features.h> + +#include <gnu/types.h> /* For __mode_t and __dev_t. */ + +__BEGIN_DECLS + +#include <statbuf.h> + +#if defined(__USE_BSD) || defined(__USE_MISC) +#define S_IFMT __S_IFMT +#define S_IFDIR __S_IFDIR +#define S_IFCHR __S_IFCHR +#define S_IFBLK __S_IFBLK +#define S_IFREG __S_IFREG +#ifdef __S_IFLNK +#define S_IFLNK __S_IFLNK +#endif +#ifdef __S_IFSOCK +#define S_IFSOCK __S_IFSOCK +#endif +#ifdef __S_IFIFO +#define S_IFIFO __S_IFIFO +#endif +#endif + +/* Test macros for file types. */ + +#define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask)) + +#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR) +#define S_ISCHR(mode) __S_ISTYPE((mode), __S_IFCHR) +#define S_ISBLK(mode) __S_ISTYPE((mode), __S_IFBLK) +#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG) +#ifdef __S_IFIFO +#define S_ISFIFO(mode) __S_ISTYPE((mode), __S_IFIFO) +#endif + +#ifdef __USE_GNU +#ifdef __S_IFLNK +#define S_ISLNK(mode) __S_ISTYPE((mode), __S_IFLNK) +#endif +#ifdef __S_IFSOCK +#define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK) +#endif +#endif + + +/* Protection bits. */ + +#define S_ISUID __S_ISUID /* Set user ID on execution. */ +#define S_ISGID __S_ISGID /* Set group ID on execution. */ + +#if defined(__USE_BSD) || defined(__USE_MISC) +/* Save swapped text after use (sticky bit). This is pretty well obsolete. */ +#define S_ISVTX __S_ISVTX +#endif + +#define S_IRUSR __S_IREAD /* Read by owner. */ +#define S_IWUSR __S_IWRITE /* Write by owner. */ +#define S_IXUSR __S_IEXEC /* Execute by owner. */ +/* Read, write, and execute by owner. */ +#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC) + +#if defined(__USE_MISC) && defined(__USE_BSD) +#define S_IREAD S_IRUSR +#define S_IWRITE S_IWUSR +#define S_IEXEC S_IXUSR +#endif + +#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */ +#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */ +#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */ +/* Read, write, and execute by group. */ +#define S_IRWXG (S_IRWXU >> 3) + +#define S_IROTH (S_IRGRP >> 3) /* Read by others. */ +#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */ +#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */ +/* Read, write, and execute by others. */ +#define S_IRWXO (S_IRWXG >> 3) + + +/* Get file attributes for FILE and put them in BUF. */ +extern int __stat __P ((__const char *__file, struct stat *__buf)); +extern int stat __P ((__const char *__file, struct stat *__buf)); + +/* Get file attributes for the file, device, pipe, or socket + that file descriptor FD is open on and put them in BUF. */ +extern int __fstat __P ((int __fd, struct stat *__buf)); +extern int fstat __P ((int __fd, struct stat *__buf)); + +/* Get file attributes about FILE and put them in BUF. + If FILE is a symbolic link, do not follow it. */ +extern int __lstat __P ((__const char *__file, struct stat *__buf)); +#ifdef __USE_BSD +extern int lstat __P ((__const char *__file, struct stat *__buf)); +#endif + +/* Set file access permissions for FILE to MODE. + This takes an `int' MODE argument because that + is what `mode_t's get widened to. */ +extern int __chmod __P ((__const char *__file, __mode_t __mode)); +extern int chmod __P ((__const char *__file, __mode_t __mode)); + +/* Set file access permissions of the file FD is open on to MODE. */ +extern int __fchmod __P ((int __fd, __mode_t __mode)); +#ifdef __USE_BSD +extern int fchmod __P ((int __fd, __mode_t __mode)); +#endif + + +/* Set the file creation mask of the current process to MASK, + and return the old creation mask. */ +extern __mode_t __umask __P ((__mode_t __mask)); +extern __mode_t umask __P ((__mode_t __mask)); + +#ifdef __USE_GNU +/* Get the current `umask' value without changing it. + This function is only available under the GNU Hurd. */ +extern __mode_t getumask __P ((void)); +#endif + +/* Create a new directory named PATH, with permission bits MODE. */ +extern int __mkdir __P ((__const char *__path, __mode_t __mode)); +extern int mkdir __P ((__const char *__path, __mode_t __mode)); + +/* Create a device file named PATH, with permission and special bits MODE + and device number DEV (which can be constructed from major and minor + device numbers with the `makedev' macro above). */ +extern int __mknod __P ((__const char *__path, + __mode_t __mode, __dev_t __dev)); +#if defined(__USE_MISC) || defined(__USE_BSD) +extern int mknod __P ((__const char *__path, + __mode_t __mode, __dev_t __dev)); +#endif + + +/* Create a new FIFO named PATH, with permission bits MODE. */ +extern int mkfifo __P ((__const char *__path, __mode_t __mode)); + +__END_DECLS + +#endif /* sys/stat.h */ diff --git a/io/test-utime.c b/io/test-utime.c new file mode 100644 index 0000000000..565e010815 --- /dev/null +++ b/io/test-utime.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <utime.h> +#include <stdio.h> +#include <sys/stat.h> +#include <unistd.h> + +int +main () +{ + char file[L_tmpnam]; + struct utimbuf ut; + struct stat st; + int fd; + + if (tmpnam (file) == 0) + { + perror ("tmpnam"); + exit (1); + } + + fd = creat (file, 0666); + if (fd < 0) + { + perror ("creat"); + exit (1); + } + close (fd); + + ut.actime = 500000000; + ut.modtime = 500000001; + if (utime (file, &ut)) + { + perror ("utime"); + remove (file); + exit (1); + } + + if (stat (file, &st)) + { + perror ("stat"); + remove (file); + exit (1); + } + + remove (file); + + if (st.st_mtime != ut.modtime) + { + printf ("modtime %ld != %ld\n", st.st_mtime, ut.modtime); + exit (1); + } + + if (st.st_atime != ut.actime) + { + printf ("actime %ld != %ld\n", st.st_atime, ut.actime); + exit (1); + } + + puts ("Test succeeded."); + exit (0); +} diff --git a/io/utime.h b/io/utime.h new file mode 100644 index 0000000000..6985a58859 --- /dev/null +++ b/io/utime.h @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 5.6.6 Set File Access and Modification Times <utime.h> + */ + +#ifndef _UTIME_H + +#define _UTIME_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_NULL +#include <stddef.h> + +#include <gnu/types.h> + +/* Structure describing file times. */ +struct utimbuf + { + __time_t actime; /* Access time. */ + __time_t modtime; /* Modification time. */ + }; + +/* Set the access and modification times of FILE to those given in TIMES. + If TIMES is NULL, set them to the current time. */ +extern int utime __P ((__const char *__file, + __const struct utimbuf *__times)); + +__END_DECLS + +#endif /* utime.h */ diff --git a/libc-symbols.h b/libc-symbols.h new file mode 100644 index 0000000000..d1d9fe4e19 --- /dev/null +++ b/libc-symbols.h @@ -0,0 +1,182 @@ +/* Support macros for making weak and strong aliases for symbols, + and for using symbol sets and linker warnings with GNU ld. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _LIBC_SYMBOLS_H +#define _LIBC_SYMBOLS_H + +/* This file's macros are included implicitly in the compilation of every + file in the C library by -imacros. + + We include config.h which is generated by configure. + It should define for us the following symbols: + + * HAVE_GNU_LD if using GNU ld, with support for weak symbols in a.out, + and for symbol set and warning messages extensions in a.out and ELF. + This implies HAVE_WEAK_SYMBOLS; set by --with-gnu-ld. + * HAVE_ELF if using ELF, which supports weak symbols. + This implies HAVE_WEAK_SYMBOLS; set by --with-elf. + + * HAVE_WEAK_SYMBOLS if weak symbols are available in the assembler and + linker being used. Set by --with-weak-symbols. + + */ +#include <config.h> + +/* This is defined for the compilation of all C library code. + features.h tests this to avoid inclusion of stubs.h while + compiling the library, before stubs.h has been generated. + Some library code that is shared with other packages also + tests this symbol to see if it is being compiled as part + of the C library. */ +#define _LIBC + +/* The symbols in all the user (non-_) macros are C symbols. Predefined + should be HAVE_WEAK_SYMBOLS and/or HAVE_ELF and/or HAVE_GNU_LD. + HAVE_WEAK_SYMBOLS is implied by the other two. HAVE_GNU_LD without + HAVE_ELF implies a.out. */ + +#ifndef HAVE_WEAK_SYMBOLS +#if defined (HAVE_ELF) || defined (HAVE_GNU_LD) +#define HAVE_WEAK_SYMBOLS +#endif +#endif + +#ifndef __SYMBOL_PREFIX +#ifdef HAVE_ELF +#define NO_UNDERSCORES +#else +#include <sysdep.h> /* Should define NO_UNDERSCORES. */ +#endif +#ifdef NO_UNDERSCORES +#define __SYMBOL_PREFIX +#else +#define __SYMBOL_PREFIX "_" +#endif +#endif + +#ifndef C_SYMBOL_NAME +#ifdef NO_UNDERSCORES +#define C_SYMBOL_NAME(name) name +#else +#define C_SYMBOL_NAME(name) _##name +#endif +#endif + +/* Define ALIAS as a strong alias for ORIGINAL. */ +#define strong_alias_asm(original, alias) \ + .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original) +#ifdef ASSEMBLER +#define strong_alias(original, alias) strong_alias_asm (original, alias) +#else +#define strong_alias(original, alias) \ + asm (".set " __SYMBOL_PREFIX #alias "," __SYMBOL_PREFIX #original); +#endif + +/* Define ALIAS as a weak alias for ORIGINAL. + If weak aliases are not available, this defines a strong alias. */ +#ifdef HAVE_WEAK_SYMBOLS +#ifdef ASSEMBLER +#define weak_alias(original, alias) \ + .weak C_SYMBOL_NAME (alias); \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) +#else +#define weak_alias(original, alias) \ + asm (".weak " __SYMBOL_PREFIX #alias "\n" \ + __SYMBOL_PREFIX #alias " = " __SYMBOL_PREFIX #original); +#endif +#else +#define weak_alias(original, alias) strong_alias(original, alias) +#endif + + + +/* When the file using this macro is linked in, the linker + will emit a warning message MSG. */ +#ifdef HAVE_GNU_LD +#ifdef HAVE_ELF +#define link_warning(msg) \ + static const char __evoke_link_warning__[] \ + __attribute__ ((section (".gnu.warning"))) = msg; +#else +#define link_warning(msg) \ + asm(".stabs \"" msg "\",30,0,0,0\n" \ + ".stabs \"__evoke_link_warning__\",1,0,0,0\n"\ + ".stabs \"__evoke_link_warning__\",2,0,0,0\n"); +#endif +#else +/* We will never be heard; they will all die horribly. */ +#define link_warning(msg) +#endif + +/* A canned warning for sysdeps/stub functions. */ +#define stub_warning(name) \ + link_warning ("warning: " #name " is not implemented and will always fail") + +#ifdef HAVE_GNU_LD + +/* Symbol set support macros. */ + +#ifdef HAVE_ELF + +/* Make SYMBOL, which is in the text segment, an element of SET. */ +#define text_set_element(set, symbol) _elf_set_element(set, symbol) +/* Make SYMBOL, which is in the data segment, an element of SET. */ +#define data_set_element(set, symbol) _elf_set_element(set, symbol) +/* Make SYMBOL, which is in the bss segment, an element of SET. */ +#define bss_set_element(set, symbol) _elf_set_element(set, symbol) + +/* These are all done the same way in ELF. + There is a new section created for each set. */ +#define _elf_set_element(set, symbol) \ + static const void *const __elf_set_##set##_element_##symbol##__ \ + __attribute__ ((section (#set))) = &(symbol) + +/* Define SET as a symbol set. This may be required (it is in a.out) to + be able to use the set's contents. */ +#define symbol_set_define(set) symbol_set_declare(set) + +/* Declare SET for use in this module, if defined in another module. */ +#define symbol_set_declare(set) \ + extern void *const __start_##set, *const __stop_##set; + +/* Return a pointer (void *const *) to the first element of SET. */ +#define symbol_set_first_element(set) (&__start_##set) + +/* Return true iff PTR (a void *const *) has been incremented + past the last element in SET. */ +#define symbol_set_end_p(set, ptr) ((ptr) >= &__stop_##set) + +#else /* Not ELF: a.out. */ + +#define text_set_element(set, symbol) \ + asm(".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) +#define data_set_element(set, symbol) \ + asm(".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) +#define bss_set_element(set, symbol) ?error Must use initialized data. +#define symbol_set_define(set) void *const (set)[1]; +#define symbol_set_declare(set) extern void *const (set)[1]; + +#define symbol_set_first_element(set) &(set)[1] +#define symbol_set_end_p(set, ptr) (*(ptr) == 0) + +#endif /* ELF. */ +#endif /* Have GNU ld. */ + +#endif /* libc-symbols.h */ diff --git a/limits.h b/limits.h new file mode 100644 index 0000000000..15ff7d1d83 --- /dev/null +++ b/limits.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.14/2.2.4.2 Limits of integral types <limits.h> + */ + +#include <features.h> + +#ifdef __USE_POSIX +/* POSIX adds things to <limits.h>. */ +#include <posix1_lim.h> +#endif + +#ifdef __USE_POSIX2 +#include <posix2_lim.h> +#endif + + +#if __GNUC__ >= 2 + + /* Get the compiler's limits.h, which defines all the ANSI constants. */ + #ifndef _LIBC_LIMITS_H_ + #define _LIBC_LIMITS_H_ /* This tells it not to look for another. */ + #endif + #ifndef _GCC_LIMITS_H_ /* This is what GCC's file defines. */ + #include_next <limits.h> + #endif + +#else /* Not GCC 2. */ + +/* We only protect from multiple inclusion here, because all the other + #include's protect themselves, and in GCC 2 we may #include_next through + multiple copies of this file before we get to GCC's. */ +#ifndef _LIMITS_H +#define _LIMITS_H + +/* We don't have #include_next. + Define ANSI <limits.h> for standard 32-bit words. */ + +/* These assume 8-bit `char's, 16-bit `short int's, + and 32-bit `int's and `long int's. */ + +/* Number of bits in a `char'. */ +#define CHAR_BIT 8 + +/* Maximum length of any multibyte character in any locale. + Locale-writers should change this as necessary. */ +#define MB_LEN_MAX 1 + +/* Minimum and maximum values a `signed char' can hold. */ +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UCHAR_MAX 255U +#else +#define UCHAR_MAX 255 +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ +#define USHRT_MAX 65535 + +/* Minimum and maximum values a `signed int' can hold. */ +#define INT_MIN (- INT_MAX - 1) +#define INT_MAX 2147483647 + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UINT_MAX 4294967295U +#else +#define UINT_MAX 4294967295 +#endif + +/* Minimum and maximum values a `signed long int' can hold. */ +#define LONG_MIN INT_MIN +#define LONG_MAX INT_MAX + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ +#define ULONG_MAX UINT_MAX + +#endif /* limits.h */ +#endif /* GCC 2. */ diff --git a/locale.h b/locale.h new file mode 100644 index 0000000000..6e0bd916dc --- /dev/null +++ b/locale.h @@ -0,0 +1 @@ +#include <locale/locale.h> diff --git a/locale/.cvsignore b/locale/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/locale/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/locale/C-collate.c b/locale/C-collate.c new file mode 100644 index 0000000000..eddcafa297 --- /dev/null +++ b/locale/C-collate.c @@ -0,0 +1,7 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct collate_info __collate_C = { 0, NULL, NULL, NULL }; +CONST struct collate_info *_collate_info = &__collate_C; diff --git a/locale/C-ctype.c b/locale/C-ctype.c new file mode 100644 index 0000000000..7131a6f78c --- /dev/null +++ b/locale/C-ctype.c @@ -0,0 +1,14 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +extern CONST struct ctype_ctype_info __ctype_ctype_C; +extern CONST struct ctype_mbchar_info __ctype_mbchar_C; +CONST struct ctype_info __ctype_C = + { + (struct ctype_ctype_info*)&__ctype_ctype_C, + (struct ctype_mbchar_info*) &__ctype_mbchar_C + }; + +CONST struct ctype_info *_ctype_info = &__ctype_C; diff --git a/locale/C-ctype_ct.c b/locale/C-ctype_ct.c new file mode 100644 index 0000000000..b77e809a52 --- /dev/null +++ b/locale/C-ctype_ct.c @@ -0,0 +1,793 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> +#include <ctype.h> + +CONST unsigned short int __ctype_b_C[] = + { + 0, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl|_ISspace|_ISblank, + _IScntrl|_ISspace, + _IScntrl|_ISspace, + _IScntrl|_ISspace, + _IScntrl|_ISspace, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _ISspace|_NOgraph|_ISblank, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISdigit|_IShex, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper|_IShex, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISalpha|_ISupper, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower|_IShex, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISalpha|_ISlower, + _ISpunct, + _ISpunct, + _ISpunct, + _ISpunct, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + _IScntrl, + }; +CONST short int __ctype_tolower_C[] = + { + -1, + 0000, + 0001, + 0002, + 0003, + 0004, + 0005, + 0006, + 0007, + 0010, + 0011, + 0012, + 0013, + 0014, + 0015, + 0016, + 0017, + 0020, + 0021, + 0022, + 0023, + 0024, + 0025, + 0026, + 0027, + 0030, + 0031, + 0032, + 0033, + 0034, + 0035, + 0036, + 0037, + 0040, + '!', + '"', + '#', + '$', + '%', + '&', + '\'', + '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + '@', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '[', + '\\', + ']', + '^', + '_', + '`', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '{', + '|', + '}', + '~', + 0177, + 0200, + 0201, + 0202, + 0203, + 0204, + 0205, + 0206, + 0207, + 0210, + 0211, + 0212, + 0213, + 0214, + 0215, + 0216, + 0217, + 0220, + 0221, + 0222, + 0223, + 0224, + 0225, + 0226, + 0227, + 0230, + 0231, + 0232, + 0233, + 0234, + 0235, + 0236, + 0237, + 0240, + 0241, + 0242, + 0243, + 0244, + 0245, + 0246, + 0247, + 0250, + 0251, + 0252, + 0253, + 0254, + 0255, + 0256, + 0257, + 0260, + 0261, + 0262, + 0263, + 0264, + 0265, + 0266, + 0267, + 0270, + 0271, + 0272, + 0273, + 0274, + 0275, + 0276, + 0277, + 0300, + 0301, + 0302, + 0303, + 0304, + 0305, + 0306, + 0307, + 0310, + 0311, + 0312, + 0313, + 0314, + 0315, + 0316, + 0317, + 0320, + 0321, + 0322, + 0323, + 0324, + 0325, + 0326, + 0327, + 0330, + 0331, + 0332, + 0333, + 0334, + 0335, + 0336, + 0337, + 0340, + 0341, + 0342, + 0343, + 0344, + 0345, + 0346, + 0347, + 0350, + 0351, + 0352, + 0353, + 0354, + 0355, + 0356, + 0357, + 0360, + 0361, + 0362, + 0363, + 0364, + 0365, + 0366, + 0367, + 0370, + 0371, + 0372, + 0373, + 0374, + 0375, + 0376, + 0377, + }; +CONST short int __ctype_toupper_C[] = + { + -1, + 0000, + 0001, + 0002, + 0003, + 0004, + 0005, + 0006, + 0007, + 0010, + 0011, + 0012, + 0013, + 0014, + 0015, + 0016, + 0017, + 0020, + 0021, + 0022, + 0023, + 0024, + 0025, + 0026, + 0027, + 0030, + 0031, + 0032, + 0033, + 0034, + 0035, + 0036, + 0037, + 0040, + '!', + '"', + '#', + '$', + '%', + '&', + '\'', + '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + '@', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '[', + '\\', + ']', + '^', + '_', + '`', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + '{', + '|', + '}', + '~', + 0177, + 0200, + 0201, + 0202, + 0203, + 0204, + 0205, + 0206, + 0207, + 0210, + 0211, + 0212, + 0213, + 0214, + 0215, + 0216, + 0217, + 0220, + 0221, + 0222, + 0223, + 0224, + 0225, + 0226, + 0227, + 0230, + 0231, + 0232, + 0233, + 0234, + 0235, + 0236, + 0237, + 0240, + 0241, + 0242, + 0243, + 0244, + 0245, + 0246, + 0247, + 0250, + 0251, + 0252, + 0253, + 0254, + 0255, + 0256, + 0257, + 0260, + 0261, + 0262, + 0263, + 0264, + 0265, + 0266, + 0267, + 0270, + 0271, + 0272, + 0273, + 0274, + 0275, + 0276, + 0277, + 0300, + 0301, + 0302, + 0303, + 0304, + 0305, + 0306, + 0307, + 0310, + 0311, + 0312, + 0313, + 0314, + 0315, + 0316, + 0317, + 0320, + 0321, + 0322, + 0323, + 0324, + 0325, + 0326, + 0327, + 0330, + 0331, + 0332, + 0333, + 0334, + 0335, + 0336, + 0337, + 0340, + 0341, + 0342, + 0343, + 0344, + 0345, + 0346, + 0347, + 0350, + 0351, + 0352, + 0353, + 0354, + 0355, + 0356, + 0357, + 0360, + 0361, + 0362, + 0363, + 0364, + 0365, + 0366, + 0367, + 0370, + 0371, + 0372, + 0373, + 0374, + 0375, + 0376, + 0377, + }; + + +CONST struct ctype_ctype_info __ctype_ctype_C = + { + (unsigned short int *) __ctype_b_C, + (short int *) __ctype_tolower_C, + (short int *) __ctype_toupper_C + }; diff --git a/locale/C-ctype_mb.c b/locale/C-ctype_mb.c new file mode 100644 index 0000000000..fb2309a88d --- /dev/null +++ b/locale/C-ctype_mb.c @@ -0,0 +1,9 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct ctype_mbchar_info __ctype_mbchar_C = + { + 0, NULL + }; diff --git a/locale/C-monetary.c b/locale/C-monetary.c new file mode 100644 index 0000000000..1e5990f317 --- /dev/null +++ b/locale/C-monetary.c @@ -0,0 +1,22 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct monetary_info __monetary_C = + { + (char *) "", (char *) "", + (char *) "", (char *) "", + (char *) "", + (char *) "", (char *) "", + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX + }; + +CONST struct monetary_info *_monetary_info = &__monetary_C; diff --git a/locale/C-numeric.c b/locale/C-numeric.c new file mode 100644 index 0000000000..890ab37d16 --- /dev/null +++ b/locale/C-numeric.c @@ -0,0 +1,12 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct numeric_info __numeric_C = + { + (char *) ".", (char *) "", + (char *) "" + }; + +CONST struct numeric_info *_numeric_info = &__numeric_C; diff --git a/locale/C-response.c b/locale/C-response.c new file mode 100644 index 0000000000..d823886b34 --- /dev/null +++ b/locale/C-response.c @@ -0,0 +1,12 @@ +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct response_info __response_C = + { + (char *) "[yY][[:alpha:]]", + (char *) "[nN][[:alpha:]]" + }; + +CONST struct response_info *_response_info = &__response_C; diff --git a/locale/C-time.c b/locale/C-time.c new file mode 100644 index 0000000000..43930612ef --- /dev/null +++ b/locale/C-time.c @@ -0,0 +1,25 @@ +/* Built-in time information for `C' locale, + generated Thu Jan 1 00:00:00 1970 by li2c. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> + + +CONST struct time_info __time_C = + { + { +(char *) "Sun", (char *) "Mon", (char *) "Tue", (char *) "Wed", (char *) "Thu", (char *) "Fri", (char *) "Sat", }, + + { +(char *) "Sunday", (char *) "Monday", (char *) "Tuesday", (char *) "Wednesday", (char *) "Thursday", (char *) "Friday", (char *) "Saturday", }, + { +(char *) "Jan", (char *) "Feb", (char *) "Mar", (char *) "Apr", (char *) "May", (char *) "Jun", (char *) "Jul", (char *) "Aug", (char *) "Sep", (char *) "Oct", (char *) "Nov", (char *) "Dec", }, + { +(char *) "January", (char *) "February", (char *) "March", (char *) "April", (char *) "May", (char *) "June", (char *) "July", (char *) "August", (char *) "September", (char *) "October", (char *) "November", (char *) "December", }, + { (char *) "AM", (char *) "PM" }, + (char *) "%a %b %d %H:%M:%S %Y", (char *) "%m/%d/%y", (char *) "%H:%M:%S", + (char *) "GMT", (char *) "" + }; + +CONST struct time_info *_time_info = &__time_C; diff --git a/locale/Makefile b/locale/Makefile new file mode 100644 index 0000000000..630b96032f --- /dev/null +++ b/locale/Makefile @@ -0,0 +1,31 @@ +# Copyright (C) 1991, 1992 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for locales. +# +subdir := locale + +headers := locale.h localeinfo.h + +routines := setlocale localeconv +aux := C-collate C-ctype C-ctype_ct C-ctype_mb \ + C-monetary C-numeric C-response C-time + + +include ../Rules diff --git a/locale/locale.h b/locale/locale.h new file mode 100644 index 0000000000..80f9f90e7b --- /dev/null +++ b/locale/locale.h @@ -0,0 +1,97 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.4 LOCALIZATION <locale.h> + */ + +#ifndef _LOCALE_H + +#define _LOCALE_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* These are the possibilities for the first argument to setlocale. + Note that although they are bit masks, they cannot be OR'd together + to form a new argument to pass. They must be used one at a time. */ +#define LC_COLLATE (1 << 0) +#define LC_CTYPE (1 << 1) +#define LC_MONETARY (1 << 2) +#define LC_NUMERIC (1 << 3) +#define LC_TIME (1 << 4) +#define LC_RESPONSE (1 << 5) +#define LC_ALL (LC_COLLATE|LC_CTYPE|LC_MONETARY|LC_NUMERIC|LC_TIME|\ + LC_RESPONSE) + + +/* Structure giving information about numeric and monetary notation. */ +struct lconv +{ + /* Numeric (non-monetary) information. */ + + char *decimal_point; /* Decimal point character. */ + char *thousands_sep; /* Thousands separator. */ + /* Each element is the number of digits in each group; + elements with higher indices are farther left. + An element with value CHAR_MAX means that no further grouping is done. + An element with value 0 means that the previous element is used + for all groups farther left. */ + char *grouping; + + /* Monetary information. */ + + /* First three chars are a currency symbol from ISO 4217. + Fourth char is the separator. Fifth char is '\0'. */ + char *int_curr_symbol; + char *currency_symbol; /* Local currency symbol. */ + char *mon_decimal_point; /* Decimal point character. */ + char *mon_thousands_sep; /* Thousands separator. */ + char *mon_grouping; /* Like `grouping' element (above). */ + char *positive_sign; /* Sign for positive values. */ + char *negative_sign; /* Sign for negative values. */ + char int_frac_digits; /* Int'l fractional digits. */ + char frac_digits; /* Local fractional digits. */ + /* 1 if currency_symbol precedes a positive value, 0 if succeeds. */ + char p_cs_precedes; + /* 1 iff a space separates currency_symbol from a positive value. */ + char p_sep_by_space; + /* 1 if currency_symbol precedes a negative value, 0 if succeeds. */ + char n_cs_precedes; + /* 1 iff a space separates currency_symbol from a negative value. */ + char n_sep_by_space; + /* Positive and negative sign positions: + 0 Parentheses surround the quantity and currency_symbol. + 1 The sign string precedes the quantity and currency_symbol. + 2 The sign string succedes the quantity and currency_symbol. + 3 The sign string immediately precedes the currency_symbol. + 4 The sign string immediately succedes the currency_symbol. */ + char p_sign_posn; + char n_sign_posn; +}; + + +/* Set and/or return the current locale. */ +extern char *setlocale __P ((int __category, __const char *__locale)); + +/* Return the numeric/monetary information for the current locale. */ +extern struct lconv *localeconv __P ((void)); + +__END_DECLS + +#endif /* locale.h */ diff --git a/locale/localeconv.c b/locale/localeconv.c new file mode 100644 index 0000000000..1f15165fb3 --- /dev/null +++ b/locale/localeconv.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <locale.h> + + +/* Return monetary and numeric information about the current locale. */ +struct lconv * +DEFUN_VOID(localeconv) +{ + static struct lconv result; + + result.decimal_point = (char *) _numeric_info->decimal_point; + result.thousands_sep = (char *) _numeric_info->thousands_sep; + result.grouping = (char *) _numeric_info->grouping; + + result.int_curr_symbol = (char *) _monetary_info->int_curr_symbol; + result.currency_symbol = (char *) _monetary_info->currency_symbol; + result.mon_decimal_point = (char *) _monetary_info->mon_decimal_point; + result.mon_thousands_sep = (char *) _monetary_info->mon_thousands_sep; + result.mon_grouping = (char *) _monetary_info->mon_grouping; + result.positive_sign = (char *) _monetary_info->positive_sign; + result.negative_sign = (char *) _monetary_info->negative_sign; + result.int_frac_digits = _monetary_info->int_frac_digits; + result.frac_digits = _monetary_info->frac_digits; + result.p_cs_precedes = _monetary_info->p_cs_precedes; + result.p_sep_by_space = _monetary_info->p_sep_by_space; + result.n_cs_precedes = _monetary_info->p_cs_precedes; + result.n_sep_by_space = _monetary_info->n_sep_by_space; + result.p_sign_posn = _monetary_info->p_sign_posn; + result.n_sign_posn = _monetary_info->n_sign_posn; + + return &result; +} diff --git a/locale/localeinfo.h b/locale/localeinfo.h new file mode 100644 index 0000000000..5ba5fefa05 --- /dev/null +++ b/locale/localeinfo.h @@ -0,0 +1,208 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Locale-specific information. */ + +#ifndef _LOCALEINFO_H + +#define _LOCALEINFO_H 1 + +#define __need_size_t +#define __need_wchar_t +#include <stddef.h> +#include <limits.h> + + +/* Change these if the `wchar_t' type is changed. */ +#define WCHAR_MAX ((wchar_t) UCHAR_MAX) + + +/* Used by multibyte char functions. */ +typedef struct +{ + char *string; /* Bytes. */ + size_t len; /* # of bytes. */ + long int shift; /* # of mb_char's to shift. */ +} mb_char; + +struct ctype_mbchar_info +{ + size_t mb_max; /* Max MB char length. */ + mb_char *mb_chars; /* MB chars. */ +}; + +struct ctype_ctype_info +{ + unsigned short int *ctype_b; /* Characteristics. */ + short int *ctype_tolower; /* Case mappings. */ + short int *ctype_toupper; /* Case mappings. */ +}; + +struct ctype_info +{ + struct ctype_ctype_info *ctype; + struct ctype_mbchar_info *mbchar; +}; + +extern __const struct ctype_info *_ctype_info; + +/* These are necessary because they are used in a header file. */ +extern __const unsigned short int *__ctype_b; +extern __const short int *__ctype_tolower; +extern __const short int *__ctype_toupper; + + +/* Used by strcoll and strxfrm. */ +typedef struct +{ + unsigned char *values; + size_t nvalues; +} literal_value; + +typedef struct +{ + union + { + literal_value literal; + /* %%% This may become a regex_t in the future. */ + char *regexp; + } replace, with; + unsigned int regexp:1; +} subst; + +struct collate_info +{ + size_t nsubsts; + subst *substs; + + unsigned char *values; + unsigned char *offsets; +}; + +extern __const struct collate_info *_collate_info; + + +/* Used by strtod, atof. */ +struct numeric_info +{ + char *decimal_point; + char *thousands_sep; + char *grouping; +}; + +extern __const struct numeric_info *_numeric_info; + + +/* Used in the return value of localeconv. */ +struct monetary_info +{ + char *int_curr_symbol; + char *currency_symbol; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; +}; + +extern __const struct monetary_info *_monetary_info; + + +/* Used by strftime, asctime. */ +struct time_info +{ + char *abbrev_wkday[7]; /* Short weekday names. */ + char *full_wkday[7]; /* Full weekday names. */ + char *abbrev_month[12]; /* Short month names. */ + char *full_month[12]; /* Full month names. */ + char *ampm[2]; /* "AM" and "PM" strings. */ + + char *date_time; /* Appropriate date and time format. */ + char *date; /* Appropriate date format. */ + char *time; /* Appropriate time format. */ + + char *ut0; /* Name for GMT. */ + char *tz; /* Default TZ value. */ +}; + +extern __const struct time_info *_time_info; + +struct response_info +{ + /* Regexp for affirmative answers. */ + char *yesexpr; + + /* Regexp for negative answers. */ + char *noexpr; +}; + +extern __const struct response_info *_response_info; + +/* Locale structure. */ +typedef struct +{ + char *name; + int categories; + + unsigned int allocated:1; + + int subcategories; + size_t num_sublocales; + struct sub_locale *sublocales; + + __ptr_t *info; +} locale; + +typedef struct sub_locale +{ + unsigned int pointer:1; + + int categories; + char *name; + + locale *locale; +} sublocale; + + +/* This is the magic number that localeinfo object files begin with. + In case you're wondering why I chose the value 0x051472CA, it's + because I was born on 05-14-72 in Oakland, CA. */ +#define LIMAGIC 0x051472CA +/* This is the magic number that precedes each category-specific section + of a localeinfo object file. It's the arbitrary magic number above, + but modified by the category so that it's different from the per-file + magic number and unique for each category. */ +#define CATEGORY_MAGIC(x) (LIMAGIC ^ (x)) + +extern __const char *__lidir, *__lidefault; + +extern locale *__find_locale __P ((int categories, __const char *name)); +extern locale *__new_locale __P ((locale *)); +extern locale *__localefile __P ((__const char *file)); +extern void __free_locale __P ((locale *)); + + +#endif /* localeinfo.h */ diff --git a/locale/setlocale.c b/locale/setlocale.c new file mode 100644 index 0000000000..784ccb1272 --- /dev/null +++ b/locale/setlocale.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <errno.h> +#include <locale.h> +#include <string.h> + + +/* Switch to the locale called NAME in CATEGORY. + Return a string describing the locale. This string can + be used as the NAME argument in a later call. + If NAME is NULL, don't switch locales, but return the current one. + If NAME is "", switch to a locale based on the environment variables, + as per POSIX. Return NULL on error. */ +char * +DEFUN(setlocale, (category, name), int category AND CONST char *name) +{ + /* Braindead implementation until I finish the fancy one. */ + + if (name == NULL || name[0] == '\0') + return (char *) "C"; + + if (!strcmp(name, "C") || !strcmp(name, "POSIX")) + return (char *) name; + + errno = EINVAL; + return NULL; +} diff --git a/localeinfo.h b/localeinfo.h new file mode 100644 index 0000000000..7b0f3e0639 --- /dev/null +++ b/localeinfo.h @@ -0,0 +1 @@ +#include <locale/localeinfo.h> diff --git a/mach/.cvsignore b/mach/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/mach/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/mach/Machrules b/mach/Machrules new file mode 100644 index 0000000000..4f91d9bab7 --- /dev/null +++ b/mach/Machrules @@ -0,0 +1,212 @@ +# Rules for MiG interfaces that want to go into the C library. + +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Makefiles may define these variable before including this file: +# user-interfaces Names of interfaces to put user stubs in for. +# server-interfaces Names of interfaces to put server stubs in for. +# interface-library Name of interface library to build and install. +# This file sets: +# interface-headers Names of generated interface header files. +# interface-routines Names of generated interface routines. +# All user stubs are put in individual files, prefixed with RPC_; header +# for both __ and non-__ names is put in foo.h. Server interfaces are +# written to foo_server.c and foo_server.h; the server functions are called +# _S_rpcname. + +# Includers can also add to or modify `migdefines' to set MiG flags. + +all: + +# Make sure no value comes from the environment, since we append to it. +# This is done also in ../Rules, but we append to the value before +# including Rules, which changes the origin. +ifneq "$(findstring env,$(origin generated))" "" +generated := +endif + + +include ../Makeconfig + +ifndef MIG +MIG = mig +endif +MIGFLAGS = -DMACH_IPC_COMPAT=0 -DSTANDALONE -DTypeCheck=0 \ + $(+includes) $(migdefines) -subrprefix __ + +.SUFFIXES: .defs # Just to set specified_rule_matched. + +define nl # This is needed by *.ir. + + +endef +ifdef user-interfaces +*.ir := $(addprefix $(objpfx),$(foreach if,$(user-interfaces),$(if).ir)) +ifndef inhibit_interface_rules +include $(*.ir) +endif +ifneq "$(*.ir)" "$(wildcard $(*.ir))" +# If any .ir file is missing, we will be unable to make all the deps. +no_deps=t +endif +generated += $(*.ir:$(objpfx)%=%) +endif + + +# %.ir defines a variable `%-calls', which lists the RPCs defined by +# %.defs, and a rule to build $(%-calls:%=RPC_$(%-userprefix)%.c) from +# %.defs, where $(%-userprefix) is the user prefix given in %.defs. We use +# the kludgificacious method of defining a pattern rule to build files +# matching patterns we are pretty damn sure will only match the particular +# files we have in mind. To be so damn sure, we use the silly names +# RPC_*.c and the pattern R%C_*.c because using __*.c and _%*.c (or any +# other useful pattern) causes the rule for `host_info' to also match +# `xxx_host_info', and analogous lossage. +# +# While we're at it, we figure out the imports used by %.defs and give them +# as dependencies of the object files for the generated RPC_*.c files. +# +# Depend on %.h just so they will be built from %.uh in the +# makefile-rebuilding run which builds %.ir; otherwise, %.uh is built as an +# intermediate in order to make %.ir and then removed before re-exec, when +# %.uh is built all over again to build %.h. +$(objpfx)%.ir: $(objpfx)%.uh $(objpfx)%.h + (awk "NF == 4 && (\$$2 == \"Routine\" || \$$2 == \"SimpleRoutine\")\ + { printf \"$*-calls += %s\\n\", \$$3 } \ + /^#include/ { printf \"$*-imports += %s\\n\", \$$2 }" $< ;\ + echo '$$($*-calls:%=$$(objpfx)R\%C_%.c): $$(objpfx)$*.ustamp ;';\ + echo '$$($*-calls:%=$$(objpfx)RPC_%.o): $$($*-imports:<%>=%)' ;\ + ) > $@-new + mv $@-new $@ +vpath Machrules ../mach # Find ourselves. + +ifndef transform-user-stub-output +transform-user-stub-output = tmp +define transform-user-stub +echo "weak_alias (__$$call, $$call)" >> $(objpfx)tmp_$${call}.c; +endef +endif + +# Not an implicit rule so the stamps are never removed as intermediates! +$(patsubst %,$(objpfx)%.ustamp,$(user-interfaces)): $(objpfx)%.ustamp: %.defs + $(MIG) $< $(MIGFLAGS) $(user-MIGFLAGS) \ + -prefix __ -i $(objpfx)tmp_ \ + -server /dev/null -user /dev/null -header /dev/null + for call in $($*-calls); do \ + $(transform-user-stub) \ + ../move-if-change $(objpfx)$(transform-user-stub-output)_$${call}.c \ + $(objpfx)RPC_$${call}.c; \ + done + touch $@ + +# Look for the server stub files where they will be written. +vpath %_server.c $(addprefix $(objpfx),$(sort $(dir $(server-interfaces)))) + +# Build the server stubs in $(objdir). +$(objpfx)%_server.c $(objpfx)%_server.h: %.defs + $(MIG) $< $(MIGFLAGS) $(server-MIGFLAGS) \ + -prefix _S_ \ + -user /dev/null -header /dev/null \ + -server $(@:.h=.c) -sheader $(@:.c=.h) + +# To get header files that declare both the straight and __ functions, +# we generate two files and paste them together. +$(objpfx)%.uh: %.defs; $(mig.uh) +define mig.uh +$(make-target-directory) +$(MIG) $< $(MIGFLAGS) \ + -header $@ -server /dev/null -user /dev/null +endef +$(objpfx)%.__h: %.defs; $(mig.__h) +define mig.__h +$(make-target-directory) +$(MIG) $< $(MIGFLAGS) -prefix __ \ + -header $@ -server /dev/null -user /dev/null +endef + +$(objpfx)%.h: $(objpfx)%.__h $(objpfx)%.uh +# The last line of foo.__h is "#endif _foo_user_". +# The first two lines of foo.uh are "#ifndef _foo_user_"/"#define _foo_user_". + (sed -e '$$d' $<; sed -e '1,2d' $(word 2,$^)) > $@-new + mv $@-new $@ + +interface-routines := $(foreach if,$(user-interfaces), \ + $(addprefix RPC_,$($(if)-calls))) \ + $(server-interfaces:%=%_server) +interface-headers := $(user-interfaces:%=%.h) \ + $(server-interfaces:%=%_server.h) + +# Remove the generated user stub source and header files, +# and don't distribute them. +mach-generated = $(interface-routines:%=%.c) \ + $(foreach h,$(interface-headers:%.h=%),$h.h $h.uh $h.__h) +generated += $(mach-generated) + +# These are needed to generate the dependencies. +before-compile += $(interface-headers:%=$(objpfx)%) + +# Don't let these be intermediate files and get removed. +$(foreach h,$(interface-headers:%.h=$(objpfx)%),$h.h $h.__h $h.uh) : +$(interface-routines:%=$(objpfx)%.c) : + +# Convenient target to generate all the headers. +.PHONY: interface-headers +interface-headers: $(interface-headers) + +# Don't automatically generate dependencies for the sources we generate. +# There are likely to be a whole lot of them, and we know their +# dependencies ahead of time anyway because they're boilerplate. +omit-deps += $(interface-routines) + +# Specify the static dependencies of the generated files. +$(foreach if,$(user-interfaces),$($(if)-calls:%=$(objpfx)RPC_%.o))): \ + mach/boolean.h mach/kern_return.h mach/message.h mach/notify.h \ + mach/mach_types.h mach/mig_errors.h mach/mig_support.h mach/msg_type.h \ + $(..)libc-symbols.h $(objpfx)config.h +$(server-interfaces:%=$(objpfx)%.o): \ + mach/boolean.h mach/kern_return.h mach/message.h mach/mig_errors.h \ + mach/mig_support.h mach/std_types.h +# The MiG-generated sources also depend on the imports in their .defs files. +# These dependencies are generated into the .ir files above. + +# If defined, $(interface-library) is `libNAME.a'. It is to be a library +# containing all the MiG-generated functions for the specified interfaces. + +ifdef interface-library + +$(interface-library)-objs := $(interface-routines:%=%.o) + +install-lib += $(interface-library) +extra-objs += $($(interface-library)-objs) + +$(objpfx)$(interface-library): $(addprefix $(objpfx),\ + $($(interface-library)-objs)) +ifdef objdir + cd $(objdir); $(AR) cru$(verbose) $(@:$(objpfx)%=%) $(^:$(objpfx)%=%) +else + $(AR) cru$(verbose) $@ $^ +endif + $(RANLIB) $@ + +lib-noranlib: $(objpfx)$(interface-library) + +mostlyclean: + -rm -f $(objpfx)$(interface-library) + +endif diff --git a/mach/Makefile b/mach/Makefile new file mode 100644 index 0000000000..ce2670092e --- /dev/null +++ b/mach/Makefile @@ -0,0 +1,195 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := mach + +all: + +# Some things below (but before including Rules) use configuration variables. +include ../Makeconfig + + +headers = mach_init.h mach.h mach_error.h mach-shortcuts.h \ + $(interface-headers) mach/mach.h mach/mig_support.h mach/error.h \ + $(lock-headers) machine-sp.h +distribute = thread_state.h +lock = spin-solid spin-lock mutex-solid +lock-headers = lock-intern.h machine-lock.h spin-lock.h +routines = $(mach-syscalls) $(mach-shortcuts) \ + mach_init mig_strncpy msg \ + mig-alloc mig-dealloc mig-reply \ + msg-destroy msgserver \ + mach_error errstring error_compat errsystems \ + devstream bootprivport setup-thread $(lock) +# The RPC interfaces go in a separate library. +interface-library := libmachuser.a +user-interfaces := $(addprefix mach/,mach_interface mach_port mach_host \ + memory_object_user \ + memory_object_default \ + exc mach4 \ + )\ + $(addprefix device/,device device_request) +server-interfaces := device/device_reply mach/exc mach/notify +tests := hello +# It is important that we do not use the wildcard function to expand +# `err_*.sub'. Leaving the wildcard allows Make-dist to find all matching +# files in all sysdep directories. +distribute += Machrules syscalls.awk shortcut.awk \ + errorlib.h err_*.sub + + +# Clear any environment value. +generated = + +# Get the proper definition of `mach-srcdir'. +include ../sysdeps/mach/Makefile + +# Use and install the Mach header files directly out of the Mach kernel source. + +# Find the MiG defs files in the kernel source. +vpath %.defs $(mach-srcdir) + +# Install all .h and .defs files we find in some of the kernel's source +# directories and their subdirectories (in MK82, max one level deep). +mach-src-headers := $(wildcard $(foreach dir,mach device mach_debug \ + $(config-machine),\ + $(addprefix $(mach-srcdir)/$(dir)/,\ + *.defs *.h \ + */*.defs */*.h))) +# Exclude mach/machine/*. A symlink will be installed for mach/machine. +# Exclude $(headers) for Mach files we have our own versions of. +mach-headers = $(filter-out mach/machine/% $(headers),\ + $(mach-src-headers:$(mach-srcdir)/%=%)) +# Rename Mach's sys/version.h to mach/version.h. +mach-headers := $(patsubst sys/version.h,mach/version.h,$(mach-headers)) + +# Don't distribute the Mach headers; they are in the Mach distribution. +dont_distribute = $(mach-headers) + +# DO NOT try to remake these in any way!!! +$(addprefix $(mach-srcdir)/,$(mach-headers)) : ; +install-others += $(addprefix $(includedir)/,$(mach-headers)) +$(includedir)/%: $(mach-srcdir)/%; $(do-install) + +# Make symlinks for machine and mach/machine in the include directory. +install-others += $(includedir)/mach/machine $(includedir)/machine +$(includedir)/mach/machine $(includedir)/machine: $(common-objpfx)config.make + -rm -f $@ + cd $(@D); ln -s $(config-machine) $(@F) + +# Install Mach's <sys/version.h> as <mach/version.h>. +install-others += $(includedir)/mach/version.h +$(includedir)/mach/version.h: $(mach-srcdir)/sys/version.h; $(do-install) + +# Define mach-syscalls and sysno-*. +ifndef inhibit_mach_syscalls +include $(objpfx)mach-syscalls.mk +endif +$(objpfx)mach-syscalls.mk: mach/syscall_sw.h syscalls.awk +# Go kludges!!! + sed -n -e '/Unix server implement them/,$$d' \ + -e 's/^kernel_trap(\(.*\),\([-0-9]*\),\([0-9]*\))$$/\1 \2 \3/p'\ + < $< | awk -f $(word 2,$^) > $@-new + mv $@-new $@ +generated += mach-syscalls.mk + +ifndef mach-syscalls +# We cannot make the deps properly until we know how to make the system +# call functions, and for that we must know what they all are. +no_deps=t +else +$(mach-syscalls:%=$(objpfx)%.S): $(objpfx)%.S: $(objpfx)mach-syscalls.mk + (echo '#include <sysdep.h>'; \ + echo 'kernel_trap(__$*,$(sysno-$*),$(nargs-$*))'; \ + echo 'weak_alias (__$*, $*)') > $@-new + mv $@-new $@ +generated += $(mach-syscalls:=.S) +endif # mach-syscalls + +# syscall_device_writev_request has no RPC equivalent. +mach-shortcuts := $(filter-out device_writev_request,\ + $(patsubst syscall_%,%,$(filter syscall_%,$(mach-syscalls)))) + +ifndef mach-shortcuts +# Forget about mach_interface.defs for this run. On the next run, +# $(mach-shortcuts) will be set, and that will change how +# mach_interface.defs is processed: it will get the -D flags below. +user-interfaces := $(filter-out mach/mach_interface \ + mach/mach_port mach/mach_host mach/mach4 \ + device/device_request,\ + $(user-interfaces)) +endif + +# Make the MiG stubs for $(mach-shortcuts) be CALL_rpc. +migdefines += $(foreach call,$(mach-shortcuts),-D$(call)=$(call)_rpc) +mach/mach_interface.uh mach/mach_port.uh: $(objpfx)mach-syscalls.mk + +ifdef mach-shortcuts +$(mach-shortcuts:%=$(objpfx)%.c): $(objpfx)%.c: shortcut.awk \ + $(objpfx)RPC_%_rpc.c + gawk -v alias=$* -v call=__$* -v rpc=__$*_rpc -v syscall=__syscall_$* \ + -f $^ > $@-new + mv $@-new $@ +generated += $(mach-shortcuts:%=%.c) +endif # mach-shortcuts + +# Generate mach-shortcuts.h, which will contain the prototypes for the +# shortcutted kernel RPC functions. +$(objpfx)mach-shortcuts.h: $(objpfx)mach/mach_interface.h \ + $(objpfx)mach/mach_port.h +# The first line gets us one paragraph per line, with @s separating real lines. +# The second line selects paragraphs for the shortcutted functions. +# The third line removes `_rpc' from the names and rerealifies the lines. + cat $^ | tr \\012 @ | sed s/@@/@%/g | tr % \\012 \ + | grep '^/\* Routine [a-z0-9_]*_rpc \*/' \ + | sed 's/_rpc//g' | tr @ \\012 > $@-new + mv $@-new $@ +generated += mach-shortcuts.h + +before-compile += $(objpfx)mach-shortcuts.h + +include Machrules +include ../Rules + + +# There is already a mach.h, so mach.defs generates mach_interface.h. +$(objpfx)mach/mach_interface.defs: $(mach-srcdir)/mach/mach.defs + ln $< $@ || cp $< $@ +# There is already a memory_object.h, +# so memory_object.defs generates memory_object_user.h. +$(objpfx)mach/memory_object_user.defs: $(mach-srcdir)/mach/memory_object.defs + ln $< $@ || cp $< $@ + +ifdef objdir +vpath mach/mach_interface.defs $(objdir) +vpath mach/memory_object_user.defs $(objdir) +endif + +# Be sure not to make these with implicit rules from foo.defs. +mach.h mach/memory_object.h: ; + +ifeq (,) +# XXX we have an errsystems.c here because a gcc bug makes the generated +# version lose. +else +generated += errsystems.c +$(objpfx)errsystems.c: errsystems.awk err_*.sub \ + $(wildcard $(addsuffix /err_*.sub,$(+sysdep_dirs))) + gawk -v subsys='$(filter-out $<,$^)' -f $^ > $@.n + mv $@.n $@ +endif diff --git a/mach/bootprivport.c b/mach/bootprivport.c new file mode 100644 index 0000000000..85c63309e7 --- /dev/null +++ b/mach/bootprivport.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> + +kern_return_t +__mach_get_priv_ports (mach_port_t *host_priv_ptr, + mach_port_t *device_master_ptr) +{ + kern_return_t err; + mach_port_t bootstrap, reply; + + struct + { + mach_msg_header_t hdr; + mach_msg_type_t host_priv_type; + mach_port_t host_priv; + mach_msg_type_t dev_master_type; + mach_port_t dev_master; + } msg; + + if (err = task_get_bootstrap_port (mach_task_self (), &bootstrap)) + return err; + + /* We cannot simply use a MiG-generated user stub to do this, + because the return message does not contain a return code datum. */ + reply = __mach_reply_port (); + msg.hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, + MACH_MSG_TYPE_MAKE_SEND_ONCE); + msg.hdr.msgh_size = 0; + msg.hdr.msgh_remote_port = bootstrap; + msg.hdr.msgh_local_port = reply; + msg.hdr.msgh_kind = MACH_MSGH_KIND_NORMAL; + msg.hdr.msgh_id = 999999; + err = __mach_msg (&msg.hdr, + MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_TIMEOUT, + sizeof (msg.hdr), sizeof (msg), reply, + 500, MACH_PORT_NULL); /* XXX timeout is arbitrary */ + mach_port_deallocate (mach_task_self (), bootstrap); + mach_port_deallocate (mach_task_self (), reply); + + if (err == KERN_SUCCESS) + { + *host_priv_ptr = msg.host_priv; + *device_master_ptr = msg.dev_master; + } + + return err; +} diff --git a/mach/devstream.c b/mach/devstream.c new file mode 100644 index 0000000000..a2162db98b --- /dev/null +++ b/mach/devstream.c @@ -0,0 +1,264 @@ +/* stdio on a Mach device port. + Translates \n to \r\n on output, echos input. + +Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <mach.h> +#include <device/device.h> +#include <errno.h> +#include <string.h> + +static int +input (FILE *f) +{ + kern_return_t err; + char *buffer; + size_t to_read; + mach_msg_type_number_t nread; + char c; + + if (f->__buffer == NULL) + { + buffer = &c; + to_read = 1; + } + else + { + buffer = f->__buffer; + to_read = f->__bufsize; + } + + f->__eof = 0; + + nread = to_read; + err = device_read_inband ((device_t) f->__cookie, 0, f->__target, + to_read, buffer, &nread); + + if (err) + { + f->__error = 1; + f->__bufp = f->__get_limit = f->__put_limit = f->__buffer; + errno = err; + return EOF; + } + + /* Echo it back. */ + err = device_write_inband ((device_t) f->__cookie, 0, f->__target, + buffer, nread, (int *) &to_read); + + if (f->__buffer == NULL) + return (unsigned char) c; + + f->__get_limit = f->__buffer + nread; + f->__bufp = f->__buffer; + f->__put_limit = f->__buffer + (f->__mode.__write ? f->__bufsize : 0); + return (unsigned char) *f->__bufp++; +} + + +#if 0 +static void +output (FILE *f, int c) +{ + inline void write_some (const char *p, size_t to_write) + { + kern_return_t err; + int wrote; + while (to_write > 0) + { + if (err = device_write ((device_t) f->__cookie, 0, + f->__target, (char *)p, + to_write, &wrote)) + { + errno = err; + f->__error = 1; + break; + } + p += wrote; + to_write -= wrote; + f->__target += wrote; + } + } + + if (f->__buffer != NULL) + { + if (f->__put_limit == f->__buffer) + { + /* Prime the stream for writing. */ + f->__put_limit = f->__buffer + f->__bufsize; + f->__bufp = f->__buffer; + if (c != EOF) + { + *f->__bufp++ = (unsigned char) c; + c = EOF; + } + } + + + /* Write out the buffer. */ + + write_some (f->__buffer, f->__bufp - f->__buffer); + + f->__bufp = f->__buffer; + } + + if (c != EOF && !ferror (f)) + { + if (f->__linebuf && (unsigned char) c == '\n') + { + static const char nl = '\n'; + write_some (&nl, 1); + } + else + *f->__bufp++ = (unsigned char) c; + } +} +#endif + + +static void +output (FILE *f, int c) +{ + void write_some (const char *p, size_t to_write) + { + kern_return_t err; + int wrote; + while (to_write > 0) + { + if (err = device_write_inband ((device_t) f->__cookie, 0, + f->__target, p, to_write, &wrote)) + { + errno = err; + f->__error = 1; + break; + } + p += wrote; + to_write -= wrote; + f->__target += wrote; + } + } + void write_crlf (void) + { + static const char crlf[] = "\r\n"; + write_some (crlf, 2); + } + + if (f->__buffer == NULL) + { + /* The stream is unbuffered. */ + + if (c == '\n') + write_crlf (); + else if (c != EOF) + { + char cc = (unsigned char) c; + write_some (&cc, 1); + } + + return; + } + + if (f->__put_limit == f->__buffer) + { + /* Prime the stream for writing. */ + f->__put_limit = f->__buffer + f->__bufsize; + f->__bufp = f->__buffer; + if (c != EOF) + { + *f->__bufp++ = (unsigned char) c; + c = EOF; + } + } + + { + /* Search for newlines (LFs) in the buffer. */ + + char *start = f->__buffer, *p = start; + + while (!ferror (f) && (p = memchr (p, '\n', f->__bufp - start))) + { + /* Found one. Replace it with a CR and write out through that CR. */ + + *p = '\r'; + write_some (start, p + 1 - start); + + /* Change it back to an LF; the next iteration will write it out + first thing. Start the next searching iteration one char later. */ + + start = p; + *p++ = '\n'; + } + + /* Write the remainder of the buffer. */ + + if (!ferror (f)) + write_some (start, f->__bufp - start); + } + + f->__bufp = f->__buffer; + + if (c != EOF && !ferror (f)) + { + if (f->__linebuf && (unsigned char) c == '\n') + write_crlf (); + else + *f->__bufp++ = (unsigned char) c; + } +} + +static int +dealloc_ref (void *cookie) +{ + if (mach_port_deallocate (mach_task_self (), (mach_port_t) cookie)) + { + errno = EINVAL; + return -1; + } + return 0; +} + + +FILE * +mach_open_devstream (mach_port_t dev, const char *mode) +{ + FILE *stream; + + if (mach_port_mod_refs (mach_task_self (), dev, MACH_PORT_RIGHT_SEND, 1)) + { + errno = EINVAL; + return NULL; + } + + stream = fopencookie ((void *) dev, mode, __default_io_functions); + if (stream == NULL) + { + mach_port_deallocate (mach_task_self (), dev); + return NULL; + } + + stream->__room_funcs.__input = input; + stream->__room_funcs.__output = output; + stream->__io_funcs.__close = dealloc_ref; + stream->__io_funcs.__seek = NULL; /* Cannot seek. */ + stream->__io_funcs.__fileno = NULL; /* No corresponding POSIX.1 fd. */ + stream->__seen = 1; + + return stream; +} diff --git a/mach/err_boot.sub b/mach/err_boot.sub new file mode 100644 index 0000000000..5393ab1335 --- /dev/null +++ b/mach/err_boot.sub @@ -0,0 +1,63 @@ +/* + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1992/10/06 18:29:52 roland + * entered into RCS + * + * Revision 2.2 92/04/01 19:37:59 rpd + * Created. + * [92/03/09 rpd] + * + */ +/* + * File: err_bootstrap.sub + * Author: Richard Draves, Carnegie Mellon University + * Date: March 9, 1992 + * + * Error string definitions for bootstrap + */ + +static char * err_codes_bootstrap_fs[] = { + /* 0 */ "(bootstrap/fs) not a directory", + /* 1 */ "(bootstrap/fs) name not found", + /* 2 */ "(bootstrap/fs) name too long", + /* 3 */ "(bootstrap/fs) symbolic link loop", + /* 4 */ "(bootstrap/fs) bad file system", + /* 5 */ "(bootstrap/fs) offset not in file", + /* 6 */ "(bootstrap/fs) invalid parameter", +}; + +/* err_bootstrap subsystems */ +static struct error_subsystem err_bootstrap_sub[] = { + /* bootstrap/0; */ + { + "(bootstrap/fs)", + errlib_count(err_codes_bootstrap_fs), + err_codes_bootstrap_fs, + }, +}; diff --git a/mach/err_ipc.sub b/mach/err_ipc.sub new file mode 100644 index 0000000000..1de186e2e7 --- /dev/null +++ b/mach/err_ipc.sub @@ -0,0 +1,109 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1992/10/06 18:29:52 roland + * entered into RCS + * + * Revision 2.2 92/01/16 00:08:40 rpd + * Moved from user collection to mk collection. + * + * Revision 2.2 91/03/27 16:05:16 mrt + * First checkin + * + * + */ +/* + * File: err_ipc.sub + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar, 1988 + * + * Definitions of error strings for original IPC + */ + +static char * err_codes_send[] = { + "(ipc/send) unknown error", /* -100 */ + "(ipc/send) invalid memory", /* -101 */ + "(ipc/send) invalid port", /* -102 */ + "(ipc/send) timed out", /* -103 */ + "(ipc/send) unused error", /* -104 */ + "(ipc/send) will notify", /* -105 */ + "(ipc/send) notify in progress", /* -106 */ + "(ipc/send) kernel refused message", /* -107 */ + "(ipc/send) send interrupted", /* -108 */ + "(ipc/send) send message too large", /* -109 */ + "(ipc/send) send message too small", /* -110 */ + "(ipc/send) message size changed while being copied", /* -111 */ +}; + +static char * err_codes_rcv[] = { + "(ipc/rcv) unknown error", /* -200 */ + "(ipc/rcv) invalid memory", /* -201 */ + "(ipc/rcv) invalid port", /* -202 */ + "(ipc/rcv) receive timed out", /* -203 */ + "(ipc/rcv) message too large", /* -204 */ + "(ipc/rcv) no space for message data", /* -205 */ + "(ipc/rcv) only sender remaining", /* -206 */ + "(ipc/rcv) receive interrupted", /* -207 */ + "(ipc/rcv) port receiver changed or port became enabled", /* -208 */ +}; + +static char * err_codes_mig[] = { + "(ipc/mig) type check failure in message interface", /* 0 (-300) */ + "(ipc/mig) wrong return message ID", /* 1 */ + "(ipc/mig) server detected error", /* 2 */ + "(ipc/mig) bad message ID", /* 3 */ + "(ipc/mig) server found wrong arguments", /* 4 */ + "(ipc/mig) no reply should be sent", /* 5 */ + "(ipc/mig) server raised exception", /* 6 */ + "(ipc/mig) user specified array not large enough for return info", /* 7 */ +}; + +/* err_ipc subsystems */ +static struct error_subsystem err_ipc_sub[] = { + /* ipc/0; */ + { + "(ipc/send)", + errlib_count(err_codes_send), + err_codes_send, + }, + /* ipc/1; */ + { + "(ipc/rcv)", + errlib_count(err_codes_rcv), + err_codes_rcv, + + }, + /* ipc/2 */ + { + "(ipc/mig)", + errlib_count(err_codes_mig), + err_codes_mig, + }, + +}; + diff --git a/mach/err_kern.sub b/mach/err_kern.sub new file mode 100644 index 0000000000..d5290b4e9b --- /dev/null +++ b/mach/err_kern.sub @@ -0,0 +1,188 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.4 1993/12/17 06:14:52 mib + * entered into RCS + * + * Revision 2.3 92/04/01 19:38:02 rpd + * Added err_codes_device. + * [92/03/09 rpd] + * + * Revision 2.2 92/01/16 00:08:50 rpd + * Moved from user collection to mk collection. + * + * Revision 2.3 91/08/29 15:51:22 rpd + * Updated err_codes_kern. + * [91/08/15 rpd] + * + * Revision 2.2 91/03/27 16:05:27 mrt + * First checkin + * + */ +/* + * File: err_kern.sub + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar, 1988 + * + * error codes for Mach and Unix kernels + */ + +static char * err_codes_kern[] = { + "(os/kern) successful", + "(os/kern) invalid address", + "(os/kern) protection failure", + "(os/kern) no space available", + "(os/kern) invalid argument", + "(os/kern) failure", + "(os/kern) resource shortage", + "(os/kern) not receiver", + "(os/kern) no access", + "(os/kern) memory failure", + "(os/kern) memory error", + "(os/kern) already in set", + "(os/kern) not in set", + "(os/kern) name exists", + "(os/kern) aborted", + "(os/kern) invalid name", + "(os/kern) invalid task", + "(os/kern) invalid right", + "(os/kern) invalid value", + "(os/kern) urefs overflow", + "(os/kern) invalid capability", + "(os/kern) right exists", + "(os/kern) invalid host", + "(os/kern) memory present", +}; + +static char * err_codes_device[] = { + "(os/device) hardware IO error", + "(os/device) operation would block", + "(os/device) no such device", + "(os/device) device already open", + "(os/device) device is shut down", + "(os/device) invalid operation", + "(os/device) invalid record number", + "(os/device) invalid IO size", + "(os/device) memory allocation failure", + "(os/device) read only", +}; + +static char * err_codes_unix[] = { + NO_SUCH_ERROR, + "(os/unix) no rights to object", + "(os/unix) file or directory does not exist", + "(os/unix) no such process", + "(os/unix) interrupted system call", + "(os/unix) i/o error", + "(os/unix) device does not exist", + "(os/unix) argument list is too long", + "(os/unix) invalid executable object format", + "(os/unix) bad file descriptor number", + "(os/unix) no child processes are present", + "(os/unix) no more processes are available", + "(os/unix) insufficient memory", + "(os/unix) access denied", + "(os/unix) memory access fault", + "(os/unix) block device required for operation", + "(os/unix) mount device busy", + "(os/unix) file already exists", + "(os/unix) cross device link", + "(os/unix) device does not exist", + "(os/unix) object is not a directory", + "(os/unix) object is a directory", + "(os/unix) invalid argument", + "(os/unix) internal file table overflow", + "(os/unix) maximum number of open files reached", + "(os/unix) object is not a tty-like device", + "(os/unix) executable object is in use", + "(os/unix) file is too large", + "(os/unix) no space is left on device", + "(os/unix) illegal seek attempt", + "(os/unix) read-only file system", + "(os/unix) too many links", + "(os/unix) broken pipe", + "(os/unix) argument is too large", + "(os/unix) result is out of range", + "(os/unix) operation on device would block", + "(os/unix) operation is now in progress", + "(os/unix) operation is already in progress", + "(os/unix) socket operation attempted on non-socket object", + "(os/unix) destination address is required", + "(os/unix) message is too long", + "(os/unix) protocol type is incorrect for socket", + "(os/unix) protocol type is not availaible", + "(os/unix) protocol type is not supported", + "(os/unix) socket type is not supported", + "(os/unix) operation is not supported on sockets", + "(os/unix) protocol family is not supported", + "(os/unix) address family is not supported by protocol family", + "(os/unix) address is already in use", + "(os/unix) can't assign requested address", + "(os/unix) network is down", + "(os/unix) network is unreachable", + "(os/unix) network dropped connection on reset", + "(os/unix) software aborted connection", + "(os/unix) connection reset by peer", + "(os/unix) no buffer space is available", + "(os/unix) socket is already connected", + "(os/unix) socket is not connected", + "(os/unix) can't send after socket shutdown", + "(os/unix) too many references; can't splice", + "(os/unix) connection timed out", + "(os/unix) connection was refused", + "(os/unix) too many levels of symbolic links", + "(os/unix) file name exceeds system maximum limit", + "(os/unix) host is down", + "(os/unix) there is no route to host", + "(os/unix) directory is not empty", + "(os/unix) quota on number of processes exceeded", + "(os/unix) quota on number of users exceeded", + "(os/unix) quota on available disk space exceeded", +}; + +static struct error_subsystem err_kern_sub[] = { + { + "(os/kern)", + errlib_count(err_codes_kern), + err_codes_kern, + }, + { + "(os/device)", + errlib_count(err_codes_device), + err_codes_device, + }, + { + "(os/?)", + 0, + }, + { + "(os/unix)", + errlib_count(err_codes_unix), + err_codes_unix, + }, +}; diff --git a/mach/err_mach.sub b/mach/err_mach.sub new file mode 100644 index 0000000000..b33522c344 --- /dev/null +++ b/mach/err_mach.sub @@ -0,0 +1,130 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1992/10/06 18:29:52 roland + * entered into RCS + * + * Revision 2.3 92/04/01 19:38:05 rpd + * Added MIG_DESTROY_REQUEST. + * [92/03/09 rpd] + * + * Revision 2.2 92/01/16 00:09:05 rpd + * Moved from user collection to mk collection. + * + * Revision 2.3 91/08/29 15:51:30 rpd + * Added MIG_SERVER_DIED. + * [91/08/21 rpd] + * + * Revision 2.2 91/03/27 16:05:37 mrt + * First checkin + * + * Revision 2.2 91/03/18 17:39:03 rpd + * Created. + * [91/03/18 rpd] + * + */ +/* + * File: err_mach_ipc.sub + * Author: Richard Draves, Carnegie Mellon University + * Date: Jan, 1990 + * + * Error string definitions for the new Mach IPC + */ + +static char * err_codes_mach_send[] = { + /* 0 */ "(ipc/send) no error", + /* 1 */ "(ipc/send) send in progress", + /* 2 */ "(ipc/send) invalid data", + /* 3 */ "(ipc/send) invalid destination port", + /* 4 */ "(ipc/send) timed out", + /* 5 */ "(ipc/send) will notify", + /* 6 */ "(ipc/send) notify in progress", + /* 7 */ "(ipc/send) interrupted", + /* 8 */ "(ipc/send) msg too small", + /* 9 */ "(ipc/send) invalid reply port", + /* 10 */ "(ipc/send) invalid port right", + /* 11 */ "(ipc/send) invalid notify port", + /* 12 */ "(ipc/send) invalid memory", + /* 13 */ "(ipc/send) no msg buffer", + /* 14 */ "(ipc/send) no notify possible", + /* 15 */ "(ipc/send) invalid msg-type", + /* 16 */ "(ipc/send) invalid msg-header", +}; + +static char * err_codes_mach_rcv[] = { + /* 0 */ "(ipc/rcv) no error", + /* 1 */ "(ipc/rcv) receive in progress", + /* 2 */ "(ipc/rcv) invalid name", + /* 3 */ "(ipc/rcv) timed out", + /* 4 */ "(ipc/rcv) msg too large", + /* 5 */ "(ipc/rcv) interrupted", + /* 6 */ "(ipc/rcv) port changed", + /* 7 */ "(ipc/rcv) invalid notify port", + /* 8 */ "(ipc/rcv) invalid data", + /* 9 */ "(ipc/rcv) port died", + /* 10 */ "(ipc/rcv) port in set", + /* 11 */ "(ipc/rcv) header error", + /* 12 */ "(ipc/rcv) body error", +}; + +static char * err_codes_mach_mig[] = { + /* 0 */ "(ipc/mig) client type check failure", + /* 1 */ "(ipc/mig) wrong reply message ID", + /* 2 */ "(ipc/mig) server detected error", + /* 3 */ "(ipc/mig) bad request message ID", + /* 4 */ "(ipc/mig) server type check failure", + /* 5 */ "(ipc/mig) no reply should be sent", + /* 6 */ "(ipc/mig) server raised exception", + /* 7 */ "(ipc/mig) array not large enough", + /* 8 */ "(ipc/mig) server died", + /* 9 */ "(ipc/mig) destroy request with no reply", +}; + +/* err_mach_ipc subsystems */ +static struct error_subsystem err_mach_ipc_sub[] = { + /* ipc/0; */ + { + "(ipc/send)", + errlib_count(err_codes_mach_send), + err_codes_mach_send, + }, + /* ipc/1; */ + { + "(ipc/rcv)", + errlib_count(err_codes_mach_rcv), + err_codes_mach_rcv, + + }, + /* ipc/2 */ + { + "(ipc/mig)", + errlib_count(err_codes_mach_mig), + err_codes_mach_mig, + }, + +}; diff --git a/mach/err_server.sub b/mach/err_server.sub new file mode 100644 index 0000000000..1594246462 --- /dev/null +++ b/mach/err_server.sub @@ -0,0 +1,374 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1992/10/06 18:29:53 roland + * entered into RCS + * + * Revision 2.2 92/01/16 00:10:29 rpd + * Moved from user collection to mk collection. + * + * Revision 2.3 91/08/29 15:51:39 rpd + * Fixed err_codes_netname. + * [91/08/22 rpd] + * + * Revision 2.2 91/03/27 16:05:51 mrt + * First checkin + * + * Revision 2.3 90/10/29 17:27:20 dpj + * Merged-up to U25 + * [90/09/02 20:00:25 dpj] + * + */ +/* + * File: err_server.sub + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar, 1988 + * + * Definitions of Servers error strings + */ + +static char * err_codes_netname[] = { /* 0 */ + "(server/netname) name is not yours", + "(server/netname) name not checked in", + "(server/netname) no such host", + "(server/netname) host not found", +}; +static char * err_codes_env_mgr[] = { /* 1 */ + NO_SUCH_ERROR, + "(server/env_mgr) variable not found", + "(server/env_mgr) wrong type of variable", + "(server/env_mgr) unknown port", + "(server/env_mgr) read only environment", + "(server/env_mgr) no more connections available", + "(server/env_mgr) port table full", + "(server/env_mgr) attempting to enter a null port ", +}; +static char * err_codes_execd[] = { /* 2 */ + NO_SUCH_ERROR, + "(server/execd) could not find file to run", + "(server/execd) userid or password incorrect", + "(server/execd) fork failed", +}; +static char * err_codes_netmemory[] = { /* 3 */ + "(server/netmemory) successful", + "(server/netmemory) invalid argument", + "(server/netmemory) resource shortage", +}; +static char * err_codes_ufs[] = { /* 4 */ + NO_SUCH_ERROR, +/* XXX "(server/ufs) invalid port", */ +}; + +static char * err_codes_task_master[] = { /* 5 */ + "(server/task_master) GENERIC ERROR", + "(server/task_master) invalid tm_task port", + "(server/task_master) invalid task id", + "(server/task_master) invalid kernel port", + "(server/task_master) invalid job group", + "(server/task_master) invalid action", +}; + +static char * err_codes_ns[] = { /* 6 */ + "(server/ns) GENERIC ERROR", + "(server/ns) invalid handle", + "(server/ns) name not found", + "(server/ns) name already exists", + "(server/ns) name too long", + "(server/ns) path too long", + "(server/ns) invalid name", + "(server/ns) not a directory", + "(server/ns) is a directory", + "(server/ns) directory not empty", + "(server/ns) infinite retry loop in resolver", + "(server/ns) infinite forwarding loop in resolver", + "(server/ns) invalid prefix", + "(server/ns) prefix table overflow", + "(server/ns) bad format for directory", + "(server/ns) unknown entry type", + "(server/ns) invalid generation", + "(server/ns) entry not reserved", +}; + +static char * err_codes_io[] = { /* 7 */ + "(server/io) GENERIC ERROR", + "(server/io) invalid offset", + "(server/io) invalid size", + "(server/io) invalid mode", + "(server/io) invalid strategy", + "(server/io) operation rejected under current I/O strategy", +}; + +static char * err_codes_auth[] = { /* 8 */ + "(server/auth) GENERIC ERROR", + "(server/auth) bad private port", + "(server/auth) bad name", + "(server/auth) not primary", + "(server/auth) bad pauthsword", + "(server/auth) bad group", + "(server/auth) duplicate id", + "(server/auth) duplicate name", + "(server/auth) not secondary", +}; + +static char * err_codes_us[] = { /* 9 */ + "(server/us) GENERIC ERROR", + "(server/us) unknown error", + "(server/us) object not found", + "(server/us) object exists", + "(server/us) object busy", + "(server/us) object not started", + "(server/us) object dead", + "(server/us) invalid args", + "(server/us) invalid access", + "(server/us) invalid format", + "(server/us) invalid buffer size", + "(server/us) access denied", + "(server/us) resource exhausted", + "(server/us) quota exceeded", + "(server/us) limit exceeded", + "(server/us) not implemented", + "(server/us) not supported", + "(server/us) hardware error", + "(server/us) retry required", + "(server/us) not authenticated", + "(server/us) exclusive access", + "(server/us) timeout", + "(server/us) bad reference count", + "(server/us) internal error", +}; + +static char * err_codes_sunrpc[] = { /* 10 */ + "(server/sunrpc) GENERIC ERROR", + "(server/sunrpc) cannot encode arguments", + "(server/sunrpc) cannot decode results", + "(server/sunrpc) failure in sending call", + "(server/sunrpc) failure in receiving result", + "(server/sunrpc) call timed out", + "(server/sunrpc) rpc versions not compatible", + "(server/sunrpc) authentication error", + "(server/sunrpc) program not available", + "(server/sunrpc) program version mismatched", + "(server/sunrpc) procedure unavailable", + "(server/sunrpc) decode arguments error", + "(server/sunrpc) generic other problem", + "(server/sunrpc) unknown host name", + "(server/sunrpc) portmapper failed", + "(server/sunrpc) remote program not registered", + "(server/sunrpc) unspecified error", + "(server/sunrpc) unknown protocol", +}; + +static char * err_codes_machobj[] = { /* 11 */ + "(server/object system) GENERIC ERROR", + "(server/object system) object not found", + "(server/object system) no such operation", + "(server/object system) undefined ipc method arguments", + "(server/object system) too many arguments to method", + "(server/object system) bad ipc message format", +}; + +static char * err_codes_loader[] = { /* 12 */ + "(server/loader) GENERIC ERROR", + "(server/loader) object file not relocated", + "(server/loader) unknown file type", + "(server/loader) symbol not found", + "(server/loader) symbol multiply defined", + "(server/loader) memory region overlap", +}; + + +static char * err_codes_exception[] = { /* 13 */ + "(server/exception) GENERIC ERROR", + "(server/exception) invalid access", + "(server/exception) invalid instruction", + "(server/exception) arithmetic exception", + "(server/exception) emulation exception", + "(server/exception) software exception", + "(server/exception) breakpoint exception", +}; + +static char * err_codes_ux_signal[] = { /* 14 */ + "(server/unix-signal) GENERIC ERROR", + "(server/unix-signal) hangup", + "(server/unix-signal) interrupt", + "(server/unix-signal) quit", + "(server/unix-signal) undefined", + "(server/unix-signal) undefined", + "(server/unix-signal) undefined", + "(server/unix-signal) undefined", + "(server/unix-signal) kill", + "(server/unix-signal) undefined", + "(server/unix-signal) undefined", + "(server/unix-signal) system error", + "(server/unix-signal) pipe signal", + "(server/unix-signal) alarm", + "(server/unix-signal) terminate", + "(server/unix-signal) urgent i/o", + "(server/unix-signal) stop", + "(server/unix-signal) terminal stop", + "(server/unix-signal) continue", + "(server/unix-signal) child death", + "(server/unix-signal) tty input", + "(server/unix-signal) tty output", + "(server/unix-signal) i/o signal", + "(server/unix-signal) cpu time limit exceeded", + "(server/unix-signal) file size exceeded", + "(server/unix-signal) virtual alarm", + "(server/unix-signal) profile signal", + "(server/unix-signal) window size change", + "(server/unix-signal) user-defined signal 1", + "(server/unix-signal) user-defined signal 2", +}; + +static char * err_codes_xkernel[] = { /* 15 */ + "(server/xkernel) GENERIC ERROR", + "(server/xkernel) map full", + "(server/xkernel) inconsistent bind", + "(server/xkernel) cannot resolve", + "(server/xkernel) cannot unbind", + "(server/xkernel) invalid type", + "(server/xkernel) invalid opcode", + "(server/xkernel) buffer too small", + "(server/xkernel) invalid ev code", + "(server/xkernel) event not registered", + "(server/xkernel) invalid open", + "(server/xkernel) already open", + "(server/xkernel) bad addr", +}; + + +/* err_server subsystems */ +static struct error_subsystem err_server_sub[] = { + /* server/0; */ + { + "(server/netname)", + errlib_count(err_codes_netname), + err_codes_netname, + }, + /* server/1; */ + { + "(server/env_mgr)", + errlib_count(err_codes_env_mgr), + err_codes_env_mgr, + }, + /* server/2; */ + { + "(server/execd)", + errlib_count(err_codes_execd), + err_codes_execd, + }, + /* server/3; */ + { + "(server/netmemory)", + errlib_count(err_codes_netmemory), + err_codes_netmemory, + }, + /* server/4; */ + { + "(server/ufs)", + errlib_count(err_codes_ufs), + err_codes_ufs, + }, + /* server/5; */ + { + "(server/task_master)", + errlib_count(err_codes_task_master), + err_codes_task_master, + }, + /* server/6; */ + { + "(server/ns)", + errlib_count(err_codes_ns), + err_codes_ns, + }, + + /* server/7; i/o subsystem */ + { + "(server/io)", + errlib_count(err_codes_io), + err_codes_io, + }, + + /* server/8; authentication server */ + { + "(server/auth)", + errlib_count(err_codes_auth), + err_codes_auth, + }, + + /* server/9; generic US system */ + { + "(server/us)", + errlib_count(err_codes_us), + err_codes_us, + }, + + /* server/10; SUN RPC package */ + { + "(server/sunrpc)", + errlib_count(err_codes_sunrpc), + err_codes_sunrpc, + }, + + /* server/11; MachObject system */ + { + "(server/object system)", + errlib_count(err_codes_machobj), + err_codes_machobj, + }, + + /* server/12; loader */ + { + "(server/loader)", + errlib_count(err_codes_loader), + err_codes_loader, + }, + + /* server/13; mach exception */ + { + "(server/exception)", + errlib_count(err_codes_exception), + err_codes_exception, + }, + + /* server/14; unix signal */ + { + "(server/unix-signal)", + errlib_count(err_codes_ux_signal), + err_codes_ux_signal, + }, + + /* server/15; xkernel */ + { + "(server/xkernel)", + errlib_count(err_codes_xkernel), + err_codes_xkernel, + }, + +}; + diff --git a/mach/err_us.sub b/mach/err_us.sub new file mode 100644 index 0000000000..7261165d8d --- /dev/null +++ b/mach/err_us.sub @@ -0,0 +1,56 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.2 1993/11/23 21:14:05 mib + * entered into RCS + * + * Revision 2.2 92/01/16 00:10:45 rpd + * Moved from user collection to mk collection. + * + * Revision 2.2 91/03/27 16:06:06 mrt + * First checkin + * + */ +/* + * File: err_us.sub + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar, 1988 + * + * A place to define User errors + */ + + +/* err_us subsystems */ +static struct error_subsystem err_us_sub[] = { + {0,0,0} +}; + + + + + diff --git a/mach/error_compat.c b/mach/error_compat.c new file mode 100644 index 0000000000..0498f017ba --- /dev/null +++ b/mach/error_compat.c @@ -0,0 +1,70 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* This file was broken out from: + $Log$ + Revision 1.1 1993/11/30 17:35:24 roland + entered into RCS + + Revision 2.3 92/04/01 19:38:18 rpd + The static do_compat function is renamed to be globally accessible. + */ + +#include <mach/error.h> +#include <mach_error.h> +#include <errorlib.h> + + +void +__mach_error_map_compat( org_err ) + mach_error_t * org_err; +{ + mach_error_t err = *org_err; + + /* + * map old error numbers to + * to new error sys & subsystem + */ + + if ((-200 < err) && (err <= -100)) + err = -(err + 100) | IPC_SEND_MOD; + else if ((-300 < err) && (err <= -200)) + err = -(err + 200) | IPC_RCV_MOD; + else if ((-400 < err) && (err <= -300)) + err = -(err + 300) | MACH_IPC_MIG_MOD; + else if ((1000 <= err) && (err < 1100)) + err = (err - 1000) | SERV_NETNAME_MOD; + else if ((1600 <= err) && (err < 1700)) + err = (err - 1600) | SERV_ENV_MOD; + else if ((27600 <= err) && (err < 27700)) + err = (err - 27600) | SERV_EXECD_MOD; + else if ((2500 <= err) && (err < 2600)) + err = (err - 2500) | KERN_DEVICE_MOD; + else if ((5000 <= err) && (err < 5100)) + err = (err - 5000) | BOOTSTRAP_FS_MOD; + + *org_err = err; +} diff --git a/mach/errorlib.h b/mach/errorlib.h new file mode 100644 index 0000000000..b60fc5e5a4 --- /dev/null +++ b/mach/errorlib.h @@ -0,0 +1,87 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.4 1993/12/17 21:56:16 roland + * entered into RCS + * + * Revision 2.3 92/03/31 15:18:52 rpd + * Added KERN_DEVICE_MOD for device errors. + * [92/03/09 rpd] + * + * Revision 2.2 92/01/16 00:21:17 rpd + * Moved from user collection to mk collection. + * + * Revision 2.2 91/03/27 15:37:37 mrt + * First checkin + * + */ +/* + * File: errorlib.h + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar. 1988 + * + * Error bases for subsytems errors. + */ + +#include <mach/error.h> + +#define KERN_DEVICE_MOD (err_kern|err_sub(1)) + +#define BOOTSTRAP_FS_MOD (err_bootstrap|err_sub(0)) + +#define MACH_IPC_SEND_MOD (err_mach_ipc|err_sub(0)) +#define MACH_IPC_RCV_MOD (err_mach_ipc|err_sub(1)) +#define MACH_IPC_MIG_MOD (err_mach_ipc|err_sub(2)) + +#define IPC_SEND_MOD (err_ipc|err_sub(0)) +#define IPC_RCV_MOD (err_ipc|err_sub(1)) +#define IPC_MIG_MOD (err_ipc|err_sub(2)) + +#define SERV_NETNAME_MOD (err_server|err_sub(0)) +#define SERV_ENV_MOD (err_server|err_sub(1)) +#define SERV_EXECD_MOD (err_server|err_sub(2)) + + +#define NO_SUCH_ERROR "unknown error code" + +struct error_subsystem { + const char * subsys_name; + int max_code; + const char * const * codes; +}; + +struct error_system { + int max_sub; + const char * bad_sub; + const struct error_subsystem * subsystem; +}; + +#define errors __mach_error_systems +extern struct error_system errors[err_max_system+1]; + +#define errlib_count(s) (sizeof(s)/sizeof(s[0])) diff --git a/mach/errstring.c b/mach/errstring.c new file mode 100644 index 0000000000..761a615e29 --- /dev/null +++ b/mach/errstring.c @@ -0,0 +1,100 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1993/11/30 17:35:58 roland + * entered into RCS + * + * Revision 2.3 92/04/01 19:38:18 rpd + * Updated do_compat for kernel device errors, + * bootstrap file-system errors. + * [92/03/09 rpd] + * + * Revision 2.2 92/02/20 15:58:08 elf + * Created from mach_error.c. + * [92/02/11 rpd] + * + */ + +#define EXPORT_BOOLEAN +#include <mach/boolean.h> +#include <mach/error.h> +#include <mach_error.h> +#include <errorlib.h> + +extern void __mach_error_map_compat (mach_error_t *); + +const char * +mach_error_type( err ) + mach_error_t err; +{ + int sub, system; + + __mach_error_map_compat( &err ); + + sub = err_get_sub(err); + system = err_get_system(err); + + if (system > err_max_system + || sub >= errors[system].max_sub ) return( "(?/?)" ); + return( errors[system].subsystem[sub].subsys_name ); +} + +boolean_t mach_error_full_diag = FALSE; + +const char * +mach_error_string_int( err, diag ) + mach_error_t err; + boolean_t * diag; +{ + int sub, system, code; + + __mach_error_map_compat( &err ); + + sub = err_get_sub(err); + system = err_get_system(err); + code = err_get_code(err); + + *diag = TRUE; + + if (system > err_max_system) return( "(?/?) unknown error system" ); + if (sub >= errors[system].max_sub) return( errors[system].bad_sub ); + if (code >= errors[system].subsystem[sub].max_code) return ( NO_SUCH_ERROR ); + + *diag = mach_error_full_diag; + return( errors[system].subsystem[sub].codes[code] ); +} + +const char * +mach_error_string( err ) + mach_error_t err; +{ + boolean_t diag; + + return mach_error_string_int( err, &diag ); + +} diff --git a/mach/errsystems.awk b/mach/errsystems.awk new file mode 100644 index 0000000000..c5cc5302b4 --- /dev/null +++ b/mach/errsystems.awk @@ -0,0 +1,21 @@ +BEGIN { + print "#include <mach/error.h>\n#include <errorlib.h>"; + print "#define static static const" + nsubs = split(subsys, subs); + while (nsubs > 0) printf "#include \"%s\"\n", subs[nsubs--]; + print "\n\n\ +const struct error_system __mach_error_systems[err_max_system + 1] ="; + print " {"; +} +/^static.*err_[a-z0-9A-Z_]+_sub *\[/ { + s = $0; sub(/^.*err_/, "", s); sub(/_sub.*$/, "", s); + printf " [err_get_system (err_%s)] = { errlib_count (err_%s_sub),", + s, s; + printf "\"(system %s) error with unknown subsystem\", err_%s_sub },\n", + s, s; +} +END { + print " };"; + printf "\n\ +const int __mach_error_system_count = errlib_count (__mach_error_systems);"; +} diff --git a/mach/errsystems.c b/mach/errsystems.c new file mode 100644 index 0000000000..19909607f8 --- /dev/null +++ b/mach/errsystems.c @@ -0,0 +1,27 @@ +/* XXX temp kludge: this file should be generated, but a gcc bug screws it. */ + +#include <mach/error.h> +#include <errorlib.h> +#define static static const +#include "../sysdeps/mach/hurd/err_hurd.sub" +#include "err_us.sub" +#include "err_server.sub" +#include "err_mach.sub" +#include "err_kern.sub" +#include "err_ipc.sub" +#include "err_boot.sub" + + +const struct error_system __mach_error_systems[err_max_system + 1] = + { + /* 0 [err_get_system (err_kern)] = */ { errlib_count (err_kern_sub),"(system kern) error with unknown subsystem", err_kern_sub }, + /* 1 [err_get_system (err_us)] = */ { errlib_count (err_us_sub),"(system us) error with unknown subsystem", err_us_sub }, + /* 2 [err_get_system (err_server)] = */ { errlib_count (err_server_sub),"(system server) error with unknown subsystem", err_server_sub }, + /* 3 [err_get_system (err_ipc)] = */ { errlib_count (err_ipc_sub),"(system ipc) error with unknown subsystem", err_ipc_sub }, + /* 4 [err_get_system (err_mach_ipc)] = */ { errlib_count (err_mach_ipc_sub),"(system mach_ipc) error with unknown subsystem", err_mach_ipc_sub }, + /* 5 [err_get_system (err_bootstrap)] = */ { errlib_count (err_bootstrap_sub),"(system bootstrap) error with unknown subsystem", err_bootstrap_sub }, + /* [6..15] */ {},{},{},{},{},{},{},{},{},{}, + /* 16==0x10 [err_get_system (err_hurd)] = */ { errlib_count (err_hurd_sub),"(system hurd) error with unknown subsystem", err_hurd_sub }, + }; + +const int __mach_error_system_count = errlib_count (__mach_error_systems); diff --git a/mach/hello.c b/mach/hello.c new file mode 100644 index 0000000000..4712038e10 --- /dev/null +++ b/mach/hello.c @@ -0,0 +1,48 @@ +/* "Hello world" program for GNU C Library on bare Mach 3.0. + +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <device/device.h> +#include <errno.h> +#include <stdio.h> + +int +main (void) +{ + kern_return_t err; + mach_port_t device, consdev; + FILE *consf; + + err = get_privileged_ports (NULL, &device); + if (err) + _exit (err); + err = device_open (device, D_WRITE, "console", &consdev); + mach_port_deallocate (mach_task_self (), device); + if (err) + _exit (err); + + consf = mach_open_devstream (consdev, "w"); + if (consf == NULL) + exit (errno); + + fputs ("Hello, world!\n", consf); + + return 0; +} diff --git a/mach/lock-intern.h b/mach/lock-intern.h new file mode 100644 index 0000000000..9c6bab5ae2 --- /dev/null +++ b/mach/lock-intern.h @@ -0,0 +1,89 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _LOCK_INTERN_H +#define _LOCK_INTERN_H + +#include <machine-lock.h> + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + + +/* Initialize LOCK. */ + +_EXTERN_INLINE void +__spin_lock_init (__spin_lock_t *__lock) +{ + *__lock = __SPIN_LOCK_INITIALIZER; +} + + +/* Lock LOCK, blocking if we can't get it. */ +extern void __spin_lock_solid (__spin_lock_t *__lock); + +/* Lock the spin lock LOCK. */ + +_EXTERN_INLINE void +__spin_lock (__spin_lock_t *__lock) +{ + if (! __spin_try_lock (__lock)) + __spin_lock_solid (__lock); +} + +/* Name space-clean internal interface to mutex locks. + + Code internal to the C library uses these functions to lock and unlock + mutex locks. These locks are of type `struct mutex', defined in + <cthreads.h>. The functions here are name space-clean. If the program + is linked with the cthreads library, `__mutex_lock_solid' and + `__mutex_unlock_solid' will invoke the corresponding cthreads functions + to implement real mutex locks. If not, simple stub versions just use + spin locks. */ + + +/* Initialize the newly allocated mutex lock LOCK for further use. */ +extern void __mutex_init (void *__lock); + +/* Lock LOCK, blocking if we can't get it. */ +extern void __mutex_lock_solid (void *__lock); + +/* Finish unlocking LOCK, after the spin lock LOCK->held has already been + unlocked. This function will wake up any thread waiting on LOCK. */ +extern void __mutex_unlock_solid (void *__lock); + +/* Lock the mutex lock LOCK. */ + +_EXTERN_INLINE void +__mutex_lock (void *__lock) +{ + if (! __spin_try_lock ((__spin_lock_t *) __lock)) + __mutex_lock_solid (__lock); +} + +/* Unlock the mutex lock LOCK. */ + +_EXTERN_INLINE void +__mutex_unlock (void *__lock) +{ + __spin_unlock ((__spin_lock_t *) __lock); + __mutex_unlock_solid (__lock); +} + +#endif /* lock-intern.h */ diff --git a/mach/mach.h b/mach/mach.h new file mode 100644 index 0000000000..ea39fb45fe --- /dev/null +++ b/mach/mach.h @@ -0,0 +1,95 @@ +/* Standard header for all Mach programs. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACH_H + +#define _MACH_H 1 + +/* Get the basic types used by Mach. */ +#include <mach/mach_types.h> + +/* This declares the basic variables and macros everything needs. */ +#include <mach_init.h> + +/* This declares all the real system call functions. */ +#include <mach/mach_traps.h> + +/* These are MiG-generated headers for the kernel interfaces commonly used. */ +#include <mach/mach_interface.h> /* From <mach/mach.defs>. */ +#include <mach/mach_port.h> +#include <mach/mach_host.h> + +/* For the kernel RPCs which have system call shortcut versions, + the MiG-generated header in fact declares `CALL_rpc' rather than `CALL'. + This file declares the simple `CALL' functions. */ +#include <mach-shortcuts.h> + + +/* Receive RPC request messages on RCV_NAME and pass them to DEMUX, which + decodes them and produces reply messages. MAX_SIZE is the maximum size + (in bytes) of the request and reply buffers. */ +extern mach_msg_return_t +__mach_msg_server (boolean_t (*__demux) (mach_msg_header_t *__request, + mach_msg_header_t *__reply), + mach_msg_size_t __max_size, + mach_port_t __rcv_name), +mach_msg_server (boolean_t (*__demux) (mach_msg_header_t *__request, + mach_msg_header_t *__reply), + mach_msg_size_t __max_size, + mach_port_t __rcv_name); + +/* Just like `mach_msg_server', but the OPTION and TIMEOUT parameters are + passed on to `mach_msg'. */ +extern mach_msg_return_t +__mach_msg_server_timeout (boolean_t (*__demux) (mach_msg_header_t *__request, + mach_msg_header_t *__reply), + mach_msg_size_t __max_size, + mach_port_t __rcv_name, + mach_msg_option_t __option, + mach_msg_timeout_t __timeout), +mach_msg_server_timeout (boolean_t (*__demux) (mach_msg_header_t *__request, + mach_msg_header_t *__reply), + mach_msg_size_t __max_size, + mach_port_t __rcv_name, + mach_msg_option_t __option, + mach_msg_timeout_t __timeout); + + +#define __need_FILE +#include <stdio.h> + +/* Open a stream on a Mach device. */ +extern FILE *mach_open_devstream (mach_port_t device_port, const char *mode); + +/* Give THREAD a stack and set it to run at PC when resumed. + If *STACK_SIZE is nonzero, that size of stack is allocated. + If *STACK_BASE is nonzero, that stack location is used. + If STACK_BASE is not null it is filled in with the chosen stack base. + If STACK_SIZE is not null it is filled in with the chosen stack size. + Regardless, an extra page of red zone is allocated off the end; this + is not included in *STACK_SIZE. */ +kern_return_t __mach_setup_thread (task_t task, thread_t thread, void *pc, + vm_address_t *stack_base, + vm_size_t *stack_size); +kern_return_t mach_setup_thread (task_t task, thread_t thread, void *pc, + vm_address_t *stack_base, + vm_size_t *stack_size); + + +#endif /* mach.h */ diff --git a/mach/mach/error.h b/mach/mach/error.h new file mode 100644 index 0000000000..e75ccf3f66 --- /dev/null +++ b/mach/mach/error.h @@ -0,0 +1,140 @@ +/* err_hurd added by roland@gnu.ai.mit.edu for GNU Hurd. + * + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1993/12/17 21:40:28 roland + * entered into RCS + * + * Revision 2.6 93/01/14 17:41:31 danner + * Standardized include symbol name. + * [92/06/10 pds] + * + * Revision 2.5 92/03/31 15:18:11 rpd + * Added err_bootstrap for bootstrap errors. + * [92/03/09 rpd] + * + * Revision 2.4 91/05/14 16:51:24 mrt + * Correcting copyright + * + * Revision 2.3 91/02/05 17:31:48 mrt + * Changed to new Mach copyright + * [91/02/01 17:16:50 mrt] + * + * Revision 2.2 90/06/02 14:57:47 rpd + * Added err_mach_ipc for new IPC. + * [90/03/26 22:28:42 rpd] + * + * Revision 2.1 89/08/03 16:02:07 rwd + * Created. + * + * Revision 2.4 89/02/25 18:13:18 gm0w + * Changes for cleanup. + * + * Revision 2.3 89/02/07 00:51:57 mwyoung + * Relocated from sys/error.h + * + * Revision 2.2 88/10/18 00:37:31 mwyoung + * Added {system,sub and code}_emask + * [88/10/17 17:06:58 mrt] + * + * Added {system,sub and code}_emask + * + * 12-May-88 Mary Thompson (mrt) at Carnegie Mellon + * Changed mach_error_t from unsigned int to kern_return_t + * which is a 32 bit integer regardless of machine type. + * insigned int was incompatible with old usages of mach_error. + * + * 10-May-88 Douglas Orr (dorr) at Carnegie-Mellon University + * Missing endif replaced + * + * 5-May-88 Mary Thompson (mrt) at Carnegie Mellon + * Changed typedef of mach_error_t from long to unsigned int + * to keep our Camelot users happy. Also moved the nonkernel + * function declarations from here to mach_error.h. + * + * 10-Feb-88 Douglas Orr (dorr) at Carnegie-Mellon University + * Created. + * + */ +/* + * File: mach/error.h + * Purpose: + * error module definitions + * + */ + +#ifndef _MACH_ERROR_H_ +#define _MACH_ERROR_H_ +#include <mach/kern_return.h> + +/* + * error number layout as follows: + * + * hi lo + * | system(6) | subsystem(12) | code(14) | + */ + + +#define err_none (mach_error_t)0 +#define ERR_SUCCESS (mach_error_t)0 +#define ERR_ROUTINE_NIL (mach_error_fn_t)0 + + +#define err_system(x) (((x)&0x3f)<<26) +#define err_sub(x) (((x)&0xfff)<<14) + +#define err_get_system(err) (((err)>>26)&0x3f) +#define err_get_sub(err) (((err)>>14)&0xfff) +#define err_get_code(err) ((err)&0x3fff) + +#define system_emask (err_system(0x3f)) +#define sub_emask (err_sub(0xfff)) +#define code_emask (0x3fff) + + +/* major error systems */ +#define err_kern err_system(0x0) /* kernel */ +#define err_us err_system(0x1) /* user space library */ +#define err_server err_system(0x2) /* user space servers */ +#define err_ipc err_system(0x3) /* old ipc errors */ +#define err_mach_ipc err_system(0x4) /* mach-ipc errors */ +#define err_bootstrap err_system(0x5) /* bootstrap errors */ +#define err_hurd err_system(0x10) /* GNU Hurd server errors */ +#define err_local err_system(0x3e) /* user defined errors */ +#define err_ipc_compat err_system(0x3f) /* (compatibility) mach-ipc errors */ + +#define err_max_system 0x3f + + +/* unix errors get lumped into one subsystem */ +#define unix_err(errno) (err_kern|err_sub(3)|errno) + +typedef kern_return_t mach_error_t; +typedef mach_error_t (* mach_error_fn_t)(); + +#endif /* _MACH_ERROR_H_ */ diff --git a/mach/mach/mach.h b/mach/mach/mach.h new file mode 100644 index 0000000000..826e7172a7 --- /dev/null +++ b/mach/mach/mach.h @@ -0,0 +1,3 @@ +/* Some old programs may expect to find <mach.h> in <mach/mach.h>. */ + +#include <mach.h> diff --git a/mach/mach/mach_traps.h b/mach/mach/mach_traps.h new file mode 100644 index 0000000000..e741e16996 --- /dev/null +++ b/mach/mach/mach_traps.h @@ -0,0 +1,76 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Declare the few Mach system calls (except mach_msg, in <mach/message.h>). + This does not include the kernel RPC shortcut calls (in <mach-shortcuts.h>). + + This file omits the MACH_IPC_COMPAT functions. */ + +#ifndef _MACH_MACH_TRAPS_H + +#define _MACH_MACH_TRAPS_H_ 1 + +#include <mach/port.h> + + +/* Create and return a new receive right. */ +extern mach_port_t mach_reply_port (void); +extern mach_port_t __mach_reply_port (void); + +/* Return the thread control port for the calling thread. */ +extern mach_port_t mach_thread_self (void); +extern mach_port_t __mach_thread_self (void); + +/* Return the task control port for the calling task. + The parens are needed to protect against the macro in <mach_init.h>. */ +extern mach_port_t (mach_task_self) (void); +extern mach_port_t (__mach_task_self) (void); + +/* Return the host information port for the host of the calling task. */ +extern mach_port_t mach_host_self (void); +extern mach_port_t __mach_host_self (void); + +/* Attempt to context switch the current thread off the processor. Returns + true if there are other threads that can be run and false if not. */ +extern boolean_t swtch (void); +extern boolean_t __swtch (void); + +/* Attempt to context switch the current thread off the processor. Lower + the thread's priority as much as possible. The thread's priority will + be restored when it runs again. PRIORITY is currently unused. Return + true if there are other threads that can be run and false if not. */ +extern boolean_t swtch_pri (int priority); +extern boolean_t __swtch_pri (int priority); + +/* Attempt to context switch the current thread of the rpocessor. Try + to run NEW_THREAD next, ignoring normal scheduling policies. The + OPTION value comes from <mach/thread_switch.h>. If OPTION is + SWITCH_OPTION_WAIT, then block the current thread for TIME + milliseconds. If OPTION is SWITCH_OPTION_DEPRESS, then block for + TIME milliseconds and depress the thread's priority as done by + swtch_pri. If OPTION is SWITCH_OPTION_NONE, ignore TIME. */ +kern_return_t thread_switch (mach_port_t new_thread, int option, int time); +kern_return_t __thread_switch (mach_port_t new_thread, int option, int time); + +/* Block the current thread until the kernel (or device) event + identified by EVENT occurs. */ +kern_return_t evc_wait (unsigned int event); +kern_return_t __evc_wait (unsigned int event); + + +#endif /* mach/mach_traps.h */ diff --git a/mach/mach/mig_support.h b/mach/mach/mig_support.h new file mode 100644 index 0000000000..0f8c983c87 --- /dev/null +++ b/mach/mach/mig_support.h @@ -0,0 +1,68 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Useful declarations and support functions for MiG-generated stubs. */ + +#ifndef _MACH_MIG_SUPPORT_H + +#define _MACH_MIG_SUPPORT_H 1 + +#include <mach/std_types.h> +#include <mach/message.h> +#include <sys/types.h> +#include <string.h> + +/* MiG initialization. */ +extern void __mig_init (void *__first); +extern void mig_init (void *__first); + +/* Shorthand functions for vm_allocate and vm_deallocate on + mach_task_self () (and with ANYWHERE=1). */ +extern void __mig_allocate (vm_address_t *__addr_p, vm_size_t __size); +extern void mig_allocate (vm_address_t *__addr_p, vm_size_t __size); +extern void __mig_deallocate (vm_address_t __addr, vm_size_t __size); +extern void mig_deallocate (vm_address_t __addr, vm_size_t __size); + +/* Reply-port management support functions. */ +extern void __mig_dealloc_reply_port (mach_port_t); +extern void mig_dealloc_reply_port (mach_port_t); +extern mach_port_t __mig_get_reply_port (void); +extern mach_port_t mig_get_reply_port (void); +extern void __mig_put_reply_port (mach_port_t); +extern void mig_put_reply_port (mach_port_t); + +extern void __mig_reply_setup (const mach_msg_header_t *__request, + mach_msg_header_t *__reply); +extern void mig_reply_setup (const mach_msg_header_t *__request, + mach_msg_header_t *__reply); + +/* Idiocy support function. */ +extern __inline vm_size_t +__mig_strncpy (char *__dst, const char *__src, vm_size_t __len) +{ + return __stpncpy (__dst, __src, __len) - __dst; +} +extern __inline vm_size_t +mig_strncpy (char *__dst, const char *__src, vm_size_t __len) +{ + return __mig_strncpy (__dst, __src, __len); +} + + + +#endif /* mach/mig_support.h */ diff --git a/mach/mach_error.c b/mach/mach_error.c new file mode 100644 index 0000000000..6cac0a5a7c --- /dev/null +++ b/mach/mach_error.c @@ -0,0 +1,85 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1992/10/06 18:29:54 roland + * entered into RCS + * + * Revision 2.4 92/02/19 15:10:52 elf + * Moved mach_error_string and mach_error_type to mach_error_string.c. + * [92/02/11 rpd] + * + * Revision 2.3 92/01/23 15:22:06 rpd + * Changed <servers/errorlib.h> to <errorlib.h>. + * [92/01/16 rpd] + * + * Revision 2.2 92/01/16 00:08:03 rpd + * Moved from user collection to mk collection. + * + * Revision 2.3 91/08/29 15:51:50 rpd + * Changed IPC_MIG_MOD to MACH_IPC_MIG_MOD, to get the new error strings. + * [91/08/22 rpd] + * + * Revision 2.2 91/03/27 16:06:29 mrt + * Changed include of "errorlib.h" to <servers/errorlib.h> + * Added new copyright + * [91/03/20 mrt] + * + */ +/* + * File: mach_error.c + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar 1988 + * + * interprets structured mach error codes and prints + * or returns a descriptive string. + */ + +#include <stdio.h> +#include <mach_error.h> +#include <mach/boolean.h> + +extern char * mach_error_string_int(); + +void +mach_error( str, err ) + char *str; + mach_error_t err; +{ + char * err_str; + char buf[1024]; + boolean_t diag; + + err_str=mach_error_string_int(err, &diag); + + if ( diag ) { + sprintf( buf, "%s %s (%x)", mach_error_type(err), err_str, err ); + err_str = buf; + } + + fprintf(stderr, "%s %s\n", str, err_str); +} diff --git a/mach/mach_error.h b/mach/mach_error.h new file mode 100644 index 0000000000..852ab4e622 --- /dev/null +++ b/mach/mach_error.h @@ -0,0 +1,80 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.2 1993/11/23 20:39:08 mib + * entered into RCS + * + * Revision 2.2 92/01/16 00:08:10 rpd + * Moved from user collection to mk collection. + * + * Revision 2.2 91/03/27 15:39:13 mrt + * First checkin + * + */ +/* + * File: mach_error.h + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar. 1988 + * + * Definitions of routines in mach_error.c + */ + +#ifndef _MACH_ERROR_ +#define _MACH_ERROR_ 1 + +#include <mach/error.h> + +const char *mach_error_string( +/* + * Returns a string appropriate to the error argument given + */ +#if c_plusplus + mach_error_t error_value +#endif c_plusplus + ); + +void mach_error( +/* + * Prints an appropriate message on the standard error stream + */ +#if c_plusplus + char *str, + mach_error_t error_value +#endif c_plusplus + ); + +const char *mach_error_type( +/* + * Returns a string with the error system, subsystem and code +*/ +#if c_plusplus + mach_error_t error_value +#endif c_plusplus + ); + +#endif _MACH_ERROR_ diff --git a/mach/mach_init.c b/mach/mach_init.c new file mode 100644 index 0000000000..42379feb85 --- /dev/null +++ b/mach/mach_init.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach_init.h> +#include <mach/mach_interface.h> + +mach_port_t __mach_task_self_; +vm_size_t __vm_page_size; +weak_alias (__vm_page_size, vm_page_size) + +void +__mach_init (void) +{ + kern_return_t err; + vm_statistics_data_t stats; + + __mach_task_self_ = (__mach_task_self) (); + __mig_init (0); + + if (err = __vm_statistics (__mach_task_self (), &stats)) + _exit (err); + __vm_page_size = stats.pagesize; +} +weak_alias (__mach_init, mach_init) diff --git a/mach/mach_init.h b/mach/mach_init.h new file mode 100644 index 0000000000..904473dd3a --- /dev/null +++ b/mach/mach_init.h @@ -0,0 +1,48 @@ +/* Declarations and macros for the basic Mach things set at startup. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACH_INIT_H + +#define _MACH_INIT_H 1 + +#include <mach/mach_types.h> + +/* Return the current task's task port. */ +extern mach_port_t __mach_task_self (void); +extern mach_port_t mach_task_self (void); + +/* This cache is initialized at startup. */ +extern mach_port_t __mach_task_self_; +#define __mach_task_self() (__mach_task_self_ + 0) /* Not an lvalue. */ +#define mach_task_self() (__mach_task_self ()) + +/* Kernel page size. */ +extern vm_size_t __vm_page_size; +extern vm_size_t vm_page_size; + +/* Round the address X up to a page boundary. */ +#define round_page(x) \ + ((((vm_offset_t) (x) + __vm_page_size - 1) / __vm_page_size) * \ + __vm_page_size) + +/* Truncate the address X down to a page boundary. */ +#define trunc_page(x) \ + ((((vm_offset_t) (x)) / __vm_page_size) * __vm_page_size) + +#endif /* mach_init.h */ diff --git a/mach/mach_shortcuts.c b/mach/mach_shortcuts.c new file mode 100644 index 0000000000..ef1792b003 --- /dev/null +++ b/mach/mach_shortcuts.c @@ -0,0 +1,13 @@ +#include <mach/mach_types.h> +#include <mach/mach_port.h> + +#define SHORTCUT(name, number, args, typed_args) \ +kern_return_t __##name typed_args \ +{ \ + kern_return_t ret = __syscall_##name args; \ + if (ret == MACH_SEND_INTERRUPTED) \ + ret = __mig_##name args; \ + return ret; \ +} + +#include "mach_shortcuts.h" diff --git a/mach/mach_syscalls.c b/mach/mach_syscalls.c new file mode 100644 index 0000000000..44930c33cf --- /dev/null +++ b/mach/mach_syscalls.c @@ -0,0 +1,10 @@ +/* Aliases for basic Mach system calls: + mach_task_self -> __mach_task_self, etc. */ + +#include <gnu-stabs.h> + +#define SYSCALL(name, number, type, args, typed_args) \ + function_alias (name, __##name, type, args, \ + name typed_args) + +#include "mach_syscalls.h" diff --git a/mach/mach_syscalls.h b/mach/mach_syscalls.h new file mode 100644 index 0000000000..8b33dc4e7e --- /dev/null +++ b/mach/mach_syscalls.h @@ -0,0 +1,31 @@ +SYSCALL (mach_msg_trap, -25, + mach_msg_return_t, + (msg, option, send_size, + rcv_size, rcv_name, timeout, notify), + (mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify)) + +SYSCALL (mach_reply_port, -26, + mach_port_t, + (), + (void)) + +SYSCALL (mach_thread_self, -27, + mach_port_t, + (), + (void)) + +SYSCALL (mach_task_self, -28, + mach_port_t, + (), + (void)) + +SYSCALL (mach_host_self, -29, + mach_port_t, + (), + (void)) diff --git a/mach/mach_traps.S b/mach/mach_traps.S new file mode 100644 index 0000000000..bd53646294 --- /dev/null +++ b/mach/mach_traps.S @@ -0,0 +1,15 @@ +/* Traps for Mach basic system calls and kernel RPC shortcuts. */ + +#include <sysdep.h> + +#define SYSCALL(name, number, type, args, typed_args) \ + SYSCALL_TRAP (__##name, number) + +/* Basic syscalls. */ +#include "mach_syscalls.h" + +/* RPC shortcuts. */ +#define SHORTCUT(name, number, args, typed_args) \ + SYSCALL_TRAP (__syscall_##name, number) + +#include "mach_shortcuts.h" diff --git a/mach/mig-alloc.c b/mach/mig-alloc.c new file mode 100644 index 0000000000..6f05153acc --- /dev/null +++ b/mach/mig-alloc.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> + +/* Called by MiG to allocate space. */ +void +__mig_allocate (vm_address_t *addr, + vm_size_t size) +{ + if (__vm_allocate (__mach_task_self (), addr, size, 1) != KERN_SUCCESS) + *addr = 0; +} diff --git a/mach/mig-dealloc.c b/mach/mig-dealloc.c new file mode 100644 index 0000000000..3942acac58 --- /dev/null +++ b/mach/mig-dealloc.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> + +/* Called by MiG to deallocate space. */ +void +__mig_deallocate (vm_address_t addr, + vm_size_t size) +{ + (void) __vm_deallocate (__mach_task_self (), addr, size); +} +weak_alias (__mig_deallocate, mig_deallocate) diff --git a/mach/mig_strncpy.c b/mach/mig_strncpy.c new file mode 100644 index 0000000000..b0c001d775 --- /dev/null +++ b/mach/mig_strncpy.c @@ -0,0 +1,11 @@ +/* Silly pointless function MiG needs. */ + +#include <mach.h> +#include <string.h> + +vm_size_t +__mig_strncpy (char *dst, const char *src, vm_size_t len) +{ + return __stpncpy (dst, src, len) - dst; +} +weak_alias (__mig_strncpy, mig_strncpy) diff --git a/mach/msg-destroy.c b/mach/msg-destroy.c new file mode 100644 index 0000000000..c0841f1190 --- /dev/null +++ b/mach/msg-destroy.c @@ -0,0 +1,160 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.3 1995/01/23 22:16:52 roland + * (mach_msg_destroy): Define as weak alias for __mach_msg_destroy. + * + * Revision 1.2 1993/08/03 06:13:18 roland + * entered into RCS + * + * Revision 2.4 91/05/14 17:53:15 mrt + * Correcting copyright + * + * Revision 2.3 91/02/14 14:17:43 mrt + * Added new Mach copyright + * [91/02/13 12:44:15 mrt] + * + * Revision 2.2 90/08/06 17:24:22 rpd + * Created. + * + */ + +#if 1 +#include <mach.h> +#else +/* This is what CMU did, but that fails to declare some used functions. */ +#include <mach/port.h> +#include <mach/message.h> +#include <mach_init.h> +#endif + +static void mach_msg_destroy_port(); +static void mach_msg_destroy_memory(); + +/* + * Routine: mach_msg_destroy + * Purpose: + * Deallocates all port rights and out-of-line memory + * found in a received message. + */ + +void +__mach_msg_destroy(msg) + mach_msg_header_t *msg; +{ + mach_msg_bits_t mbits = msg->msgh_bits; + + /* + * The msgh_local_port field doesn't hold a port right. + * The receive operation consumes the destination port right. + */ + + mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits)); + + if (mbits & MACH_MSGH_BITS_COMPLEX) { + vm_offset_t saddr; + vm_offset_t eaddr; + + saddr = (vm_offset_t) (msg + 1); + eaddr = (vm_offset_t) msg + msg->msgh_size; + + while (saddr < eaddr) { + mach_msg_type_long_t *type; + mach_msg_type_name_t name; + mach_msg_type_size_t size; + mach_msg_type_number_t number; + boolean_t is_inline; + vm_size_t length; + vm_offset_t addr; + + type = (mach_msg_type_long_t *) saddr; + is_inline = type->msgtl_header.msgt_inline; + if (type->msgtl_header.msgt_longform) { + name = type->msgtl_name; + size = type->msgtl_size; + number = type->msgtl_number; + saddr += sizeof(mach_msg_type_long_t); + } else { + name = type->msgtl_header.msgt_name; + size = type->msgtl_header.msgt_size; + number = type->msgtl_header.msgt_number; + saddr += sizeof(mach_msg_type_t); + } + + /* calculate length of data in bytes, rounding up */ + length = ((((number * size) + 7) >> 3) + 3) &~ 3; + + addr = is_inline ? saddr : * (vm_offset_t *) saddr; + + if (MACH_MSG_TYPE_PORT_ANY(name)) { + mach_port_t *ports = (mach_port_t *) addr; + mach_msg_type_number_t i; + + for (i = 0; i < number; i++) + mach_msg_destroy_port(*ports++, name); + } + + if (is_inline) { + /* inline data sizes round up to int boundaries */ + saddr += length; + } else { + mach_msg_destroy_memory(addr, length); + saddr += sizeof(vm_offset_t); + } + } + } +} + +weak_alias (__mach_msg_destroy, mach_msg_destroy) + +static void +mach_msg_destroy_port(port, type) + mach_port_t port; + mach_msg_type_name_t type; +{ + if (MACH_PORT_VALID(port)) switch (type) { + case MACH_MSG_TYPE_PORT_SEND: + case MACH_MSG_TYPE_PORT_SEND_ONCE: + (void) __mach_port_deallocate(__mach_task_self(), port); + break; + + case MACH_MSG_TYPE_PORT_RECEIVE: + (void) __mach_port_mod_refs(__mach_task_self(), port, + MACH_PORT_RIGHT_RECEIVE, -1); + break; + } +} + +static void +mach_msg_destroy_memory(addr, size) + vm_offset_t addr; + vm_size_t size; +{ + if (size > 0) + (void) __vm_deallocate(__mach_task_self(), addr, size); +} diff --git a/mach/msg.c b/mach/msg.c new file mode 100644 index 0000000000..ece110868d --- /dev/null +++ b/mach/msg.c @@ -0,0 +1,82 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989, 1995 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#include <mach/port.h> +#include <mach/message.h> + +mach_msg_return_t +__mach_msg (mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify) +{ + mach_msg_return_t ret; + + /* Consider the following cases: + 1. Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED + plus special bits). + 2. Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. + 3. RPC calls with interruptions in one/both halves. + */ + + ret = __mach_msg_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify); + if (ret == MACH_MSG_SUCCESS) + return MACH_MSG_SUCCESS; + + if (!(option & MACH_SEND_INTERRUPT)) + while (ret == MACH_SEND_INTERRUPTED) + ret = __mach_msg_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify); + + if (!(option & MACH_RCV_INTERRUPT)) + while (ret == MACH_RCV_INTERRUPTED) + ret = __mach_msg_trap (msg, option & ~MACH_SEND_MSG, + 0, rcv_size, rcv_name, timeout, notify); + + return ret; +} +weak_alias (__mach_msg, mach_msg) + +mach_msg_return_t +__mach_msg_send (mach_msg_header_t *msg) +{ + return __mach_msg (msg, MACH_SEND_MSG, + msg->msgh_size, 0, MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); +} +weak_alias (__mach_msg_send, mach_msg_send) + +mach_msg_return_t +__mach_msg_receive (mach_msg_header_t *msg) +{ + return __mach_msg (msg, MACH_RCV_MSG, + 0, msg->msgh_size, msg->msgh_local_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); +} +weak_alias (__mach_msg_receive, mach_msg_receive) diff --git a/mach/msg_destroy.c b/mach/msg_destroy.c new file mode 100644 index 0000000000..9461e3d1a2 --- /dev/null +++ b/mach/msg_destroy.c @@ -0,0 +1,4 @@ +#include <gnu-stabs.h> + +#undef mach_msg_destroy +symbol_alias (__mach_msg_destroy, mach_msg_destroy); diff --git a/mach/msgserver.c b/mach/msgserver.c new file mode 100644 index 0000000000..e0dc29b754 --- /dev/null +++ b/mach/msgserver.c @@ -0,0 +1,194 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Based on CMU's mach_msg_server.c revision 2.4 of 91/05/14, and thus + under the following copyright. Rewritten by Roland McGrath (FSF) + 93/12/06 to use stack space instead of malloc, and to handle + large messages with MACH_RCV_LARGE. */ + +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.3 1995/01/21 15:00:57 roland + * Converted to use weak aliases with macros from libc-symbols.h. + * + * Revision 1.2 1994/10/10 07:20:14 roland + * Increase default MAX_SIZE to two pages. + * + * Revision 1.1 1993/12/06 23:25:25 roland + * entered into RCS + * + * Revision 2.4 91/05/14 17:53:22 mrt + * Correcting copyright + * + * Revision 2.3 91/02/14 14:17:47 mrt + * Added new Mach copyright + * [91/02/13 12:44:20 mrt] + * + * Revision 2.2 90/08/06 17:23:58 rpd + * Created. + * + */ + + +#include <mach.h> +#include <mach/mig_errors.h> +#include <stdlib.h> /* For malloc and free. */ + +mach_msg_return_t +__mach_msg_server_timeout (boolean_t (*demux) (mach_msg_header_t *request, + mach_msg_header_t *reply), + mach_msg_size_t max_size, + mach_port_t rcv_name, + mach_msg_option_t option, + mach_msg_timeout_t timeout) +{ + register mig_reply_header_t *request, *reply; + register mach_msg_return_t mr; + + if (max_size == 0) + { + option |= MACH_RCV_LARGE; + max_size = 2 * __vm_page_size; /* Generic. Good? XXX */ + } + + request = __alloca (max_size); + reply = __alloca (max_size); + + while (1) + { + get_request: + mr = __mach_msg (&request->Head, MACH_RCV_MSG|option, + 0, max_size, rcv_name, + timeout, MACH_PORT_NULL); + while (mr == MACH_MSG_SUCCESS) + { + /* We have a request message. + Pass it to DEMUX for processing. */ + + (void) (*demux) (&request->Head, &reply->Head); + + switch (reply->RetCode) + { + case KERN_SUCCESS: + /* Hunky dory. */ + break; + + case MIG_NO_REPLY: + /* The server function wanted no reply sent. + Loop for another request. */ + goto get_request; + + default: + /* Some error; destroy the request message to release any + port rights or VM it holds. Don't destroy the reply port + right, so we can send an error message. */ + request->Head.msgh_remote_port = MACH_PORT_NULL; + __mach_msg_destroy (&request->Head); + break; + } + + if (reply->Head.msgh_remote_port == MACH_PORT_NULL) + { + /* No reply port, so destroy the reply. */ + if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) + __mach_msg_destroy (&reply->Head); + goto get_request; + } + + /* Send the reply and the get next request. */ + + { + /* Swap the request and reply buffers. mach_msg will read the + reply message from the buffer we pass and write the new + request message to the same buffer. */ + void *tmp = request; + request = reply; + reply = tmp; + } + + mr = __mach_msg (&request->Head, + MACH_SEND_MSG|MACH_RCV_MSG|option, + request->Head.msgh_size, max_size, rcv_name, + timeout, MACH_PORT_NULL); + } + + /* A message error occurred. */ + + switch (mr) + { + case MACH_RCV_TOO_LARGE: + /* The request message is larger than MAX_SIZE, and has not + been dequued. The message header has the actual size of + the message. We recurse here in hopes that the compiler + will optimize the tail-call and allocate some more stack + space instead of way too much. */ + return __mach_msg_server_timeout (demux, request->Head.msgh_size, + rcv_name, option, timeout); + + case MACH_SEND_INVALID_DEST: + /* The reply can't be delivered, so destroy it. This error + indicates only that the requestor went away, so we + continue and get the next request. */ + __mach_msg_destroy (&request->Head); + break; + + default: + /* Some other form of lossage; return to caller. */ + return mr; + } + } +} +weak_alias (__mach_msg_server_timeout, mach_msg_server_timeout) + +mach_msg_return_t +__mach_msg_server (demux, max_size, rcv_name) + boolean_t (*demux) (); + mach_msg_size_t max_size; + mach_port_t rcv_name; +{ + return __mach_msg_server_timeout (demux, max_size, rcv_name, + MACH_MSG_OPTION_NONE, + MACH_MSG_TIMEOUT_NONE); +} +weak_alias (__mach_msg_server, mach_msg_server) diff --git a/mach/mutex-solid.c b/mach/mutex-solid.c new file mode 100644 index 0000000000..aeaa269c6b --- /dev/null +++ b/mach/mutex-solid.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <lock-intern.h> +#include <cthreads.h> + +/* If cthreads is linked in, it will define these variables with values + that point to its mutex functions. */ +void (*_cthread_mutex_lock_routine) (struct mutex *); +void (*_cthread_mutex_unlock_routine) (struct mutex *); + +void +__mutex_lock_solid (void *lock) +{ + if (_cthread_mutex_lock_routine) + (*_cthread_mutex_lock_routine) (lock); + else + __spin_lock_solid (lock); +} + +void +__mutex_unlock_solid (void *lock) +{ + if (_cthread_mutex_unlock_routine) + (*_cthread_mutex_unlock_routine) (lock); +} + +void +__mutex_init (void *lock) +{ + /* This happens to be name space-safe because it is a macro. + It invokes only spin_lock_init, which is a macro for __spin_lock_init; + and cthread_queue_init, which is a macro for some simple code. */ + mutex_init ((struct mutex *) lock); +} diff --git a/mach/setup-thread.c b/mach/setup-thread.c new file mode 100644 index 0000000000..a00edacdfd --- /dev/null +++ b/mach/setup-thread.c @@ -0,0 +1,99 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include "thread_state.h" +#include <string.h> +#include <mach/machine/vm_param.h> +#include "sysdep.h" /* Defines stack direction. */ + +#define STACK_SIZE (16 * 1024 * 1024) /* 16MB, arbitrary. */ + +/* Give THREAD a stack and set it to run at PC when resumed. + If *STACK_SIZE is nonzero, that size of stack is allocated. + If *STACK_BASE is nonzero, that stack location is used. + If STACK_BASE is not null it is filled in with the chosen stack base. + If STACK_SIZE is not null it is filled in with the chosen stack size. + Regardless, an extra page of red zone is allocated off the end; this + is not included in *STACK_SIZE. */ + +kern_return_t +__mach_setup_thread (task_t task, thread_t thread, void *pc, + vm_address_t *stack_base, vm_size_t *stack_size) +{ + kern_return_t error; + struct machine_thread_state ts; + mach_msg_type_number_t tssize = MACHINE_THREAD_STATE_COUNT; + vm_address_t stack; + vm_size_t size; + int anywhere = 0; + + size = stack_size ? *stack_size ? : STACK_SIZE : STACK_SIZE; + + if (stack_base && *stack_base) + stack = *stack_base; + else if (size == STACK_SIZE) + { + /* Cthreads has a bug that makes its stack-probing code fail if + the stack is too low in memory. It's bad to try and fix it there + until cthreads is integrated into libc, so we'll just do it here + by requesting a high address. When the cthreads bug is fixed, + this assignment to STACK should be changed to 0, and the ANYWHERE + argument to vm_allocate should be changed to 0. This comment should + be left, however, in order to confuse people who wonder why its + here. (Though perhaps that last sentence (and this one) should + be deleted to maximize the effect.) */ +#ifdef STACK_GROWTH_DOWN + stack = VM_MAX_ADDRESS - size - __vm_page_size; +#else + stack = VM_MIN_ADDRESS; +#endif + } + else + anywhere = 1; + + if (error = __vm_allocate (task, &stack, size + __vm_page_size, anywhere)) + return error; + + if (stack_size) + *stack_size = size; + + memset (&ts, 0, sizeof (ts)); + MACHINE_THREAD_STATE_SET_PC (&ts, pc); +#ifdef STACK_GROWTH_DOWN + if (stack_base) + *stack_base = stack + __vm_page_size; + ts.SP = stack + __vm_page_size + size; +#elif defined (STACK_GROWTH_UP) + if (stack_base) + *stack_base = stack; + ts.SP = stack; + stack += size; +#else + #error stack direction unknown +#endif + + /* Create the red zone. */ + if (error = __vm_protect (task, stack, __vm_page_size, 0, VM_PROT_NONE)) + return error; + + return __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR, + (int *) &ts, tssize); +} + +weak_alias (__mach_setup_thread, mach_setup_thread) diff --git a/mach/shortcut.awk b/mach/shortcut.awk new file mode 100644 index 0000000000..d6090d7bf7 --- /dev/null +++ b/mach/shortcut.awk @@ -0,0 +1,45 @@ +# Icky intimate knowledge of MiG output. + +BEGIN { print "/* This file is generated by shortcut.awk. */"; + echo=1; + inproto=0; proto=""; arglist=""; + } + +$1 == "LINTLIBRARY" { print "#include <mach.h>"; next } + +# Copy the first line of the definition, but +# replace the function name (RPC) with CALL. +$NF == rpc \ + { + for (i = 1; i < NF; ++i) printf "%s ", $i; + print call; + next; + } + +# Collect the lines of the prototype in PROTO, and extract the parameter +# names into ARGLIST. +NF == 1 && $1 == ")" { inproto=0 } +inproto { proto = proto $0; + arg = $NF; + gsub(/[^a-zA-Z0-9_,]/, "", arg); + arglist = arglist arg; + } +NF == 1 && $1 == "(" { inproto=1 } + +/^{$/ { echo=0; } + +echo == 1 { print $0; } + +/^}$/ \ + { + print "{"; + print " kern_return_t err;"; + print " extern kern_return_t " syscall " (" proto ");"; + print " err = " syscall " (" arglist ");"; + print " if (err == MACH_SEND_INTERRUPTED)"; + print " err = " rpc " (" arglist ");"; + print " return err;" + print "}"; + print "weak_alias (" call ", " alias ")" + echo = 1; + } diff --git a/mach/spin-lock.c b/mach/spin-lock.c new file mode 100644 index 0000000000..aaebc55cf4 --- /dev/null +++ b/mach/spin-lock.c @@ -0,0 +1,8 @@ +#define _EXTERN_INLINE /* Empty to define the real functions. */ +#include "spin-lock.h" + +weak_alias (__spin_lock_init, spin_lock_init); +weak_alias (__spin_lock_locked, spin_lock_locked); +weak_alias (__spin_lock, spin_lock); +weak_alias (__spin_unlock, spin_unlock); +weak_alias (__spin_try_lock, spin_try_lock); diff --git a/mach/spin-lock.h b/mach/spin-lock.h new file mode 100644 index 0000000000..13b5e245b6 --- /dev/null +++ b/mach/spin-lock.h @@ -0,0 +1,34 @@ +/* Definitions of user-visible names for spin locks. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SPIN_LOCK_H +#define _SPIN_LOCK_H + +#include <lock-intern.h> /* This does all the work. */ + +typedef __spin_lock_t spin_lock_t; +#define SPIN_LOCK_INITIALIZER __SPIN_LOCK_INITIALIZER + +#define spin_lock_init(lock) __spin_lock_init (lock) +#define spin_lock(lock) __spin_lock (lock) +#define spin_try_lock(lock) __spin_try_lock (lock) +#define spin_unlock(lock) __spin_unlock (lock) +#define spin_lock_locked(lock) __spin_lock_locked (lock) + +#endif /* spin-lock.h */ diff --git a/mach/spin-solid.c b/mach/spin-solid.c new file mode 100644 index 0000000000..265df0632e --- /dev/null +++ b/mach/spin-solid.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <spin-lock.h> + +void +__spin_lock_solid (spin_lock_t *lock) +{ + while (__spin_lock_locked (lock) || ! __spin_try_lock (lock)) + /* Yield to another thread (system call). */ + __swtch_pri (); +} +weak_alias (__spin_lock_solid, spin_lock_solid); diff --git a/mach/syscalls.awk b/mach/syscalls.awk new file mode 100644 index 0000000000..dec8a3b537 --- /dev/null +++ b/mach/syscalls.awk @@ -0,0 +1,9 @@ +BEGIN { calls="" } + +{ + calls = calls " " $1; + print "sysno-" $1 " = " $2; + print "nargs-" $1 " = " $3; +} + +END { print "mach-syscalls := " calls } diff --git a/mach/vm_page_size.c b/mach/vm_page_size.c new file mode 100644 index 0000000000..767e709f5c --- /dev/null +++ b/mach/vm_page_size.c @@ -0,0 +1,3 @@ +#include <gnu-stabs.h> + +symbol_alias (__vm_page_size, vm_page_size); diff --git a/malloc.h b/malloc.h new file mode 100644 index 0000000000..448e0a8c6b --- /dev/null +++ b/malloc.h @@ -0,0 +1 @@ +#include <malloc/malloc.h> diff --git a/manual/.cvsignore b/manual/.cvsignore new file mode 100644 index 0000000000..999d5615a7 --- /dev/null +++ b/manual/.cvsignore @@ -0,0 +1,10 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* + +*.dvi* *.info* *.c.texi +*.toc *.aux *.log +*.cp *.cps *.fn *.fns *.vr *.vrs *.tp *.tps *.ky *.kys *.pg *.pgs + +chapters chapters-incl summary.texi stamp-* diff --git a/manual/=copying.texinfo b/manual/=copying.texinfo new file mode 100644 index 0000000000..6a61d64bfb --- /dev/null +++ b/manual/=copying.texinfo @@ -0,0 +1,540 @@ +@comment This material was copied from /gd/gnu/doc/lgpl.texinfo. + +@node Copying, Concept Index, Maintenance, Top +@appendix GNU GENERAL PUBLIC LICENSE +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1991 Free Software Foundation, Inc. +675 Mass Ave, Cambridge, MA 02139, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] +@end display + +@unnumberedsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate +@item +This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called ``this License''). Each licensee is +addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also compile or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate a +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate a +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and a brief idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@example +Yoyodyne, Inc., hereby disclaims all copyright interest in the +library `Frob' (a library for tweaking knobs) written by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end example + +That's all there is to it! diff --git a/manual/=float.texinfo b/manual/=float.texinfo new file mode 100644 index 0000000000..a8c901542e --- /dev/null +++ b/manual/=float.texinfo @@ -0,0 +1,416 @@ +@node Floating-Point Limits +@chapter Floating-Point Limits +@pindex <float.h> +@cindex floating-point number representation +@cindex representation of floating-point numbers + +Because floating-point numbers are represented internally as approximate +quantities, algorithms for manipulating floating-point data often need +to be parameterized in terms of the accuracy of the representation. +Some of the functions in the C library itself need this information; for +example, the algorithms for printing and reading floating-point numbers +(@pxref{I/O on Streams}) and for calculating trigonometric and +irrational functions (@pxref{Mathematics}) use information about the +underlying floating-point representation to avoid round-off error and +loss of accuracy. User programs that implement numerical analysis +techniques also often need to be parameterized in this way in order to +minimize or compute error bounds. + +The specific representation of floating-point numbers varies from +machine to machine. The GNU C Library defines a set of parameters which +characterize each of the supported floating-point representations on a +particular system. + +@menu +* Floating-Point Representation:: Definitions of terminology. +* Floating-Point Parameters:: Descriptions of the library facilities. +* IEEE Floating-Point:: An example of a common representation. +@end menu + +@node Floating-Point Representation +@section Floating-Point Representation + +This section introduces the terminology used to characterize the +representation of floating-point numbers. + +You are probably already familiar with most of these concepts in terms +of scientific or exponential notation for floating-point numbers. For +example, the number @code{123456.0} could be expressed in exponential +notation as @code{1.23456e+05}, a shorthand notation indicating that the +mantissa @code{1.23456} is multiplied by the base @code{10} raised to +power @code{5}. + +More formally, the internal representation of a floating-point number +can be characterized in terms of the following parameters: + +@itemize @bullet +@item +The @dfn{sign} is either @code{-1} or @code{1}. +@cindex sign (of floating-point number) + +@item +The @dfn{base} or @dfn{radix} for exponentiation; an integer greater +than @code{1}. This is a constant for the particular representation. +@cindex base (of floating-point number) +@cindex radix (of floating-point number) + +@item +The @dfn{exponent} to which the base is raised. The upper and lower +bounds of the exponent value are constants for the particular +representation. +@cindex exponent (of floating-point number) + +Sometimes, in the actual bits representing the floating-point number, +the exponent is @dfn{biased} by adding a constant to it, to make it +always be represented as an unsigned quantity. This is only important +if you have some reason to pick apart the bit fields making up the +floating-point number by hand, which is something for which the GNU +library provides no support. So this is ignored in the discussion that +follows. +@cindex bias, in exponent (of floating-point number) + +@item +The value of the @dfn{mantissa} or @dfn{significand}, which is an +unsigned quantity. +@cindex mantissa (of floating-point number) +@cindex significand (of floating-point number) + +@item +The @dfn{precision} of the mantissa. If the base of the representation +is @var{b}, then the precision is the number of base-@var{b} digits in +the mantissa. This is a constant for the particular representation. + +Many floating-point representations have an implicit @dfn{hidden bit} in +the mantissa. Any such hidden bits are counted in the precision. +Again, the GNU library provides no facilities for dealing with such low-level +aspects of the representation. +@cindex precision (of floating-point number) +@cindex hidden bit, in mantissa (of floating-point number) +@end itemize + +The mantissa of a floating-point number actually represents an implicit +fraction whose denominator is the base raised to the power of the +precision. Since the largest representable mantissa is one less than +this denominator, the value of the fraction is always strictly less than +@code{1}. The mathematical value of a floating-point number is then the +product of this fraction; the sign; and the base raised to the exponent. + +If the floating-point number is @dfn{normalized}, the mantissa is also +greater than or equal to the base raised to the power of one less +than the precision (unless the number represents a floating-point zero, +in which case the mantissa is zero). The fractional quantity is +therefore greater than or equal to @code{1/@var{b}}, where @var{b} is +the base. +@cindex normalized floating-point number + +@node Floating-Point Parameters +@section Floating-Point Parameters + +@strong{Incomplete:} This section needs some more concrete examples +of what these parameters mean and how to use them in a program. + +These macro definitions can be accessed by including the header file +@file{<float.h>} in your program. + +Macro names starting with @samp{FLT_} refer to the @code{float} type, +while names beginning with @samp{DBL_} refer to the @code{double} type +and names beginning with @samp{LDBL_} refer to the @code{long double} +type. (In implementations that do not support @code{long double} as +a distinct data type, the values for those constants are the same +as the corresponding constants for the @code{double} type.)@refill + +Note that only @code{FLT_RADIX} is guaranteed to be a constant +expression, so the other macros listed here cannot be reliably used in +places that require constant expressions, such as @samp{#if} +preprocessing directives and array size specifications. + +Although the ANSI C standard specifies minimum and maximum values for +most of these parameters, the GNU C implementation uses whatever +floating-point representations are supported by the underlying hardware. +So whether GNU C actually satisfies the ANSI C requirements depends on +what machine it is running on. + +@comment float.h +@comment ANSI +@defvr Macro FLT_ROUNDS +This value characterizes the rounding mode for floating-point addition. +The following values indicate standard rounding modes: + +@table @code +@item -1 +The mode is indeterminable. +@item 0 +Rounding is towards zero. +@item 1 +Rounding is to the nearest number. +@item 2 +Rounding is towards positive infinity. +@item 3 +Rounding is towards negative infinity. +@end table + +@noindent +Any other value represents a machine-dependent nonstandard rounding +mode. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_RADIX +This is the value of the base, or radix, of exponent representation. +This is guaranteed to be a constant expression, unlike the other macros +described in this section. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{float} data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{double} data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{long double} data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_DIG +This is the number of decimal digits of precision for the @code{float} +data type. Technically, if @var{p} and @var{b} are the precision and +base (respectively) for the representation, then the decimal precision +@var{q} is the maximum number of decimal digits such that any floating +point number with @var{q} base 10 digits can be rounded to a floating +point number with @var{p} base @var{b} digits and back again, without +change to the @var{q} decimal digits. + +The value of this macro is guaranteed to be at least @code{6}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_DIG +This is similar to @code{FLT_DIG}, but is for the @code{double} data +type. The value of this macro is guaranteed to be at least @code{10}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_DIG +This is similar to @code{FLT_DIG}, but is for the @code{long double} +data type. The value of this macro is guaranteed to be at least +@code{10}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_MIN_EXP +This is the minimum negative integer such that the mathematical value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. In terms of the +actual implementation, this is just the smallest value that can be +represented in the exponent field of the number. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MIN_EXP +This is similar to @code{FLT_MIN_EXP}, but is for the @code{double} data +type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MIN_EXP +This is similar to @code{FLT_MIN_EXP}, but is for the @code{long double} +data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_MIN_10_EXP +This is the minimum negative integer such that the mathematical value +@code{10} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. This is +guaranteed to be no greater than @code{-37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MIN_10_EXP +This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{double} +data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MIN_10_EXP +This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{long +double} data type. +@end defvr + + + +@comment float.h +@comment ANSI +@defvr Macro FLT_MAX_EXP +This is the maximum negative integer such that the mathematical value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +floating-point number of type @code{float}. In terms of the actual +implementation, this is just the largest value that can be represented +in the exponent field of the number. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MAX_EXP +This is similar to @code{FLT_MAX_EXP}, but is for the @code{double} data +type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MAX_EXP +This is similar to @code{FLT_MAX_EXP}, but is for the @code{long double} +data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro FLT_MAX_10_EXP +This is the maximum negative integer such that the mathematical value +@code{10} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. This is +guaranteed to be at least @code{37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MAX_10_EXP +This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{double} +data type. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MAX_10_EXP +This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{long +double} data type. +@end defvr + + +@comment float.h +@comment ANSI +@defvr Macro FLT_MAX +The value of this macro is the maximum representable floating-point +number of type @code{float}, and is guaranteed to be at least +@code{1E+37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MAX +The value of this macro is the maximum representable floating-point +number of type @code{double}, and is guaranteed to be at least +@code{1E+37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MAX +The value of this macro is the maximum representable floating-point +number of type @code{long double}, and is guaranteed to be at least +@code{1E+37}. +@end defvr + + +@comment float.h +@comment ANSI +@defvr Macro FLT_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{float}, and is +guaranteed to be no more than @code{1E-37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{double}, and +is guaranteed to be no more than @code{1E-37}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{long double}, +and is guaranteed to be no more than @code{1E-37}. +@end defvr + + +@comment float.h +@comment ANSI +@defvr Macro FLT_EPSILON +This is the minimum positive floating-point number of type @code{float} +such that @code{1.0 + FLT_EPSILON != 1.0} is true. It's guaranteed to +be no greater than @code{1E-5}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro DBL_EPSILON +This is similar to @code{FLT_EPSILON}, but is for the @code{double} +type. The maximum value is @code{1E-9}. +@end defvr + +@comment float.h +@comment ANSI +@defvr Macro LDBL_EPSILON +This is similar to @code{FLT_EPSILON}, but is for the @code{long double} +type. The maximum value is @code{1E-9}. +@end defvr + + + +@node IEEE Floating Point +@section IEEE Floating Point + +Here is an example showing how these parameters work for a common +floating point representation, specified by the @cite{IEEE Standard for +Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)}. + +The IEEE single-precision float representation uses a base of 2. There +is a sign bit, a mantissa with 23 bits plus one hidden bit (so the total +precision is 24 base-2 digits), and an 8-bit exponent that can represent +values in the range -125 to 128, inclusive. + +So, for an implementation that uses this representation for the +@code{float} data type, appropriate values for the corresponding +parameters are: + +@example +FLT_RADIX 2 +FLT_MANT_DIG 24 +FLT_DIG 6 +FLT_MIN_EXP -125 +FLT_MIN_10_EXP -37 +FLT_MAX_EXP 128 +FLT_MAX_10_EXP +38 +FLT_MIN 1.17549435E-38F +FLT_MAX 3.40282347E+38F +FLT_EPSILON 1.19209290E-07F +@end example + + + diff --git a/manual/=limits.texinfo b/manual/=limits.texinfo new file mode 100644 index 0000000000..3e384dd6b6 --- /dev/null +++ b/manual/=limits.texinfo @@ -0,0 +1,593 @@ +@node Representation Limits, System Configuration Limits, System Information, Top +@chapter Representation Limits + +This chapter contains information about constants and parameters that +characterize the representation of the various integer and +floating-point types supported by the GNU C library. + +@menu +* Integer Representation Limits:: Determining maximum and minimum + representation values of + various integer subtypes. +* Floating-Point Limits :: Parameters which characterize + supported floating-point + representations on a particular + system. +@end menu + +@node Integer Representation Limits, Floating-Point Limits , , Representation Limits +@section Integer Representation Limits +@cindex integer representation limits +@cindex representation limits, integer +@cindex limits, integer representation + +Sometimes it is necessary for programs to know about the internal +representation of various integer subtypes. For example, if you want +your program to be careful not to overflow an @code{int} counter +variable, you need to know what the largest representable value that +fits in an @code{int} is. These kinds of parameters can vary from +compiler to compiler and machine to machine. Another typical use of +this kind of parameter is in conditionalizing data structure definitions +with @samp{#ifdef} to select the most appropriate integer subtype that +can represent the required range of values. + +Macros representing the minimum and maximum limits of the integer types +are defined in the header file @file{limits.h}. The values of these +macros are all integer constant expressions. +@pindex limits.h + +@comment limits.h +@comment ANSI +@deftypevr Macro int CHAR_BIT +This is the number of bits in a @code{char}, usually eight. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int SCHAR_MIN +This is the minimum value that can be represented by a @code{signed char}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int SCHAR_MAX +This is the maximum value that can be represented by a @code{signed char}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int UCHAR_MAX +This is the maximum value that can be represented by a @code{unsigned char}. +(The minimum value of an @code{unsigned char} is zero.) +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int CHAR_MIN +This is the minimum value that can be represented by a @code{char}. +It's equal to @code{SCHAR_MIN} if @code{char} is signed, or zero +otherwise. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int CHAR_MAX +This is the maximum value that can be represented by a @code{char}. +It's equal to @code{SCHAR_MAX} if @code{char} is signed, or +@code{UCHAR_MAX} otherwise. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int SHRT_MIN +This is the minimum value that can be represented by a @code{signed +short int}. On most machines that the GNU C library runs on, +@code{short} integers are 16-bit quantities. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int SHRT_MAX +This is the maximum value that can be represented by a @code{signed +short int}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int USHRT_MAX +This is the maximum value that can be represented by an @code{unsigned +short int}. (The minimum value of an @code{unsigned short int} is zero.) +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int INT_MIN +This is the minimum value that can be represented by a @code{signed +int}. On most machines that the GNU C system runs on, an @code{int} is +a 32-bit quantity. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro int INT_MAX +This is the maximum value that can be represented by a @code{signed +int}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro {unsigned int} UINT_MAX +This is the maximum value that can be represented by an @code{unsigned +int}. (The minimum value of an @code{unsigned int} is zero.) +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro {long int} LONG_MIN +This is the minimum value that can be represented by a @code{signed long +int}. On most machines that the GNU C system runs on, @code{long} +integers are 32-bit quantities, the same size as @code{int}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro {long int} LONG_MAX +This is the maximum value that can be represented by a @code{signed long +int}. +@end deftypevr + +@comment limits.h +@comment ANSI +@deftypevr Macro {unsigned long int} ULONG_MAX +This is the maximum value that can be represented by an @code{unsigned +long int}. (The minimum value of an @code{unsigned long int} is zero.) +@end deftypevr + +@strong{Incomplete:} There should be corresponding limits for the GNU +C Compiler's @code{long long} type, too. (But they are not now present +in the header file.) + +The header file @file{limits.h} also defines some additional constants +that parameterize various operating system and file system limits. These +constants are described in @ref{System Parameters} and @ref{File System +Parameters}. +@pindex limits.h + + +@node Floating-Point Limits , , Integer Representation Limits, Representation Limits +@section Floating-Point Limits +@cindex floating-point number representation +@cindex representation, floating-point number +@cindex limits, floating-point representation + +Because floating-point numbers are represented internally as approximate +quantities, algorithms for manipulating floating-point data often need +to be parameterized in terms of the accuracy of the representation. +Some of the functions in the C library itself need this information; for +example, the algorithms for printing and reading floating-point numbers +(@pxref{I/O on Streams}) and for calculating trigonometric and +irrational functions (@pxref{Mathematics}) use information about the +underlying floating-point representation to avoid round-off error and +loss of accuracy. User programs that implement numerical analysis +techniques also often need to be parameterized in this way in order to +minimize or compute error bounds. + +The specific representation of floating-point numbers varies from +machine to machine. The GNU C library defines a set of parameters which +characterize each of the supported floating-point representations on a +particular system. + +@menu +* Floating-Point Representation:: Definitions of terminology. +* Floating-Point Parameters:: Descriptions of the library + facilities. +* IEEE Floating Point:: An example of a common + representation. +@end menu + +@node Floating-Point Representation, Floating-Point Parameters, , Floating-Point Limits +@subsection Floating-Point Representation + +This section introduces the terminology used to characterize the +representation of floating-point numbers. + +You are probably already familiar with most of these concepts in terms +of scientific or exponential notation for floating-point numbers. For +example, the number @code{123456.0} could be expressed in exponential +notation as @code{1.23456e+05}, a shorthand notation indicating that the +mantissa @code{1.23456} is multiplied by the base @code{10} raised to +power @code{5}. + +More formally, the internal representation of a floating-point number +can be characterized in terms of the following parameters: + +@itemize @bullet +@item +The @dfn{sign} is either @code{-1} or @code{1}. +@cindex sign (of floating-point number) + +@item +The @dfn{base} or @dfn{radix} for exponentiation; an integer greater +than @code{1}. This is a constant for the particular representation. +@cindex base (of floating-point number) +@cindex radix (of floating-point number) + +@item +The @dfn{exponent} to which the base is raised. The upper and lower +bounds of the exponent value are constants for the particular +representation. +@cindex exponent (of floating-point number) + +Sometimes, in the actual bits representing the floating-point number, +the exponent is @dfn{biased} by adding a constant to it, to make it +always be represented as an unsigned quantity. This is only important +if you have some reason to pick apart the bit fields making up the +floating-point number by hand, which is something for which the GNU +library provides no support. So this is ignored in the discussion that +follows. +@cindex bias (of floating-point number exponent) + +@item +The value of the @dfn{mantissa} or @dfn{significand}, which is an +unsigned integer. +@cindex mantissa (of floating-point number) +@cindex significand (of floating-point number) + +@item +The @dfn{precision} of the mantissa. If the base of the representation +is @var{b}, then the precision is the number of base-@var{b} digits in +the mantissa. This is a constant for the particular representation. + +Many floating-point representations have an implicit @dfn{hidden bit} in +the mantissa. Any such hidden bits are counted in the precision. +Again, the GNU library provides no facilities for dealing with such low-level +aspects of the representation. +@cindex precision (of floating-point number) +@cindex hidden bit (of floating-point number mantissa) +@end itemize + +The mantissa of a floating-point number actually represents an implicit +fraction whose denominator is the base raised to the power of the +precision. Since the largest representable mantissa is one less than +this denominator, the value of the fraction is always strictly less than +@code{1}. The mathematical value of a floating-point number is then the +product of this fraction; the sign; and the base raised to the exponent. + +If the floating-point number is @dfn{normalized}, the mantissa is also +greater than or equal to the base raised to the power of one less +than the precision (unless the number represents a floating-point zero, +in which case the mantissa is zero). The fractional quantity is +therefore greater than or equal to @code{1/@var{b}}, where @var{b} is +the base. +@cindex normalized floating-point number + +@node Floating-Point Parameters, IEEE Floating Point, Floating-Point Representation, Floating-Point Limits +@subsection Floating-Point Parameters + +@strong{Incomplete:} This section needs some more concrete examples +of what these parameters mean and how to use them in a program. + +These macro definitions can be accessed by including the header file +@file{float.h} in your program. +@pindex float.h + +Macro names starting with @samp{FLT_} refer to the @code{float} type, +while names beginning with @samp{DBL_} refer to the @code{double} type +and names beginning with @samp{LDBL_} refer to the @code{long double} +type. (In implementations that do not support @code{long double} as +a distinct data type, the values for those constants are the same +as the corresponding constants for the @code{double} type.)@refill +@cindex @code{float} representation limits +@cindex @code{double} representation limits +@cindex @code{long double} representation limits + +Of these macros, only @code{FLT_RADIX} is guaranteed to be a constant +expression. The other macros listed here cannot be reliably used in +places that require constant expressions, such as @samp{#if} +preprocessing directives or array size specifications. + +Although the ANSI C standard specifies minimum and maximum values for +most of these parameters, the GNU C implementation uses whatever +floating-point representations are supported by the underlying hardware. +So whether GNU C actually satisfies the ANSI C requirements depends on +what machine it is running on. + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_ROUNDS +This value characterizes the rounding mode for floating-point addition. +The following values indicate standard rounding modes: + +@table @code +@item -1 +The mode is indeterminable. +@item 0 +Rounding is towards zero. +@item 1 +Rounding is to the nearest number. +@item 2 +Rounding is towards positive infinity. +@item 3 +Rounding is towards negative infinity. +@end table + +@noindent +Any other value represents a machine-dependent nonstandard rounding +mode. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_RADIX +This is the value of the base, or radix, of exponent representation. +This is guaranteed to be a constant expression, unlike the other macros +described in this section. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{float} data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{double} data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating-point +mantissa for the @code{long double} data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_DIG +This is the number of decimal digits of precision for the @code{float} +data type. Technically, if @var{p} and @var{b} are the precision and +base (respectively) for the representation, then the decimal precision +@var{q} is the maximum number of decimal digits such that any floating +point number with @var{q} base 10 digits can be rounded to a floating +point number with @var{p} base @var{b} digits and back again, without +change to the @var{q} decimal digits. + +The value of this macro is guaranteed to be at least @code{6}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_DIG +This is similar to @code{FLT_DIG}, but is for the @code{double} data +type. The value of this macro is guaranteed to be at least @code{10}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_DIG +This is similar to @code{FLT_DIG}, but is for the @code{long double} +data type. The value of this macro is guaranteed to be at least +@code{10}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_MIN_EXP +This is the minimum negative integer such that the mathematical value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. In terms of the +actual implementation, this is just the smallest value that can be +represented in the exponent field of the number. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_MIN_EXP +This is similar to @code{FLT_MIN_EXP}, but is for the @code{double} data +type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_MIN_EXP +This is similar to @code{FLT_MIN_EXP}, but is for the @code{long double} +data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_MIN_10_EXP +This is the minimum negative integer such that the mathematical value +@code{10} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. This is +guaranteed to be no greater than @code{-37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_MIN_10_EXP +This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{double} +data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_MIN_10_EXP +This is similar to @code{FLT_MIN_10_EXP}, but is for the @code{long +double} data type. +@end deftypevr + + + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_MAX_EXP +This is the maximum negative integer such that the mathematical value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +floating-point number of type @code{float}. In terms of the actual +implementation, this is just the largest value that can be represented +in the exponent field of the number. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_MAX_EXP +This is similar to @code{FLT_MAX_EXP}, but is for the @code{double} data +type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_MAX_EXP +This is similar to @code{FLT_MAX_EXP}, but is for the @code{long double} +data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int FLT_MAX_10_EXP +This is the maximum negative integer such that the mathematical value +@code{10} raised to this power minus 1 can be represented as a +normalized floating-point number of type @code{float}. This is +guaranteed to be at least @code{37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int DBL_MAX_10_EXP +This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{double} +data type. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro int LDBL_MAX_10_EXP +This is similar to @code{FLT_MAX_10_EXP}, but is for the @code{long +double} data type. +@end deftypevr + + +@comment float.h +@comment ANSI +@deftypevr Macro double FLT_MAX +The value of this macro is the maximum representable floating-point +number of type @code{float}, and is guaranteed to be at least +@code{1E+37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro double DBL_MAX +The value of this macro is the maximum representable floating-point +number of type @code{double}, and is guaranteed to be at least +@code{1E+37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro {long double} LDBL_MAX +The value of this macro is the maximum representable floating-point +number of type @code{long double}, and is guaranteed to be at least +@code{1E+37}. +@end deftypevr + + +@comment float.h +@comment ANSI +@deftypevr Macro double FLT_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{float}, and is +guaranteed to be no more than @code{1E-37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro double DBL_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{double}, and +is guaranteed to be no more than @code{1E-37}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro {long double} LDBL_MIN +The value of this macro is the minimum normalized positive +floating-point number that is representable by type @code{long double}, +and is guaranteed to be no more than @code{1E-37}. +@end deftypevr + + +@comment float.h +@comment ANSI +@deftypevr Macro double FLT_EPSILON +This is the minimum positive floating-point number of type @code{float} +such that @code{1.0 + FLT_EPSILON != 1.0} is true. It's guaranteed to +be no greater than @code{1E-5}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro double DBL_EPSILON +This is similar to @code{FLT_EPSILON}, but is for the @code{double} +type. The maximum value is @code{1E-9}. +@end deftypevr + +@comment float.h +@comment ANSI +@deftypevr Macro {long double} LDBL_EPSILON +This is similar to @code{FLT_EPSILON}, but is for the @code{long double} +type. The maximum value is @code{1E-9}. +@end deftypevr + + +@node IEEE Floating Point, , Floating-Point Parameters, Floating-Point Limits +@subsection IEEE Floating Point +@cindex IEEE floating-point representation +@cindex floating-point, IEEE +@cindex IEEE Std 754 + + +Here is an example showing how these parameters work for a common +floating point representation, specified by the @cite{IEEE Standard for +Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)}. Nearly +all computers today use this format. + +The IEEE single-precision float representation uses a base of 2. There +is a sign bit, a mantissa with 23 bits plus one hidden bit (so the total +precision is 24 base-2 digits), and an 8-bit exponent that can represent +values in the range -125 to 128, inclusive. + +So, for an implementation that uses this representation for the +@code{float} data type, appropriate values for the corresponding +parameters are: + +@example +FLT_RADIX 2 +FLT_MANT_DIG 24 +FLT_DIG 6 +FLT_MIN_EXP -125 +FLT_MIN_10_EXP -37 +FLT_MAX_EXP 128 +FLT_MAX_10_EXP +38 +FLT_MIN 1.17549435E-38F +FLT_MAX 3.40282347E+38F +FLT_EPSILON 1.19209290E-07F +@end example + +Here are the values for the @code{double} data type: + +@example +DBL_MANT_DIG 53 +DBL_DIG 15 +DBL_MIN_EXP -1021 +DBL_MIN_10_EXP -307 +DBL_MAX_EXP 1024 +DBL_MAX_10_EXP 308 +DBL_MAX 1.7976931348623157E+308 +DBL_MIN 2.2250738585072014E-308 +DBL_EPSILON 2.2204460492503131E-016 +@end example diff --git a/manual/=process.texinfo b/manual/=process.texinfo new file mode 100644 index 0000000000..63c723ed37 --- /dev/null +++ b/manual/=process.texinfo @@ -0,0 +1,1452 @@ +@node Processes, Job Control, Signal Handling, Top +@chapter Processes + +@cindex process +@dfn{Processes} are the primitive units for allocation of system +resources. Each process has its own address space and (usually) one +thread of control. A process executes a program; you can have multiple +processes executing the same program, but each process has its own copy +of the program within its own address space and executes it +independently of the other copies. + +Processes are organized hierarchically. Child processes are created by +a parent process, and inherit many of their attributes from the parent +process. + +This chapter describes how a program can create, terminate, and control +child processes. + +@menu +* Program Arguments:: Parsing the command-line arguments to + a program. +* Environment Variables:: How to access parameters inherited from + a parent process. +* Program Termination:: How to cause a process to terminate and + return status information to its parent. +* Creating New Processes:: Running other programs. +@end menu + + +@node Program Arguments, Environment Variables, , Processes +@section Program Arguments +@cindex program arguments +@cindex command line arguments + +@cindex @code{main} function +When your C program starts, it begins by executing the function called +@code{main}. You can define @code{main} either to take no arguments, +or to take two arguments that represent the command line arguments +to the program, like this: + +@example +int main (int @var{argc}, char *@var{argv}[]) +@end example + +@cindex argc (program argument count) +@cindex argv (program argument vector) +The command line arguments are the whitespace-separated tokens typed by +the user to the shell in invoking the program. The value of the +@var{argc} argument is the number of command line arguments. The +@var{argv} argument is a vector of pointers to @code{char}; sometimes it +is also declared as @samp{char **@var{argv}}. The elements of +@var{argv} are the individual command line argument strings. By +convention, @code{@var{argv}[0]} is the file name of the program being +run, and @code{@var{argv}[@var{argc}]} is a null pointer. + +If the syntax for the command line arguments to your program is simple +enough, you can simply pick the arguments off from @var{argv} by hand. +But unless your program takes a fixed number of arguments, or all of the +arguments are interpreted in the same way (as file names, for example), +you are usually better off using @code{getopt} to do the parsing. + +@menu +* Argument Syntax Conventions:: By convention, program + options are specified by a + leading hyphen. +* Parsing Program Arguments:: The @code{getopt} function. +* Example Using getopt:: An example of @code{getopt}. +@end menu + +@node Argument Syntax Conventions, Parsing Program Arguments, , Program Arguments +@subsection Program Argument Syntax Conventions +@cindex program argument syntax +@cindex syntax, for program arguments +@cindex command argument syntax + +The @code{getopt} function decodes options following the usual +conventions for POSIX utilities: + +@itemize @bullet +@item +Arguments are options if they begin with a hyphen delimiter (@samp{-}). + +@item +Multiple options may follow a hyphen delimiter in a single token if +the options do not take arguments. Thus, @samp{-abc} is equivalent to +@samp{-a -b -c}. + +@item +Option names are single alphanumeric (as for @code{isalnum}; +see @ref{Classification of Characters}). + +@item +Certain options require an argument. For example, the @samp{-o} +command of the ld command requires an argument---an output file name. + +@item +An option and its argument may or may appear as separate tokens. (In +other words, the whitespace separating them is optional.) Thus, +@samp{-o foo} and @samp{-ofoo} are equivalent. + +@item +Options typically precede other non-option arguments. + +The implementation of @code{getopt} in the GNU C library normally makes +it appear as if all the option arguments were specified before all the +non-option arguments for the purposes of parsing, even if the user of +your program intermixed option and non-option arguments. It does this +by reordering the elements of the @var{argv} array. This behavior is +nonstandard; if you want to suppress it, define the +@code{_POSIX_OPTION_ORDER} environment variable. @xref{Standard +Environment Variables}. + +@item +The argument @samp{--} terminates all options; any following arguments +are treated as non-option arguments, even if they begin with a hyphen. + +@item +A token consisting of a single hyphen character is interpreted as an +ordinary non-option argument. By convention, it is used to specify +input from or output to the standard input and output streams. + +@item +Options may be supplied in any order, or appear multiple times. The +interpretation is left up to the particular application program. +@end itemize + +@node Parsing Program Arguments, Example Using getopt, Argument Syntax Conventions, Program Arguments +@subsection Parsing Program Arguments +@cindex program arguments, parsing +@cindex command arguments, parsing +@cindex parsing program arguments + +Here are the details about how to call the @code{getopt} function. To +use this facility, your program must include the header file +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.2 +@deftypevar int opterr +If the value of this variable is nonzero, then @code{getopt} prints an +error message to the standard error stream if it encounters an unknown +option character or an option with a missing required argument. This is +the default behavior. If you set this variable to zero, @code{getopt} +does not print any messages, but it still returns @code{?} to indicate +an error. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar int optopt +When @code{getopt} encounters an unknown option character or an option +with a missing required argument, it stores that option character in +this variable. You can use this for providing your own diagnostic +messages. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar int optind +This variable is set by @code{getopt} to the index of the next element +of the @var{argv} array to be processed. Once @code{getopt} has found +all of the option arguments, you can use this variable to determine +where the remaining non-option arguments begin. The initial value of +this variable is @code{1}. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar {char *} optarg +This variable is set by @code{getopt} to point at the value of the +option argument, for those options that accept arguments. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypefun int getopt (int @var{argc}, char **@var{argv}, const char *@var{options}) +The @code{getopt} function gets the next option argument from the +argument list specified by the @var{argv} and @var{argc} arguments. +Normally these arguments' values come directly from the arguments of +@code{main}. + +The @var{options} argument is a string that specifies the option +characters that are valid for this program. An option character in this +string can be followed by a colon (@samp{:}) to indicate that it takes a +required argument. + +If the @var{options} argument string begins with a hyphen (@samp{-}), this +is treated specially. It permits arguments without an option to be +returned as if they were associated with option character @samp{\0}. + +The @code{getopt} function returns the option character for the next +command line option. When no more option arguments are available, it +returns @code{-1}. There may still be more non-option arguments; you +must compare the external variable @code{optind} against the @var{argv} +parameter to check this. + +If the options has an argument, @code{getopt} returns the argument by +storing it in the varables @var{optarg}. You don't ordinarily need to +copy the @code{optarg} string, since it is a pointer into the original +@var{argv} array, not into a static area that might be overwritten. + +If @code{getopt} finds an option character in @var{argv} that was not +included in @var{options}, or a missing option argument, it returns +@samp{?} and sets the external variable @code{optopt} to the actual +option character. In addition, if the external variable @code{opterr} +is nonzero, @code{getopt} prints an error message. +@end deftypefun + +@node Example Using getopt, , Parsing Program Arguments, Program Arguments +@subsection Example of Parsing Program Arguments + +Here is an example showing how @code{getopt} is typically used. The +key points to notice are: + +@itemize @bullet +@item +Normally, @code{getopt} is called in a loop. When @code{getopt} returns +@code{-1}, indicating no more options are present, the loop terminates. + +@item +A @code{switch} statement is used to dispatch on the return value from +@code{getopt}. In typical use, each case just sets a variable that +is used later in the program. + +@item +A second loop is used to process the remaining non-option arguments. +@end itemize + +@example +@include testopt.c.texi +@end example + +Here are some examples showing what this program prints with different +combinations of arguments: + +@example +% testopt +aflag = 0, bflag = 0, cvalue = (null) + +% testopt -a -b +aflag = 1, bflag = 1, cvalue = (null) + +% testopt -ab +aflag = 1, bflag = 1, cvalue = (null) + +% testopt -c foo +aflag = 0, bflag = 0, cvalue = foo + +% testopt -cfoo +aflag = 0, bflag = 0, cvalue = foo + +% testopt arg1 +aflag = 0, bflag = 0, cvalue = (null) +Non-option argument arg1 + +% testopt -a arg1 +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument arg1 + +% testopt -c foo arg1 +aflag = 0, bflag = 0, cvalue = foo +Non-option argument arg1 + +% testopt -a -- -b +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument -b + +% testopt -a - +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument - +@end example + +@node Environment Variables, Program Termination, Program Arguments, Processes +@section Environment Variables + +@cindex environment variable +When a program is executed, it receives information about the context in +which it was invoked in two ways. The first mechanism uses the +@var{argv} and @var{argc} arguments to its @code{main} function, and is +discussed in @ref{Program Arguments}. The second mechanism is +uses @dfn{environment variables} and is discussed in this section. + +The @var{argv} mechanism is typically used to pass command-line +arguments specific to the particular program being invoked. The +environment, on the other hand, keeps track of information that is +shared by many programs, changes infrequently, and that is less +frequently accessed. + +The environment variables discussed in this section are the same +environment variables that you set using the assignments and the +@code{export} command in the shell. Programs executed from the shell +inherit all of the environment variables from the shell. + +@cindex environment +Standard environment variables are used for information about the user's +home directory, terminal type, current locale, and so on; you can define +additional variables for other purposes. The set of all environment +variables that have values is collectively known as the +@dfn{environment}. + +Names of environment variables are case-sensitive and must not contain +the character @samp{=}. System-defined environment variables are +invariably uppercase. + +The values of environment variables can be anything that can be +represented as a string. A value must not contain an embedded null +character, since this is assumed to terminate the string. + + +@menu +* Environment Access:: How to get and set the values of + environment variables. +* Standard Environment Variables:: These environment variables have + standard interpretations. +@end menu + +@node Environment Access, Standard Environment Variables, , Environment Variables +@subsection Environment Access +@cindex environment access +@cindex environment representation + +The value of an environment variable can be accessed with the +@code{getenv} function. This is declared in the header file +@file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun {char *} getenv (const char *@var{name}) +This function returns a string that is the value of the environment +variable @var{name}. You must not modify this string. In some systems +not using the GNU library, it might be overwritten by subsequent calls +to @code{getenv} (but not by any other library function). If the +environment variable @var{name} is not defined, the value is a null +pointer. +@end deftypefun + + +@comment stdlib.h +@comment SVID +@deftypefun int putenv (const char *@var{string}) +The @code{putenv} function adds or removes definitions from the environment. +If the @var{string} is of the form @samp{@var{name}=@var{value}}, the +definition is added to the environment. Otherwise, the @var{string} is +interpreted as the name of an environment variable, and any definition +for this variable in the environment is removed. + +The GNU library provides this function for compatibility with SVID; it +may not be available in other systems. +@end deftypefun + +You can deal directly with the underlying representation of environment +objects to add more variables to the environment (for example, to +communicate with another program you are about to execute; see +@ref{Executing a File}). + +@comment unistd.h +@comment POSIX.1 +@deftypevar {char **} environ +The environment is represented as an array of strings. Each string is +of the format @samp{@var{name}=@var{value}}. The order in which +strings appear in the environment is not significant, but the same +@var{name} must not appear more than once. The last element of the +array is a null pointer. + +This variable is not declared in any header file, but if you declare it +in your own program as @code{extern}, the right thing will happen. + +If you just want to get the value of an environment variable, use +@code{getenv}. +@end deftypevar + +@node Standard Environment Variables, , Environment Access, Environment Variables +@subsection Standard Environment Variables +@cindex standard environment variables + +These environment variables have standard meanings. +This doesn't mean that they are always present in the +environment, though; it just means that if these variables @emph{are} +present, they have these meanings, and that you shouldn't try to use +these environment variable names for some other purpose. + +@table @code +@item HOME +@cindex HOME environment variable +@cindex home directory +This is a string representing the user's @dfn{home directory}, or +initial default working directory. @xref{User Database}, for a +more secure way of determining this information. + +@comment RMS says to explay why HOME is better, but I don't know why. + +@item LOGNAME +@cindex LOGNAME environment variable +This is the name that the user used to log in. Since the value in the +environment can be tweaked arbitrarily, this is not a reliable way to +identify the user who is running a process; a function like +@code{getlogin} (@pxref{User Identification Functions}) is better for +that purpose. + +@comment RMS says to explay why LOGNAME is better, but I don't know why. + +@item PATH +@cindex PATH environment variable +A @dfn{path} is a sequence of directory names which is used for +searching for a file. The variable @var{PATH} holds a path The +@code{execlp} and @code{execvp} functions (@pxref{Executing a File}) +uses this environment variable, as do many shells and other utilities +which are implemented in terms of those functions. + +The syntax of a path is a sequence of directory names separated by +colons. An empty string instead of a directory name stands for the +current directory. (@xref{Working Directory}.) + +A typical value for this environment variable might be a string like: + +@example +.:/bin:/etc:/usr/bin:/usr/new/X11:/usr/new:/usr/local:/usr/local/bin +@end example + +This means that if the user tries to execute a program named @code{foo}, +the system will look for files named @file{./foo}, @file{/bin/foo}, +@file{/etc/foo}, and so on. The first of these files that exists is +the one that is executed. + +@item TERM +@cindex TERM environment variable +This specifies the kind of terminal that is receiving program output. +Some programs can make use of this information to take advantage of +special escape sequences or terminal modes supported by particular kinds +of terminals. Many programs which use the termcap library +(@pxref{Finding a Terminal Description,Find,,termcap,The Termcap Library +Manual}) use the @code{TERM} environment variable, for example. + +@item TZ +@cindex TZ environment variable +This specifies the time zone. @xref{Time Zone}, for information about +the format of this string and how it is used. + +@item LANG +@cindex LANG environment variable +This specifies the default locale to use for attribute categories where +neither @code{LC_ALL} nor the specific environment variable for that +category is set. @xref{Locales}, for more information about +locales. + +@item LC_ALL +@cindex LC_ALL environment variable +This is similar to the @code{LANG} environment variable. However, its +value takes precedence over any values provided for the individual +attribute category environment variables, or for the @code{LANG} +environment variable. + +@item LC_COLLATE +@cindex LC_COLLATE environment variable +This specifies what locale to use for string sorting. + +@item LC_CTYPE +@cindex LC_CTYPE environment variable +This specifies what locale to use for character sets and character +classification. + +@item LC_MONETARY +@cindex LC_MONETARY environment variable +This specifies what locale to use for formatting monetary values. + +@item LC_NUMERIC +@cindex LC_NUMERIC environment variable +This specifies what locale to use for formatting numbers. + +@item LC_TIME +@cindex LC_TIME environment variable +This specifies what locale to use for formatting date/time values. + +@item _POSIX_OPTION_ORDER +@cindex _POSIX_OPTION_ORDER environment variable. +If this environment variable is defined, it suppresses the usual +reordering of command line arguments by @code{getopt}. @xref{Program +Argument Syntax Conventions}. +@end table + +@node Program Termination, Creating New Processes, Environment Variables, Processes +@section Program Termination +@cindex program termination +@cindex process termination + +@cindex exit status value +The usual way for a program to terminate is simply for its @code{main} +function to return. The @dfn{exit status value} returned from the +@code{main} function is used to report information back to the process's +parent process or shell. + +A program can also terminate normally calling the @code{exit} +function + +In addition, programs can be terminated by signals; this is discussed in +more detail in @ref{Signal Handling}. The @code{abort} function causes +a terminal that kills the program. + +@menu +* Normal Program Termination:: +* Exit Status:: Exit Status +* Cleanups on Exit:: Cleanups on Exit +* Aborting a Program:: +* Termination Internals:: Termination Internals +@end menu + +@node Normal Program Termination, Exit Status, , Program Termination +@subsection Normal Program Termination + +@comment stdlib.h +@comment ANSI +@deftypefun void exit (int @var{status}) +The @code{exit} function causes normal program termination with status +@var{status}. This function does not return. +@end deftypefun + +When a program terminates normally by returning from its @code{main} +function or by calling @code{exit}, the following actions occur in +sequence: + +@enumerate +@item +Functions that were registered with the @code{atexit} or @code{on_exit} +functions are called in the reverse order of their registration. This +mechanism allows your application to specify its own ``cleanup'' actions +to be performed at program termination. Typically, this is used to do +things like saving program state information in a file, or unlock locks +in shared data bases. + +@item +All open streams are closed; writing out any buffered output data. See +@ref{Opening and Closing Streams}. In addition, temporary files opened +with the @code{tmpfile} function are removed; see @ref{Temporary Files}. + +@item +@code{_exit} is called. @xref{Termination Internals} +@end enumerate + +@node Exit Status, Cleanups on Exit, Normal Program Termination, Program Termination +@subsection Exit Status +@cindex exit status + +When a program exits, it can return to the parent process a small +amount of information about the cause of termination, using the +@dfn{exit status}. This is a value between 0 and 255 that the exiting +process passes as an argument to @code{exit}. + +Normally you should use the exit status to report very broad information +about success or failure. You can't provide a lot of detail about the +reasons for the failure, and most parent processes would not want much +detail anyway. + +There are conventions for what sorts of status values certain programs +should return. The most common convention is simply 0 for success and 1 +for failure. Programs that perform comparison use a different +convention: they use status 1 to indicate a mismatch, and status 2 to +indicate an inability to compare. Your program should follow an +existing convention if an existing convention makes sense for it. + +A general convention reserves status values 128 and up for special +purposes. In particular, the value 128 is used to indicate failure to +execute another program in a subprocess. This convention is not +universally obeyed, but it is a good idea to follow it in your programs. + +@strong{Warning:} Don't try to use the number of errors as the exit +status. This is actually not very useful; a parent process would +generally not care how many errors occurred. Worse than that, it does +not work, because the status value is truncated to eight bits. +Thus, if the program tried to report 256 errors, the parent would +receive a report of 0 errors---that is, success. + +For the same reason, it does not work to use the value of @code{errno} +as the exit status---these can exceed 255. + +@strong{Portability note:} Some non-POSIX systems use different +conventions for exit status values. For greater portability, you can +use the macros @code{EXIT_SUCCESS} and @code{EXIT_FAILURE} for the +conventional status value for success and failure, respectively. They +are declared in the file @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int EXIT_SUCCESS +This macro can be used with the @code{exit} function to indicate +successful program completion. + +On POSIX systems, the value of this macro is @code{0}. On other +systems, the value might be some other (possibly non-constant) integer +expression. +@end deftypevr + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int EXIT_FAILURE +This macro can be used with the @code{exit} function to indicate +unsuccessful program completion in a general sense. + +On POSIX systems, the value of this macro is @code{1}. On other +systems, the value might be some other (possibly non-constant) integer +expression. Other nonzero status values also indicate future. Certain +programs use different nonzero status values to indicate particular +kinds of "non-success". For example, @code{diff} uses status value +@code{1} to mean that the files are different, and @code{2} or more to +mean that there was difficulty in opening the files. +@end deftypevr + +@node Cleanups on Exit, Aborting a Program, Exit Status, Program Termination +@subsection Cleanups on Exit + +@comment stdlib.h +@comment ANSI +@deftypefun int atexit (void (*@var{function})) +The @code{atexit} function registers the function @var{function} to be +called at normal program termination. The @var{function} is called with +no arguments. + +The return value from @code{atexit} is zero on success and nonzero if +the function cannot be registered. +@end deftypefun + +@comment stdlib.h +@comment GNU +@deftypefun int on_exit (void (*@var{function})(int @var{status}, void *@var{arg}), void *@var{arg}) +This function is a somewhat more powerful variant of @code{atexit}. It +accepts two arguments, a function @var{function} and an arbitrary +pointer @var{arg}. At normal program termination, the @var{function} is +called with two arguments: the @var{status} value passed to @code{exit}, +and the @var{arg}. + +This function is a GNU extension, and may not be supported by other +implementations. +@end deftypefun + +Here's a trivial program that illustrates the use of @code{exit} and +@code{atexit}: + +@example +#include <stdio.h> +#include <stdlib.h> + +void bye (void) +@{ + printf ("Goodbye, cruel world....\n"); +@} + +void main (void) +@{ + atexit (bye); + exit (EXIT_SUCCESS); +@} +@end example + +@noindent +When this program is executed, it just prints the message and exits. + + +@node Aborting a Program, Termination Internals, Cleanups on Exit, Program Termination +@subsection Aborting a Program +@cindex aborting a program + +You can abort your program using the @code{abort} function. The prototype +for this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun void abort () +The @code{abort} function causes abnormal program termination, without +executing functions registered with @code{atexit} or @code{on_exit}. + +This function actually terminates the process by raising a +@code{SIGABRT} signal, and your program can include a handler to +intercept this signal; see @ref{Signal Handling}. + +@strong{Incomplete:} Why would you want to define such a handler? +@end deftypefun + +@node Termination Internals, , Aborting a Program, Program Termination +@subsection Termination Internals + +The @code{_exit} function is the primitive used for process termination +by @code{exit}. It is declared in the header file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun void _exit (int @var{status}) +The @code{_exit} function is the primitive for causing a process to +terminate with status @var{status}. Calling this function does not +execute cleanup functions registered with @code{atexit} or +@code{on_exit}. +@end deftypefun + +When a process terminates for any reason---either by an explicit +termination call, or termination as a result of a signal---the +following things happen: + +@itemize @bullet +@item +All open file descriptors in the process are closed. @xref{Low-Level +Input/Output}. + +@item +The low-order 8 bits of the return status code are saved to be reported +back to the parent process via @code{wait} or @code{waitpid}; see +@ref{Process Completion}. + +@item +Any child processes of the process being terminated are assigned a new +parent process. (This is the @code{init} process, with process ID 1.) + +@item +A @code{SIGCHLD} signal is sent to the parent process. + +@item +If the process is a session leader that has a controlling terminal, then +a @code{SIGHUP} signal is sent to each process in the foreground job, +and the controlling terminal is disassociated from that session. +@xref{Job Control}. + +@item +If termination of a process causes a process group to become orphaned, +and any member of that process group is stopped, then a @code{SIGHUP} +signal and a @code{SIGCONT} signal are sent to each process in the +group. @xref{Job Control}. +@end itemize + +@node Creating New Processes, , Program Termination, Processes +@section Creating New Processes + +This section describes how your program can cause other programs to be +executed. Actually, there are three distinct operations involved: +creating a new child process, causing the new process to execute a +program, and coordinating the completion of the child process with the +original program. + +The @code{system} function provides a simple, portable mechanism for +running another program; it does all three steps automatically. If you +need more control over the details of how this is done, you can use the +primitive functions to do each step individually instead. + +@menu +* Running a Command:: The easy way to run another program. +* Process Creation Concepts:: An overview of the hard way to do it. +* Process Identification:: How to get the process ID of a process. +* Creating a Process:: How to fork a child process. +* Executing a File:: How to get a process to execute another + program. +* Process Completion:: How to tell when a child process has + completed. +* Process Completion Status:: How to interpret the status value + returned from a child process. +* BSD wait Functions:: More functions, for backward + compatibility. +* Process Creation Example:: A complete example program. +@end menu + + +@node Running a Command, Process Creation Concepts, , Creating New Processes +@subsection Running a Command +@cindex running a command + +The easy way to run another program is to use the @code{system} +function. This function does all the work of running a subprogram, but +it doesn't give you much control over the details: you have to wait +until the subprogram terminates before you can do anything else. + +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun int system (const char *@var{command}) +This function executes @var{command} as a shell command. In the GNU C +library, it always uses the default shell @code{sh} to run the command. +In particular, it searching the directories in @code{PATH} to find +programs to execute. The return value is @code{-1} if it wasn't +possible to create the shell process, and otherwise is the status of the +shell process. @xref{Process Completion}, for details on how this +status code can be interpreted. +@pindex sh +@end deftypefun + +The @code{system} function is declared in the header file +@file{stdlib.h}. + +@strong{Portability Note:} Some C implementations may not have any +notion of a command processor that can execute other programs. You can +determine whether a command processor exists by executing @code{system +(o)}; in this case the return value is nonzero if and only if such a +processor is available. + +The @code{popen} and @code{pclose} functions (@pxref{Pipe to a +Subprocess}) are closely related to the @code{system} function. They +allow the parent process to communicate with the standard input and +output channels of the command being executed. + +@node Process Creation Concepts, Process Identification, Running a Command, Creating New Processes +@subsection Process Creation Concepts + +This section gives an overview of processes and of the steps involved in +creating a process and making it run another program. + +@cindex process ID +@cindex process lifetime +Each process is named by a @dfn{process ID} number. A unique process ID +is allocated to each process when it is created. The @dfn{lifetime} of +a process ends when its termination is reported to its parent process; +at that time, all of the process resources, including its process ID, +are freed. + +@cindex creating a process +@cindex forking a process +@cindex child process +@cindex parent process +Processes are created with the @code{fork} system call (so the operation +of creating a new process is sometimes called @dfn{forking} a process). +The @dfn{child process} created by @code{fork} is an exact clone of the +original @dfn{parent process}, except that it has its own process ID. + +After forking a child process, both the parent and child processes +continue to execute normally. If you want your program to wait for a +child process to finish executing before continuing, you must do this +explicitly after the fork operation. This is done with the @code{wait} +or @code{waitpid} functions (@pxref{Process Completion}). These +functions give the parent information about why the child +terminated---for example, its exit status code. + +A newly forked child process continues to execute the same program as +its parent process, at the point where the @code{fork} call returns. +You can use the return value from @code{fork} to tell whether the program +is running in the parent process or the child. + +@cindex process image +Having all processes run the same program is usually not very useful. +But the child can execute another program using one of the @code{exec} +functions; see @ref{Executing a File}. The program that the process is +executing is called its @dfn{process image}. Starting execution of a +new program causes the process to forget all about its current process +image; when the new program exits, the process exits too, instead of +returning to the previous process image. + + +@node Process Identification, Creating a Process, Process Creation Concepts, Creating New Processes +@subsection Process Identification + +The @code{pid_t} data type represents process IDs. You can get the +process ID of a process by calling @code{getpid}. The function +@code{getppid} returns the process ID of the parent of the parent of the +current process (this is also known as the @dfn{parent process ID}). +Your program should include the header files @file{unistd.h} and +@file{sys/types.h} to use these functions. +@pindex sys/types.h +@pindex unistd.h + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} pid_t +The @code{pid_t} data type is a signed integer type which is capable +of representing a process ID. In the GNU library, this is an @code{int}. +@end deftp + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t getpid () +The @code{getpid} function returns the process ID of the current process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t getppid () +The @code{getppid} function returns the process ID of the parent of the +current process. +@end deftypefun + +@node Creating a Process, Executing a File, Process Identification, Creating New Processes +@subsection Creating a Process + +The @code{fork} function is the primitive for creating a process. +It is declared in the header file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t fork () +The @code{fork} function creates a new process. + +If the operation is successful, there are then both parent and child +processes and both see @code{fork} return, but with different values: it +returns a value of @code{0} in the child process and returns the child's +process ID in the parent process. If the child process could not be +created, a value of @code{-1} is returned in the parent process. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EAGAIN +There aren't enough system resources to create another process, or the +user already has too many processes running. + +@item ENOMEM +The process requires more space than the system can supply. +@end table +@end deftypefun + +The specific attributes of the child process that differ from the +parent process are: + +@itemize @bullet +@item +The child process has its own unique process ID. + +@item +The parent process ID of the child process is the process ID of its +parent process. + +@item +The child process gets its own copies of the parent process's open file +descriptors. Subsequently changing attributes of the file descriptors +in the parent process won't affect the file descriptors in the child, +and vice versa. @xref{Control Operations}. + +@item +The elapsed processor times for the child process are set to zero; +see @ref{Processor Time}. + +@item +The child doesn't inherit file locks set by the parent process. +@xref{Control Operations}. + +@item +The child doesn't inherit alarms set by the parent process. +@xref{Setting an Alarm}. + +@item +The set of pending signals (@pxref{Delivery of Signal}) for the child +process is cleared. (The child process inherits its mask of blocked +signals and signal actions from the parent process.) +@end itemize + + +@comment unistd.h +@comment BSD +@deftypefun pid_t vfork (void) +The @code{vfork} function is similar to @code{fork} but more efficient; +however, there are restrictions you must follow to use it safely. + +While @code{fork} makes a complete copy of the calling process's address +space and allows both the parent and child to execute independently, +@code{vfork} does not make this copy. Instead, the child process +created with @code{vfork} shares its parent's address space until it calls +one of the @code{exec} functions. In the meantime, the parent process +suspends execution. + +You must be very careful not to allow the child process created with +@code{vfork} to modify any global data or even local variables shared +with the parent. Furthermore, the child process cannot return from (or +do a long jump out of) the function that called @code{vfork}! This +would leave the parent process's control information very confused. If +in doubt, use @code{fork} instead. + +Some operating systems don't really implement @code{vfork}. The GNU C +library permits you to use @code{vfork} on all systems, but actually +executes @code{fork} if @code{vfork} isn't available. +@end deftypefun + +@node Executing a File, Process Completion, Creating a Process, Creating New Processes +@subsection Executing a File +@cindex executing a file +@cindex @code{exec} functions + +This section describes the @code{exec} family of functions, for executing +a file as a process image. You can use these functions to make a child +process execute a new program after it has been forked. + +The functions in this family differ in how you specify the arguments, +but otherwise they all do the same thing. They are declared in the +header file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]}) +The @code{execv} function executes the file named by @var{filename} as a +new process image. + +The @var{argv} argument is an array of null-terminated strings that is +used to provide a value for the @code{argv} argument to the @code{main} +function of the program to be executed. The last element of this array +must be a null pointer. @xref{Program Arguments}, for information on +how programs can access these arguments. + +The environment for the new process image is taken from the +@code{environ} variable of the current process image; see @ref{Environment +Variables}, for information about environments. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{}) +This is similar to @code{execv}, but the @var{argv} strings are +specified individually instead of as an array. A null pointer must be +passed as the last such argument. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]}) +This is similar to @code{execv}, but permits you to specify the environment +for the new program explicitly as the @var{env} argument. This should +be an array of strings in the same format as for the @code{environ} +variable; see @ref{Environment Access}. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, char *const @var{env}@t{[]}, @dots{}) +This is similar to @code{execl}, but permits you to specify the +environment for the new program explicitly. The environment argument is +passed following the null pointer that marks the last @var{argv} +argument, and should be an array of strings in the same format as for +the @code{environ} variable. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]}) +The @code{execvp} function is similar to @code{execv}, except that it +searches the directories listed in the @code{PATH} environment variable +(@pxref{Standard Environment Variables}) to find the full file name of a +file from @var{filename} if @var{filename} does not contain a slash. + +This function is useful for executing installed system utility programs, +so that the user can control where to look for them. It is also useful +in shells, for executing commands typed by the user. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{}) +This function is like @code{execl}, except that it performs the same +file name searching as the @code{execvp} function. +@end deftypefun + + +The size of the argument list and environment list taken together must not +be greater than @code{ARG_MAX} bytes. @xref{System Parameters}. + +@strong{Incomplete:} The POSIX.1 standard requires some statement here +about how null terminators, null pointers, and alignment requirements +affect the total size of the argument and environment lists. + +These functions normally don't return, since execution of a new program +causes the currently executing program to go away completely. A value +of @code{-1} is returned in the event of a failure. In addition to the +usual file name syntax errors (@pxref{File Name Errors}), the following +@code{errno} error conditions are defined for these functions: + +@table @code +@item E2BIG +The combined size of the new program's argument list and environment list +is larger than @code{ARG_MAX} bytes. + +@item ENOEXEC +The specified file can't be executed because it isn't in the right format. + +@item ENOMEM +Executing the specified file requires more storage than is available. +@end table + +If execution of the new file is successful, the access time field of the +file is updated as if the file had been opened. @xref{File Times}, for +more details about access times of files. + +The point at which the file is closed again is not specified, but +is at some point before the process exits or before another process +image is executed. + +Executing a new process image completely changes the contents of memory, +except for the arguments and the environment, but many other attributes +of the process are unchanged: + +@itemize @bullet +@item +The process ID and the parent process ID. @xref{Process Creation Concepts}. + +@item +Session and process group membership. @xref{Job Control Concepts}. + +@item +Real user ID and group ID, and supplementary group IDs. @xref{User/Group +IDs of a Process}. + +@item +Pending alarms. @xref{Setting an Alarm}. + +@item +Current working directory and root directory. @xref{Working Directory}. + +@item +File mode creation mask. @xref{Setting Permissions}. + +@item +Process signal mask; see @ref{Process Signal Mask}. + +@item +Pending signals; see @ref{Blocking Signals}. + +@item +Elapsed processor time associated with the process; see @ref{Processor Time}. +@end itemize + +If the set-user-ID and set-group-ID mode bits of the process image file +are set, this affects the effective user ID and effective group ID +(respectively) of the process. These concepts are discussed in detail +in @ref{User/Group IDs of a Process}. + +Signals that are set to be ignored in the existing process image are +also set to be ignored in the new process image. All other signals are +set to the default action in the new process image. For more +information about signals, see @ref{Signal Handling}. + +File descriptors open in the existing process image remain open in the +new process image, unless they have the @code{FD_CLOEXEC} +(close-on-exec) flag set. The files that remain open inherit all +attributes of the open file description from the existing process image, +including file locks. File descriptors are discussed in @ref{Low-Level +Input/Output}. + +Streams, by contrast, cannot survive through @code{exec} functions, +because they are located in the memory of the process itself. The new +process image has no streams except those it creates afresh. Each of +the streams in the pre-@code{exec} process image has a descriptor inside +it, and these descriptors do survive through @code{exec} (provided that +they do not have @code{FD_CLOEXEC} set. The new process image can +reconnect these to new streams using @code{fdopen}. + +@node Process Completion, Process Completion Status, Executing a File, Creating New Processes +@subsection Process Completion +@cindex process completion +@cindex waiting for completion of child process +@cindex testing exit status of child process + +The functions described in this section are used to wait for a child +process to terminate or stop, and determine its status. These functions +are declared in the header file @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment POSIX.1 +@deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status_ptr}, int @var{options}) +The @code{waitpid} function is used to request status information from a +child process whose process ID is @var{pid}. Normally, the calling +process is suspended until the child process makes status information +available by terminating. + +Other values for the @var{pid} argument have special interpretations. A +value of @code{-1} or @code{WAIT_ANY} requests status information for +any child process; a value of @code{0} or @code{WAIT_MYPGRP} requests +information for any child process in the same process group as the +calling process; and any other negative value @minus{} @var{pgid} +requests information for any child process whose process group ID is +@var{pgid}. + +If status information for a child process is available immediately, this +function returns immediately without waiting. If more than one eligible +child process has status information available, one of them is chosen +randomly, and its status is returned immediately. To get the status +from the other programs, you need to call @code{waitpid} again. + +The @var{options} argument is a bit mask. Its value should be the +bitwise OR (that is, the @samp{|} operator) of zero or more of the +@code{WNOHANG} and @code{WUNTRACED} flags. You can use the +@code{WNOHANG} flag to indicate that the parent process shouldn't wait; +and the @code{WUNTRACED} flag to request status information from stopped +processes as well as processes that have terminated. + +The status information from the child process is stored in the object +that @var{status_ptr} points to, unless @var{status_ptr} is a null pointer. + +The return value is normally the process ID of the child process whose +status is reported. If the @code{WNOHANG} option was specified and no +child process is waiting to be noticed, a value of zero is returned. A +value of @code{-1} is returned in case of error. The following +@code{errno} error conditions are defined for this function: + +@table @code +@item EINTR +The function was interrupted by delivery of a signal to the calling +process. + +@item ECHILD +There are no child processes to wait for, or the specified @var{pid} +is not a child of the calling process. + +@item EINVAL +An invalid value was provided for the @var{options} argument. +@end table +@end deftypefun + +These symbolic constants are defined as values for the @var{pid} argument +to the @code{waitpid} function. + +@table @code +@item WAIT_ANY +This constant macro (whose value is @code{-1}) specifies that +@code{waitpid} should return status information about any child process. + +@item WAIT_MYPGRP +This constant (with value @code{0}) specifies that @code{waitpid} should +return status information about any child process in the same process +group as the calling process. + +These symbolic constants are defined as flags for the @var{options} +argument to the @code{waitpid} function. You can bitwise-OR the flags +together to obtain a value to use as the argument. + +@item WNOHANG +This flag specifies that @code{waitpid} should return immediately +instead of waiting if there is no child process ready to be noticed. + +@item WUNTRACED +This macro is used to specify that @code{waitpid} should also report the +status of any child processes that have been stopped as well as those +that have terminated. +@end table + +@deftypefun pid_t wait (int *@var{status_ptr}) +This is a simplified version of @code{waitpid}, and is used to wait +until any one child process terminates. + +@example +wait (&status) +@end example + +@noindent +is equivalent to: + +@example +waitpid (-1, &status, 0) +@end example + +Here's an example of how to use @code{waitpid} to get the status from +all child processes that have terminated, without ever waiting. This +function is designed to be used as a handler for @code{SIGCHLD}, the +signal that indicates that at least one child process has terminated. + +@example +void +sigchld_handler (int signum) +@{ + int pid; + int status; + while (1) @{ + pid = waitpid (WAIT_ANY, Estatus, WNOHANG); + if (pid < 0) @{ + perror ("waitpid"); + break; + @} + if (pid == 0) + break; + notice_termination (pid, status); + @} +@} +@end example +@end deftypefun + +@node Process Completion Status, BSD wait Functions, Process Completion, Creating New Processes +@subsection Process Completion Status + +If the exit status value (@pxref{Program Termination}) of the child +process is zero, then the status value reported by @code{waitpid} or +@code{wait} is also zero. You can test for other kinds of information +encoded in the returned status value using the following macros. +These macros are defined in the header file @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFEXITED (int @var{status}) +This macro returns a non-zero value if the child process terminated +normally with @code{exit} or @code{_exit}. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WEXITSTATUS (int @var{status}) +If @code{WIFEXITED} is true of @var{status}, this macro returns the +low-order 8 bits of the exit status value from the child process. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFSIGNALED (int @var{status}) +This macro returns a non-zero value if the child process terminated +by receiving a signal that was not handled. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WTERMSIG (int @var{status}) +If @code{WIFSIGNALED} is true of @var{status}, this macro returns the +number of the signal that terminated the child process. +@end deftypefn + +@comment sys/wait.h +@comment BSD +@deftypefn Macro int WCOREDUMP (int @var{status}) +This macro returns a non-zero value if the child process terminated +and produced a core dump. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFSTOPPED (int @var{status}) +This macro returns a non-zero value if the child process is stopped. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WSTOPSIG (int @var{status}) +If @code{WIFSTOPPED} is true of @var{status}, this macro returns the +number of the signal that caused the child process to stop. +@end deftypefn + + +@node BSD wait Functions, Process Creation Example, Process Completion Status, Creating New Processes +@subsection BSD Process Completion Functions + +The GNU library also provides these related facilities for compatibility +with BSD Unix. BSD uses the @code{union wait} data type to represent +status values rather than an @code{int}. The two representations are +actually interchangeable; they describe the same bit patterns. The macros +such as @code{WEXITSTATUS} are defined so that they will work on either +kind of object, and the @code{wait} function is defined to accept either +type of pointer as its @var{status_ptr} argument. + +These functions are declared in @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment BSD +@deftp {union Type} wait +This data type represents program termination status values. It has +the following members: + +@table @code +@item int w_termsig +This member is equivalent to the @code{WTERMSIG} macro. + +@item int w_coredump +This member is equivalent to the @code{WCOREDUMP} macro. + +@item int w_retcode +This member is equivalent to the @code{WEXISTATUS} macro. + +@item int w_stopsig +This member is equivalent to the @code{WSTOPSIG} macro. +@end table + +Instead of accessing these members directly, you should use the +equivalent macros. +@end deftp + +@comment sys/wait.h +@comment BSD +@deftypefun pid_t wait3 (union wait *@var{status_ptr}, int @var{options}, void * @var{usage}) +If @var{usage} is a null pointer, this function is equivalent to +@code{waitpid (-1, @var{status_ptr}, @var{options})}. + +The @var{usage} argument may also be a pointer to a +@code{struct rusage} object. Information about system resources used by +terminated processes (but not stopped processes) is returned in this +structure. + +@strong{Incomplete:} The description of the @code{struct rusage} structure +hasn't been written yet. Put in a cross-reference here. +@end deftypefun + +@comment sys/wait.h +@comment BSD +@deftypefun pid_t wait4 (pid_t @var{pid}, union wait *@var{status_ptr}, int @var{options}, void *@var{usage}) +If @var{usage} is a null pointer, this function is equivalent to +@code{waitpid (@var{pid}, @var{status_ptr}, @var{options})}. + +The @var{usage} argument may also be a pointer to a +@code{struct rusage} object. Information about system resources used by +terminated processes (but not stopped processes) is returned in this +structure. + +@strong{Incomplete:} The description of the @code{struct rusage} structure +hasn't been written yet. Put in a cross-reference here. +@end deftypefun + +@node Process Creation Example, , BSD wait Functions, Creating New Processes +@subsection Process Creation Example + +Here is an example program showing how you might write a function +similar to the built-in @code{system}. It executes its @var{command} +argument using the equivalent of @samp{sh -c @var{command}}. + +@example +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +/* @r{Execute the command using this shell program.} */ +#define SHELL "/bin/sh" + +int +my_system (char *command) +@{ + int status; + pid_t pid; + + pid = fork (); + if (pid == 0) @{ + /* @r{This is the child process. Execute the shell command.} */ + execl (SHELL, SHELL, "-c", command, NULL); + exit (EXIT_FAILURE); + @} + else if (pid < 0) + /* @r{The fork failed. Report failure.} */ + status = -1; + else @{ + /* @r{This is the parent process. Wait for the child to complete.} */ + if (waitpid (pid, &status, 0) != pid) + status = -1; + @} + return status; +@} +@end example + +@comment Yes, this example has been tested. + +There are a couple of things you should pay attention to in this +example. + +Remember that the first @code{argv} argument supplied to the program +represents the name of the program being executed. That is why, in the +call to @code{execl}, @code{SHELL} is supplied once to name the program +to execute and a second time to supply a value for @code{argv[0]}. + +The @code{execl} call in the child process doesn't return if it is +successful. If it fails, you must do something to make the child +process terminate. Just returning a bad status code with @code{return} +would leave two processes running the original program. Instead, the +right behavior is for the child process to report failure to its parent +process. To do this, @code{exit} is called with a failure status. diff --git a/manual/=stdarg.texi b/manual/=stdarg.texi new file mode 100644 index 0000000000..384c992f13 --- /dev/null +++ b/manual/=stdarg.texi @@ -0,0 +1,290 @@ +@node Variable Argument Facilities, Memory Allocation, Common Definitions, Top +@chapter Variable Argument Facilities +@cindex variadic argument functions +@cindex variadic functions +@cindex variable number of arguments +@cindex optional arguments + +ANSI C defines a syntax as part of the kernel language for specifying +functions that take a variable number or type of arguments. (Such +functions are also referred to as @dfn{variadic functions}.) However, +the kernel language provides no mechanism for actually accessing +non-required arguments; instead, you use the variable arguments macros +defined in @file{stdarg.h}. +@pindex stdarg.h + +@menu +* Why Variable Arguments are Used:: Using variable arguments can + save you time and effort. +* How Variable Arguments are Used:: An overview of the facilities for + receiving variable arguments. +* Variable Arguments Interface:: Detailed specification of the + library facilities. +* Example of Variable Arguments:: A complete example. +@end menu + +@node Why Variable Arguments are Used, How Variable Arguments are Used, , Variable Argument Facilities +@section Why Variable Arguments are Used + +Most C functions take a fixed number of arguments. When you define a +function, you also supply a specific data type for each argument. +Every call to the function should supply the same number and type of +arguments as specified in the function definition. + +On the other hand, sometimes a function performs an operation that can +meaningfully accept an unlimited number of arguments. + +For example, consider a function that joins its arguments into a linked +list. It makes sense to connect any number of arguments together into a +list of arbitrary length. Without facilities for variable arguments, +you would have to define a separate function for each possible number of +arguments you might want to link together. This is an example of a +situation where some kind of mapping or iteration is performed over an +arbitrary number of arguments of the same type. + +Another kind of application where variable arguments can be useful is +for functions where values for some arguments can simply be omitted in +some calls, either because they are not used at all or because the +function can determine appropriate defaults for them if they're missing. + +The library function @code{printf} (@pxref{Formatted Output}) is an +example of still another class of function where variable arguments are +useful. This function prints its arguments (which can vary in type as +well as number) under the control of a format template string. + +@node How Variable Arguments are Used, Variable Arguments Interface, Why Variable Arguments are Used, Variable Argument Facilities +@section How Variable Arguments are Used + +This section describes how you can define and call functions that take +variable arguments, and how to access the values of the non-required +arguments. + +@menu +* Syntax for Variable Arguments:: How to make a prototype for a + function with variable arguments. +* Receiving the Argument Values:: Steps you must follow to access the + optional argument values. +* How Many Arguments:: How to decide whether there are more + arguments. +* Calling Variadic Functions:: Things you need to know about calling + variable arguments functions. +@end menu + +@node Syntax for Variable Arguments, Receiving the Argument Values, , How Variable Arguments are Used +@subsection Syntax for Variable Arguments + +A function that accepts a variable number of arguments must have at +least one required argument with a specified type. In the function +definition or prototype declaration, you indicate the fact that a +function can accept additional arguments of unspecified type by putting +@samp{@dots{}} at the end of the arguments. For example, + +@example +int +func (const char *a, int b, @dots{}) +@{ + @dots{} +@} +@end example + +@noindent +outlines a definition of a function @code{func} which returns an +@code{int} and takes at least two arguments, the first two being a +@code{const char *} and an @code{int}.@refill + +An obscure restriction placed by the ANSI C standard is that the last +required argument must not be declared @code{register} in the function +definition. Furthermore, this argument must not be of a function or +array type, and may not be, for example, a @code{char} or @code{short +int} (whether signed or not) or a @code{float}. + +@strong{Compatibility Note:} Many older C dialects provide a similar, +but incompatible, mechanism for defining functions with variable numbers +of arguments. In particular, the @samp{@dots{}} syntax is a new feature +of ANSI C. + + +@node Receiving the Argument Values, How Many Arguments, Syntax for Variable Arguments, How Variable Arguments are Used +@subsection Receiving the Argument Values + +Inside the definition of a variadic function, to access the optional +arguments with the following three step process: + +@enumerate +@item +You initialize an argument pointer variable of type @code{va_list} using +@code{va_start}. + +@item +You access the optional arguments by successive calls to @code{va_arg}. + +@item +You call @code{va_end} to indicate that you are finished accessing the +arguments. +@end enumerate + +Steps 1 and 3 must be performed in the function that is defined to +accept variable arguments. However, you can pass the @code{va_list} +variable as an argument to another function and perform all or part of +step 2 there. After doing this, the value of the @code{va_list} +variable in the calling function becomes undefined for further calls to +@code{va_arg}; you should just pass it to @code{va_end}. + +You can perform the entire sequence of the three steps multiple times +within a single function invocation. And, if the function doesn't want +to look at its optional arguments at all, it doesn't have to do any of +these steps. It is also perfectly all right for a function to access +fewer arguments than were supplied in the call, but you will get garbage +values if you try to access too many arguments. + + +@node How Many Arguments, Calling Variadic Functions, Receiving the Argument Values, How Variable Arguments are Used +@subsection How Many Arguments Were Supplied + +There is no general way for a function to determine the number and type +of the actual values that were passed as optional arguments. Typically, +the value of one of the required arguments is used to tell the function +this information. It is up to you to define an appropriate calling +convention for each function, and write all calls accordingly. + +One calling convention is to make one of the required arguments be an +explicit argument count. This convention is usable if all of the +optional arguments are of the same type. + +A required argument can be used as a pattern to specify both the number +and types of the optional arguments. The format template string +argument to @code{printf} is one example of this. + +A similar technique that is sometimes used is to have one of the +required arguments be a bit mask, with a bit for each possible optional +argument that might be supplied. The bits are tested in a predefined +sequence; if the bit is set, the value of the next argument is +retrieved, and otherwise a default value is used. + +Another technique that is sometimes used is to pass an ``end marker'' +value as the last optional argument. For example, for a function that +manipulates an arbitrary number of pointer arguments, a null pointer +might indicate the end of the argument list, provided that a null +pointer isn't otherwise meaningful to the function. + + +@node Calling Variadic Functions, , How Many Arguments, How Variable Arguments are Used +@subsection Calling Variadic Functions + +Functions that are @emph{defined} to be variadic must also be +@emph{declared} to be variadic using a function prototype in the scope +of all calls to it. This is because C compilers might use a different +internal function call protocol for variadic functions than for +functions that take a fixed number and type of arguments. If the +compiler can't determine in advance that the function being called is +variadic, it may end up trying to call it incorrectly and your program +won't work. +@cindex function prototypes +@cindex prototypes for variadic functions +@cindex variadic functions need prototypes + +Since the prototype doesn't specify types for optional arguments, in a +call to a variadic function the @dfn{default argument promotions} are +performed on the optional argument values. This means the objects of +type @code{char} or @code{short int} (whether signed or not) are +promoted to either @code{int} or @code{unsigned int}, as appropriate; +and that objects of type @code{float} are promoted to type +@code{double}. So, if the caller passes a @code{char} as an optional +argument, it is promoted to a @code{int}, and the function should get it +with @code{va_arg (@var{ap}, int)}. + +Promotions of the required arguments are determined by the function +prototype in the usual way (as if by assignment to the types of the +corresponding formal parameters). +@cindex default argument promotions +@cindex argument promotion + +@node Variable Arguments Interface, Example of Variable Arguments, How Variable Arguments are Used, Variable Argument Facilities +@section Variable Arguments Interface + +Here are descriptions of the macros used to retrieve variable arguments. +These macros are defined in the header file @file{stdarg.h}. +@pindex stdarg.h + +@comment stdarg.h +@comment ANSI +@deftp {Data Type} va_list +The type @code{va_list} is used for argument pointer variables. +@end deftp + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} void va_start (va_list @var{ap}, @var{last_required}) +This macro initialized the argument pointer variable @var{ap} to point +to the first of the optional arguments of the current function; +@var{last_required} must be the last required argument to the function. +@end deftypefn + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type}) +The @code{va_arg} macro returns the value of the next optional argument, +and changes the internal state of @var{ap} to move past this argument. +Thus, successive uses of @code{va_arg} return successive optional +arguments. +The type of the value returned by @code{va_arg} is the @var{type} +specified in the call. + +The @var{type} must match the type of the actual argument, and must not +be @code{char} or @code{short int} or @code{float}. (Remember that the +default argument promotions apply to optional arguments.) +@end deftypefn + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} void va_end (va_list @var{ap}) +This ends the use of @var{ap}. After a @code{va_end} call, further +@code{va_arg} calls with the same @var{ap} may not work. You should invoke +@code{va_end} before returning from the function in which @code{va_start} +was invoked with the same @var{ap} argument. + +In the GNU C library, @code{va_end} does nothing, and you need not ever +use it except for reasons of portability. +@refill +@end deftypefn + + +@node Example of Variable Arguments, , Variable Arguments Interface, Variable Argument Facilities +@section Example of Variable Arguments + +Here is a complete sample function that accepts variable numbers of +arguments. The first argument to the function is the count of remaining +arguments, which are added up and the result returned. (This is +obviously a rather pointless function, but it serves to illustrate the +way the variable arguments facility is commonly used.) + +@comment Yes, this example has been tested. + +@example +#include <stdarg.h> + +int +add_em_up (int count, @dots{}) +@{ + va_list ap; + int i, sum; + + va_start (ap, count); /* @r{Initialize the argument list.} */ + + sum = 0; + for (i = 0; i < count; i++) + sum = sum + va_arg (ap, int); /* @r{Get the next argument value.} */ + + va_end (ap); /* @r{Clean up.} */ + return sum; +@} + +void main (void) +@{ + /* @r{This call prints 16.} */ + printf ("%d\n", add_em_up (3, 5, 5, 6)); + + /* @r{This call prints 55.} */ + printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); +@} +@end example diff --git a/manual/=stddef.texi b/manual/=stddef.texi new file mode 100644 index 0000000000..28d4b26f33 --- /dev/null +++ b/manual/=stddef.texi @@ -0,0 +1,81 @@ +@node Common Definitions, Memory Allocation, Error Reporting, Top +@chapter Common Definitions + +There are some miscellaneous data types and macros that are not part of +the C language kernel but are nonetheless almost universally used, such +as the macro @code{NULL}. In order to use these type and macro +definitions, your program should include the header file +@file{stddef.h}. +@pindex stddef.h + +@comment stddef.h +@comment ANSI +@deftp {Data Type} ptrdiff_t +This is the signed integer type of the result of subtracting two +pointers. For example, with the declaration @code{char *p1, *p2;}, the +expression @code{p2 - p1} is of type @code{ptrdiff_t}. This will +probably be one of the standard signed integer types (@code{short int}, +@code{int} or @code{long int}), but might be a nonstandard type that +exists only for this purpose. +@end deftp + +@comment stddef.h +@comment ANSI +@deftp {Data Type} size_t +This is an unsigned integer type used to represent the sizes of objects. +The result of the @code{sizeof} operator is of this type, and functions +such as @code{malloc} (@pxref{Unconstrained Allocation}) and +@code{memcpy} (@pxref{Copying and Concatenation}) that manipulate +objects of arbitrary sizes accept arguments of this type to specify +object sizes. +@end deftp + +In the GNU system @code{size_t} is equivalent to one of the types +@code{unsigned int} and @code{unsigned long int}. These types have +identical properties on the GNU system, and for most purposes, you +can use them interchangeably. However, they are distinct types, +and in certain contexts, you may not treat them as identical. For +example, when you specify the type of a function argument in a +function prototype, it makes a difference which one you use. If +the system header files declare @code{malloc} with an argument +of type @code{size_t} and you declare @code{malloc} with an argument +of type @code{unsigned int}, you will get a compilation error if +@code{size_t} happens to be @code{unsigned long int} on your system. +To avoid any possibility of error, when a function argument is +supposed to have type @code{size_t}, always write the type as +@code{size_t}, and make no assumptions about what that type might +actually be. + +@strong{Compatibility Note:} Types such as @code{size_t} are new +features of ANSI C. Older, pre-ANSI C implementations have +traditionally used @code{unsigned int} for representing object sizes +and @code{int} for pointer subtraction results. + +@comment stddef.h +@comment ANSI +@deftypevr Macro {void *} NULL +@cindex null pointer +This is a null pointer constant. It can be assigned to any pointer +variable since it has type @code{void *}, and is guaranteed not to +point to any real object. This macro is the best way to get a null +pointer value. You can also use @code{0} or @code{(void *)0} as a null +pointer constant, but using @code{NULL} makes the purpose of the +constant more evident. + +When passing a null pointer as an argument to a function for which there +is no prototype declaration in scope, you should explicitly cast +@code{NULL} or @code{0} into a pointer of the appropriate type. Again, +this is because the default argument promotions may not do the right +thing. +@end deftypevr + +@comment stddef.h +@comment ANSI +@deftypefn {Macro} size_t offsetof (@var{type}, @var{member}) +This expands to a integer constant expression that is the offset of the +structure member named @var{member} in a @code{struct} of type +@var{type}. For example, @code{offsetof (struct s, elem)} is the +offset, in bytes, of the member @code{elem} in a @code{struct s}. This +macro won't work if @var{member} is a bit field; you get an error from +the C compiler in that case. +@end deftypefn diff --git a/manual/Makefile b/manual/Makefile new file mode 100644 index 0000000000..57e6ae2306 --- /dev/null +++ b/manual/Makefile @@ -0,0 +1,186 @@ +# Makefile for the GNU C Library manual. + +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := manual +export subdir := $(subdir) + +.PHONY: all dvi info +all: dvi info +dvi: libc.dvi +info: libc.info + +# Get glibc's configuration info. +ifneq (,$(wildcard ../Makeconfig)) +include ../Makeconfig +endif + +# Set chapters and chapters-incl. +include chapters +chapters: libc.texinfo + $(find-includes) +chapters := $(filter-out summary.texi,$(chapters)) +ifdef chapters +include chapters-incl +chapters-incl: $(chapters) + $(find-includes) +endif + +define find-includes +(echo '$(@F) :=' \\ ;\ + awk '$$1 == "@include" { print $$2 " \\" }' $^) > $@.new +mv -f $@.new $@ +endef + +libc.dvi libc.info: $(chapters) summary.texi $(chapters-incl) +libc.dvi: texinfo.tex + +# Generate the summary from the Texinfo source files for each chapter. +summary.texi: stamp-summary ; +stamp-summary: summary.awk $(chapters) $(chapters-incl) + awk -f $^ \ + | sort -df +1 -2 | tr '\014' '\012' > summary-tmp + ./move-if-change summary-tmp summary.texi +# touch is broken on our machines. Sigh. + date > $@ + +# Generate Texinfo files from the C source for the example programs. +%.c.texi: examples/%.c + sed -e 's,[{}],@&,g' \ + -e 's,/\*\(@.*\)\*/,\1,g' \ + -e 's,/\* *,/* @r{,g' -e 's, *\*/,} */,' \ + -e 's/\(@[a-z][a-z]*\)@{\([^}]*\)@}/\1{\2}/'\ + $< | expand > $@.new + mv -f $@.new $@ + + +minimal-dist = summary.awk move-if-change libc.texinfo $(chapters) \ + $(patsubst %.c.texi,examples/%.c, \ + $(filter-out summary.texi,$(chapters-incl))) +doc-only-dist = Makefile COPYING.LIB mkinstalldirs +distribute = $(minimal-dist) \ + $(patsubst examples/%.c,%.c.texi,$(filter examples/%.c, \ + $(minimal-dist))) \ + libc.?? libc.??s texinfo.tex summary.texi \ + stamp-summary chapters chapters-incl +export distribute := $(distribute) + +tar-it = tar chovf $@ $^ + +manual.tar: $(doc-only-dist) $(minimal-dist) ; $(tar-it) +mandist.tar: $(doc-only-dist) $(distribute) ; $(tar-it) + +edition := $(shell sed -n 's/^@set EDITION \([0-9][0-9.]*\)[^0-9.]*.*$$/\1/p' \ + libc.texinfo) + +glibc-doc-$(edition).tar: $(doc-only-dist) $(distribute) + @rm -f glibc-doc-$(edition) + ln -s . glibc-doc-$(edition) + tar chovf $@ $(addprefix glibc-doc-$(edition)/,$^) + rm -f glibc-doc-$(edition) + +%.Z: % + compress -c $< > $@.new + mv -f $@.new $@ +%.gz: % + gzip -9 -c $< > $@.new + mv -f $@.new $@ +%.uu: % + uuencode $< < $< > $@.new + mv -f $@.new $@ + +# The parent makefile sometimes invokes us with targets `subdir_REAL-TARGET'. +subdir_%: % ; + +.PHONY: mostlyclean distclean realclean clean +mostlyclean: + -rm -f libc.dvi libc.info* +clean: mostlyclean +distclean: clean +indices = cp fn pg tp vr ky +realclean: distclean + -rm -f chapters chapters-incl summary.texi stamp-summary *.c.texi + -rm -f $(foreach index,$(indices),libc.$(index) libc.$(index)s) + -rm -f libc.log libc.aux libc.toc + +.PHONY: install subdir_install installdirs install-data +install-data subdir_install: install +install: $(infodir)/libc.info +# Catchall implicit rule for other installation targets from the parent. +install-%: ; + +ifndef infodir +infodir = $(prefix)/info +endif +ifndef prefix +prefix = /usr/local +endif + +ifndef INSTALL_DATA +INSTALL_DATA = $(INSTALL) -m 644 +endif +ifndef INSTALL +INSTALL = install +endif + +$(infodir)/libc.info: libc.info installdirs + for file in $<*; do \ + name=`basename $$file`; \ + $(INSTALL_DATA) $$file \ + `echo $@ | sed "s,$<\$$,$$name,"`; \ + done + +installdirs: $(firstword $(wildcard mkinstalldirs ../mkinstalldirs)) + $(dir $<)$(notdir $<) $(infodir) + +.PHONY: dist +dist: # glibc-doc-$(edition).tar.gz + +ifneq (,$(wildcard ../Make-dist)) +dist: ../Make-dist + $(MAKE) -f $< $(Make-dist-args) +endif + +ifndef ETAGS +ETAGS = etags -T +endif +TAGS: $(minimal-dist) + $(ETAGS) -o $@ $^ + +# These are targets that each glibc subdirectory is expected to understand. +# ../Rules defines them for code subdirectories; for us, they are no-ops. +glibc-targets := subdir_lib objects objs others tests subdir_lint.out \ + subdir_echo-headers subdir_echo-distinfo stubs +.PHONY: $(glibc-targets) +$(glibc-targets): + +stubs: $(common-objpfx)stub-manual +$(common-objpfx)stub-manual: + cp /dev/null $@ + +# The top-level glibc Makefile expects subdir_install to update the stubs file. +subdir_install: stubs + + +# Get rid of these variables if they came from the parent. +routines = +aux = +sources = +objects = +headers = diff --git a/manual/arith.texi b/manual/arith.texi new file mode 100644 index 0000000000..a5d2814b1d --- /dev/null +++ b/manual/arith.texi @@ -0,0 +1,623 @@ +@node Arithmetic, Date and Time, Mathematics, Top +@chapter Low-Level Arithmetic Functions + +This chapter contains information about functions for doing basic +arithmetic operations, such as splitting a float into its integer and +fractional parts. These functions are declared in the header file +@file{math.h}. + +@menu +* Not a Number:: Making NaNs and testing for NaNs. +* Predicates on Floats:: Testing for infinity and for NaNs. +* Absolute Value:: Absolute value functions. +* Normalization Functions:: Hacks for radix-2 representations. +* Rounding and Remainders:: Determinining the integer and + fractional parts of a float. +* Integer Division:: Functions for performing integer + division. +* Parsing of Numbers:: Functions for ``reading'' numbers + from strings. +@end menu + +@node Not a Number +@section ``Not a Number'' Values +@cindex NaN +@cindex not a number +@cindex IEEE floating point + +The IEEE floating point format used by most modern computers supports +values that are ``not a number''. These values are called @dfn{NaNs}. +``Not a number'' values result from certain operations which have no +meaningful numeric result, such as zero divided by zero or infinity +divided by infinity. + +One noteworthy property of NaNs is that they are not equal to +themselves. Thus, @code{x == x} can be 0 if the value of @code{x} is a +NaN. You can use this to test whether a value is a NaN or not: if it is +not equal to itself, then it is a NaN. But the recommended way to test +for a NaN is with the @code{isnan} function (@pxref{Predicates on Floats}). + +Almost any arithmetic operation in which one argument is a NaN returns +a NaN. + +@comment math.h +@comment GNU +@deftypevr Macro double NAN +An expression representing a value which is ``not a number''. This +macro is a GNU extension, available only on machines that support ``not +a number'' values---that is to say, on all machines that support IEEE +floating point. + +You can use @samp{#ifdef NAN} to test whether the machine supports +NaNs. (Of course, you must arrange for GNU extensions to be visible, +such as by defining @code{_GNU_SOURCE}, and then you must include +@file{math.h}.) +@end deftypevr + +@node Predicates on Floats +@section Predicates on Floats + +@pindex math.h +This section describes some miscellaneous test functions on doubles. +Prototypes for these functions appear in @file{math.h}. These are BSD +functions, and thus are available if you define @code{_BSD_SOURCE} or +@code{_GNU_SOURCE}. + +@comment math.h +@comment BSD +@deftypefun int isinf (double @var{x}) +This function returns @code{-1} if @var{x} represents negative infinity, +@code{1} if @var{x} represents positive infinity, and @code{0} otherwise. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun int isnan (double @var{x}) +This function returns a nonzero value if @var{x} is a ``not a number'' +value, and zero otherwise. (You can just as well use @code{@var{x} != +@var{x}} to get the same result). +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun int finite (double @var{x}) +This function returns a nonzero value if @var{x} is finite or a ``not a +number'' value, and zero otherwise. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double infnan (int @var{error}) +This function is provided for compatibility with BSD. The other +mathematical functions use @code{infnan} to decide what to return on +occasion of an error. Its argument is an error code, @code{EDOM} or +@code{ERANGE}; @code{infnan} returns a suitable value to indicate this +with. @code{-ERANGE} is also acceptable as an argument, and corresponds +to @code{-HUGE_VAL} as a value. + +In the BSD library, on certain machines, @code{infnan} raises a fatal +signal in all cases. The GNU library does not do likewise, because that +does not fit the ANSI C specification. +@end deftypefun + +@strong{Portability Note:} The functions listed in this section are BSD +extensions. + +@node Absolute Value +@section Absolute Value +@cindex absolute value functions + +These functions are provided for obtaining the @dfn{absolute value} (or +@dfn{magnitude}) of a number. The absolute value of a real number +@var{x} is @var{x} is @var{x} is positive, @minus{}@var{x} if @var{x} is +negative. For a complex number @var{z}, whose real part is @var{x} and +whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt +(@var{x}*@var{x} + @var{y}*@var{y})}}. + +@pindex math.h +@pindex stdlib.h +Prototypes for @code{abs} and @code{labs} are in @file{stdlib.h}; +@code{fabs} and @code{cabs} are declared in @file{math.h}. + +@comment stdlib.h +@comment ANSI +@deftypefun int abs (int @var{number}) +This function returns the absolute value of @var{number}. + +Most computers use a two's complement integer representation, in which +the absolute value of @code{INT_MIN} (the smallest possible @code{int}) +cannot be represented; thus, @w{@code{abs (INT_MIN)}} is not defined. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun {long int} labs (long int @var{number}) +This is similar to @code{abs}, except that both the argument and result +are of type @code{long int} rather than @code{int}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double fabs (double @var{number}) +This function returns the absolute value of the floating-point number +@var{number}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double cabs (struct @{ double real, imag; @} @var{z}) +The @code{cabs} function returns the absolute value of the complex +number @var{z}, whose real part is @code{@var{z}.real} and whose +imaginary part is @code{@var{z}.imag}. (See also the function +@code{hypot} in @ref{Exponents and Logarithms}.) The value is: + +@smallexample +sqrt (@var{z}.real*@var{z}.real + @var{z}.imag*@var{z}.imag) +@end smallexample +@end deftypefun + +@node Normalization Functions +@section Normalization Functions +@cindex normalization functions (floating-point) + +The functions described in this section are primarily provided as a way +to efficiently perform certain low-level manipulations on floating point +numbers that are represented internally using a binary radix; +see @ref{Floating Point Concepts}. These functions are required to +have equivalent behavior even if the representation does not use a radix +of 2, but of course they are unlikely to be particularly efficient in +those cases. + +@pindex math.h +All these functions are declared in @file{math.h}. + +@comment math.h +@comment ANSI +@deftypefun double frexp (double @var{value}, int *@var{exponent}) +The @code{frexp} function is used to split the number @var{value} +into a normalized fraction and an exponent. + +If the argument @var{value} is not zero, the return value is @var{value} +times a power of two, and is always in the range 1/2 (inclusive) to 1 +(exclusive). The corresponding exponent is stored in +@code{*@var{exponent}}; the return value multiplied by 2 raised to this +exponent equals the original number @var{value}. + +For example, @code{frexp (12.8, &exponent)} returns @code{0.8} and +stores @code{4} in @code{exponent}. + +If @var{value} is zero, then the return value is zero and +zero is stored in @code{*@var{exponent}}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double ldexp (double @var{value}, int @var{exponent}) +This function returns the result of multiplying the floating-point +number @var{value} by 2 raised to the power @var{exponent}. (It can +be used to reassemble floating-point numbers that were taken apart +by @code{frexp}.) + +For example, @code{ldexp (0.8, 4)} returns @code{12.8}. +@end deftypefun + +The following functions which come from BSD provide facilities +equivalent to those of @code{ldexp} and @code{frexp}: + +@comment math.h +@comment BSD +@deftypefun double scalb (double @var{value}, int @var{exponent}) +The @code{scalb} function is the BSD name for @code{ldexp}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double logb (double @var{x}) +This BSD function returns the integer part of the base-2 logarithm of +@var{x}, an integer value represented in type @code{double}. This is +the highest integer power of @code{2} contained in @var{x}. The sign of +@var{x} is ignored. For example, @code{logb (3.5)} is @code{1.0} and +@code{logb (4.0)} is @code{2.0}. + +When @code{2} raised to this power is divided into @var{x}, it gives a +quotient between @code{1} (inclusive) and @code{2} (exclusive). + +If @var{x} is zero, the value is minus infinity (if the machine supports +such a value), or else a very small number. If @var{x} is infinity, the +value is infinity. + +The value returned by @code{logb} is one less than the value that +@code{frexp} would store into @code{*@var{exponent}}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double copysign (double @var{value}, double @var{sign}) +The @code{copysign} function returns a value whose absolute value is the +same as that of @var{value}, and whose sign matches that of @var{sign}. +This is a BSD function. +@end deftypefun + +@node Rounding and Remainders +@section Rounding and Remainder Functions +@cindex rounding functions +@cindex remainder functions +@cindex converting floats to integers + +@pindex math.h +The functions listed here perform operations such as rounding, +truncation, and remainder in division of floating point numbers. Some +of these functions convert floating point numbers to integer values. +They are all declared in @file{math.h}. + +You can also convert floating-point numbers to integers simply by +casting them to @code{int}. This discards the fractional part, +effectively rounding towards zero. However, this only works if the +result can actually be represented as an @code{int}---for very large +numbers, this is impossible. The functions listed here return the +result as a @code{double} instead to get around this problem. + +@comment math.h +@comment ANSI +@deftypefun double ceil (double @var{x}) +The @code{ceil} function rounds @var{x} upwards to the nearest integer, +returning that value as a @code{double}. Thus, @code{ceil (1.5)} +is @code{2.0}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double floor (double @var{x}) +The @code{ceil} function rounds @var{x} downwards to the nearest +integer, returning that value as a @code{double}. Thus, @code{floor +(1.5)} is @code{1.0} and @code{floor (-1.5)} is @code{-2.0}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double rint (double @var{x}) +This function rounds @var{x} to an integer value according to the +current rounding mode. @xref{Floating Point Parameters}, for +information about the various rounding modes. The default +rounding mode is to round to the nearest integer; some machines +support other modes, but round-to-nearest is always used unless +you explicit select another. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double modf (double @var{value}, double *@var{integer-part}) +This function breaks the argument @var{value} into an integer part and a +fractional part (between @code{-1} and @code{1}, exclusive). Their sum +equals @var{value}. Each of the parts has the same sign as @var{value}, +so the rounding of the integer part is towards zero. + +@code{modf} stores the integer part in @code{*@var{integer-part}}, and +returns the fractional part. For example, @code{modf (2.5, &intpart)} +returns @code{0.5} and stores @code{2.0} into @code{intpart}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double fmod (double @var{numerator}, double @var{denominator}) +This function computes the remainder from the division of +@var{numerator} by @var{denominator}. Specifically, the return value is +@code{@var{numerator} - @w{@var{n} * @var{denominator}}}, where @var{n} +is the quotient of @var{numerator} divided by @var{denominator}, rounded +towards zero to an integer. Thus, @w{@code{fmod (6.5, 2.3)}} returns +@code{1.9}, which is @code{6.5} minus @code{4.6}. + +The result has the same sign as the @var{numerator} and has magnitude +less than the magnitude of the @var{denominator}. + +If @var{denominator} is zero, @code{fmod} fails and sets @code{errno} to +@code{EDOM}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double drem (double @var{numerator}, double @var{denominator}) +The function @code{drem} is like @code{fmod} except that it rounds the +internal quotient @var{n} to the nearest integer instead of towards zero +to an integer. For example, @code{drem (6.5, 2.3)} returns @code{-0.4}, +which is @code{6.5} minus @code{6.9}. + +The absolute value of the result is less than or equal to half the +absolute value of the @var{denominator}. The difference between +@code{fmod (@var{numerator}, @var{denominator})} and @code{drem +(@var{numerator}, @var{denominator})} is always either +@var{denominator}, minus @var{denominator}, or zero. + +If @var{denominator} is zero, @code{drem} fails and sets @code{errno} to +@code{EDOM}. +@end deftypefun + + +@node Integer Division +@section Integer Division +@cindex integer division functions + +This section describes functions for performing integer division. These +functions are redundant in the GNU C library, since in GNU C the @samp{/} +operator always rounds towards zero. But in other C implementations, +@samp{/} may round differently with negative arguments. @code{div} and +@code{ldiv} are useful because they specify how to round the quotient: +towards zero. The remainder has the same sign as the numerator. + +These functions are specified to return a result @var{r} such that the value +@code{@var{r}.quot*@var{denominator} + @var{r}.rem} equals +@var{numerator}. + +@pindex stdlib.h +To use these facilities, you should include the header file +@file{stdlib.h} in your program. + +@comment stdlib.h +@comment ANSI +@deftp {Data Type} div_t +This is a structure type used to hold the result returned by the @code{div} +function. It has the following members: + +@table @code +@item int quot +The quotient from the division. + +@item int rem +The remainder from the division. +@end table +@end deftp + +@comment stdlib.h +@comment ANSI +@deftypefun div_t div (int @var{numerator}, int @var{denominator}) +This function @code{div} computes the quotient and remainder from +the division of @var{numerator} by @var{denominator}, returning the +result in a structure of type @code{div_t}. + +If the result cannot be represented (as in a division by zero), the +behavior is undefined. + +Here is an example, albeit not a very useful one. + +@smallexample +div_t result; +result = div (20, -6); +@end smallexample + +@noindent +Now @code{result.quot} is @code{-3} and @code{result.rem} is @code{2}. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftp {Data Type} ldiv_t +This is a structure type used to hold the result returned by the @code{ldiv} +function. It has the following members: + +@table @code +@item long int quot +The quotient from the division. + +@item long int rem +The remainder from the division. +@end table + +(This is identical to @code{div_t} except that the components are of +type @code{long int} rather than @code{int}.) +@end deftp + +@comment stdlib.h +@comment ANSI +@deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator}) +The @code{ldiv} function is similar to @code{div}, except that the +arguments are of type @code{long int} and the result is returned as a +structure of type @code{ldiv}. +@end deftypefun + + +@node Parsing of Numbers +@section Parsing of Numbers +@cindex parsing numbers (in formatted input) +@cindex converting strings to numbers +@cindex number syntax, parsing +@cindex syntax, for reading numbers + +This section describes functions for ``reading'' integer and +floating-point numbers from a string. It may be more convenient in some +cases to use @code{sscanf} or one of the related functions; see +@ref{Formatted Input}. But often you can make a program more robust by +finding the tokens in the string by hand, then converting the numbers +one by one. + +@menu +* Parsing of Integers:: Functions for conversion of integer values. +* Parsing of Floats:: Functions for conversion of floating-point + values. +@end menu + +@node Parsing of Integers +@subsection Parsing of Integers + +@pindex stdlib.h +These functions are declared in @file{stdlib.h}. + +@comment stdlib.h +@comment ANSI +@deftypefun {long int} strtol (const char *@var{string}, char **@var{tailptr}, int @var{base}) +The @code{strtol} (``string-to-long'') function converts the initial +part of @var{string} to a signed integer, which is returned as a value +of type @code{long int}. + +This function attempts to decompose @var{string} as follows: + +@itemize @bullet +@item +A (possibly empty) sequence of whitespace characters. Which characters +are whitespace is determined by the @code{isspace} function +(@pxref{Classification of Characters}). These are discarded. + +@item +An optional plus or minus sign (@samp{+} or @samp{-}). + +@item +A nonempty sequence of digits in the radix specified by @var{base}. + +If @var{base} is zero, decimal radix is assumed unless the series of +digits begins with @samp{0} (specifying octal radix), or @samp{0x} or +@samp{0X} (specifying hexadecimal radix); in other words, the same +syntax used for integer constants in C. + +Otherwise @var{base} must have a value between @code{2} and @code{35}. +If @var{base} is @code{16}, the digits may optionally be preceded by +@samp{0x} or @samp{0X}. + +@item +Any remaining characters in the string. If @var{tailptr} is not a null +pointer, @code{strtol} stores a pointer to this tail in +@code{*@var{tailptr}}. +@end itemize + +If the string is empty, contains only whitespace, or does not contain an +initial substring that has the expected syntax for an integer in the +specified @var{base}, no conversion is performed. In this case, +@code{strtol} returns a value of zero and the value stored in +@code{*@var{tailptr}} is the value of @var{string}. + +In a locale other than the standard @code{"C"} locale, this function +may recognize additional implementation-dependent syntax. + +If the string has valid syntax for an integer but the value is not +representable because of overflow, @code{strtol} returns either +@code{LONG_MAX} or @code{LONG_MIN} (@pxref{Range of Type}), as +appropriate for the sign of the value. It also sets @code{errno} +to @code{ERANGE} to indicate there was overflow. + +There is an example at the end of this section. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun {unsigned long int} strtoul (const char *@var{string}, char **@var{tailptr}, int @var{base}) +The @code{strtoul} (``string-to-unsigned-long'') function is like +@code{strtol} except that it returns its value with type @code{unsigned +long int}. The value returned in case of overflow is @code{ULONG_MAX} +(@pxref{Range of Type}). +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun {long int} atol (const char *@var{string}) +This function is similar to the @code{strtol} function with a @var{base} +argument of @code{10}, except that it need not detect overflow errors. +The @code{atol} function is provided mostly for compatibility with +existing code; using @code{strtol} is more robust. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun int atoi (const char *@var{string}) +This function is like @code{atol}, except that it returns an @code{int} +value rather than @code{long int}. The @code{atoi} function is also +considered obsolete; use @code{strtol} instead. +@end deftypefun + +Here is a function which parses a string as a sequence of integers and +returns the sum of them: + +@smallexample +int +sum_ints_from_string (char *string) +@{ + int sum = 0; + + while (1) @{ + char *tail; + int next; + + /* @r{Skip whitespace by hand, to detect the end.} */ + while (isspace (*string)) string++; + if (*string == 0) + break; + + /* @r{There is more nonwhitespace,} */ + /* @r{so it ought to be another number.} */ + errno = 0; + /* @r{Parse it.} */ + next = strtol (string, &tail, 0); + /* @r{Add it in, if not overflow.} */ + if (errno) + printf ("Overflow\n"); + else + sum += next; + /* @r{Advance past it.} */ + string = tail; + @} + + return sum; +@} +@end smallexample + +@node Parsing of Floats +@subsection Parsing of Floats + +@pindex stdlib.h +These functions are declared in @file{stdlib.h}. + +@comment stdlib.h +@comment ANSI +@deftypefun double strtod (const char *@var{string}, char **@var{tailptr}) +The @code{strtod} (``string-to-double'') function converts the initial +part of @var{string} to a floating-point number, which is returned as a +value of type @code{double}. + +This function attempts to decompose @var{string} as follows: + +@itemize @bullet +@item +A (possibly empty) sequence of whitespace characters. Which characters +are whitespace is determined by the @code{isspace} function +(@pxref{Classification of Characters}). These are discarded. + +@item +An optional plus or minus sign (@samp{+} or @samp{-}). + +@item +A nonempty sequence of digits optionally containing a decimal-point +character---normally @samp{.}, but it depends on the locale +(@pxref{Numeric Formatting}). + +@item +An optional exponent part, consisting of a character @samp{e} or +@samp{E}, an optional sign, and a sequence of digits. + +@item +Any remaining characters in the string. If @var{tailptr} is not a null +pointer, a pointer to this tail of the string is stored in +@code{*@var{tailptr}}. +@end itemize + +If the string is empty, contains only whitespace, or does not contain an +initial substring that has the expected syntax for a floating-point +number, no conversion is performed. In this case, @code{strtod} returns +a value of zero and the value returned in @code{*@var{tailptr}} is the +value of @var{string}. + +In a locale other than the standard @code{"C"} locale, this function may +recognize additional locale-dependent syntax. + +If the string has valid syntax for a floating-point number but the value +is not representable because of overflow, @code{strtod} returns either +positive or negative @code{HUGE_VAL} (@pxref{Mathematics}), depending on +the sign of the value. Similarly, if the value is not representable +because of underflow, @code{strtod} returns zero. It also sets @code{errno} +to @code{ERANGE} if there was overflow or underflow. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun double atof (const char *@var{string}) +This function is similar to the @code{strtod} function, except that it +need not detect overflow and underflow errors. The @code{atof} function +is provided mostly for compatibility with existing code; using +@code{strtod} is more robust. +@end deftypefun diff --git a/manual/assert.texi b/manual/assert.texi new file mode 100644 index 0000000000..1095dc4754 --- /dev/null +++ b/manual/assert.texi @@ -0,0 +1,113 @@ +@node Consistency Checking, Mathematics, Low-Level Terminal Interface, Top +@chapter Explicitly Checking Internal Consistency +@cindex consistency checking +@cindex impossible events +@cindex assertions + +When you're writing a program, it's often a good idea to put in checks +at strategic places for ``impossible'' errors or violations of basic +assumptions. These kinds of checks are helpful in debugging problems +with the interfaces between different parts of the program, for example. + +@pindex assert.h +The @code{assert} macro, defined in the header file @file{assert.h}, +provides a convenient way to abort the program while printing some +debugging information about where in the program the error was detected. + +@vindex NDEBUG +Once you think your program is debugged, you can disable the error +checks performed by the @code{assert} macro by recompiling with the +macro @code{NDEBUG} defined. This means you don't actually have to +change the program source code to disable these checks. + +But disabling these consistency checks is undesirable unless they make +the program significantly slower. All else being equal, more error +checking is good no matter who is running the program. A wise user +would rather have a program crash, visibly, than have it return nonsense +without indicating anything might be wrong. + +@comment assert.h +@comment ANSI +@deftypefn Macro void assert (int @var{expression}) +Verify the programmer's belief that @var{expression} should be nonzero +at a certain point in the program. + +If @code{NDEBUG} is not defined, @code{assert} tests the value of +@var{expression}. If it is false (zero), @code{assert} aborts the +program (@pxref{Aborting a Program}) after printing a message of the +form: + +@smallexample +@file{@var{file}}:@var{linenum}: @var{function}: Assertion `@var{expression}' failed. +@end smallexample + +@noindent +on the standard error stream @code{stderr} (@pxref{Standard Streams}). +The filename and line number are taken from the C preprocessor macros +@code{__FILE__} and @code{__LINE__} and specify where the call to +@code{assert} was written. When using the GNU C compiler, the name of +the function which calls @code{assert} is taken from the built-in +variable @code{__PRETTY_FUNCTION__}; with older compilers, the function +name and following colon are omitted. + +If the preprocessor macro @code{NDEBUG} is defined before +@file{assert.h} is included, the @code{assert} macro is defined to do +absolutely nothing. Even the argument expression @var{expression} is +not evaluated, so you should avoid calling @code{assert} with arguments +that involve side effects. + +For example, @code{assert (++i > 0);} is a bad idea, because @code{i} +will not be incremented if @code{NDEBUG} is defined. +@end deftypefn + +Sometimes the ``impossible'' condition you want to check for is an error +return from an operating system function. Then it is useful to display +not only where the program crashes, but also what error was returned. +The @code{assert_perror} macro makes this easy. + +@comment assert.h +@comment GNU +@deftypefn Macro void assert_perror (int @var{errnum}) +Similar to @code{assert}, but verifies that @var{errnum} is zero. + +If @code{NDEBUG} is defined, @code{assert_perror} tests the value of +@var{errnum}. If it is nonzero, @code{assert_perror} aborts the program +after a printing a message of the form: + +@smallexample +@file{@var{file}}:@var{linenum}: @var{function}: @var{error text} +@end smallexample + +@noindent +on the standard error stream. The file name, line number, and function +name are as for @code{assert}. The error text is the result of +@w{@code{strerror (@var{errnum})}}. @xref{Error Messages}. + +Like @code{assert}, if @code{NDEBUG} is defined before @file{assert.h} +is included, the @code{assert_perror} macro does absolutely nothing. It +does not evaluate the argument, so @var{errnum} should not have any side +effects. It is best for @var{errnum} to be a just simple variable +reference; often it will be @code{errno}. + +This macro is a GNU extension. +@end deftypefn + +@strong{Usage note:} The @code{assert} facility is designed for +detecting @emph{internal inconsistency}; it is not suitable for +reporting invalid input or improper usage. + +The information in the diagnostic messages provided by the @code{assert} +macro is intended to to help you, the programmer, track down the cause +of a bug, but is not really useful in telling a user of your program why +his or her input was invalid or why a command could not be carried out. +So you can't use @code{assert} to print the error messages for these +eventualities. + +What's more, your program should not abort when given invalid input, as +@code{assert} would do---it should exit with nonzero status after +printing its error messages, or perhaps read another command or move +on to the next input file. + +@xref{Error Messages}, for information on printing error messages for +problems that @emph{do not} represent bugs in the program. + diff --git a/manual/conf.texi b/manual/conf.texi new file mode 100644 index 0000000000..86afeca597 --- /dev/null +++ b/manual/conf.texi @@ -0,0 +1,1091 @@ +@node System Configuration, Language Features, System Information, Top +@chapter System Configuration Parameters + +The functions and macros listed in this chapter give information about +configuration parameters of the operating system---for example, capacity +limits, presence of optional POSIX features, and the default path for +executable files (@pxref{String Parameters}). + +@menu +* General Limits:: Constants and functions that describe + various process-related limits that have + one uniform value for any given machine. +* System Options:: Optional POSIX features. +* Version Supported:: Version numbers of POSIX.1 and POSIX.2. +* Sysconf:: Getting specific configuration values + of general limits and system options. +* Minimums:: Minimum values for general limits. + +* Limits for Files:: Size limitations that pertain to individual files. + These can vary between file systems + or even from file to file. +* Options for Files:: Optional features that some files may support. +* File Minimums:: Minimum values for file limits. +* Pathconf:: Getting the limit values for a particular file. + +* Utility Limits:: Capacity limits of some POSIX.2 utility programs. +* Utility Minimums:: Minimum allowable values of those limits. + +* String Parameters:: Getting the default search path. +@end menu + +@node General Limits +@section General Capacity Limits +@cindex POSIX capacity limits +@cindex limits, POSIX +@cindex capacity limits, POSIX + +The POSIX.1 and POSIX.2 standards specify a number of parameters that +describe capacity limitations of the system. These limits can be fixed +constants for a given operating system, or they can vary from machine to +machine. For example, some limit values may be configurable by the +system administrator, either at run time or by rebuilding the kernel, +and this should not require recompiling application programs. + +@pindex limits.h +Each of the following limit parameters has a macro that is defined in +@file{limits.h} only if the system has a fixed, uniform limit for the +parameter in question. If the system allows different file systems or +files to have different limits, then the macro is undefined; use +@code{sysconf} to find out the limit that applies at a particular time +on a particular machine. @xref{Sysconf}. + +Each of these parameters also has another macro, with a name starting +with @samp{_POSIX}, which gives the lowest value that the limit is +allowed to have on @emph{any} POSIX system. @xref{Minimums}. + +@cindex limits, program argument size +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int ARG_MAX +If defined, the unvarying maximum combined length of the @var{argv} and +@var{environ} arguments that can be passed to the @code{exec} functions. +@end deftypevr + +@cindex limits, number of processes +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int CHILD_MAX +If defined, the unvarying maximum number of processes that can exist +with the same real user ID at any one time. In BSD and GNU, this is +controlled by the @code{RLIMIT_NPROC} resource limit; @pxref{Limits on +Resources}. +@end deftypevr + +@cindex limits, number of open files +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int OPEN_MAX +If defined, the unvarying maximum number of files that a single process +can have open simultaneously. In BSD and GNU, this is controlled +by the @code{RLIMIT_NOFILE} resource limit; @pxref{Limits on Resources}. +@end deftypevr + +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int STREAM_MAX +If defined, the unvarying maximum number of streams that a single +process can have open simultaneously. @xref{Opening Streams}. +@end deftypevr + +@cindex limits, time zone name length +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int TZNAME_MAX +If defined, the unvarying maximum length of a time zone name. +@xref{Time Zone Functions}. +@end deftypevr + +These limit macros are always defined in @file{limits.h}. + +@cindex limits, number of supplementary group IDs +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int NGROUPS_MAX +The maximum number of supplementary group IDs that one process can have. + +The value of this macro is actually a lower bound for the maximum. That +is, you can count on being able to have that many supplementary group +IDs, but a particular machine might let you have even more. You can use +@code{sysconf} to see whether a particular machine will let you have +more (@pxref{Sysconf}). +@end deftypevr + +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int SSIZE_MAX +The largest value that can fit in an object of type @code{ssize_t}. +Effectively, this is the limit on the number of bytes that can be read +or written in a single operation. + +This macro is defined in all POSIX systems because this limit is never +configurable. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int RE_DUP_MAX +The largest number of repetitions you are guaranteed is allowed in the +construct @samp{\@{@var{min},@var{max}\@}} in a regular expression. + +The value of this macro is actually a lower bound for the maximum. That +is, you can count on being able to have that many repetitions, but a +particular machine might let you have even more. You can use +@code{sysconf} to see whether a particular machine will let you have +more (@pxref{Sysconf}). And even the value that @code{sysconf} tells +you is just a lower bound---larger values might work. + +This macro is defined in all POSIX.2 systems, because POSIX.2 says it +should always be defined even if there is no specific imposed limit. +@end deftypevr + +@node System Options +@section Overall System Options +@cindex POSIX optional features +@cindex optional POSIX features + +POSIX defines certain system-specific options that not all POSIX systems +support. Since these options are provided in the kernel, not in the +library, simply using the GNU C library does not guarantee any of these +features is supported; it depends on the system you are using. + +@pindex unistd.h +You can test for the availability of a given option using the macros in +this section, together with the function @code{sysconf}. The macros are +defined only if you include @file{unistd.h}. + +For the following macros, if the macro is defined in @file{unistd.h}, +then the option is supported. Otherwise, the option may or may not be +supported; use @code{sysconf} to find out. @xref{Sysconf}. + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int _POSIX_JOB_CONTROL +If this symbol is defined, it indicates that the system supports job +control. Otherwise, the implementation behaves as if all processes +within a session belong to a single process group. @xref{Job Control}. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int _POSIX_SAVED_IDS +If this symbol is defined, it indicates that the system remembers the +effective user and group IDs of a process before it executes an +executable file with the set-user-ID or set-group-ID bits set, and that +explicitly changing the effective user or group IDs back to these values +is permitted. If this option is not defined, then if a nonprivileged +process changes its effective user or group ID to the real user or group +ID of the process, it can't change it back again. @xref{Enable/Disable +Setuid}. +@end deftypevr + +For the following macros, if the macro is defined in @file{unistd.h}, +then its value indicates whether the option is supported. A value of +@code{-1} means no, and any other value means yes. If the macro is not +defined, then the option may or may not be supported; use @code{sysconf} +to find out. @xref{Sysconf}. + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro int _POSIX2_C_DEV +If this symbol is defined, it indicates that the system has the POSIX.2 +C compiler command, @code{c89}. The GNU C library always defines this +as @code{1}, on the assumption that you would not have installed it if +you didn't have a C compiler. +@end deftypevr + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro int _POSIX2_FORT_DEV +If this symbol is defined, it indicates that the system has the POSIX.2 +Fortran compiler command, @code{fort77}. The GNU C library never +defines this, because we don't know what the system has. +@end deftypevr + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro int _POSIX2_FORT_RUN +If this symbol is defined, it indicates that the system has the POSIX.2 +@code{asa} command to interpret Fortran carriage control. The GNU C +library never defines this, because we don't know what the system has. +@end deftypevr + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro int _POSIX2_LOCALEDEF +If this symbol is defined, it indicates that the system has the POSIX.2 +@code{localedef} command. The GNU C library never defines this, because +we don't know what the system has. +@end deftypevr + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro int _POSIX2_SW_DEV +If this symbol is defined, it indicates that the system has the POSIX.2 +commands @code{ar}, @code{make}, and @code{strip}. The GNU C library +always defines this as @code{1}, on the assumption that you had to have +@code{ar} and @code{make} to install the library, and it's unlikely that +@code{strip} would be absent when those are present. +@end deftypevr + +@node Version Supported +@section Which Version of POSIX is Supported + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro {long int} _POSIX_VERSION +This constant represents the version of the POSIX.1 standard to which +the implementation conforms. For an implementation conforming to the +1990 POSIX.1 standard, the value is the integer @code{199009L}. + +@code{_POSIX_VERSION} is always defined (in @file{unistd.h}) in any +POSIX system. + +@strong{Usage Note:} Don't try to test whether the system supports POSIX +by including @file{unistd.h} and then checking whether +@code{_POSIX_VERSION} is defined. On a non-POSIX system, this will +probably fail because there is no @file{unistd.h}. We do not know of +@emph{any} way you can reliably test at compilation time whether your +target system supports POSIX or whether @file{unistd.h} exists. + +The GNU C compiler predefines the symbol @code{__POSIX__} if the target +system is a POSIX system. Provided you do not use any other compilers +on POSIX systems, testing @code{defined (__POSIX__)} will reliably +detect such systems. +@end deftypevr + +@comment unistd.h +@comment POSIX.2 +@deftypevr Macro {long int} _POSIX2_C_VERSION +This constant represents the version of the POSIX.2 standard which the +library and system kernel support. We don't know what value this will +be for the first version of the POSIX.2 standard, because the value is +based on the year and month in which the standard is officially adopted. + +The value of this symbol says nothing about the utilities installed on +the system. + +@strong{Usage Note:} You can use this macro to tell whether a POSIX.1 +system library supports POSIX.2 as well. Any POSIX.1 system contains +@file{unistd.h}, so include that file and then test @code{defined +(_POSIX2_C_VERSION)}. +@end deftypevr + +@node Sysconf +@section Using @code{sysconf} + +When your system has configurable system limits, you can use the +@code{sysconf} function to find out the value that applies to any +particular machine. The function and the associated @var{parameter} +constants are declared in the header file @file{unistd.h}. + +@menu +* Sysconf Definition:: Detailed specifications of @code{sysconf}. +* Constants for Sysconf:: The list of parameters @code{sysconf} can read. +* Examples of Sysconf:: How to use @code{sysconf} and the parameter + macros properly together. +@end menu + +@node Sysconf Definition +@subsection Definition of @code{sysconf} + +@comment unistd.h +@comment POSIX.1 +@deftypefun {long int} sysconf (int @var{parameter}) +This function is used to inquire about runtime system parameters. The +@var{parameter} argument should be one of the @samp{_SC_} symbols listed +below. + +The normal return value from @code{sysconf} is the value you requested. +A value of @code{-1} is returned both if the implementation does not +impose a limit, and in case of an error. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The value of the @var{parameter} is invalid. +@end table +@end deftypefun + +@node Constants for Sysconf +@subsection Constants for @code{sysconf} Parameters + +Here are the symbolic constants for use as the @var{parameter} argument +to @code{sysconf}. The values are all integer constants (more +specifically, enumeration type values). + +@table @code +@comment unistd.h +@comment POSIX.1 +@item _SC_ARG_MAX +Inquire about the parameter corresponding to @code{ARG_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_CHILD_MAX +Inquire about the parameter corresponding to @code{CHILD_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_OPEN_MAX +Inquire about the parameter corresponding to @code{OPEN_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_STREAM_MAX +Inquire about the parameter corresponding to @code{STREAM_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_TZNAME_MAX +Inquire about the parameter corresponding to @code{TZNAME_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_NGROUPS_MAX +Inquire about the parameter corresponding to @code{NGROUPS_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_JOB_CONTROL +Inquire about the parameter corresponding to @code{_POSIX_JOB_CONTROL}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_SAVED_IDS +Inquire about the parameter corresponding to @code{_POSIX_SAVED_IDS}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_VERSION +Inquire about the parameter corresponding to @code{_POSIX_VERSION}. + +@comment unistd.h +@comment POSIX.1 +@item _SC_CLK_TCK +Inquire about the parameter corresponding to @code{CLOCKS_PER_SEC}; +@pxref{Basic CPU Time}. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_C_DEV +Inquire about whether the system has the POSIX.2 C compiler command, +@code{c89}. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_FORT_DEV +Inquire about whether the system has the POSIX.2 Fortran compiler +command, @code{fort77}. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_FORT_RUN +Inquire about whether the system has the POSIX.2 @code{asa} command to +interpret Fortran carriage control. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_LOCALEDEF +Inquire about whether the system has the POSIX.2 @code{localedef} +command. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_SW_DEV +Inquire about whether the system has the POSIX.2 commands @code{ar}, +@code{make}, and @code{strip}. + +@comment unistd.h +@comment POSIX.2 +@item _SC_BC_BASE_MAX +Inquire about the maximum value of @code{obase} in the @code{bc} +utility. + +@comment unistd.h +@comment POSIX.2 +@item _SC_BC_DIM_MAX +Inquire about the maximum size of an array in the @code{bc} +utility. + +@comment unistd.h +@comment POSIX.2 +@item _SC_BC_SCALE_MAX +Inquire about the maximum value of @code{scale} in the @code{bc} +utility. + +@comment unistd.h +@comment POSIX.2 +@item _SC_BC_STRING_MAX +Inquire about the maximum size of a string constant in the +@code{bc} utility. + +@comment unistd.h +@comment POSIX.2 +@item _SC_COLL_WEIGHTS_MAX +Inquire about the maximum number of weights that can necessarily +be used in defining the collating sequence for a locale. + +@comment unistd.h +@comment POSIX.2 +@item _SC_EXPR_NEST_MAX +Inquire about the maximum number of expressions nested within +parentheses when using the @code{expr} utility. + +@comment unistd.h +@comment POSIX.2 +@item _SC_LINE_MAX +Inquire about the maximum size of a text line that the POSIX.2 text +utilities can handle. + +@comment unistd.h +@comment POSIX.2 +@item _SC_EQUIV_CLASS_MAX +Inquire about the maximum number of weights that can be assigned to an +entry of the @code{LC_COLLATE} category @samp{order} keyword in a locale +definition. The GNU C library does not presently support locale +definitions. + +@comment unistd.h +@comment POSIX.2 +@item _SC_VERSION +Inquire about the version number of POSIX.1 that the library and kernel +support. + +@comment unistd.h +@comment POSIX.2 +@item _SC_2_VERSION +Inquire about the version number of POSIX.2 that the system utilities +support. + +@comment unistd.h +@comment GNU +@item _SC_PAGESIZE +Inquire about the virtual memory page size of the machine. +@code{getpagesize} returns the same value. +@c @xref{XXX getpagesize}. !!! ??? +@end table + +@node Examples of Sysconf +@subsection Examples of @code{sysconf} + +We recommend that you first test for a macro definition for the +parameter you are interested in, and call @code{sysconf} only if the +macro is not defined. For example, here is how to test whether job +control is supported: + +@smallexample +@group +int +have_job_control (void) +@{ +#ifdef _POSIX_JOB_CONTROL + return 1; +#else + int value = sysconf (_SC_JOB_CONTROL); + if (value < 0) + /* @r{If the system is that badly wedged,} + @r{there's no use trying to go on.} */ + fatal (strerror (errno)); + return value; +#endif +@} +@end group +@end smallexample + +Here is how to get the value of a numeric limit: + +@smallexample +int +get_child_max () +@{ +#ifdef CHILD_MAX + return CHILD_MAX; +#else + int value = sysconf (_SC_CHILD_MAX); + if (value < 0) + fatal (strerror (errno)); + return value; +#endif +@} +@end smallexample + +@node Minimums +@section Minimum Values for General Capacity Limits + +Here are the names for the POSIX minimum upper bounds for the system +limit parameters. The significance of these values is that you can +safely push to these limits without checking whether the particular +system you are using can go that far. + +@table @code +@comment limits.h +@comment POSIX.1 +@item _POSIX_ARG_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum combined length of the @var{argv} and @var{environ} +arguments that can be passed to the @code{exec} functions. +Its value is @code{4096}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_CHILD_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum number of simultaneous processes per real user ID. Its +value is @code{6}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_NGROUPS_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum number of supplementary group IDs per process. Its +value is @code{0}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_OPEN_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum number of files that a single process can have open +simultaneously. Its value is @code{16}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_SSIZE_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum value that can be stored in an object of type +@code{ssize_t}. Its value is @code{32767}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_STREAM_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum number of streams that a single process can have open +simultaneously. Its value is @code{8}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_TZNAME_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the maximum length of a time zone name. Its value is @code{3}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_RE_DUP_MAX +The value of this macro is the most restrictive limit permitted by POSIX +for the numbers used in the @samp{\@{@var{min},@var{max}\@}} construct +in a regular expression. Its value is @code{255}. +@end table + +@node Limits for Files +@section Limits on File System Capacity + +The POSIX.1 standard specifies a number of parameters that describe the +limitations of the file system. It's possible for the system to have a +fixed, uniform limit for a parameter, but this isn't the usual case. On +most systems, it's possible for different file systems (and, for some +parameters, even different files) to have different maximum limits. For +example, this is very likely if you use NFS to mount some of the file +systems from other machines. + +@pindex limits.h +Each of the following macros is defined in @file{limits.h} only if the +system has a fixed, uniform limit for the parameter in question. If the +system allows different file systems or files to have different limits, +then the macro is undefined; use @code{pathconf} or @code{fpathconf} to +find out the limit that applies to a particular file. @xref{Pathconf}. + +Each parameter also has another macro, with a name starting with +@samp{_POSIX}, which gives the lowest value that the limit is allowed to +have on @emph{any} POSIX system. @xref{File Minimums}. + +@cindex limits, link count of files +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int LINK_MAX +The uniform system limit (if any) for the number of names for a given +file. @xref{Hard Links}. +@end deftypevr + +@cindex limits, terminal input queue +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int MAX_CANON +The uniform system limit (if any) for the amount of text in a line of +input when input editing is enabled. @xref{Canonical or Not}. +@end deftypevr + +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int MAX_INPUT +The uniform system limit (if any) for the total number of characters +typed ahead as input. @xref{I/O Queues}. +@end deftypevr + +@cindex limits, file name length +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int NAME_MAX +The uniform system limit (if any) for the length of a file name component. +@end deftypevr + +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int PATH_MAX +The uniform system limit (if any) for the length of an entire file name (that +is, the argument given to system calls such as @code{open}). +@end deftypevr + +@cindex limits, pipe buffer size +@comment limits.h +@comment POSIX.1 +@deftypevr Macro int PIPE_BUF +The uniform system limit (if any) for the number of bytes that can be +written atomically to a pipe. If multiple processes are writing to the +same pipe simultaneously, output from different processes might be +interleaved in chunks of this size. @xref{Pipes and FIFOs}. +@end deftypevr + +These are alternative macro names for some of the same information. + +@comment dirent.h +@comment BSD +@deftypevr Macro int MAXNAMLEN +This is the BSD name for @code{NAME_MAX}. It is defined in +@file{dirent.h}. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int FILENAME_MAX +The value of this macro is an integer constant expression that +represents the maximum length of a file name string. It is defined in +@file{stdio.h}. + +Unlike @code{PATH_MAX}, this macro is defined even if there is no actual +limit imposed. In such a case, its value is typically a very large +number. @strong{This is always the case on the GNU system.} + +@strong{Usage Note:} Don't use @code{FILENAME_MAX} as the size of an +array in which to store a file name! You can't possibly make an array +that big! Use dynamic allocation (@pxref{Memory Allocation}) instead. +@end deftypevr + +@node Options for Files +@section Optional Features in File Support + +POSIX defines certain system-specific options in the system calls for +operating on files. Some systems support these options and others do +not. Since these options are provided in the kernel, not in the +library, simply using the GNU C library does not guarantee any of these +features is supported; it depends on the system you are using. They can +also vary between file systems on a single machine. + +@pindex unistd.h +This section describes the macros you can test to determine whether a +particular option is supported on your machine. If a given macro is +defined in @file{unistd.h}, then its value says whether the +corresponding feature is supported. (A value of @code{-1} indicates no; +any other value indicates yes.) If the macro is undefined, it means +particular files may or may not support the feature. + +Since all the machines that support the GNU C library also support NFS, +one can never make a general statement about whether all file systems +support the @code{_POSIX_CHOWN_RESTRICTED} and @code{_POSIX_NO_TRUNC} +features. So these names are never defined as macros in the GNU C +library. + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int _POSIX_CHOWN_RESTRICTED +If this option is in effect, the @code{chown} function is restricted so +that the only changes permitted to nonprivileged processes is to change +the group owner of a file to either be the effective group ID of the +process, or one of its supplementary group IDs. @xref{File Owner}. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int _POSIX_NO_TRUNC +If this option is in effect, file name components longer than +@code{NAME_MAX} generate an @code{ENAMETOOLONG} error. Otherwise, file +name components that are too long are silently truncated. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro {unsigned char} _POSIX_VDISABLE +This option is only meaningful for files that are terminal devices. +If it is enabled, then handling for special control characters can +be disabled individually. @xref{Special Characters}. +@end deftypevr + +@pindex unistd.h +If one of these macros is undefined, that means that the option might be +in effect for some files and not for others. To inquire about a +particular file, call @code{pathconf} or @code{fpathconf}. +@xref{Pathconf}. + +@node File Minimums +@section Minimum Values for File System Limits + +Here are the names for the POSIX minimum upper bounds for some of the +above parameters. The significance of these values is that you can +safely push to these limits without checking whether the particular +system you are using can go that far. + +@table @code +@comment limits.h +@comment POSIX.1 +@item _POSIX_LINK_MAX +The most restrictive limit permitted by POSIX for the maximum value of a +file's link count. The value of this constant is @code{8}; thus, you +can always make up to eight names for a file without running into a +system limit. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_MAX_CANON +The most restrictive limit permitted by POSIX for the maximum number of +bytes in a canonical input line from a terminal device. The value of +this constant is @code{255}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_MAX_INPUT +The most restrictive limit permitted by POSIX for the maximum number of +bytes in a terminal device input queue (or typeahead buffer). +@xref{Input Modes}. The value of this constant is @code{255}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_NAME_MAX +The most restrictive limit permitted by POSIX for the maximum number of +bytes in a file name component. The value of this constant is +@code{14}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_PATH_MAX +The most restrictive limit permitted by POSIX for the maximum number of +bytes in a file name. The value of this constant is @code{255}. + +@comment limits.h +@comment POSIX.1 +@item _POSIX_PIPE_BUF +The most restrictive limit permitted by POSIX for the maximum number of +bytes that can be written atomically to a pipe. The value of this +constant is @code{512}. +@end table + +@node Pathconf +@section Using @code{pathconf} + +When your machine allows different files to have different values for a +file system parameter, you can use the functions in this section to find +out the value that applies to any particular file. + +These functions and the associated constants for the @var{parameter} +argument are declared in the header file @file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun {long int} pathconf (const char *@var{filename}, int @var{parameter}) +This function is used to inquire about the limits that apply to +the file named @var{filename}. + +The @var{parameter} argument should be one of the @samp{_PC_} constants +listed below. + +The normal return value from @code{pathconf} is the value you requested. +A value of @code{-1} is returned both if the implementation does not +impose a limit, and in case of an error. In the former case, +@code{errno} is not set, while in the latter case, @code{errno} is set +to indicate the cause of the problem. So the only way to use this +function robustly is to store @code{0} into @code{errno} just before +calling it. + +Besides the usual file name errors (@pxref{File Name Errors}), +the following error condition is defined for this function: + +@table @code +@item EINVAL +The value of @var{parameter} is invalid, or the implementation doesn't +support the @var{parameter} for the specific file. +@end table +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun {long int} fpathconf (int @var{filedes}, int @var{parameter}) +This is just like @code{pathconf} except that an open file descriptor +is used to specify the file for which information is requested, instead +of a file name. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINVAL +The value of @var{parameter} is invalid, or the implementation doesn't +support the @var{parameter} for the specific file. +@end table +@end deftypefun + +Here are the symbolic constants that you can use as the @var{parameter} +argument to @code{pathconf} and @code{fpathconf}. The values are all +integer constants. + +@table @code +@comment unistd.h +@comment POSIX.1 +@item _PC_LINK_MAX +Inquire about the value of @code{LINK_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_MAX_CANON +Inquire about the value of @code{MAX_CANON}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_MAX_INPUT +Inquire about the value of @code{MAX_INPUT}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_NAME_MAX +Inquire about the value of @code{NAME_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_PATH_MAX +Inquire about the value of @code{PATH_MAX}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_PIPE_BUF +Inquire about the value of @code{PIPE_BUF}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_CHOWN_RESTRICTED +Inquire about the value of @code{_POSIX_CHOWN_RESTRICTED}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_NO_TRUNC +Inquire about the value of @code{_POSIX_NO_TRUNC}. + +@comment unistd.h +@comment POSIX.1 +@item _PC_VDISABLE +Inquire about the value of @code{_POSIX_VDISABLE}. +@end table + +@node Utility Limits +@section Utility Program Capacity Limits + +The POSIX.2 standard specifies certain system limits that you can access +through @code{sysconf} that apply to utility behavior rather than the +behavior of the library or the operating system. + +The GNU C library defines macros for these limits, and @code{sysconf} +returns values for them if you ask; but these values convey no +meaningful information. They are simply the smallest values that +POSIX.2 permits. + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int BC_BASE_MAX +The largest value of @code{obase} that the @code{bc} utility is +guaranteed to support. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int BC_SCALE_MAX +The largest value of @code{scale} that the @code{bc} utility is +guaranteed to support. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int BC_DIM_MAX +The largest number of elements in one array that the @code{bc} utility +is guaranteed to support. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int BC_STRING_MAX +The largest number of characters in one string constant that the +@code{bc} utility is guaranteed to support. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int BC_DIM_MAX +The largest number of elements in one array that the @code{bc} utility +is guaranteed to support. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int COLL_WEIGHTS_MAX +The largest number of weights that can necessarily be used in defining +the collating sequence for a locale. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int EXPR_NEST_MAX +The maximum number of expressions that can be nested within parenthesis +by the @code{expr} utility. +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int LINE_MAX +The largest text line that the text-oriented POSIX.2 utilities can +support. (If you are using the GNU versions of these utilities, then +there is no actual limit except that imposed by the available virtual +memory, but there is no way that the library can tell you this.) +@end deftypevr + +@comment limits.h +@comment POSIX.2 +@deftypevr Macro int EQUIV_CLASS_MAX +The maximum number of weights that can be assigned to an entry of the +@code{LC_COLLATE} category @samp{order} keyword in a locale definition. +The GNU C library does not presently support locale definitions. +@end deftypevr + +@node Utility Minimums +@section Minimum Values for Utility Limits + +@table @code +@comment limits.h +@comment POSIX.2 +@item _POSIX2_BC_BASE_MAX +The most restrictive limit permitted by POSIX.2 for the maximum value of +@code{obase} in the @code{bc} utility. Its value is @code{99}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_BC_DIM_MAX +The most restrictive limit permitted by POSIX.2 for the maximum size of +an array in the @code{bc} utility. Its value is @code{2048}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_BC_SCALE_MAX +The most restrictive limit permitted by POSIX.2 for the maximum value of +@code{scale} in the @code{bc} utility. Its value is @code{99}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_BC_STRING_MAX +The most restrictive limit permitted by POSIX.2 for the maximum size of +a string constant in the @code{bc} utility. Its value is @code{1000}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_COLL_WEIGHTS_MAX +The most restrictive limit permitted by POSIX.2 for the maximum number +of weights that can necessarily be used in defining the collating +sequence for a locale. Its value is @code{2}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_EXPR_NEST_MAX +The most restrictive limit permitted by POSIX.2 for the maximum number +of expressions nested within parenthesis when using the @code{expr} utility. +Its value is @code{32}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_LINE_MAX +The most restrictive limit permitted by POSIX.2 for the maximum size of +a text line that the text utilities can handle. Its value is +@code{2048}. + +@comment limits.h +@comment POSIX.2 +@item _POSIX2_EQUIV_CLASS_MAX +The most restrictive limit permitted by POSIX.2 for the maximum number +of weights that can be assigned to an entry of the @code{LC_COLLATE} +category @samp{order} keyword in a locale definition. Its value is +@code{2}. The GNU C library does not presently support locale +definitions. +@end table + +@node String Parameters +@section String-Valued Parameters + +POSIX.2 defines a way to get string-valued parameters from the operating +system with the function @code{confstr}: + +@comment unistd.h +@comment POSIX.2 +@deftypefun size_t confstr (int @var{parameter}, char *@var{buf}, size_t @var{len}) +This function reads the value of a string-valued system parameter, +storing the string into @var{len} bytes of memory space starting at +@var{buf}. The @var{parameter} argument should be one of the +@samp{_CS_} symbols listed below. + +The normal return value from @code{confstr} is the length of the string +value that you asked for. If you supply a null pointer for @var{buf}, +then @code{confstr} does not try to store the string; it just returns +its length. A value of @code{0} indicates an error. + +If the string you asked for is too long for the buffer (that is, longer +than @code{@var{len} - 1}), then @code{confstr} stores just that much +(leaving room for the terminating null character). You can tell that +this has happened because @code{confstr} returns a value greater than or +equal to @var{len}. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The value of the @var{parameter} is invalid. +@end table +@end deftypefun + +Currently there is just one parameter you can read with @code{confstr}: + +@table @code +@comment unistd.h +@comment POSIX.2 +@item _CS_PATH +This parameter's value is the recommended default path for searching for +executable files. This is the path that a user has by default just +after logging in. +@end table + +The way to use @code{confstr} without any arbitrary limit on string size +is to call it twice: first call it to get the length, allocate the +buffer accordingly, and then call @code{confstr} again to fill the +buffer, like this: + +@smallexample +@group +char * +get_default_path (void) +@{ + size_t len = confstr (_CS_PATH, NULL, 0); + char *buffer = (char *) xmalloc (len); + + if (confstr (_CS_PATH, buf, len + 1) == 0) + @{ + free (buffer); + return NULL; + @} + + return buffer; +@} +@end group +@end smallexample diff --git a/manual/creature.texi b/manual/creature.texi new file mode 100644 index 0000000000..51bf53a0c2 --- /dev/null +++ b/manual/creature.texi @@ -0,0 +1,113 @@ +@node Feature Test Macros +@subsection Feature Test Macros + +@cindex feature test macros +The exact set of features available when you compile a source file +is controlled by which @dfn{feature test macros} you define. + +If you compile your programs using @samp{gcc -ansi}, you get only the +ANSI C library features, unless you explicitly request additional +features by defining one or more of the feature macros. +@xref{Invoking GCC,, GNU CC Command Options, gcc.info, The GNU CC Manual}, +for more information about GCC options.@refill + +You should define these macros by using @samp{#define} preprocessor +directives at the top of your source code files. These directives +@emph{must} come before any @code{#include} of a system header file. It +is best to make them the very first thing in the file, preceded only by +comments. You could also use the @samp{-D} option to GCC, but it's +better if you make the source files indicate their own meaning in a +self-contained way. + +@comment (none) +@comment POSIX.1 +@defvr Macro _POSIX_SOURCE +If you define this macro, then the functionality from the POSIX.1 +standard (IEEE Standard 1003.1) is available, as well as all of the +ANSI C facilities. +@end defvr + +@comment (none) +@comment POSIX.2 +@defvr Macro _POSIX_C_SOURCE +If you define this macro with a value of @code{1}, then the +functionality from the POSIX.1 standard (IEEE Standard 1003.1) is made +available. If you define this macro with a value of @code{2}, then both +the functionality from the POSIX.1 standard and the functionality from +the POSIX.2 standard (IEEE Standard 1003.2) are made available. This is +in addition to the ANSI C facilities. +@end defvr + +@comment (none) +@comment GNU +@defvr Macro _BSD_SOURCE +If you define this macro, functionality derived from 4.3 BSD Unix is +included as well as the ANSI C, POSIX.1, and POSIX.2 material. + +Some of the features derived from 4.3 BSD Unix conflict with the +corresponding features specified by the POSIX.1 standard. If this +macro is defined, the 4.3 BSD definitions take precedence over the +POSIX definitions. + +Due to the nature of some of the conflicts between 4.3 BSD and POSIX.1, +you need to use a special @dfn{BSD compatibility library} when linking +programs compiled for BSD compatibility. This is because some functions +must be defined in two different ways, one of them in the normal C +library, and one of them in the compatibility library. If your program +defines @code{_BSD_SOURCE}, you must give the option @samp{-lbsd-compat} +to the compiler or linker when linking the program, to tell it to find +functions in this special compatibility library before looking for them in +the normal C library. +@pindex -lbsd-compat +@pindex bsd-compat +@cindex BSD compatibility library. +@end defvr + +@comment (none) +@comment GNU +@defvr Macro _SVID_SOURCE +If you define this macro, functionality derived from SVID is +included as well as the ANSI C, POSIX.1, and POSIX.2 material. +@end defvr + +@comment (none) +@comment GNU +@defvr Macro _GNU_SOURCE +If you define this macro, everything is included: ANSI C, POSIX.1, +POSIX.2, BSD, SVID, and GNU extensions. In the cases where POSIX.1 +conflicts with BSD, the POSIX definitions take precedence. + +If you want to get the full effect of @code{_GNU_SOURCE} but make the +BSD definitions take precedence over the POSIX definitions, use this +sequence of definitions: + +@smallexample +#define _GNU_SOURCE +#define _BSD_SOURCE +#define _SVID_SOURCE +@end smallexample + +Note that if you do this, you must link your program with the BSD +compatibility library by passing the @samp{-lbsd-compat} option to the +compiler or linker. @strong{Note:} If you forget to do this, you may +get very strange errors at run time. +@end defvr + +We recommend you use @code{_GNU_SOURCE} in new programs. If you don't +specify the @samp{-ansi} option to GCC and don't define any of these macros +explicitly, the effect is the same as defining @code{_GNU_SOURCE}. + +When you define a feature test macro to request a larger class of features, +it is harmless to define in addition a feature test macro for a subset of +those features. For example, if you define @code{_POSIX_C_SOURCE}, then +defining @code{_POSIX_SOURCE} as well has no effect. Likewise, if you +define @code{_GNU_SOURCE}, then defining either @code{_POSIX_SOURCE} or +@code{_POSIX_C_SOURCE} or @code{_SVID_SOURCE} as well has no effect. + +Note, however, that the features of @code{_BSD_SOURCE} are not a subset of +any of the other feature test macros supported. This is because it defines +BSD features that take precedence over the POSIX features that are +requested by the other macros. For this reason, defining +@code{_BSD_SOURCE} in addition to the other feature test macros does have +an effect: it causes the BSD features to take priority over the conflicting +POSIX features. diff --git a/manual/ctype.texi b/manual/ctype.texi new file mode 100644 index 0000000000..e7a7946466 --- /dev/null +++ b/manual/ctype.texi @@ -0,0 +1,250 @@ +@node Character Handling, String and Array Utilities, Memory Allocation, Top +@chapter Character Handling + +Programs that work with characters and strings often need to classify a +character---is it alphabetic, is it a digit, is it whitespace, and so +on---and perform case conversion operations on characters. The +functions in the header file @file{ctype.h} are provided for this +purpose. +@pindex ctype.h + +Since the choice of locale and character set can alter the +classifications of particular character codes, all of these functions +are affected by the current locale. (More precisely, they are affected +by the locale currently selected for character classification---the +@code{LC_CTYPE} category; see @ref{Locale Categories}.) + +@menu +* Classification of Characters:: Testing whether characters are + letters, digits, punctuation, etc. + +* Case Conversion:: Case mapping, and the like. +@end menu + +@node Classification of Characters, Case Conversion, , Character Handling +@section Classification of Characters +@cindex character testing +@cindex classification of characters +@cindex predicates on characters +@cindex character predicates + +This section explains the library functions for classifying characters. +For example, @code{isalpha} is the function to test for an alphabetic +character. It takes one argument, the character to test, and returns a +nonzero integer if the character is alphabetic, and zero otherwise. You +would use it like this: + +@smallexample +if (isalpha (c)) + printf ("The character `%c' is alphabetic.\n", c); +@end smallexample + +Each of the functions in this section tests for membership in a +particular class of characters; each has a name starting with @samp{is}. +Each of them takes one argument, which is a character to test, and +returns an @code{int} which is treated as a boolean value. The +character argument is passed as an @code{int}, and it may be the +constant value @code{EOF} instead of a real character. + +The attributes of any given character can vary between locales. +@xref{Locales}, for more information on locales.@refill + +These functions are declared in the header file @file{ctype.h}. +@pindex ctype.h + +@cindex lower-case character +@comment ctype.h +@comment ANSI +@deftypefun int islower (int @var{c}) +Returns true if @var{c} is a lower-case letter. +@end deftypefun + +@cindex upper-case character +@comment ctype.h +@comment ANSI +@deftypefun int isupper (int @var{c}) +Returns true if @var{c} is an upper-case letter. +@end deftypefun + +@cindex alphabetic character +@comment ctype.h +@comment ANSI +@deftypefun int isalpha (int @var{c}) +Returns true if @var{c} is an alphabetic character (a letter). If +@code{islower} or @code{isupper} is true of a character, then +@code{isalpha} is also true. + +In some locales, there may be additional characters for which +@code{isalpha} is true--letters which are neither upper case nor lower +case. But in the standard @code{"C"} locale, there are no such +additional characters. +@end deftypefun + +@cindex digit character +@cindex decimal digit character +@comment ctype.h +@comment ANSI +@deftypefun int isdigit (int @var{c}) +Returns true if @var{c} is a decimal digit (@samp{0} through @samp{9}). +@end deftypefun + +@cindex alphanumeric character +@comment ctype.h +@comment ANSI +@deftypefun int isalnum (int @var{c}) +Returns true if @var{c} is an alphanumeric character (a letter or +number); in other words, if either @code{isalpha} or @code{isdigit} is +true of a character, then @code{isalnum} is also true. +@end deftypefun + +@cindex hexadecimal digit character +@comment ctype.h +@comment ANSI +@deftypefun int isxdigit (int @var{c}) +Returns true if @var{c} is a hexadecimal digit. +Hexadecimal digits include the normal decimal digits @samp{0} through +@samp{9} and the letters @samp{A} through @samp{F} and +@samp{a} through @samp{f}. +@end deftypefun + +@cindex punctuation character +@comment ctype.h +@comment ANSI +@deftypefun int ispunct (int @var{c}) +Returns true if @var{c} is a punctuation character. +This means any printing character that is not alphanumeric or a space +character. +@end deftypefun + +@cindex whitespace character +@comment ctype.h +@comment ANSI +@deftypefun int isspace (int @var{c}) +Returns true if @var{c} is a @dfn{whitespace} character. In the standard +@code{"C"} locale, @code{isspace} returns true for only the standard +whitespace characters: + +@table @code +@item ' ' +space + +@item '\f' +formfeed + +@item '\n' +newline + +@item '\r' +carriage return + +@item '\t' +horizontal tab + +@item '\v' +vertical tab +@end table +@end deftypefun + +@cindex blank character +@comment ctype.h +@comment GNU +@deftypefun int isblank (int @var{c}) +Returns true if @var{c} is a blank character; that is, a space or a tab. +This function is a GNU extension. +@end deftypefun + +@cindex graphic character +@comment ctype.h +@comment ANSI +@deftypefun int isgraph (int @var{c}) +Returns true if @var{c} is a graphic character; that is, a character +that has a glyph associated with it. The whitespace characters are not +considered graphic. +@end deftypefun + +@cindex printing character +@comment ctype.h +@comment ANSI +@deftypefun int isprint (int @var{c}) +Returns true if @var{c} is a printing character. Printing characters +include all the graphic characters, plus the space (@samp{ }) character. +@end deftypefun + +@cindex control character +@comment ctype.h +@comment ANSI +@deftypefun int iscntrl (int @var{c}) +Returns true if @var{c} is a control character (that is, a character that +is not a printing character). +@end deftypefun + +@cindex ASCII character +@comment ctype.h +@comment SVID, BSD +@deftypefun int isascii (int @var{c}) +Returns true if @var{c} is a 7-bit @code{unsigned char} value that fits +into the US/UK ASCII character set. This function is a BSD extension +and is also an SVID extension. +@end deftypefun + +@node Case Conversion, , Classification of Characters, Character Handling +@section Case Conversion +@cindex character case conversion +@cindex case conversion of characters +@cindex converting case of characters + +This section explains the library functions for performing conversions +such as case mappings on characters. For example, @code{toupper} +converts any character to upper case if possible. If the character +can't be converted, @code{toupper} returns it unchanged. + +These functions take one argument of type @code{int}, which is the +character to convert, and return the converted character as an +@code{int}. If the conversion is not applicable to the argument given, +the argument is returned unchanged. + +@strong{Compatibility Note:} In pre-ANSI C dialects, instead of +returning the argument unchanged, these functions may fail when the +argument is not suitable for the conversion. Thus for portability, you +may need to write @code{islower(c) ? toupper(c) : c} rather than just +@code{toupper(c)}. + +These functions are declared in the header file @file{ctype.h}. +@pindex ctype.h + +@comment ctype.h +@comment ANSI +@deftypefun int tolower (int @var{c}) +If @var{c} is an upper-case letter, @code{tolower} returns the corresponding +lower-case letter. If @var{c} is not an upper-case letter, +@var{c} is returned unchanged. +@end deftypefun + +@comment ctype.h +@comment ANSI +@deftypefun int toupper (int @var{c}) +If @var{c} is a lower-case letter, @code{tolower} returns the corresponding +upper-case letter. Otherwise @var{c} is returned unchanged. +@end deftypefun + +@comment ctype.h +@comment SVID, BSD +@deftypefun int toascii (int @var{c}) +This function converts @var{c} to a 7-bit @code{unsigned char} value +that fits into the US/UK ASCII character set, by clearing the high-order +bits. This function is a BSD extension and is also an SVID extension. +@end deftypefun + +@comment ctype.h +@comment SVID +@deftypefun int _tolower (int @var{c}) +This is identical to @code{tolower}, and is provided for compatibility +with the SVID. @xref{SVID}.@refill +@end deftypefun + +@comment ctype.h +@comment SVID +@deftypefun int _toupper (int @var{c}) +This is identical to @code{toupper}, and is provided for compatibility +with the SVID. +@end deftypefun diff --git a/manual/errno.texi b/manual/errno.texi new file mode 100644 index 0000000000..836fff3bf2 --- /dev/null +++ b/manual/errno.texi @@ -0,0 +1,1015 @@ +@node Error Reporting, Memory Allocation, Introduction, Top +@chapter Error Reporting +@cindex error reporting +@cindex reporting errors +@cindex error codes +@cindex status codes + +Many functions in the GNU C library detect and report error conditions, +and sometimes your programs need to check for these error conditions. +For example, when you open an input file, you should verify that the +file was actually opened correctly, and print an error message or take +other appropriate action if the call to the library function failed. + +This chapter describes how the error reporting facility works. Your +program should include the header file @file{errno.h} to use this +facility. +@pindex errno.h + +@menu +* Checking for Errors:: How errors are reported by library functions. +* Error Codes:: Error code macros; all of these expand + into integer constant values. +* Error Messages:: Mapping error codes onto error messages. +@end menu + +@node Checking for Errors, Error Codes, , Error Reporting +@section Checking for Errors + +Most library functions return a special value to indicate that they have +failed. The special value is typically @code{-1}, a null pointer, or a +constant such as @code{EOF} that is defined for that purpose. But this +return value tells you only that an error has occurred. To find out +what kind of error it was, you need to look at the error code stored in the +variable @code{errno}. This variable is declared in the header file +@file{errno.h}. +@pindex errno.h + +@comment errno.h +@comment ANSI +@deftypevr {Variable} {volatile int} errno +The variable @code{errno} contains the system error number. You can +change the value of @code{errno}. + +Since @code{errno} is declared @code{volatile}, it might be changed +asynchronously by a signal handler; see @ref{Defining Handlers}. +However, a properly written signal handler saves and restores the value +of @code{errno}, so you generally do not need to worry about this +possibility except when writing signal handlers. + +The initial value of @code{errno} at program startup is zero. Many +library functions are guaranteed to set it to certain nonzero values +when they encounter certain kinds of errors. These error conditions are +listed for each function. These functions do not change @code{errno} +when they succeed; thus, the value of @code{errno} after a successful +call is not necessarily zero, and you should not use @code{errno} to +determine @emph{whether} a call failed. The proper way to do that is +documented for each function. @emph{If} the call the failed, you can +examine @code{errno}. + +Many library functions can set @code{errno} to a nonzero value as a +result of calling other library functions which might fail. You should +assume that any library function might alter @code{errno} when the +function returns an error. + +@strong{Portability Note:} ANSI C specifies @code{errno} as a +``modifiable lvalue'' rather than as a variable, permitting it to be +implemented as a macro. For example, its expansion might involve a +function call, like @w{@code{*_errno ()}}. In fact, that is what it is +on the GNU system itself. The GNU library, on non-GNU systems, does +whatever is right for the particular system. + +There are a few library functions, like @code{sqrt} and @code{atan}, +that return a perfectly legitimate value in case of an error, but also +set @code{errno}. For these functions, if you want to check to see +whether an error occurred, the recommended method is to set @code{errno} +to zero before calling the function, and then check its value afterward. +@end deftypevr + +@pindex errno.h +All the error codes have symbolic names; they are macros defined in +@file{errno.h}. The names start with @samp{E} and an upper-case +letter or digit; you should consider names of this form to be +reserved names. @xref{Reserved Names}. + +The error code values are all positive integers and are all distinct, +with one exception: @code{EWOULDBLOCK} and @code{EAGAIN} are the same. +Since the values are distinct, you can use them as labels in a +@code{switch} statement; just don't use both @code{EWOULDBLOCK} and +@code{EAGAIN}. Your program should not make any other assumptions about +the specific values of these symbolic constants. + +The value of @code{errno} doesn't necessarily have to correspond to any +of these macros, since some library functions might return other error +codes of their own for other situations. The only values that are +guaranteed to be meaningful for a particular library function are the +ones that this manual lists for that function. + +On non-GNU systems, almost any system call can return @code{EFAULT} if +it is given an invalid pointer as an argument. Since this could only +happen as a result of a bug in your program, and since it will not +happen on the GNU system, we have saved space by not mentioning +@code{EFAULT} in the descriptions of individual functions. + +In some Unix systems, many system calls can also return @code{EFAULT} if +given as an argument a pointer into the stack, and the kernel for some +obscure reason fails in its attempt to extend the stack. If this ever +happens, you should probably try using statically or dynamically +allocated memory instead of stack memory on that system. + +@node Error Codes, Error Messages, Checking for Errors, Error Reporting +@section Error Codes + +@pindex errno.h +The error code macros are defined in the header file @file{errno.h}. +All of them expand into integer constant values. Some of these error +codes can't occur on the GNU system, but they can occur using the GNU +library on other systems. + +@comment errno.h +@comment POSIX.1: Operation not permitted +@deftypevr Macro int EPERM +@comment errno 1 @c DO NOT REMOVE +Operation not permitted; only the owner of the file (or other resource) +or processes with special privileges can perform the operation. +@end deftypevr + +@comment errno.h +@comment POSIX.1: No such file or directory +@deftypevr Macro int ENOENT +@comment errno 2 @c DO NOT REMOVE +No such file or directory. This is a ``file doesn't exist'' error +for ordinary files that are referenced in contexts where they are +expected to already exist. +@end deftypevr + +@comment errno.h +@comment POSIX.1: No such process +@deftypevr Macro int ESRCH +@comment errno 3 @c DO NOT REMOVE +No process matches the specified process ID. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Interrupted system call +@deftypevr Macro int EINTR +@comment errno 4 @c DO NOT REMOVE +Interrupted function call; an asynchronous signal occured and prevented +completion of the call. When this happens, you should try the call +again. + +You can choose to have functions resume after a signal that is handled, +rather than failing with @code{EINTR}; see @ref{Interrupted +Primitives}. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Input/output error +@deftypevr Macro int EIO +@comment errno 5 @c DO NOT REMOVE +Input/output error; usually used for physical read or write errors. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Device not configured +@deftypevr Macro int ENXIO +@comment errno 6 @c DO NOT REMOVE +No such device or address. The system tried to use the device +represented by a file you specified, and it couldn't find the device. +This can mean that the device file was installed incorrectly, or that +the physical device is missing or not correctly attached to the +computer. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Argument list too long +@deftypevr Macro int E2BIG +@comment errno 7 @c DO NOT REMOVE +Argument list too long; used when the arguments passed to a new program +being executed with one of the @code{exec} functions (@pxref{Executing a +File}) occupy too much memory space. This condition never arises in the +GNU system. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Exec format error +@deftypevr Macro int ENOEXEC +@comment errno 8 @c DO NOT REMOVE +Invalid executable file format. This condition is detected by the +@code{exec} functions; see @ref{Executing a File}. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Bad file descriptor +@deftypevr Macro int EBADF +@comment errno 9 @c DO NOT REMOVE +Bad file descriptor; for example, I/O on a descriptor that has been +closed or reading from a descriptor open only for writing (or vice +versa). +@end deftypevr + +@comment errno.h +@comment POSIX.1: No child processes +@deftypevr Macro int ECHILD +@comment errno 10 @c DO NOT REMOVE +There are no child processes. This error happens on operations that are +supposed to manipulate child processes, when there aren't any processes +to manipulate. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Resource deadlock avoided +@deftypevr Macro int EDEADLK +@comment errno 11 @c DO NOT REMOVE +Deadlock avoided; allocating a system resource would have resulted in a +deadlock situation. The system does not guarantee that it will notice +all such situations. This error means you got lucky and the system +noticed; it might just hang. @xref{File Locks}, for an example. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Cannot allocate memory +@deftypevr Macro int ENOMEM +@comment errno 12 @c DO NOT REMOVE +No memory available. The system cannot allocate more virtual memory +because its capacity is full. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Permission denied +@deftypevr Macro int EACCES +@comment errno 13 @c DO NOT REMOVE +Permission denied; the file permissions do not allow the attempted operation. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Bad address +@deftypevr Macro int EFAULT +@comment errno 14 @c DO NOT REMOVE +Bad address; an invalid pointer was detected. +In the GNU system, this error never happens; you get a signal instead. +@end deftypevr + +@comment errno.h +@comment BSD: Block device required +@deftypevr Macro int ENOTBLK +@comment errno 15 @c DO NOT REMOVE +A file that isn't a block special file was given in a situation that +requires one. For example, trying to mount an ordinary file as a file +system in Unix gives this error. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Device busy +@deftypevr Macro int EBUSY +@comment errno 16 @c DO NOT REMOVE +Resource busy; a system resource that can't be shared is already in use. +For example, if you try to delete a file that is the root of a currently +mounted filesystem, you get this error. +@end deftypevr + +@comment errno.h +@comment POSIX.1: File exists +@deftypevr Macro int EEXIST +@comment errno 17 @c DO NOT REMOVE +File exists; an existing file was specified in a context where it only +makes sense to specify a new file. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Invalid cross-device link +@deftypevr Macro int EXDEV +@comment errno 18 @c DO NOT REMOVE +An attempt to make an improper link across file systems was detected. +This happens not only when you use @code{link} (@pxref{Hard Links}) but +also when you rename a file with @code{rename} (@pxref{Renaming Files}). +@end deftypevr + +@comment errno.h +@comment POSIX.1: Operation not supported by device +@deftypevr Macro int ENODEV +@comment errno 19 @c DO NOT REMOVE +The wrong type of device was given to a function that expects a +particular sort of device. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Not a directory +@deftypevr Macro int ENOTDIR +@comment errno 20 @c DO NOT REMOVE +A file that isn't a directory was specified when a directory is required. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Is a directory +@deftypevr Macro int EISDIR +@comment errno 21 @c DO NOT REMOVE +File is a directory; you cannot open a directory for writing, +or create or remove hard links to it. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Invalid argument +@deftypevr Macro int EINVAL +@comment errno 22 @c DO NOT REMOVE +Invalid argument. This is used to indicate various kinds of problems +with passing the wrong argument to a library function. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Too many open files +@deftypevr Macro int EMFILE +@comment errno 24 @c DO NOT REMOVE +The current process has too many files open and can't open any more. +Duplicate descriptors do count toward this limit. + +In BSD and GNU, the number of open files is controlled by a resource +limit that can usually be increased. If you get this error, you might +want to increase the @code{RLIMIT_NOFILE} limit or make it unlimited; +@pxref{Limits on Resources}. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Too many open files in system +@deftypevr Macro int ENFILE +@comment errno 23 @c DO NOT REMOVE +There are too many distinct file openings in the entire system. Note +that any number of linked channels count as just one file opening; see +@ref{Linked Channels}. This error never occurs in the GNU system. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Inappropriate ioctl for device +@deftypevr Macro int ENOTTY +@comment errno 25 @c DO NOT REMOVE +Inappropriate I/O control operation, such as trying to set terminal +modes on an ordinary file. +@end deftypevr + +@comment errno.h +@comment BSD: Text file busy +@deftypevr Macro int ETXTBSY +@comment errno 26 @c DO NOT REMOVE +An attempt to execute a file that is currently open for writing, or +write to a file that is currently being executed. Often using a +debugger to run a program is considered having it open for writing and +will cause this error. (The name stands for ``text file busy''.) This +is not an error in the GNU system; the text is copied as necessary. +@end deftypevr + +@comment errno.h +@comment POSIX.1: File too large +@deftypevr Macro int EFBIG +@comment errno 27 @c DO NOT REMOVE +File too big; the size of a file would be larger than allowed by the system. +@end deftypevr + +@comment errno.h +@comment POSIX.1: No space left on device +@deftypevr Macro int ENOSPC +@comment errno 28 @c DO NOT REMOVE +No space left on device; write operation on a file failed because the +disk is full. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Illegal seek +@deftypevr Macro int ESPIPE +@comment errno 29 @c DO NOT REMOVE +Invalid seek operation (such as on a pipe). +@end deftypevr + +@comment errno.h +@comment POSIX.1: Read-only file system +@deftypevr Macro int EROFS +@comment errno 30 @c DO NOT REMOVE +An attempt was made to modify something on a read-only file system. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Too many links +@deftypevr Macro int EMLINK +@comment errno 31 @c DO NOT REMOVE +Too many links; the link count of a single file would become too large. +@code{rename} can cause this error if the file being renamed already has +as many links as it can take (@pxref{Renaming Files}). +@end deftypevr + +@comment errno.h +@comment POSIX.1: Broken pipe +@deftypevr Macro int EPIPE +@comment errno 32 @c DO NOT REMOVE +Broken pipe; there is no process reading from the other end of a pipe. +Every library function that returns this error code also generates a +@code{SIGPIPE} signal; this signal terminates the program if not handled +or blocked. Thus, your program will never actually see @code{EPIPE} +unless it has handled or blocked @code{SIGPIPE}. +@end deftypevr + +@comment errno.h +@comment ANSI: Numerical argument out of domain +@deftypevr Macro int EDOM +@comment errno 33 @c DO NOT REMOVE +Domain error; used by mathematical functions when an argument value does +not fall into the domain over which the function is defined. +@end deftypevr + +@comment errno.h +@comment ANSI: Numerical result out of range +@deftypevr Macro int ERANGE +@comment errno 34 @c DO NOT REMOVE +Range error; used by mathematical functions when the result value is +not representable because of overflow or underflow. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Resource temporarily unavailable +@deftypevr Macro int EAGAIN +@comment errno 35 @c DO NOT REMOVE +Resource temporarily unavailable; the call might work if you try again +later. The macro @code{EWOULDBLOCK} is another name for @code{EAGAIN}; +they are always the same in the GNU C library. + +This error can happen in a few different situations: + +@itemize @bullet +@item +An operation that would block was attempted on an object that has +non-blocking mode selected. Trying the same operation again will block +until some external condition makes it possible to read, write, or +connect (whatever the operation). You can use @code{select} to find out +when the operation will be possible; @pxref{Waiting for I/O}. + +@strong{Portability Note:} In older Unix many systems, this condition +was indicated by @code{EWOULDBLOCK}, which was a distinct error code +different from @code{EAGAIN}. To make your program portable, you should +check for both codes and treat them the same. + +@item +A temporary resource shortage made an operation impossible. @code{fork} +can return this error. It indicates that the shortage is expected to +pass, so your program can try the call again later and it may succeed. +It is probably a good idea to delay for a few seconds before trying it +again, to allow time for other processes to release scarce resources. +Such shortages are usually fairly serious and affect the whole system, +so usually an interactive program should report the error to the user +and return to its command loop. +@end itemize +@end deftypevr + +@comment errno.h +@comment BSD: Operation would block +@deftypevr Macro int EWOULDBLOCK +@comment errno EAGAIN @c DO NOT REMOVE +In the GNU C library, this is another name for @code{EAGAIN} (above). +The values are always the same, on every operating system. + +C libraries in many older Unix systems have @code{EWOULDBLOCK} as a +separate error code. +@end deftypevr + +@comment errno.h +@comment BSD: Operation now in progress +@deftypevr Macro int EINPROGRESS +@comment errno 36 @c DO NOT REMOVE +An operation that cannot complete immediately was initiated on an object +that has non-blocking mode selected. Some functions that must always +block (such as @code{connect}; @pxref{Connecting}) never return +@code{EAGAIN}. Instead, they return @code{EINPROGRESS} to indicate that +the operation has begun and will take some time. Attempts to manipulate +the object before the call completes return @code{EALREADY}. You can +use the @code{select} function to find out when the pending operation +has completed; @pxref{Waiting for I/O}. +@end deftypevr + +@comment errno.h +@comment BSD: Operation already in progress +@deftypevr Macro int EALREADY +@comment errno 37 @c DO NOT REMOVE +An operation is already in progress on an object that has non-blocking +mode selected. +@end deftypevr + +@comment errno.h +@comment BSD: Socket operation on non-socket +@deftypevr Macro int ENOTSOCK +@comment errno 38 @c DO NOT REMOVE +A file that isn't a socket was specified when a socket is required. +@end deftypevr + +@comment errno.h +@comment BSD: Message too long +@deftypevr Macro int EMSGSIZE +@comment errno 40 @c DO NOT REMOVE +The size of a message sent on a socket was larger than the supported +maximum size. +@end deftypevr + +@comment errno.h +@comment BSD: Protocol wrong type for socket +@deftypevr Macro int EPROTOTYPE +@comment errno 41 @c DO NOT REMOVE +The socket type does not support the requested communications protocol. +@end deftypevr + +@comment errno.h +@comment BSD: Protocol not available +@deftypevr Macro int ENOPROTOOPT +@comment errno 42 @c DO NOT REMOVE +You specified a socket option that doesn't make sense for the +particular protocol being used by the socket. @xref{Socket Options}. +@end deftypevr + +@comment errno.h +@comment BSD: Protocol not supported +@deftypevr Macro int EPROTONOSUPPORT +@comment errno 43 @c DO NOT REMOVE +The socket domain does not support the requested communications protocol +(perhaps because the requested protocol is completely invalid.) +@xref{Creating a Socket}. +@end deftypevr + +@comment errno.h +@comment BSD: Socket type not supported +@deftypevr Macro int ESOCKTNOSUPPORT +@comment errno 44 @c DO NOT REMOVE +The socket type is not supported. +@end deftypevr + +@comment errno.h +@comment BSD: Operation not supported +@deftypevr Macro int EOPNOTSUPP +@comment errno 45 @c DO NOT REMOVE +The operation you requested is not supported. Some socket functions +don't make sense for all types of sockets, and others may not be +implemented for all communications protocols. In the GNU system, this +error can happen for many calls when the object does not support the +particular operation; it is a generic indication that the server knows +nothing to do for that call. +@end deftypevr + +@comment errno.h +@comment BSD: Protocol family not supported +@deftypevr Macro int EPFNOSUPPORT +@comment errno 46 @c DO NOT REMOVE +The socket communications protocol family you requested is not supported. +@end deftypevr + +@comment errno.h +@comment BSD: Address family not supported by protocol family +@deftypevr Macro int EAFNOSUPPORT +@comment errno 47 @c DO NOT REMOVE +The address family specified for a socket is not supported; it is +inconsistent with the protocol being used on the socket. @xref{Sockets}. +@end deftypevr + +@comment errno.h +@comment BSD: Address already in use +@deftypevr Macro int EADDRINUSE +@comment errno 48 @c DO NOT REMOVE +The requested socket address is already in use. @xref{Socket Addresses}. +@end deftypevr + +@comment errno.h +@comment BSD: Can't assign requested address +@deftypevr Macro int EADDRNOTAVAIL +@comment errno 49 @c DO NOT REMOVE +The requested socket address is not available; for example, you tried +to give a socket a name that doesn't match the local host name. +@xref{Socket Addresses}. +@end deftypevr + +@comment errno.h +@comment BSD: Network is down +@deftypevr Macro int ENETDOWN +@comment errno 50 @c DO NOT REMOVE +A socket operation failed because the network was down. +@end deftypevr + +@comment errno.h +@comment BSD: Network is unreachable +@deftypevr Macro int ENETUNREACH +@comment errno 51 @c DO NOT REMOVE +A socket operation failed because the subnet containing the remote host +was unreachable. +@end deftypevr + +@comment errno.h +@comment BSD: Network dropped connection on reset +@deftypevr Macro int ENETRESET +@comment errno 52 @c DO NOT REMOVE +A network connection was reset because the remote host crashed. +@end deftypevr + +@comment errno.h +@comment BSD: Software caused connection abort +@deftypevr Macro int ECONNABORTED +@comment errno 53 @c DO NOT REMOVE +A network connection was aborted locally. +@end deftypevr + +@comment errno.h +@comment BSD: Connection reset by peer +@deftypevr Macro int ECONNRESET +@comment errno 54 @c DO NOT REMOVE +A network connection was closed for reasons outside the control of the +local host, such as by the remote machine rebooting or an unrecoverable +protocol violation. +@end deftypevr + +@comment errno.h +@comment BSD: No buffer space available +@deftypevr Macro int ENOBUFS +@comment errno 55 @c DO NOT REMOVE +The kernel's buffers for I/O operations are all in use. In GNU, this +error is always synonymous with @code{ENOMEM}; you may get one or the +other from network operations. +@end deftypevr + +@comment errno.h +@comment BSD: Socket is already connected +@deftypevr Macro int EISCONN +@comment errno 56 @c DO NOT REMOVE +You tried to connect a socket that is already connected. +@xref{Connecting}. +@end deftypevr + +@comment errno.h +@comment BSD: Socket is not connected +@deftypevr Macro int ENOTCONN +@comment errno 57 @c DO NOT REMOVE +The socket is not connected to anything. You get this error when you +try to transmit data over a socket, without first specifying a +destination for the data. For a connectionless socket (for datagram +protocols, such as UDP), you get @code{EDESTADDRREQ} instead. +@end deftypevr + +@comment errno.h +@comment BSD: Destination address required +@deftypevr Macro int EDESTADDRREQ +@comment errno 39 @c DO NOT REMOVE +No default destination address was set for the socket. You get this +error when you try to transmit data over a connectionless socket, +without first specifying a destination for the data with @code{connect}. +@end deftypevr + +@comment errno.h +@comment BSD: Can't send after socket shutdown +@deftypevr Macro int ESHUTDOWN +@comment errno 58 @c DO NOT REMOVE +The socket has already been shut down. +@end deftypevr + +@comment errno.h +@comment BSD: Too many references: can't splice +@deftypevr Macro int ETOOMANYREFS +@comment errno 59 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: Connection timed out +@deftypevr Macro int ETIMEDOUT +@comment errno 60 @c DO NOT REMOVE +A socket operation with a specified timeout received no response during +the timeout period. +@end deftypevr + +@comment errno.h +@comment BSD: Connection refused +@deftypevr Macro int ECONNREFUSED +@comment errno 61 @c DO NOT REMOVE +A remote host refused to allow the network connection (typically because +it is not running the requested service). +@end deftypevr + +@comment errno.h +@comment BSD: Too many levels of symbolic links +@deftypevr Macro int ELOOP +@comment errno 62 @c DO NOT REMOVE +Too many levels of symbolic links were encountered in looking up a file name. +This often indicates a cycle of symbolic links. +@end deftypevr + +@comment errno.h +@comment POSIX.1: File name too long +@deftypevr Macro int ENAMETOOLONG +@comment errno 63 @c DO NOT REMOVE +Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for +Files}) or host name too long (in @code{gethostname} or +@code{sethostname}; @pxref{Host Identification}). +@end deftypevr + +@comment errno.h +@comment BSD: Host is down +@deftypevr Macro int EHOSTDOWN +@comment errno 64 @c DO NOT REMOVE +The remote host for a requested network connection is down. +@end deftypevr + +@comment errno.h +@comment BSD: No route to host +@deftypevr Macro int EHOSTUNREACH +@comment errno 65 @c DO NOT REMOVE +The remote host for a requested network connection is not reachable. +@end deftypevr + +@comment errno.h +@comment POSIX.1: Directory not empty +@deftypevr Macro int ENOTEMPTY +@comment errno 66 @c DO NOT REMOVE +Directory not empty, where an empty directory was expected. Typically, +this error occurs when you are trying to delete a directory. +@end deftypevr + +@comment errno.h +@comment BSD: Too many processes +@deftypevr Macro int EPROCLIM +@comment errno 67 @c DO NOT REMOVE +This means that the per-user limit on new process would be exceeded by +an attempted @code{fork}. @xref{Limits on Resources}, for details on +the @code{RLIMIT_NPROC} limit. +@end deftypevr + +@comment errno.h +@comment BSD: Too many users +@deftypevr Macro int EUSERS +@comment errno 68 @c DO NOT REMOVE +The file quota system is confused because there are too many users. +@c This can probably happen in a GNU system when using NFS. +@end deftypevr + +@comment errno.h +@comment BSD: Disc quota exceeded +@deftypevr Macro int EDQUOT +@comment errno 69 @c DO NOT REMOVE +The user's disk quota was exceeded. +@end deftypevr + +@comment errno.h +@comment BSD: Stale NFS file handle +@deftypevr Macro int ESTALE +@comment errno 70 @c DO NOT REMOVE +Stale NFS file handle. This indicates an internal confusion in the NFS +system which is due to file system rearrangements on the server host. +Repairing this condition usually requires unmounting and remounting +the NFS file system on the local host. +@end deftypevr + +@comment errno.h +@comment BSD: Too many levels of remote in path +@deftypevr Macro int EREMOTE +@comment errno 71 @c DO NOT REMOVE +An attempt was made to NFS-mount a remote file system with a file name that +already specifies an NFS-mounted file. +(This is an error on some operating systems, but we expect it to work +properly on the GNU system, making this error code impossible.) +@end deftypevr + +@comment errno.h +@comment BSD: RPC struct is bad +@deftypevr Macro int EBADRPC +@comment errno 72 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: RPC version wrong +@deftypevr Macro int ERPCMISMATCH +@comment errno 73 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: RPC program not available +@deftypevr Macro int EPROGUNAVAIL +@comment errno 74 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: RPC program version wrong +@deftypevr Macro int EPROGMISMATCH +@comment errno 75 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: RPC bad procedure for program +@deftypevr Macro int EPROCUNAVAIL +@comment errno 76 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment POSIX.1: No locks available +@deftypevr Macro int ENOLCK +@comment errno 77 @c DO NOT REMOVE +No locks available. This is used by the file locking facilities; see +@ref{File Locks}. This error is never generated by the GNU system, but +it can result from an operation to an NFS server running another +operating system. +@end deftypevr + +@comment errno.h +@comment BSD: Inappropriate file type or format +@deftypevr Macro int EFTYPE +@comment errno 79 @c DO NOT REMOVE +Inappropriate file type or format. The file was the wrong type for the +operation, or a data file had the wrong format. + +On some systems @code{chmod} returns this error if you try to set the +sticky bit on a non-directory file; @pxref{Setting Permissions}. +@end deftypevr + +@comment errno.h +@comment BSD: Authentication error +@deftypevr Macro int EAUTH +@comment errno 80 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment BSD: Need authenticator +@deftypevr Macro int ENEEDAUTH +@comment errno 81 @c DO NOT REMOVE +??? +@end deftypevr + +@comment errno.h +@comment POSIX.1: Function not implemented +@deftypevr Macro int ENOSYS +@comment errno 78 @c DO NOT REMOVE +Function not implemented. Some functions have commands or options defined +that might not be supported in all implementations, and this is the kind +of error you get if you request them and they are not supported. +@end deftypevr + +@comment errno.h +@comment GNU: Inappropriate operation for background process +@deftypevr Macro int EBACKGROUND +@comment errno 100 @c DO NOT REMOVE +In the GNU system, servers supporting the @code{term} protocol return +this error for certain operations when the caller is not in the +foreground process group of the terminal. Users do not usually see this +error because functions such as @code{read} and @code{write} translate +it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control}, +for information on process groups and these signals. +@end deftypevr + +@comment errno.h +@comment GNU: Translator died +@deftypevr Macro int EDIED +@comment errno 101 @c DO NOT REMOVE +In the GNU system, opening a file returns this error when the file is +translated by a program and the translator program dies while starting +up, before it has connected to the file. +@end deftypevr + +@comment errno.h +@comment GNU: ? +@deftypevr Macro int ED +@comment errno 102 @c DO NOT REMOVE +The experienced user will know what is wrong. +@end deftypevr + +@comment errno.h +@comment GNU: You really blew it this time +@deftypevr Macro int EGREGIOUS +@comment errno 103 @c DO NOT REMOVE +You did @strong{what}? +@end deftypevr + +@comment errno.h +@comment GNU: Computer bought the farm +@deftypevr Macro int EIEIO +@comment errno 104 @c DO NOT REMOVE +Go home and have a glass of warm, dairy-fresh milk. +@end deftypevr + +@comment errno.h +@comment GNU: Gratuitous error +@deftypevr Macro int EGRATUITOUS +@comment errno 105 @c DO NOT REMOVE +This error code has no purpose. +@end deftypevr + + +@node Error Messages, , Error Codes, Error Reporting +@section Error Messages + +The library has functions and variables designed to make it easy for +your program to report informative error messages in the customary +format about the failure of a library call. The functions +@code{strerror} and @code{perror} give you the standard error message +for a given error code; the variable +@w{@code{program_invocation_short_name}} gives you convenient access to the +name of the program that encountered the error. + +@comment string.h +@comment ANSI +@deftypefun {char *} strerror (int @var{errnum}) +The @code{strerror} function maps the error code (@pxref{Checking for +Errors}) specified by the @var{errnum} argument to a descriptive error +message string. The return value is a pointer to this string. + +The value @var{errnum} normally comes from the variable @code{errno}. + +You should not modify the string returned by @code{strerror}. Also, if +you make subsequent calls to @code{strerror}, the string might be +overwritten. (But it's guaranteed that no library function ever calls +@code{strerror} behind your back.) + +The function @code{strerror} is declared in @file{string.h}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun void perror (const char *@var{message}) +This function prints an error message to the stream @code{stderr}; +see @ref{Standard Streams}. + +If you call @code{perror} with a @var{message} that is either a null +pointer or an empty string, @code{perror} just prints the error message +corresponding to @code{errno}, adding a trailing newline. + +If you supply a non-null @var{message} argument, then @code{perror} +prefixes its output with this string. It adds a colon and a space +character to separate the @var{message} from the error string corresponding +to @code{errno}. + +The function @code{perror} is declared in @file{stdio.h}. +@end deftypefun + +@code{strerror} and @code{perror} produce the exact same message for any +given error code; the precise text varies from system to system. On the +GNU system, the messages are fairly short; there are no multi-line +messages or embedded newlines. Each error message begins with a capital +letter and does not include any terminating punctuation. + +@strong{Compatibility Note:} The @code{strerror} function is a new +feature of ANSI C. Many older C systems do not support this function +yet. + +@cindex program name +@cindex name of running program +Many programs that don't read input from the terminal are designed to +exit if any system call fails. By convention, the error message from +such a program should start with the program's name, sans directories. +You can find that name in the variable +@code{program_invocation_short_name}; the full file name is stored the +variable @code{program_invocation_name}: + +@comment errno.h +@comment GNU +@deftypevar {char *} program_invocation_name +This variable's value is the name that was used to invoke the program +running in the current process. It is the same as @code{argv[0]}. Note +that this is not necessarily a useful file name; often it contains no +directory names. @xref{Program Arguments}. +@end deftypevar + +@comment errno.h +@comment GNU +@deftypevar {char *} program_invocation_short_name +This variable's value is the name that was used to invoke the program +running in the current process, with directory names removed. (That is +to say, it is the same as @code{program_invocation_name} minus +everything up to the last slash, if any.) +@end deftypevar + +The library initialization code sets up both of these variables before +calling @code{main}. + +@strong{Portability Note:} These two variables are GNU extensions. If +you want your program to work with non-GNU libraries, you must save the +value of @code{argv[0]} in @code{main}, and then strip off the directory +names yourself. We added these extensions to make it possible to write +self-contained error-reporting subroutines that require no explicit +cooperation from @code{main}. + +Here is an example showing how to handle failure to open a file +correctly. The function @code{open_sesame} tries to open the named file +for reading and returns a stream if successful. The @code{fopen} +library function returns a null pointer if it couldn't open the file for +some reason. In that situation, @code{open_sesame} constructs an +appropriate error message using the @code{strerror} function, and +terminates the program. If we were going to make some other library +calls before passing the error code to @code{strerror}, we'd have to +save it in a local variable instead, because those other library +functions might overwrite @code{errno} in the meantime. + +@smallexample +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +FILE * +open_sesame (char *name) +@{ + FILE *stream; + + errno = 0; + stream = fopen (name, "r"); + if (stream == NULL) + @{ + fprintf (stderr, "%s: Couldn't open file %s; %s\n", + program_invocation_short_name, name, strerror (errno)); + exit (EXIT_FAILURE); + @} + else + return stream; +@} +@end smallexample + diff --git a/manual/examples/add.c b/manual/examples/add.c new file mode 100644 index 0000000000..e4b1bba365 --- /dev/null +++ b/manual/examples/add.c @@ -0,0 +1,30 @@ +#include <stdarg.h> +#include <stdio.h> + +int +add_em_up (int count,...) +{ + va_list ap; + int i, sum; + + va_start (ap, count); /* Initialize the argument list. */ + + sum = 0; + for (i = 0; i < count; i++) + sum += va_arg (ap, int); /* Get the next argument value. */ + + va_end (ap); /* Clean up. */ + return sum; +} + +int +main (void) +{ + /* This call prints 16. */ + printf ("%d\n", add_em_up (3, 5, 5, 6)); + + /* This call prints 55. */ + printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + + return 0; +} diff --git a/manual/examples/atexit.c b/manual/examples/atexit.c new file mode 100644 index 0000000000..42bba71126 --- /dev/null +++ b/manual/examples/atexit.c @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <stdlib.h> + +void +bye (void) +{ + puts ("Goodbye, cruel world...."); +} + +int +main (void) +{ + atexit (bye); + exit (EXIT_SUCCESS); +} diff --git a/manual/examples/db.c b/manual/examples/db.c new file mode 100644 index 0000000000..1a1cb0c0d7 --- /dev/null +++ b/manual/examples/db.c @@ -0,0 +1,52 @@ +#include <grp.h> +#include <pwd.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdlib.h> + +int +main (void) +{ + uid_t me; + struct passwd *my_passwd; + struct group *my_group; + char **members; + + /* Get information about the user ID. */ + me = getuid (); + my_passwd = getpwuid (me); + if (!my_passwd) + { + printf ("Couldn't find out about user %d.\n", (int) me); + exit (EXIT_FAILURE); + } + + /* Print the information. */ + printf ("I am %s.\n", my_passwd->pw_gecos); + printf ("My login name is %s.\n", my_passwd->pw_name); + printf ("My uid is %d.\n", (int) (my_passwd->pw_uid)); + printf ("My home directory is %s.\n", my_passwd->pw_dir); + printf ("My default shell is %s.\n", my_passwd->pw_shell); + + /* Get information about the default group ID. */ + my_group = getgrgid (my_passwd->pw_gid); + if (!my_group) + { + printf ("Couldn't find out about group %d.\n", + (int) my_passwd->pw_gid); + exit (EXIT_FAILURE); + } + + /* Print the information. */ + printf ("My default group is %s (%d).\n", + my_group->gr_name, (int) (my_passwd->pw_gid)); + printf ("The members of this group are:\n"); + members = my_group->gr_mem; + while (*members) + { + printf (" %s\n", *(members)); + members++; + } + + return EXIT_SUCCESS; +} diff --git a/manual/examples/dir.c b/manual/examples/dir.c new file mode 100644 index 0000000000..b90f72da03 --- /dev/null +++ b/manual/examples/dir.c @@ -0,0 +1,25 @@ +/*@group*/ +#include <stddef.h> +#include <stdio.h> +#include <sys/types.h> +#include <dirent.h> +/*@end group*/ + +int +main (void) +{ + DIR *dp; + struct dirent *ep; + + dp = opendir ("./"); + if (dp != NULL) + { + while (ep = readdir (dp)) + puts (ep->d_name); + (void) closedir (dp); + } + else + puts ("Couldn't open the directory."); + + return 0; +} diff --git a/manual/examples/filecli.c b/manual/examples/filecli.c new file mode 100644 index 0000000000..b77ae6763e --- /dev/null +++ b/manual/examples/filecli.c @@ -0,0 +1,54 @@ +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> + +#define SERVER "/tmp/serversocket" +#define CLIENT "/tmp/mysocket" +#define MAXMSG 512 +#define MESSAGE "Yow!!! Are we having fun yet?!?" + +int +main (void) +{ + extern int make_named_socket (const char *name); + int sock; + char message[MAXMSG]; + struct sockaddr_un name; + size_t size; + int nbytes; + + /* Make the socket. */ + sock = make_named_socket (CLIENT); + + /* Initialize the server socket address. */ + name.sun_family = AF_UNIX; + strcpy (name.sun_path, SERVER); + size = strlen (name.sun_path) + sizeof (name.sun_family); + + /* Send the datagram. */ + nbytes = sendto (sock, MESSAGE, strlen (MESSAGE) + 1, 0, + (struct sockaddr *) & name, size); + if (nbytes < 0) + { + perror ("sendto (client)"); + exit (EXIT_FAILURE); + } + + /* Wait for a reply. */ + nbytes = recvfrom (sock, message, MAXMSG, 0, NULL, 0); + if (nbytes < 0) + { + perror ("recfrom (client)"); + exit (EXIT_FAILURE); + } + + /* Print a diagnostic message. */ + fprintf (stderr, "Client: got message: %s\n", message); + + /* Clean up. */ + remove (CLIENT); + close (sock); +} diff --git a/manual/examples/filesrv.c b/manual/examples/filesrv.c new file mode 100644 index 0000000000..3596b99982 --- /dev/null +++ b/manual/examples/filesrv.c @@ -0,0 +1,46 @@ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> + +#define SERVER "/tmp/serversocket" +#define MAXMSG 512 + +int +main (void) +{ + int sock; + char message[MAXMSG]; + struct sockaddr_un name; + size_t size; + int nbytes; + + /* Make the socket, then loop endlessly. */ + + sock = make_named_socket (SERVER); + while (1) + { + /* Wait for a datagram. */ + size = sizeof (name); + nbytes = recvfrom (sock, message, MAXMSG, 0, + (struct sockaddr *) & name, &size); + if (nbytes < 0) + { + perror ("recfrom (server)"); + exit (EXIT_FAILURE); + } + + /* Give a diagnostic message. */ + fprintf (stderr, "Server: got message: %s\n", message); + + /* Bounce the message back to the sender. */ + nbytes = sendto (sock, message, nbytes, 0, + (struct sockaddr *) & name, size); + if (nbytes < 0) + { + perror ("sendto (server)"); + exit (EXIT_FAILURE); + } + } +} diff --git a/manual/examples/inetcli.c b/manual/examples/inetcli.c new file mode 100644 index 0000000000..258c6892aa --- /dev/null +++ b/manual/examples/inetcli.c @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +#define PORT 5555 +#define MESSAGE "Yow!!! Are we having fun yet?!?" +#define SERVERHOST "churchy.gnu.ai.mit.edu" + +void +write_to_server (int filedes) +{ + int nbytes; + + nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1); + if (nbytes < 0) + { + perror ("write"); + exit (EXIT_FAILURE); + } +} + + +int +main (void) +{ + extern void init_sockaddr (struct sockaddr_in *name, + const char *hostname, + unsigned short int port); + int sock; + struct sockaddr_in servername; + + /* Create the socket. */ + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + perror ("socket (client)"); + exit (EXIT_FAILURE); + } + + /* Connect to the server. */ + init_sockaddr (&servername, SERVERHOST, PORT); + if (0 > connect (sock, + (struct sockaddr *) &servername, + sizeof (servername))) + { + perror ("connect (client)"); + exit (EXIT_FAILURE); + } + + /* Send data to the server. */ + write_to_server (sock); + close (sock); + exit (EXIT_SUCCESS); +} diff --git a/manual/examples/inetsrv.c b/manual/examples/inetsrv.c new file mode 100644 index 0000000000..bd86e80f36 --- /dev/null +++ b/manual/examples/inetsrv.c @@ -0,0 +1,103 @@ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +#define PORT 5555 +#define MAXMSG 512 + +int +read_from_client (int filedes) +{ + char buffer[MAXMSG]; + int nbytes; + + nbytes = read (filedes, buffer, MAXMSG); + if (nbytes < 0) + { + /* Read error. */ + perror ("read"); + exit (EXIT_FAILURE); + } + else if (nbytes == 0) + /* End-of-file. */ + return -1; + else + { + /* Data read. */ + fprintf (stderr, "Server: got message: `%s'\n", buffer); + return 0; + } +} + +int +main (void) +{ + extern int make_socket (unsigned short int port); + int sock; + fd_set active_fd_set, read_fd_set; + int i; + struct sockaddr_in clientname; + size_t size; + + /* Create the socket and set it up to accept connections. */ + sock = make_socket (PORT); + if (listen (sock, 1) < 0) + { + perror ("listen"); + exit (EXIT_FAILURE); + } + + /* Initialize the set of active sockets. */ + FD_ZERO (&active_fd_set); + FD_SET (sock, &active_fd_set); + + while (1) + { + /* Block until input arrives on one or more active sockets. */ + read_fd_set = active_fd_set; + if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) + { + perror ("select"); + exit (EXIT_FAILURE); + } + + /* Service all the sockets with input pending. */ + for (i = 0; i < FD_SETSIZE; ++i) + if (FD_ISSET (i, &read_fd_set)) + { + if (i == sock) + { + /* Connection request on original socket. */ + int new; + size = sizeof (clientname); + new = accept (sock, + (struct sockaddr *) &clientname, + &size); + if (new < 0) + { + perror ("accept"); + exit (EXIT_FAILURE); + } + fprintf (stderr, + "Server: connect from host %s, port %hd.\n", + inet_ntoa (clientname.sin_addr), + ntohs (clientname.sin_port)); + FD_SET (new, &active_fd_set); + } + else + { + /* Data arriving on an already-connected socket. */ + if (read_from_client (i) < 0) + { + close (i); + FD_CLR (i, &active_fd_set); + } + } + } + } +} diff --git a/manual/examples/isockad.c b/manual/examples/isockad.c new file mode 100644 index 0000000000..54ec1cca4c --- /dev/null +++ b/manual/examples/isockad.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +void +init_sockaddr (struct sockaddr_in *name, + const char *hostname, + unsigned short int port) +{ + struct hostent *hostinfo; + + name->sin_family = AF_INET; + name->sin_port = htons (port); + hostinfo = gethostbyname (hostname); + if (hostinfo == NULL) + { + fprintf (stderr, "Unknown host %s.\n", hostname); + exit (EXIT_FAILURE); + } + name->sin_addr = *(struct in_addr *) hostinfo->h_addr; +} diff --git a/manual/examples/longopt.c b/manual/examples/longopt.c new file mode 100644 index 0000000000..d5c841f24a --- /dev/null +++ b/manual/examples/longopt.c @@ -0,0 +1,92 @@ +#include <stdio.h> + +/* Flag set by @samp{--verbose}. */ +static int verbose_flag; + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + + while (1) + { + static struct option long_options[] = + { + /* These options set a flag. */ + {"verbose", 0, &verbose_flag, 1}, + {"brief", 0, &verbose_flag, 0}, + /* These options don't set a flag. + We distinguish them by their indices. */ + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + /* @code{getopt_long} stores the option index here. */ + int option_index = 0; + + c = getopt_long (argc, argv, "abc:d:", + long_options, &option_index); + + /* Detect the end of the options. */ + if (c == -1) + break; + + switch (c) + { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) + break; + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case 'a': + puts ("option -a\n"); + break; + + case 'b': + puts ("option -b\n"); + break; + + case 'c': + printf ("option -c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option -d with value `%s'\n", optarg); + break; + + case '?': + /* @code{getopt_long} already printed an error message. */ + break; + + default: + abort (); + } + } + + /* Instead of reporting @samp{--verbose} + and @samp{--brief} as they are encountered, + we report the final status resulting from them. */ + if (verbose_flag) + puts ("verbose flag is set"); + + /* Print any remaining command line arguments (not options). */ + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + putchar ('\n'); + } + + exit (0); +} diff --git a/manual/examples/memopen.c b/manual/examples/memopen.c new file mode 100644 index 0000000000..682830fe5f --- /dev/null +++ b/manual/examples/memopen.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +static char buffer[] = "foobar"; + +int +main (void) +{ + int ch; + FILE *stream; + + stream = fmemopen (buffer, strlen (buffer), "r"); + while ((ch = fgetc (stream)) != EOF) + printf ("Got %c\n", ch); + fclose (stream); + + return 0; +} diff --git a/manual/examples/memstrm.c b/manual/examples/memstrm.c new file mode 100644 index 0000000000..1674c36e0b --- /dev/null +++ b/manual/examples/memstrm.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +int +main (void) +{ + char *bp; + size_t size; + FILE *stream; + + stream = open_memstream (&bp, &size); + fprintf (stream, "hello"); + fflush (stream); + printf ("buf = `%s', size = %d\n", bp, size); + fprintf (stream, ", world"); + fclose (stream); + printf ("buf = `%s', size = %d\n", bp, size); + + return 0; +} diff --git a/manual/examples/mkfsock.c b/manual/examples/mkfsock.c new file mode 100644 index 0000000000..d3750ec150 --- /dev/null +++ b/manual/examples/mkfsock.c @@ -0,0 +1,43 @@ +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> + +int +make_named_socket (const char *filename) +{ + struct sockaddr_un name; + int sock; + size_t size; + + /* Create the socket. */ + + sock = socket (PF_UNIX, SOCK_DGRAM, 0); + if (sock < 0) + { + perror ("socket"); + exit (EXIT_FAILURE); + } + + /* Bind a name to the socket. */ + + name.sun_family = AF_FILE; + strcpy (name.sun_path, filename); + + /* The size of the address is + the offset of the start of the filename, + plus its length, + plus one for the terminating null byte. */ + size = (offsetof (struct sockaddr_un, sun_path) + + strlen (name.sun_path) + 1); + + if (bind (sock, (struct sockaddr *) &name, size) < 0) + { + perror ("bind"); + exit (EXIT_FAILURE); + } + + return sock; +} diff --git a/manual/examples/mkisock.c b/manual/examples/mkisock.c new file mode 100644 index 0000000000..07411bb263 --- /dev/null +++ b/manual/examples/mkisock.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int +make_socket (unsigned short int port) +{ + int sock; + struct sockaddr_in name; + + /* Create the socket. */ + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + perror ("socket"); + exit (EXIT_FAILURE); + } + + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons (port); + name.sin_addr.s_addr = htonl (INADDR_ANY); + if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) + { + perror ("bind"); + exit (EXIT_FAILURE); + } + + return sock; +} diff --git a/manual/examples/pipe.c b/manual/examples/pipe.c new file mode 100644 index 0000000000..054550fec6 --- /dev/null +++ b/manual/examples/pipe.c @@ -0,0 +1,66 @@ +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +/* Read characters from the pipe and echo them to @code{stdout}. */ + +void +read_from_pipe (int file) +{ + FILE *stream; + int c; + stream = fdopen (file, "r"); + while ((c = fgetc (stream)) != EOF) + putchar (c); + fclose (stream); +} + +/* Write some random text to the pipe. */ + +void +write_to_pipe (int file) +{ + FILE *stream; + stream = fdopen (file, "w"); + fprintf (stream, "hello, world!\n"); + fprintf (stream, "goodbye, world!\n"); + fclose (stream); +} + +int +main (void) +{ + pid_t pid; + int mypipe[2]; + +/*@group*/ + /* Create the pipe. */ + if (pipe (mypipe)) + { + fprintf (stderr, "Pipe failed.\n"); + return EXIT_FAILURE; + } +/*@end group*/ + + /* Create the child process. */ + pid = fork (); + if (pid == (pid_t) 0) + { + /* This is the child process. */ + read_from_pipe (mypipe[0]); + return EXIT_SUCCESS; + } + else if (pid < (pid_t) 0) + { + /* The fork failed. */ + fprintf (stderr, "Fork failed.\n"); + return EXIT_FAILURE; + } + else + { + /* This is the parent process. */ + write_to_pipe (mypipe[1]); + return EXIT_SUCCESS; + } +} diff --git a/manual/examples/popen.c b/manual/examples/popen.c new file mode 100644 index 0000000000..16ae32fa16 --- /dev/null +++ b/manual/examples/popen.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> + +void +write_data (FILE * stream) +{ + int i; + for (i = 0; i < 100; i++) + fprintf (stream, "%d\n", i); + if (ferror (stream)) + { + fprintf (stderr, "Output to stream failed.\n"); + exit (EXIT_FAILURE); + } +} + +/*@group*/ +int +main (void) +{ + FILE *output; + + output = popen ("more", "w"); + if (!output) + { + fprintf (stderr, "Could not run more.\n"); + return EXIT_FAILURE; + } + write_data (output); + pclose (output); + return EXIT_SUCCESS; +} +/*@end group*/ diff --git a/manual/examples/rprintf.c b/manual/examples/rprintf.c new file mode 100644 index 0000000000..eff1d8e7cf --- /dev/null +++ b/manual/examples/rprintf.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <printf.h> +#include <stdarg.h> + +/*@group*/ +typedef struct + { + char *name; + } Widget; +/*@end group*/ + +int +print_widget (FILE *stream, const struct printf_info *info, va_list *app) +{ + Widget *w; + char *buffer; + int len; + + /* Format the output into a string. */ + w = va_arg (*app, Widget *); + len = asprintf (&buffer, "<Widget %p: %s>", w, w->name); + if (len == -1) + return -1; + + /* Pad to the minimum field width and print to the stream. */ + len = fprintf (stream, "%*s", + (info->left ? - info->width : info->width), + buffer); + + /* Clean up and return. */ + free (buffer); + return len; +} + + +int +main (void) +{ + /* Make a widget to print. */ + Widget mywidget; + mywidget.name = "mywidget"; + + /* Register the print function for widgets. */ + register_printf_function ('W', print_widget, NULL); /* No arginfo. */ + + /* Now print the widget. */ + printf ("|%W|\n", &mywidget); + printf ("|%35W|\n", &mywidget); + printf ("|%-35W|\n", &mywidget); + + return 0; +} diff --git a/manual/examples/search b/manual/examples/search Binary files differnew file mode 100755 index 0000000000..4916a2c52f --- /dev/null +++ b/manual/examples/search diff --git a/manual/examples/search.c b/manual/examples/search.c new file mode 100644 index 0000000000..182e6e4a3f --- /dev/null +++ b/manual/examples/search.c @@ -0,0 +1,93 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* Define an array of critters to sort. */ + +struct critter + { + const char *name; + const char *species; + }; + +struct critter muppets[] = + { + {"Kermit", "frog"}, + {"Piggy", "pig"}, + {"Gonzo", "whatever"}, + {"Fozzie", "bear"}, + {"Sam", "eagle"}, + {"Robin", "frog"}, + {"Animal", "animal"}, + {"Camilla", "chicken"}, + {"Sweetums", "monster"}, + {"Dr. Strangepork", "pig"}, + {"Link Hogthrob", "pig"}, + {"Zoot", "human"}, + {"Dr. Bunsen Honeydew", "human"}, + {"Beaker", "human"}, + {"Swedish Chef", "human"} + }; + +int count = sizeof (muppets) / sizeof (struct critter); + + + +/* This is the comparison function used for sorting and searching. */ + +int +critter_cmp (const struct critter *c1, const struct critter *c2) +{ + return strcmp (c1->name, c2->name); +} + + +/* Print information about a critter. */ + +void +print_critter (const struct critter *c) +{ + printf ("%s, the %s\n", c->name, c->species); +} + + +/*@group*/ +/* Do the lookup into the sorted array. */ + +void +find_critter (const char *name) +{ + struct critter target, *result; + target.name = name; + result = bsearch (&target, muppets, count, sizeof (struct critter), + critter_cmp); + if (result) + print_critter (result); + else + printf ("Couldn't find %s.\n", name); +} +/*@end group*/ + +/* Main program. */ + +int +main (void) +{ + int i; + + for (i = 0; i < count; i++) + print_critter (&muppets[i]); + printf ("\n"); + + qsort (muppets, count, sizeof (struct critter), critter_cmp); + + for (i = 0; i < count; i++) + print_critter (&muppets[i]); + printf ("\n"); + + find_critter ("Kermit"); + find_critter ("Gonzo"); + find_critter ("Janice"); + + return 0; +} diff --git a/manual/examples/select.c b/manual/examples/select.c new file mode 100644 index 0000000000..def2cd6f9f --- /dev/null +++ b/manual/examples/select.c @@ -0,0 +1,40 @@ +/*@group*/ +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/time.h> +/*@end group*/ + +/*@group*/ +int +input_timeout (int filedes, unsigned int seconds) +{ + fd_set set; + struct timeval timeout; +/*@end group*/ + + /* Initialize the file descriptor set. */ + FD_ZERO (&set); + FD_SET (filedes, &set); + + /* Initialize the timeout data structure. */ + timeout.tv_sec = seconds; + timeout.tv_usec = 0; + +/*@group*/ + /* @code{select} returns 0 if timeout, 1 if input available, -1 if error. */ + return TEMP_FAILURE_RETRY (select (FD_SETSIZE, + &set, NULL, NULL, + &timeout)); +} +/*@end group*/ + +/*@group*/ +int +main (void) +{ + fprintf (stderr, "select returned %d.\n", + input_timeout (STDIN_FILENO, 5)); + return 0; +} +/*@end group*/ diff --git a/manual/examples/setjmp.c b/manual/examples/setjmp.c new file mode 100644 index 0000000000..023339c602 --- /dev/null +++ b/manual/examples/setjmp.c @@ -0,0 +1,32 @@ +#include <setjmp.h> +#include <stdlib.h> +#include <stdio.h> + +jmp_buf main_loop; + +void +abort_to_main_loop (int status) +{ + longjmp (main_loop, status); +} + +int +main (void) +{ + while (1) + if (setjmp (main_loop)) + puts ("Back at main loop...."); + else + do_command (); +} + + +void +do_command (void) +{ + char buffer[128]; + if (fgets (buffer, 128, stdin) == NULL) + abort_to_main_loop (-1); + else + exit (EXIT_SUCCESS); +} diff --git a/manual/examples/sigh1.c b/manual/examples/sigh1.c new file mode 100644 index 0000000000..2c6e95b9c9 --- /dev/null +++ b/manual/examples/sigh1.c @@ -0,0 +1,36 @@ +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> + +/* This flag controls termination of the main loop. */ +volatile sig_atomic_t keep_going = 1; + +/* The signal handler just clears the flag and re-enables itself. */ +void +catch_alarm (int sig) +{ + keep_going = 0; + signal (sig, catch_alarm); +} + +void +do_stuff (void) +{ + puts ("Doing stuff while waiting for alarm...."); +} + +int +main (void) +{ + /* Establish a handler for SIGALRM signals. */ + signal (SIGALRM, catch_alarm); + + /* Set an alarm to go off in a little while. */ + alarm (2); + + /* Check the flag once in a while to see when to quit. */ + while (keep_going) + do_stuff (); + + return EXIT_SUCCESS; +} diff --git a/manual/examples/sigusr.c b/manual/examples/sigusr.c new file mode 100644 index 0000000000..11e3ceee8f --- /dev/null +++ b/manual/examples/sigusr.c @@ -0,0 +1,61 @@ +/*@group*/ +#include <signal.h> +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +/*@end group*/ + +/* When a @code{SIGUSR1} signal arrives, set this variable. */ +volatile sig_atomic_t usr_interrupt = 0; + +void +synch_signal (int sig) +{ + usr_interrupt = 1; +} + +/* The child process executes this function. */ +void +child_function (void) +{ + /* Perform initialization. */ + printf ("I'm here!!! My pid is %d.\n", (int) getpid ()); + + /* Let parent know you're done. */ + kill (getppid (), SIGUSR1); + + /* Continue with execution. */ + puts ("Bye, now...."); + exit (0); +} + +int +main (void) +{ + struct sigaction usr_action; + sigset_t block_mask; + pid_t child_id; + + /* Establish the signal handler. */ + sigfillset (&block_mask); + usr_action.sa_handler = synch_signal; + usr_action.sa_mask = block_mask; + usr_action.sa_flags = 0; + sigaction (SIGUSR1, &usr_action, NULL); + + /* Create the child process. */ + child_id = fork (); + if (child_id == 0) + child_function (); /* Does not return. */ + +/*@group*/ + /* Busy wait for the child to send a signal. */ + while (!usr_interrupt) + ; +/*@end group*/ + + /* Now continue execution. */ + puts ("That's all, folks!"); + + return 0; +} diff --git a/manual/examples/stpcpy.c b/manual/examples/stpcpy.c new file mode 100644 index 0000000000..b83226354b --- /dev/null +++ b/manual/examples/stpcpy.c @@ -0,0 +1,13 @@ +#include <string.h> +#include <stdio.h> + +int +main (void) +{ + char buffer[10]; + char *to = buffer; + to = stpcpy (to, "foo"); + to = stpcpy (to, "bar"); + puts (buffer); + return 0; +} diff --git a/manual/examples/strftim.c b/manual/examples/strftim.c new file mode 100644 index 0000000000..7f95ef02ad --- /dev/null +++ b/manual/examples/strftim.c @@ -0,0 +1,31 @@ +#include <time.h> +#include <stdio.h> + +#define SIZE 256 + +int +main (void) +{ + char buffer[SIZE]; + time_t curtime; + struct tm *loctime; + + /* Get the current time. */ + curtime = time (NULL); + + /* Convert it to local time representation. */ + loctime = localtime (&curtime); + + /* Print out the date and time in the standard format. */ + fputs (asctime (loctime), stdout); + +/*@group*/ + /* Print it out in a nice format. */ + strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime); + fputs (buffer, stdout); + strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime); + fputs (buffer, stdout); + + return 0; +} +/*@end group*/ diff --git a/manual/examples/strncat.c b/manual/examples/strncat.c new file mode 100644 index 0000000000..f865167f4a --- /dev/null +++ b/manual/examples/strncat.c @@ -0,0 +1,14 @@ +#include <string.h> +#include <stdio.h> + +#define SIZE 10 + +static char buffer[SIZE]; + +main () +{ + strncpy (buffer, "hello", SIZE); + puts (buffer); + strncat (buffer, ", world", SIZE - strlen (buffer) - 1); + puts (buffer); +} diff --git a/manual/examples/termios.c b/manual/examples/termios.c new file mode 100644 index 0000000000..6db5990a0c --- /dev/null +++ b/manual/examples/termios.c @@ -0,0 +1,60 @@ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> + +/* Use this variable to remember original terminal attributes. */ + +struct termios saved_attributes; + +void +reset_input_mode (void) +{ + tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes); +} + +void +set_input_mode (void) +{ + struct termios tattr; + char *name; + + /* Make sure stdin is a terminal. */ + if (!isatty (STDIN_FILENO)) + { + fprintf (stderr, "Not a terminal.\n"); + exit (EXIT_FAILURE); + } + + /* Save the terminal attributes so we can restore them later. */ + tcgetattr (STDIN_FILENO, &saved_attributes); + atexit (reset_input_mode); + +/*@group*/ + /* Set the funny terminal modes. */ + tcgetattr (STDIN_FILENO, &tattr); + tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME] = 0; + tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); +} +/*@end group*/ + +int +main (void) +{ + char c; + + set_input_mode (); + + while (1) + { + read (STDIN_FILENO, &c, 1); + if (c == '\004') /* @kbd{C-d} */ + break; + else + putchar (c); + } + + return EXIT_SUCCESS; +} diff --git a/manual/examples/testopt.c b/manual/examples/testopt.c new file mode 100644 index 0000000000..8ebc9b6f7a --- /dev/null +++ b/manual/examples/testopt.c @@ -0,0 +1,50 @@ +/*@group*/ +#include <unistd.h> +#include <stdio.h> + +int +main (int argc, char **argv) +{ + int aflag = 0; + int bflag = 0; + char *cvalue = NULL; + int index; + int c; + + opterr = 0; +/*@end group*/ + +/*@group*/ + while ((c = getopt (argc, argv, "abc:")) != -1) + switch (c) + { + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + case 'c': + cvalue = optarg; + break; + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + return 1; + default: + abort (); + } +/*@end group*/ + +/*@group*/ + printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue); + + for (index = optind; index < argc; index++) + printf ("Non-option argument %s\n", argv[index]); + return 0; +} +/*@end group*/ diff --git a/manual/filesys.texi b/manual/filesys.texi new file mode 100644 index 0000000000..d2afe8623f --- /dev/null +++ b/manual/filesys.texi @@ -0,0 +1,2080 @@ +@node File System Interface, Pipes and FIFOs, Low-Level I/O, Top +@chapter File System Interface + +This chapter describes the GNU C library's functions for manipulating +files. Unlike the input and output functions described in +@ref{I/O on Streams} and @ref{Low-Level I/O}, these +functions are concerned with operating on the files themselves, rather +than on their contents. + +Among the facilities described in this chapter are functions for +examining or modifying directories, functions for renaming and deleting +files, and functions for examining and setting file attributes such as +access permissions and modification times. + +@menu +* Working Directory:: This is used to resolve relative + file names. +* Accessing Directories:: Finding out what files a directory + contains. +* Hard Links:: Adding alternate names to a file. +* Symbolic Links:: A file that ``points to'' a file name. +* Deleting Files:: How to delete a file, and what that means. +* Renaming Files:: Changing a file's name. +* Creating Directories:: A system call just for creating a directory. +* File Attributes:: Attributes of individual files. +* Making Special Files:: How to create special files. +* Temporary Files:: Naming and creating temporary files. +@end menu + +@node Working Directory +@section Working Directory + +@cindex current working directory +@cindex working directory +@cindex change working directory +Each process has associated with it a directory, called its @dfn{current +working directory} or simply @dfn{working directory}, that is used in +the resolution of relative file names (@pxref{File Name Resolution}). + +When you log in and begin a new session, your working directory is +initially set to the home directory associated with your login account +in the system user database. You can find any user's home directory +using the @code{getpwuid} or @code{getpwnam} functions; see @ref{User +Database}. + +Users can change the working directory using shell commands like +@code{cd}. The functions described in this section are the primitives +used by those commands and by other programs for examining and changing +the working directory. +@pindex cd + +Prototypes for these functions are declared in the header file +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun {char *} getcwd (char *@var{buffer}, size_t @var{size}) +The @code{getcwd} function returns an absolute file name representing +the current working directory, storing it in the character array +@var{buffer} that you provide. The @var{size} argument is how you tell +the system the allocation size of @var{buffer}. + +The GNU library version of this function also permits you to specify a +null pointer for the @var{buffer} argument. Then @code{getcwd} +allocates a buffer automatically, as with @code{malloc} +(@pxref{Unconstrained Allocation}). If the @var{size} is greater than +zero, then the buffer is that large; otherwise, the buffer is as large +as necessary to hold the result. + +The return value is @var{buffer} on success and a null pointer on failure. +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The @var{size} argument is zero and @var{buffer} is not a null pointer. + +@item ERANGE +The @var{size} argument is less than the length of the working directory +name. You need to allocate a bigger array and try again. + +@item EACCES +Permission to read or search a component of the file name was denied. +@end table +@end deftypefun + +Here is an example showing how you could implement the behavior of GNU's +@w{@code{getcwd (NULL, 0)}} using only the standard behavior of +@code{getcwd}: + +@smallexample +char * +gnu_getcwd () +@{ + int size = 100; + char *buffer = (char *) xmalloc (size); + + while (1) + @{ + char *value = getcwd (buffer, size); + if (value != 0) + return buffer; + size *= 2; + free (buffer); + buffer = (char *) xmalloc (size); + @} +@} +@end smallexample + +@noindent +@xref{Malloc Examples}, for information about @code{xmalloc}, which is +not a library function but is a customary name used in most GNU +software. + +@comment unistd.h +@comment BSD +@deftypefun {char *} getwd (char *@var{buffer}) +This is similar to @code{getcwd}, but has no way to specify the size of +the buffer. The GNU library provides @code{getwd} only +for backwards compatibility with BSD. + +The @var{buffer} argument should be a pointer to an array at least +@code{PATH_MAX} bytes long (@pxref{Limits for Files}). In the GNU +system there is no limit to the size of a file name, so this is not +necessarily enough space to contain the directory name. That is why +this function is deprecated. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int chdir (const char *@var{filename}) +This function is used to set the process's working directory to +@var{filename}. + +The normal, successful return value from @code{chdir} is @code{0}. A +value of @code{-1} is returned to indicate an error. The @code{errno} +error conditions defined for this function are the usual file name +syntax errors (@pxref{File Name Errors}), plus @code{ENOTDIR} if the +file @var{filename} is not a directory. +@end deftypefun + + +@node Accessing Directories +@section Accessing Directories +@cindex accessing directories +@cindex reading from a directory +@cindex directories, accessing + +The facilities described in this section let you read the contents of a +directory file. This is useful if you want your program to list all the +files in a directory, perhaps as part of a menu. + +@cindex directory stream +The @code{opendir} function opens a @dfn{directory stream} whose +elements are directory entries. You use the @code{readdir} function on +the directory stream to retrieve these entries, represented as +@w{@code{struct dirent}} objects. The name of the file for each entry is +stored in the @code{d_name} member of this structure. There are obvious +parallels here to the stream facilities for ordinary files, described in +@ref{I/O on Streams}. + +@menu +* Directory Entries:: Format of one directory entry. +* Opening a Directory:: How to open a directory stream. +* Reading/Closing Directory:: How to read directory entries from the stream. +* Simple Directory Lister:: A very simple directory listing program. +* Random Access Directory:: Rereading part of the directory + already read with the same stream. +@end menu + +@node Directory Entries +@subsection Format of a Directory Entry + +@pindex dirent.h +This section describes what you find in a single directory entry, as you +might obtain it from a directory stream. All the symbols are declared +in the header file @file{dirent.h}. + +@comment dirent.h +@comment POSIX.1 +@deftp {Data Type} {struct dirent} +This is a structure type used to return information about directory +entries. It contains the following fields: + +@table @code +@item char d_name[] +This is the null-terminated file name component. This is the only +field you can count on in all POSIX systems. + +@item ino_t d_fileno +This is the file serial number. For BSD compatibility, you can also +refer to this member as @code{d_ino}. In the GNU system and most POSIX +systems, for most files this the same as the @code{st_ino} member that +@code{stat} will return for the file. @xref{File Attributes}. + +@item unsigned char d_namlen +This is the length of the file name, not including the terminating null +character. Its type is @code{unsigned char} because that is the integer +type of the appropriate size + +@item unsigned char d_type +This is the type of the file, possibly unknown. The following constants +are defined for its value: + +@table @code +@item DT_UNKNOWN +The type is unknown. On some systems this is the only value returned. + +@item DT_REG +A regular file. + +@item DT_DIR +A directory. + +@item DT_FIFO +A named pipe, or FIFO. @xref{FIFO Special Files}. + +@item DT_SOCK +A local-domain socket. @c !!! @xref{Local Domain}. + +@item DT_CHR +A character device. + +@item DT_BLK +A block device. +@end table + +This member is a BSD extension. Each value except DT_UNKNOWN +corresponds to the file type bits in the @code{st_mode} member of +@code{struct statbuf}. These two macros convert between @code{d_type} +values and @code{st_mode} values: + +@deftypefun int IFTODT (mode_t @var{mode}) +This returns the @code{d_type} value corresponding to @var{mode}. +@end deftypefun + +@deftypefun mode_t DTTOIF (int @var{dirtype}) +This returns the @code{st_mode} value corresponding to @var{dirtype}. +@end deftypefun +@end table + +This structure may contain additional members in the future. + +When a file has multiple names, each name has its own directory entry. +The only way you can tell that the directory entries belong to a +single file is that they have the same value for the @code{d_fileno} +field. + +File attributes such as size, modification times, and the like are part +of the file itself, not any particular directory entry. @xref{File +Attributes}. +@end deftp + +@node Opening a Directory +@subsection Opening a Directory Stream + +@pindex dirent.h +This section describes how to open a directory stream. All the symbols +are declared in the header file @file{dirent.h}. + +@comment dirent.h +@comment POSIX.1 +@deftp {Data Type} DIR +The @code{DIR} data type represents a directory stream. +@end deftp + +You shouldn't ever allocate objects of the @code{struct dirent} or +@code{DIR} data types, since the directory access functions do that for +you. Instead, you refer to these objects using the pointers returned by +the following functions. + +@comment dirent.h +@comment POSIX.1 +@deftypefun {DIR *} opendir (const char *@var{dirname}) +The @code{opendir} function opens and returns a directory stream for +reading the directory whose file name is @var{dirname}. The stream has +type @code{DIR *}. + +If unsuccessful, @code{opendir} returns a null pointer. In addition to +the usual file name errors (@pxref{File Name Errors}), the +following @code{errno} error conditions are defined for this function: + +@table @code +@item EACCES +Read permission is denied for the directory named by @code{dirname}. + +@item EMFILE +The process has too many files open. + +@item ENFILE +The entire system, or perhaps the file system which contains the +directory, cannot support any additional open files at the moment. +(This problem cannot happen on the GNU system.) +@end table + +The @code{DIR} type is typically implemented using a file descriptor, +and the @code{opendir} function in terms of the @code{open} function. +@xref{Low-Level I/O}. Directory streams and the underlying +file descriptors are closed on @code{exec} (@pxref{Executing a File}). +@end deftypefun + +@node Reading/Closing Directory +@subsection Reading and Closing a Directory Stream + +@pindex dirent.h +This section describes how to read directory entries from a directory +stream, and how to close the stream when you are done with it. All the +symbols are declared in the header file @file{dirent.h}. + +@comment dirent.h +@comment POSIX.1 +@deftypefun {struct dirent *} readdir (DIR *@var{dirstream}) +This function reads the next entry from the directory. It normally +returns a pointer to a structure containing information about the file. +This structure is statically allocated and can be rewritten by a +subsequent call. + +@strong{Portability Note:} On some systems, @code{readdir} may not +return entries for @file{.} and @file{..}, even though these are always +valid file names in any directory. @xref{File Name Resolution}. + +If there are no more entries in the directory or an error is detected, +@code{readdir} returns a null pointer. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EBADF +The @var{dirstream} argument is not valid. +@end table +@end deftypefun + +@comment dirent.h +@comment POSIX.1 +@deftypefun int closedir (DIR *@var{dirstream}) +This function closes the directory stream @var{dirstream}. It returns +@code{0} on success and @code{-1} on failure. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EBADF +The @var{dirstream} argument is not valid. +@end table +@end deftypefun + +@node Simple Directory Lister +@subsection Simple Program to List a Directory + +Here's a simple program that prints the names of the files in +the current working directory: + +@smallexample +@include dir.c.texi +@end smallexample + +The order in which files appear in a directory tends to be fairly +random. A more useful program would sort the entries (perhaps by +alphabetizing them) before printing them; see @ref{Array Sort Function}. + +@c ??? not documented: scandir, alphasort + +@node Random Access Directory +@subsection Random Access in a Directory Stream + +@pindex dirent.h +This section describes how to reread parts of a directory that you have +already read from an open directory stream. All the symbols are +declared in the header file @file{dirent.h}. + +@comment dirent.h +@comment POSIX.1 +@deftypefun void rewinddir (DIR *@var{dirstream}) +The @code{rewinddir} function is used to reinitialize the directory +stream @var{dirstream}, so that if you call @code{readdir} it +returns information about the first entry in the directory again. This +function also notices if files have been added or removed to the +directory since it was opened with @code{opendir}. (Entries for these +files might or might not be returned by @code{readdir} if they were +added or removed since you last called @code{opendir} or +@code{rewinddir}.) +@end deftypefun + +@comment dirent.h +@comment BSD +@deftypefun off_t telldir (DIR *@var{dirstream}) +The @code{telldir} function returns the file position of the directory +stream @var{dirstream}. You can use this value with @code{seekdir} to +restore the directory stream to that position. +@end deftypefun + +@comment dirent.h +@comment BSD +@deftypefun void seekdir (DIR *@var{dirstream}, off_t @var{pos}) +The @code{seekdir} function sets the file position of the directory +stream @var{dirstream} to @var{pos}. The value @var{pos} must be the +result of a previous call to @code{telldir} on this particular stream; +closing and reopening the directory can invalidate values returned by +@code{telldir}. +@end deftypefun + +@node Hard Links +@section Hard Links +@cindex hard link +@cindex link, hard +@cindex multiple names for one file +@cindex file names, multiple + +In POSIX systems, one file can have many names at the same time. All of +the names are equally real, and no one of them is preferred to the +others. + +To add a name to a file, use the @code{link} function. (The new name is +also called a @dfn{hard link} to the file.) Creating a new link to a +file does not copy the contents of the file; it simply makes a new name +by which the file can be known, in addition to the file's existing name +or names. + +One file can have names in several directories, so the the organization +of the file system is not a strict hierarchy or tree. + +In most implementations, it is not possible to have hard links to the +same file in multiple file systems. @code{link} reports an error if you +try to make a hard link to the file from another file system when this +cannot be done. + +The prototype for the @code{link} function is declared in the header +file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun int link (const char *@var{oldname}, const char *@var{newname}) +The @code{link} function makes a new link to the existing file named by +@var{oldname}, under the new name @var{newname}. + +This function returns a value of @code{0} if it is successful and +@code{-1} on failure. In addition to the usual file name errors +(@pxref{File Name Errors}) for both @var{oldname} and @var{newname}, the +following @code{errno} error conditions are defined for this function: + +@table @code +@item EACCES +You are not allowed to write the directory in which the new link is to +be written. +@ignore +Some implementations also require that the existing file be accessible +by the caller, and use this error to report failure for that reason. +@end ignore + +@item EEXIST +There is already a file named @var{newname}. If you want to replace +this link with a new link, you must remove the old link explicitly first. + +@item EMLINK +There are already too many links to the file named by @var{oldname}. +(The maximum number of links to a file is @w{@code{LINK_MAX}}; see +@ref{Limits for Files}.) + +@item ENOENT +The file named by @var{oldname} doesn't exist. You can't make a link to +a file that doesn't exist. + +@item ENOSPC +The directory or file system that would contain the new link is full +and cannot be extended. + +@item EPERM +In the GNU system and some others, you cannot make links to directories. +Many systems allow only privileged users to do so. This error +is used to report the problem. + +@item EROFS +The directory containing the new link can't be modified because it's on +a read-only file system. + +@item EXDEV +The directory specified in @var{newname} is on a different file system +than the existing file. + +@item EIO +A hardware error occurred while trying to read or write the to filesystem. +@end table +@end deftypefun + +@node Symbolic Links +@section Symbolic Links +@cindex soft link +@cindex link, soft +@cindex symbolic link +@cindex link, symbolic + +The GNU system supports @dfn{soft links} or @dfn{symbolic links}. This +is a kind of ``file'' that is essentially a pointer to another file +name. Unlike hard links, symbolic links can be made to directories or +across file systems with no restrictions. You can also make a symbolic +link to a name which is not the name of any file. (Opening this link +will fail until a file by that name is created.) Likewise, if the +symbolic link points to an existing file which is later deleted, the +symbolic link continues to point to the same file name even though the +name no longer names any file. + +The reason symbolic links work the way they do is that special things +happen when you try to open the link. The @code{open} function realizes +you have specified the name of a link, reads the file name contained in +the link, and opens that file name instead. The @code{stat} function +likewise operates on the file that the symbolic link points to, instead +of on the link itself. + +By contrast, other operations such as deleting or renaming the file +operate on the link itself. The functions @code{readlink} and +@code{lstat} also refrain from following symbolic links, because their +purpose is to obtain information about the link. So does @code{link}, +the function that makes a hard link---it makes a hard link to the +symbolic link, which one rarely wants. + +Prototypes for the functions listed in this section are in +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment BSD +@deftypefun int symlink (const char *@var{oldname}, const char *@var{newname}) +The @code{symlink} function makes a symbolic link to @var{oldname} named +@var{newname}. + +The normal return value from @code{symlink} is @code{0}. A return value +of @code{-1} indicates an error. In addition to the usual file name +syntax errors (@pxref{File Name Errors}), the following @code{errno} +error conditions are defined for this function: + +@table @code +@item EEXIST +There is already an existing file named @var{newname}. + +@item EROFS +The file @var{newname} would exist on a read-only file system. + +@item ENOSPC +The directory or file system cannot be extended to make the new link. + +@item EIO +A hardware error occurred while reading or writing data on the disk. + +@ignore +@comment not sure about these +@item ELOOP +There are too many levels of indirection. This can be the result of +circular symbolic links to directories. + +@item EDQUOT +The new link can't be created because the user's disk quota has been +exceeded. +@end ignore +@end table +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size}) +The @code{readlink} function gets the value of the symbolic link +@var{filename}. The file name that the link points to is copied into +@var{buffer}. This file name string is @emph{not} null-terminated; +@code{readlink} normally returns the number of characters copied. The +@var{size} argument specifies the maximum number of characters to copy, +usually the allocation size of @var{buffer}. + +If the return value equals @var{size}, you cannot tell whether or not +there was room to return the entire name. So make a bigger buffer and +call @code{readlink} again. Here is an example: + +@smallexample +char * +readlink_malloc (char *filename) +@{ + int size = 100; + + while (1) + @{ + char *buffer = (char *) xmalloc (size); + int nchars = readlink (filename, buffer, size); + if (nchars < size) + return buffer; + free (buffer); + size *= 2; + @} +@} +@end smallexample + +@c @group Invalid outside example. +A value of @code{-1} is returned in case of error. In addition to the +usual file name errors (@pxref{File Name Errors}), the following +@code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The named file is not a symbolic link. + +@item EIO +A hardware error occurred while reading or writing data on the disk. +@end table +@c @end group +@end deftypefun + +@node Deleting Files +@section Deleting Files +@cindex deleting a file +@cindex removing a file +@cindex unlinking a file + +You can delete a file with the functions @code{unlink} or @code{remove}. + +Deletion actually deletes a file name. If this is the file's only name, +then the file is deleted as well. If the file has other names as well +(@pxref{Hard Links}), it remains accessible under its other names. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int unlink (const char *@var{filename}) +The @code{unlink} function deletes the file name @var{filename}. If +this is a file's sole name, the file itself is also deleted. (Actually, +if any process has the file open when this happens, deletion is +postponed until all processes have closed the file.) + +@pindex unistd.h +The function @code{unlink} is declared in the header file @file{unistd.h}. + +This function returns @code{0} on successful completion, and @code{-1} +on error. In addition to the usual file name errors +(@pxref{File Name Errors}), the following @code{errno} error conditions are +defined for this function: + +@table @code +@item EACCES +Write permission is denied for the directory from which the file is to be +removed, or the directory has the sticky bit set and you do not own the file. + +@item EBUSY +This error indicates that the file is being used by the system in such a +way that it can't be unlinked. For example, you might see this error if +the file name specifies the root directory or a mount point for a file +system. + +@item ENOENT +The file name to be deleted doesn't exist. + +@item EPERM +On some systems, @code{unlink} cannot be used to delete the name of a +directory, or can only be used this way by a privileged user. +To avoid such problems, use @code{rmdir} to delete directories. +(In the GNU system @code{unlink} can never delete the name of a directory.) + +@item EROFS +The directory in which the file name is to be deleted is on a read-only +file system, and can't be modified. +@end table +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int rmdir (const char *@var{filename}) +@cindex directories, deleting +@cindex deleting a directory +The @code{rmdir} function deletes a directory. The directory must be +empty before it can be removed; in other words, it can only contain +entries for @file{.} and @file{..}. + +In most other respects, @code{rmdir} behaves like @code{unlink}. There +are two additional @code{errno} error conditions defined for +@code{rmdir}: + +@table @code +@item ENOTEMPTY +@itemx EEXIST +The directory to be deleted is not empty. +@end table + +These two error codes are synonymous; some systems use one, and some use +the other. The GNU system always uses @code{ENOTEMPTY}. + +The prototype for this function is declared in the header file +@file{unistd.h}. +@pindex unistd.h +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int remove (const char *@var{filename}) +This is the ANSI C function to remove a file. It works like +@code{unlink} for files and like @code{rmdir} for directories. +@code{remove} is declared in @file{stdio.h}. +@pindex stdio.h +@end deftypefun + +@node Renaming Files +@section Renaming Files + +The @code{rename} function is used to change a file's name. + +@cindex renaming a file +@comment stdio.h +@comment ANSI +@deftypefun int rename (const char *@var{oldname}, const char *@var{newname}) +The @code{rename} function renames the file name @var{oldname} with +@var{newname}. The file formerly accessible under the name +@var{oldname} is afterward accessible as @var{newname} instead. (If the +file had any other names aside from @var{oldname}, it continues to have +those names.) + +The directory containing the name @var{newname} must be on the same +file system as the file (as indicated by the name @var{oldname}). + +One special case for @code{rename} is when @var{oldname} and +@var{newname} are two names for the same file. The consistent way to +handle this case is to delete @var{oldname}. However, POSIX requires +that in this case @code{rename} do nothing and report success---which is +inconsistent. We don't know what your operating system will do. + +If the @var{oldname} is not a directory, then any existing file named +@var{newname} is removed during the renaming operation. However, if +@var{newname} is the name of a directory, @code{rename} fails in this +case. + +If the @var{oldname} is a directory, then either @var{newname} must not +exist or it must name a directory that is empty. In the latter case, +the existing directory named @var{newname} is deleted first. The name +@var{newname} must not specify a subdirectory of the directory +@code{oldname} which is being renamed. + +One useful feature of @code{rename} is that the meaning of the name +@var{newname} changes ``atomically'' from any previously existing file +by that name to its new meaning (the file that was called +@var{oldname}). There is no instant at which @var{newname} is +nonexistent ``in between'' the old meaning and the new meaning. If +there is a system crash during the operation, it is possible for both +names to still exist; but @var{newname} will always be intact if it +exists at all. + +If @code{rename} fails, it returns @code{-1}. In addition to the usual +file name errors (@pxref{File Name Errors}), the following +@code{errno} error conditions are defined for this function: + +@table @code +@item EACCES +One of the directories containing @var{newname} or @var{oldname} +refuses write permission; or @var{newname} and @var{oldname} are +directories and write permission is refused for one of them. + +@item EBUSY +A directory named by @var{oldname} or @var{newname} is being used by +the system in a way that prevents the renaming from working. This includes +directories that are mount points for filesystems, and directories +that are the current working directories of processes. + +@item ENOTEMPTY +@itemx EEXIST +The directory @var{newname} isn't empty. The GNU system always returns +@code{ENOTEMPTY} for this, but some other systems return @code{EEXIST}. + +@item EINVAL +The @var{oldname} is a directory that contains @var{newname}. + +@item EISDIR +The @var{newname} names a directory, but the @var{oldname} doesn't. + +@item EMLINK +The parent directory of @var{newname} would have too many links. + +@item ENOENT +The file named by @var{oldname} doesn't exist. + +@item ENOSPC +The directory that would contain @var{newname} has no room for another +entry, and there is no space left in the file system to expand it. + +@item EROFS +The operation would involve writing to a directory on a read-only file +system. + +@item EXDEV +The two file names @var{newname} and @var{oldnames} are on different +file systems. +@end table +@end deftypefun + +@node Creating Directories +@section Creating Directories +@cindex creating a directory +@cindex directories, creating + +@pindex mkdir +Directories are created with the @code{mkdir} function. (There is also +a shell command @code{mkdir} which does the same thing.) +@c !!! umask + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun int mkdir (const char *@var{filename}, mode_t @var{mode}) +The @code{mkdir} function creates a new, empty directory whose name is +@var{filename}. + +The argument @var{mode} specifies the file permissions for the new +directory file. @xref{Permission Bits}, for more information about +this. + +A return value of @code{0} indicates successful completion, and +@code{-1} indicates failure. In addition to the usual file name syntax +errors (@pxref{File Name Errors}), the following @code{errno} error +conditions are defined for this function: + +@table @code +@item EACCES +Write permission is denied for the parent directory in which the new +directory is to be added. + +@item EEXIST +A file named @var{filename} already exists. + +@item EMLINK +The parent directory has too many links. + +Well-designed file systems never report this error, because they permit +more links than your disk could possibly hold. However, you must still +take account of the possibility of this error, as it could result from +network access to a file system on another machine. + +@item ENOSPC +The file system doesn't have enough room to create the new directory. + +@item EROFS +The parent directory of the directory being created is on a read-only +file system, and cannot be modified. +@end table + +To use this function, your program should include the header file +@file{sys/stat.h}. +@pindex sys/stat.h +@end deftypefun + +@node File Attributes +@section File Attributes + +@pindex ls +When you issue an @samp{ls -l} shell command on a file, it gives you +information about the size of the file, who owns it, when it was last +modified, and the like. This kind of information is called the +@dfn{file attributes}; it is associated with the file itself and not a +particular one of its names. + +This section contains information about how you can inquire about and +modify these attributes of files. + +@menu +* Attribute Meanings:: The names of the file attributes, + and what their values mean. +* Reading Attributes:: How to read the attributes of a file. +* Testing File Type:: Distinguishing ordinary files, + directories, links... +* File Owner:: How ownership for new files is determined, + and how to change it. +* Permission Bits:: How information about a file's access + mode is stored. +* Access Permission:: How the system decides who can access a file. +* Setting Permissions:: How permissions for new files are assigned, + and how to change them. +* Testing File Access:: How to find out if your process can + access a file. +* File Times:: About the time attributes of a file. +@end menu + +@node Attribute Meanings +@subsection What the File Attribute Values Mean +@cindex status of a file +@cindex attributes of a file +@cindex file attributes + +When you read the attributes of a file, they come back in a structure +called @code{struct stat}. This section describes the names of the +attributes, their data types, and what they mean. For the functions +to read the attributes of a file, see @ref{Reading Attributes}. + +The header file @file{sys/stat.h} declares all the symbols defined +in this section. +@pindex sys/stat.h + +@comment sys/stat.h +@comment POSIX.1 +@deftp {Data Type} {struct stat} +The @code{stat} structure type is used to return information about the +attributes of a file. It contains at least the following members: + +@table @code +@item mode_t st_mode +Specifies the mode of the file. This includes file type information +(@pxref{Testing File Type}) and the file permission bits +(@pxref{Permission Bits}). + +@item ino_t st_ino +The file serial number, which distinguishes this file from all other +files on the same device. + +@item dev_t st_dev +Identifies the device containing the file. The @code{st_ino} and +@code{st_dev}, taken together, uniquely identify the file. The +@code{st_dev} value is not necessarily consistent across reboots or +system crashes, however. + +@item nlink_t st_nlink +The number of hard links to the file. This count keeps track of how +many directories have entries for this file. If the count is ever +decremented to zero, then the file itself is discarded as soon as no +process still holds it open. Symbolic links are not counted in the +total. + +@item uid_t st_uid +The user ID of the file's owner. @xref{File Owner}. + +@item gid_t st_gid +The group ID of the file. @xref{File Owner}. + +@item off_t st_size +This specifies the size of a regular file in bytes. For files that +are really devices and the like, this field isn't usually meaningful. +For symbolic links, this specifies the length of the file name the link +refers to. + +@item time_t st_atime +This is the last access time for the file. @xref{File Times}. + +@item unsigned long int st_atime_usec +This is the fractional part of the last access time for the file. +@xref{File Times}. + +@item time_t st_mtime +This is the time of the last modification to the contents of the file. +@xref{File Times}. + +@item unsigned long int st_mtime_usec +This is the fractional part of the time of last modification to the +contents of the file. @xref{File Times}. + +@item time_t st_ctime +This is the time of the last modification to the attributes of the file. +@xref{File Times}. + +@item unsigned long int st_ctime_usec +This is the fractional part of the time of last modification to the +attributes of the file. @xref{File Times}. + +@c !!! st_rdev +@item unsigned int st_blocks +This is the amount of disk space that the file occupies, measured in +units of 512-byte blocks. + +The number of disk blocks is not strictly proportional to the size of +the file, for two reasons: the file system may use some blocks for +internal record keeping; and the file may be sparse---it may have +``holes'' which contain zeros but do not actually take up space on the +disk. + +You can tell (approximately) whether a file is sparse by comparing this +value with @code{st_size}, like this: + +@smallexample +(st.st_blocks * 512 < st.st_size) +@end smallexample + +This test is not perfect because a file that is just slightly sparse +might not be detected as sparse at all. For practical applications, +this is not a problem. + +@item unsigned int st_blksize +The optimal block size for reading of writing this file, in bytes. You +might use this size for allocating the buffer space for reading of +writing the file. (This is unrelated to @code{st_blocks}.) +@end table +@end deftp + + Some of the file attributes have special data type names which exist +specifically for those attributes. (They are all aliases for well-known +integer types that you know and love.) These typedef names are defined +in the header file @file{sys/types.h} as well as in @file{sys/stat.h}. +Here is a list of them. + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} mode_t +This is an integer data type used to represent file modes. In the +GNU system, this is equivalent to @code{unsigned int}. +@end deftp + +@cindex inode number +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} ino_t +This is an arithmetic data type used to represent file serial numbers. +(In Unix jargon, these are sometimes called @dfn{inode numbers}.) +In the GNU system, this type is equivalent to @code{unsigned long int}. +@end deftp + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} dev_t +This is an arithmetic data type used to represent file device numbers. +In the GNU system, this is equivalent to @code{int}. +@end deftp + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} nlink_t +This is an arithmetic data type used to represent file link counts. +In the GNU system, this is equivalent to @code{unsigned short int}. +@end deftp + +@node Reading Attributes +@subsection Reading the Attributes of a File + +To examine the attributes of files, use the functions @code{stat}, +@code{fstat} and @code{lstat}. They return the attribute information in +a @code{struct stat} object. All three functions are declared in the +header file @file{sys/stat.h}. + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun int stat (const char *@var{filename}, struct stat *@var{buf}) +The @code{stat} function returns information about the attributes of the +file named by @w{@var{filename}} in the structure pointed at by @var{buf}. + +If @var{filename} is the name of a symbolic link, the attributes you get +describe the file that the link points to. If the link points to a +nonexistent file name, then @code{stat} fails, reporting a nonexistent +file. + +The return value is @code{0} if the operation is successful, and @code{-1} +on failure. In addition to the usual file name errors +(@pxref{File Name Errors}, the following @code{errno} error conditions +are defined for this function: + +@table @code +@item ENOENT +The file named by @var{filename} doesn't exist. +@end table +@end deftypefun + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun int fstat (int @var{filedes}, struct stat *@var{buf}) +The @code{fstat} function is like @code{stat}, except that it takes an +open file descriptor as an argument instead of a file name. +@xref{Low-Level I/O}. + +Like @code{stat}, @code{fstat} returns @code{0} on success and @code{-1} +on failure. The following @code{errno} error conditions are defined for +@code{fstat}: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. +@end table +@end deftypefun + +@comment sys/stat.h +@comment BSD +@deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf}) +The @code{lstat} function is like @code{stat}, except that it does not +follow symbolic links. If @var{filename} is the name of a symbolic +link, @code{lstat} returns information about the link itself; otherwise, +@code{lstat} works like @code{stat}. @xref{Symbolic Links}. +@end deftypefun + +@node Testing File Type +@subsection Testing the Type of a File + +The @dfn{file mode}, stored in the @code{st_mode} field of the file +attributes, contains two kinds of information: the file type code, and +the access permission bits. This section discusses only the type code, +which you can use to tell whether the file is a directory, whether it is +a socket, and so on. For information about the access permission, +@ref{Permission Bits}. + +There are two predefined ways you can access the file type portion of +the file mode. First of all, for each type of file, there is a +@dfn{predicate macro} which examines a file mode value and returns +true or false---is the file of that type, or not. Secondly, you can +mask out the rest of the file mode to get just a file type code. +You can compare this against various constants for the supported file +types. + +All of the symbols listed in this section are defined in the header file +@file{sys/stat.h}. +@pindex sys/stat.h + +The following predicate macros test the type of a file, given the value +@var{m} which is the @code{st_mode} field returned by @code{stat} on +that file: + +@comment sys/stat.h +@comment POSIX +@deftypefn Macro int S_ISDIR (mode_t @var{m}) +This macro returns nonzero if the file is a directory. +@end deftypefn + +@comment sys/stat.h +@comment POSIX +@deftypefn Macro int S_ISCHR (mode_t @var{m}) +This macro returns nonzero if the file is a character special file (a +device like a terminal). +@end deftypefn + +@comment sys/stat.h +@comment POSIX +@deftypefn Macro int S_ISBLK (mode_t @var{m}) +This macro returns nonzero if the file is a block special file (a device +like a disk). +@end deftypefn + +@comment sys/stat.h +@comment POSIX +@deftypefn Macro int S_ISREG (mode_t @var{m}) +This macro returns nonzero if the file is a regular file. +@end deftypefn + +@comment sys/stat.h +@comment POSIX +@deftypefn Macro int S_ISFIFO (mode_t @var{m}) +This macro returns nonzero if the file is a FIFO special file, or a +pipe. @xref{Pipes and FIFOs}. +@end deftypefn + +@comment sys/stat.h +@comment GNU +@deftypefn Macro int S_ISLNK (mode_t @var{m}) +This macro returns nonzero if the file is a symbolic link. +@xref{Symbolic Links}. +@end deftypefn + +@comment sys/stat.h +@comment GNU +@deftypefn Macro int S_ISSOCK (mode_t @var{m}) +This macro returns nonzero if the file is a socket. @xref{Sockets}. +@end deftypefn + +An alterate non-POSIX method of testing the file type is supported for +compatibility with BSD. The mode can be bitwise ANDed with +@code{S_IFMT} to extract the file type code, and compared to the +appropriate type code constant. For example, + +@smallexample +S_ISCHR (@var{mode}) +@end smallexample + +@noindent +is equivalent to: + +@smallexample +((@var{mode} & S_IFMT) == S_IFCHR) +@end smallexample + +@comment sys/stat.h +@comment BSD +@deftypevr Macro int S_IFMT +This is a bit mask used to extract the file type code portion of a mode +value. +@end deftypevr + +These are the symbolic names for the different file type codes: + +@table @code +@comment sys/stat.h +@comment BSD +@item S_IFDIR +@vindex S_IFDIR +This macro represents the value of the file type code for a directory file. + +@comment sys/stat.h +@comment BSD +@item S_IFCHR +@vindex S_IFCHR +This macro represents the value of the file type code for a +character-oriented device file. + +@comment sys/stat.h +@comment BSD +@item S_IFBLK +@vindex S_IFBLK +This macro represents the value of the file type code for a block-oriented +device file. + +@comment sys/stat.h +@comment BSD +@item S_IFREG +@vindex S_IFREG +This macro represents the value of the file type code for a regular file. + +@comment sys/stat.h +@comment BSD +@item S_IFLNK +@vindex S_IFLNK +This macro represents the value of the file type code for a symbolic link. + +@comment sys/stat.h +@comment BSD +@item S_IFSOCK +@vindex S_IFSOCK +This macro represents the value of the file type code for a socket. + +@comment sys/stat.h +@comment BSD +@item S_IFIFO +@vindex S_IFIFO +This macro represents the value of the file type code for a FIFO or pipe. +@end table + +@node File Owner +@subsection File Owner +@cindex file owner +@cindex owner of a file +@cindex group owner of a file + +Every file has an @dfn{owner} which is one of the registered user names +defined on the system. Each file also has a @dfn{group}, which is one +of the defined groups. The file owner can often be useful for showing +you who edited the file (especially when you edit with GNU Emacs), but +its main purpose is for access control. + +The file owner and group play a role in determining access because the +file has one set of access permission bits for the user that is the +owner, another set that apply to users who belong to the file's group, +and a third set of bits that apply to everyone else. @xref{Access +Permission}, for the details of how access is decided based on this +data. + +When a file is created, its owner is set from the effective user ID of +the process that creates it (@pxref{Process Persona}). The file's group +ID may be set from either effective group ID of the process, or the +group ID of the directory that contains the file, depending on the +system where the file is stored. When you access a remote file system, +it behaves according to its own rule, not according to the system your +program is running on. Thus, your program must be prepared to encounter +either kind of behavior, no matter what kind of system you run it on. + +@pindex chown +@pindex chgrp +You can change the owner and/or group owner of an existing file using +the @code{chown} function. This is the primitive for the @code{chown} +and @code{chgrp} shell commands. + +@pindex unistd.h +The prototype for this function is declared in @file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int chown (const char *@var{filename}, uid_t @var{owner}, gid_t @var{group}) +The @code{chown} function changes the owner of the file @var{filename} to +@var{owner}, and its group owner to @var{group}. + +Changing the owner of the file on certain systems clears the set-user-ID +and set-group-ID bits of the file's permissions. (This is because those +bits may not be appropriate for the new owner.) The other file +permission bits are not changed. + +The return value is @code{0} on success and @code{-1} on failure. +In addition to the usual file name errors (@pxref{File Name Errors}), +the following @code{errno} error conditions are defined for this function: + +@table @code +@item EPERM +This process lacks permission to make the requested change. + +Only privileged users or the file's owner can change the file's group. +On most file systems, only privileged users can change the file owner; +some file systems allow you to change the owner if you are currently the +owner. When you access a remote file system, the behavior you encounter +is determined by the system that actually holds the file, not by the +system your program is running on. + +@xref{Options for Files}, for information about the +@code{_POSIX_CHOWN_RESTRICTED} macro. + +@item EROFS +The file is on a read-only file system. +@end table +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int fchown (int @var{filedes}, int @var{owner}, int @var{group}) +This is like @code{chown}, except that it changes the owner of the file +with open file descriptor @var{filedes}. + +The return value from @code{fchown} is @code{0} on success and @code{-1} +on failure. The following @code{errno} error codes are defined for this +function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINVAL +The @var{filedes} argument corresponds to a pipe or socket, not an ordinary +file. + +@item EPERM +This process lacks permission to make the requested change. For +details, see @code{chmod}, above. + +@item EROFS +The file resides on a read-only file system. +@end table +@end deftypefun + +@node Permission Bits +@subsection The Mode Bits for Access Permission + +The @dfn{file mode}, stored in the @code{st_mode} field of the file +attributes, contains two kinds of information: the file type code, and +the access permission bits. This section discusses only the access +permission bits, which control who can read or write the file. +@xref{Testing File Type}, for information about the file type code. + +All of the symbols listed in this section are defined in the header file +@file{sys/stat.h}. +@pindex sys/stat.h + +@cindex file permission bits +These symbolic constants are defined for the file mode bits that control +access permission for the file: + +@table @code +@comment sys/stat.h +@comment POSIX.1 +@item S_IRUSR +@vindex S_IRUSR +@comment sys/stat.h +@comment BSD +@itemx S_IREAD +@vindex S_IREAD +Read permission bit for the owner of the file. On many systems, this +bit is 0400. @code{S_IREAD} is an obsolete synonym provided for BSD +compatibility. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IWUSR +@vindex S_IWUSR +@comment sys/stat.h +@comment BSD +@itemx S_IWRITE +@vindex S_IWRITE +Write permission bit for the owner of the file. Usually 0200. +@w{@code{S_IWRITE}} is an obsolete synonym provided for BSD compatibility. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IXUSR +@vindex S_IXUSR +@comment sys/stat.h +@comment BSD +@itemx S_IEXEC +@vindex S_IEXEC +Execute (for ordinary files) or search (for directories) permission bit +for the owner of the file. Usually 0100. @code{S_IEXEC} is an obsolete +synonym provided for BSD compatibility. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IRWXU +@vindex S_IRWXU +This is equivalent to @samp{(S_IRUSR | S_IWUSR | S_IXUSR)}. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IRGRP +@vindex S_IRGRP +Read permission bit for the group owner of the file. Usually 040. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IWGRP +@vindex S_IWGRP +Write permission bit for the group owner of the file. Usually 020. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IXGRP +@vindex S_IXGRP +Execute or search permission bit for the group owner of the file. +Usually 010. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IRWXG +@vindex S_IRWXG +This is equivalent to @samp{(S_IRGRP | S_IWGRP | S_IXGRP)}. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IROTH +@vindex S_IROTH +Read permission bit for other users. Usually 04. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IWOTH +@vindex S_IWOTH +Write permission bit for other users. Usually 02. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IXOTH +@vindex S_IXOTH +Execute or search permission bit for other users. Usually 01. + +@comment sys/stat.h +@comment POSIX.1 +@item S_IRWXO +@vindex S_IRWXO +This is equivalent to @samp{(S_IROTH | S_IWOTH | S_IXOTH)}. + +@comment sys/stat.h +@comment POSIX +@item S_ISUID +@vindex S_ISUID +This is the set-user-ID on execute bit, usually 04000. +@xref{How Change Persona}. + +@comment sys/stat.h +@comment POSIX +@item S_ISGID +@vindex S_ISGID +This is the set-group-ID on execute bit, usually 02000. +@xref{How Change Persona}. + +@cindex sticky bit +@comment sys/stat.h +@comment BSD +@item S_ISVTX +@vindex S_ISVTX +This is the @dfn{sticky} bit, usually 01000. + +On a directory, it gives permission to delete a file in the directory +only if you own that file. Ordinarily, a user either can delete all the +files in the directory or cannot delete any of them (based on whether +the user has write permission for the directory). The same restriction +applies---you must both have write permission for the directory and own +the file you want to delete. The one exception is that the owner of the +directory can delete any file in the directory, no matter who owns it +(provided the owner has given himself write permission for the +directory). This is commonly used for the @file{/tmp} directory, where +anyone may create files, but not delete files created by other users. + +Originally the sticky bit on an executable file modified the swapping +policies of the system. Normally, when a program terminated, its pages +in core were immediately freed and reused. If the sticky bit was set on +the executable file, the system kept the pages in core for a while as if +the program were still running. This was advantageous for a program +likely to be run many times in succession. This usage is obsolete in +modern systems. When a program terminates, its pages always remain in +core as long as there is no shortage of memory in the system. When the +program is next run, its pages will still be in core if no shortage +arose since the last run. + +On some modern systems where the sticky bit has no useful meaning for an +executable file, you cannot set the bit at all for a non-directory. +If you try, @code{chmod} fails with @code{EFTYPE}; +@pxref{Setting Permissions}. + +Some systems (particularly SunOS) have yet another use for the sticky +bit. If the sticky bit is set on a file that is @emph{not} executable, +it means the opposite: never cache the pages of this file at all. The +main use of this is for the files on an NFS server machine which are +used as the swap area of diskless client machines. The idea is that the +pages of the file will be cached in the client's memory, so it is a +waste of the server's memory to cache them a second time. In this use +the sticky bit also says that the filesystem may fail to record the +file's modification time onto disk reliably (the idea being that noone +cares for a swap file). +@end table + +The actual bit values of the symbols are listed in the table above +so you can decode file mode values when debugging your programs. +These bit values are correct for most systems, but they are not +guaranteed. + +@strong{Warning:} Writing explicit numbers for file permissions is bad +practice. It is not only nonportable, it also requires everyone who +reads your program to remember what the bits mean. To make your +program clean, use the symbolic names. + +@node Access Permission +@subsection How Your Access to a File is Decided +@cindex permission to access a file +@cindex access permission for a file +@cindex file access permission + +Recall that the operating system normally decides access permission for +a file based on the effective user and group IDs of the process, and its +supplementary group IDs, together with the file's owner, group and +permission bits. These concepts are discussed in detail in +@ref{Process Persona}. + +If the effective user ID of the process matches the owner user ID of the +file, then permissions for read, write, and execute/search are +controlled by the corresponding ``user'' (or ``owner'') bits. Likewise, +if any of the effective group ID or supplementary group IDs of the +process matches the group owner ID of the file, then permissions are +controlled by the ``group'' bits. Otherwise, permissions are controlled +by the ``other'' bits. + +Privileged users, like @samp{root}, can access any file, regardless of +its file permission bits. As a special case, for a file to be +executable even for a privileged user, at least one of its execute bits +must be set. + +@node Setting Permissions +@subsection Assigning File Permissions + +@cindex file creation mask +@cindex umask +The primitive functions for creating files (for example, @code{open} or +@code{mkdir}) take a @var{mode} argument, which specifies the file +permissions for the newly created file. But the specified mode is +modified by the process's @dfn{file creation mask}, or @dfn{umask}, +before it is used. + +The bits that are set in the file creation mask identify permissions +that are always to be disabled for newly created files. For example, if +you set all the ``other'' access bits in the mask, then newly created +files are not accessible at all to processes in the ``other'' +category, even if the @var{mode} argument specified to the creation +function would permit such access. In other words, the file creation +mask is the complement of the ordinary access permissions you want to +grant. + +Programs that create files typically specify a @var{mode} argument that +includes all the permissions that make sense for the particular file. +For an ordinary file, this is typically read and write permission for +all classes of users. These permissions are then restricted as +specified by the individual user's own file creation mask. + +@findex chmod +To change the permission of an existing file given its name, call +@code{chmod}. This function ignores the file creation mask; it uses +exactly the specified permission bits. + +@pindex umask +In normal use, the file creation mask is initialized in the user's login +shell (using the @code{umask} shell command), and inherited by all +subprocesses. Application programs normally don't need to worry about +the file creation mask. It will do automatically what it is supposed to +do. + +When your program should create a file and bypass the umask for its +access permissions, the easiest way to do this is to use @code{fchmod} +after opening the file, rather than changing the umask. + +In fact, changing the umask is usually done only by shells. They use +the @code{umask} function. + +The functions in this section are declared in @file{sys/stat.h}. +@pindex sys/stat.h + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun mode_t umask (mode_t @var{mask}) +The @code{umask} function sets the file creation mask of the current +process to @var{mask}, and returns the previous value of the file +creation mask. + +Here is an example showing how to read the mask with @code{umask} +without changing it permanently: + +@smallexample +mode_t +read_umask (void) +@{ + mask = umask (0); + umask (mask); +@} +@end smallexample + +@noindent +However, it is better to use @code{getumask} if you just want to read +the mask value, because that is reentrant (at least if you use the GNU +operating system). +@end deftypefun + +@comment sys/stat.h +@comment GNU +@deftypefun mode_t getumask (void) +Return the current value of the file creation mask for the current +process. This function is a GNU extension. +@end deftypefun + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun int chmod (const char *@var{filename}, mode_t @var{mode}) +The @code{chmod} function sets the access permission bits for the file +named by @var{filename} to @var{mode}. + +If the @var{filename} names a symbolic link, @code{chmod} changes the +permission of the file pointed to by the link, not those of the link +itself. + +This function returns @code{0} if successful and @code{-1} if not. In +addition to the usual file name errors (@pxref{File Name +Errors}), the following @code{errno} error conditions are defined for +this function: + +@table @code +@item ENOENT +The named file doesn't exist. + +@item EPERM +This process does not have permission to change the access permission of +this file. Only the file's owner (as judged by the effective user ID of +the process) or a privileged user can change them. + +@item EROFS +The file resides on a read-only file system. + +@item EFTYPE +@var{mode} has the @code{S_ISVTX} bit (the ``sticky bit'') set, +and the named file is not a directory. Some systems do not allow setting the +sticky bit on non-directory files, and some do (and only some of those +assign a useful meaning to the bit for non-directory files). + +You only get @code{EFTYPE} on systems where the sticky bit has no useful +meaning for non-directory files, so it is always safe to just clear the +bit in @var{mode} and call @code{chmod} again. @xref{Permission Bits}, +for full details on the sticky bit. +@end table +@end deftypefun + +@comment sys/stat.h +@comment BSD +@deftypefun int fchmod (int @var{filedes}, int @var{mode}) +This is like @code{chmod}, except that it changes the permissions of +the file currently open via descriptor @var{filedes}. + +The return value from @code{fchmod} is @code{0} on success and @code{-1} +on failure. The following @code{errno} error codes are defined for this +function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINVAL +The @var{filedes} argument corresponds to a pipe or socket, or something +else that doesn't really have access permissions. + +@item EPERM +This process does not have permission to change the access permission of +this file. Only the file's owner (as judged by the effective user ID of +the process) or a privileged user can change them. + +@item EROFS +The file resides on a read-only file system. +@end table +@end deftypefun + +@node Testing File Access +@subsection Testing Permission to Access a File +@cindex testing access permission +@cindex access, testing for +@cindex setuid programs and file access + +When a program runs as a privileged user, this permits it to access +files off-limits to ordinary users---for example, to modify +@file{/etc/passwd}. Programs designed to be run by ordinary users but +access such files use the setuid bit feature so that they always run +with @code{root} as the effective user ID. + +Such a program may also access files specified by the user, files which +conceptually are being accessed explicitly by the user. Since the +program runs as @code{root}, it has permission to access whatever file +the user specifies---but usually the desired behavior is to permit only +those files which the user could ordinarily access. + +The program therefore must explicitly check whether @emph{the user} +would have the necessary access to a file, before it reads or writes the +file. + +To do this, use the function @code{access}, which checks for access +permission based on the process's @emph{real} user ID rather than the +effective user ID. (The setuid feature does not alter the real user ID, +so it reflects the user who actually ran the program.) + +There is another way you could check this access, which is easy to +describe, but very hard to use. This is to examine the file mode bits +and mimic the system's own access computation. This method is +undesirable because many systems have additional access control +features; your program cannot portably mimic them, and you would not +want to try to keep track of the diverse features that different systems +have. Using @code{access} is simple and automatically does whatever is +appropriate for the system you are using. + +@code{access} is @emph{only} only appropriate to use in setuid programs. +A non-setuid program will always use the effective ID rather than the +real ID. + +@pindex unistd.h +The symbols in this section are declared in @file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int access (const char *@var{filename}, int @var{how}) +The @code{access} function checks to see whether the file named by +@var{filename} can be accessed in the way specified by the @var{how} +argument. The @var{how} argument either can be the bitwise OR of the +flags @code{R_OK}, @code{W_OK}, @code{X_OK}, or the existence test +@code{F_OK}. + +This function uses the @emph{real} user and group ID's of the calling +process, rather than the @emph{effective} ID's, to check for access +permission. As a result, if you use the function from a @code{setuid} +or @code{setgid} program (@pxref{How Change Persona}), it gives +information relative to the user who actually ran the program. + +The return value is @code{0} if the access is permitted, and @code{-1} +otherwise. (In other words, treated as a predicate function, +@code{access} returns true if the requested access is @emph{denied}.) + +In addition to the usual file name errors (@pxref{File Name +Errors}), the following @code{errno} error conditions are defined for +this function: + +@table @code +@item EACCES +The access specified by @var{how} is denied. + +@item ENOENT +The file doesn't exist. + +@item EROFS +Write permission was requested for a file on a read-only file system. +@end table +@end deftypefun + +These macros are defined in the header file @file{unistd.h} for use +as the @var{how} argument to the @code{access} function. The values +are integer constants. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int R_OK +Argument that means, test for read permission. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int W_OK +Argument that means, test for write permission. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int X_OK +Argument that means, test for execute/search permission. +@end deftypevr + +@comment unistd.h +@comment POSIX.1 +@deftypevr Macro int F_OK +Argument that means, test for existence of the file. +@end deftypevr + +@node File Times +@subsection File Times + +@cindex file access time +@cindex file modification time +@cindex file attribute modification time +Each file has three timestamps associated with it: its access time, +its modification time, and its attribute modification time. These +correspond to the @code{st_atime}, @code{st_mtime}, and @code{st_ctime} +members of the @code{stat} structure; see @ref{File Attributes}. + +All of these times are represented in calendar time format, as +@code{time_t} objects. This data type is defined in @file{time.h}. +For more information about representation and manipulation of time +values, see @ref{Calendar Time}. +@pindex time.h + +Reading from a file updates its access time attribute, and writing +updates its modification time. When a file is created, all three +timestamps for that file are set to the current time. In addition, the +attribute change time and modification time fields of the directory that +contains the new entry are updated. + +Adding a new name for a file with the @code{link} function updates the +attribute change time field of the file being linked, and both the +attribute change time and modification time fields of the directory +containing the new name. These same fields are affected if a file name +is deleted with @code{unlink}, @code{remove}, or @code{rmdir}. Renaming +a file with @code{rename} affects only the attribute change time and +modification time fields of the two parent directories involved, and not +the times for the file being renamed. + +Changing attributes of a file (for example, with @code{chmod}) updates +its attribute change time field. + +You can also change some of the timestamps of a file explicitly using +the @code{utime} function---all except the attribute change time. You +need to include the header file @file{utime.h} to use this facility. +@pindex utime.h + +@comment time.h +@comment POSIX.1 +@deftp {Data Type} {struct utimbuf} +The @code{utimbuf} structure is used with the @code{utime} function to +specify new access and modification times for a file. It contains the +following members: + +@table @code +@item time_t actime +This is the access time for the file. + +@item time_t modtime +This is the modification time for the file. +@end table +@end deftp + +@comment time.h +@comment POSIX.1 +@deftypefun int utime (const char *@var{filename}, const struct utimbuf *@var{times}) +This function is used to modify the file times associated with the file +named @var{filename}. + +If @var{times} is a null pointer, then the access and modification times +of the file are set to the current time. Otherwise, they are set to the +values from the @code{actime} and @code{modtime} members (respectively) +of the @code{utimbuf} structure pointed at by @var{times}. + +The attribute modification time for the file is set to the current time +in either case (since changing the timestamps is itself a modification +of the file attributes). + +The @code{utime} function returns @code{0} if successful and @code{-1} +on failure. In addition to the usual file name errors +(@pxref{File Name Errors}), the following @code{errno} error conditions +are defined for this function: + +@table @code +@item EACCES +There is a permission problem in the case where a null pointer was +passed as the @var{times} argument. In order to update the timestamp on +the file, you must either be the owner of the file, have write +permission on the file, or be a privileged user. + +@item ENOENT +The file doesn't exist. + +@item EPERM +If the @var{times} argument is not a null pointer, you must either be +the owner of the file or be a privileged user. This error is used to +report the problem. + +@item EROFS +The file lives on a read-only file system. +@end table +@end deftypefun + +Each of the three time stamps has a corresponding microsecond part, +which extends its resolution. These fields are called +@code{st_atime_usec}, @code{st_mtime_usec}, and @code{st_ctime_usec}; +each has a value between 0 and 999,999, which indicates the time in +microseconds. They correspond to the @code{tv_usec} field of a +@code{timeval} structure; see @ref{High-Resolution Calendar}. + +The @code{utimes} function is like @code{utime}, but also lets you specify +the fractional part of the file times. The prototype for this function is +in the header file @file{sys/time.h}. +@pindex sys/time.h + +@comment sys/time.h +@comment BSD +@deftypefun int utimes (const char *@var{filename}, struct timeval @var{tvp}@t{[2]}) +This function sets the file access and modification times for the file +named by @var{filename}. The new file access time is specified by +@code{@var{tvp}[0]}, and the new modification time by +@code{@var{tvp}[1]}. This function comes from BSD. + +The return values and error conditions are the same as for the @code{utime} +function. +@end deftypefun + +@node Making Special Files +@section Making Special Files +@cindex creating special files +@cindex special files + +The @code{mknod} function is the primitive for making special files, +such as files that correspond to devices. The GNU library includes +this function for compatibility with BSD. + +The prototype for @code{mknod} is declared in @file{sys/stat.h}. +@pindex sys/stat.h + +@comment sys/stat.h +@comment BSD +@deftypefun int mknod (const char *@var{filename}, int @var{mode}, int @var{dev}) +The @code{mknod} function makes a special file with name @var{filename}. +The @var{mode} specifies the mode of the file, and may include the various +special file bits, such as @code{S_IFCHR} (for a character special file) +or @code{S_IFBLK} (for a block special file). @xref{Testing File Type}. + +The @var{dev} argument specifies which device the special file refers to. +Its exact interpretation depends on the kind of special file being created. + +The return value is @code{0} on success and @code{-1} on error. In addition +to the usual file name errors (@pxref{File Name Errors}), the +following @code{errno} error conditions are defined for this function: + +@table @code +@item EPERM +The calling process is not privileged. Only the superuser can create +special files. + +@item ENOSPC +The directory or file system that would contain the new file is full +and cannot be extended. + +@item EROFS +The directory containing the new file can't be modified because it's on +a read-only file system. + +@item EEXIST +There is already a file named @var{filename}. If you want to replace +this file, you must remove the old file explicitly first. +@end table +@end deftypefun + +@node Temporary Files +@section Temporary Files + +If you need to use a temporary file in your program, you can use the +@code{tmpfile} function to open it. Or you can use the @code{tmpnam} +function make a name for a temporary file and then open it in the usual +way with @code{fopen}. + +The @code{tempnam} function is like @code{tmpnam} but lets you choose +what directory temporary files will go in, and something about what +their file names will look like. + +These facilities are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun {FILE *} tmpfile (void) +This function creates a temporary binary file for update mode, as if by +calling @code{fopen} with mode @code{"wb+"}. The file is deleted +automatically when it is closed or when the program terminates. (On +some other ANSI C systems the file may fail to be deleted if the program +terminates abnormally). +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun {char *} tmpnam (char *@var{result}) +This function constructs and returns a file name that is a valid file +name and that does not name any existing file. If the @var{result} +argument is a null pointer, the return value is a pointer to an internal +static string, which might be modified by subsequent calls. Otherwise, +the @var{result} argument should be a pointer to an array of at least +@code{L_tmpnam} characters, and the result is written into that array. + +It is possible for @code{tmpnam} to fail if you call it too many times. +This is because the fixed length of a temporary file name gives room for +only a finite number of different names. If @code{tmpnam} fails, it +returns a null pointer. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypevr Macro int L_tmpnam +The value of this macro is an integer constant expression that represents +the minimum allocation size of a string large enough to hold the +file name generated by the @code{tmpnam} function. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int TMP_MAX +The macro @code{TMP_MAX} is a lower bound for how many temporary names +you can create with @code{tmpnam}. You can rely on being able to call +@code{tmpnam} at least this many times before it might fail saying you +have made too many temporary file names. + +With the GNU library, you can create a very large number of temporary +file names---if you actually create the files, you will probably run out +of disk space before you run out of names. Some other systems have a +fixed, small limit on the number of temporary files. The limit is never +less than @code{25}. +@end deftypevr + +@comment stdio.h +@comment SVID +@deftypefun {char *} tempnam (const char *@var{dir}, const char *@var{prefix}) +This function generates a unique temporary filename. If @var{prefix} is +not a null pointer, up to five characters of this string are used as a +prefix for the file name. The return value is a string newly allocated +with @code{malloc}; you should release its storage with @code{free} when +it is no longer needed. + +The directory prefix for the temporary file name is determined by testing +each of the following, in sequence. The directory must exist and be +writable. + +@itemize @bullet +@item +The environment variable @code{TMPDIR}, if it is defined. + +@item +The @var{dir} argument, if it is not a null pointer. + +@item +The value of the @code{P_tmpdir} macro. + +@item +The directory @file{/tmp}. +@end itemize + +This function is defined for SVID compatibility. +@end deftypefun +@cindex TMPDIR environment variable + +@comment stdio.h +@comment SVID +@c !!! are we putting SVID/GNU/POSIX.1/BSD in here or not?? +@deftypevr {SVID Macro} {char *} P_tmpdir +This macro is the name of the default directory for temporary files. +@end deftypevr + +Older Unix systems did not have the functions just described. Instead +they used @code{mktemp} and @code{mkstemp}. Both of these functions +work by modifying a file name template string you pass. The last six +characters of this string must be @samp{XXXXXX}. These six @samp{X}s +are replaced with six characters which make the whole string a unique +file name. Usually the template string is something like +@samp{/tmp/@var{prefix}XXXXXX}, and each program uses a unique @var{prefix}. + +@strong{Note:} Because @code{mktemp} and @code{mkstemp} modify the +template string, you @emph{must not} pass string constants to them. +String constants are normally in read-only storage, so your program +would crash when @code{mktemp} or @code{mkstemp} tried to modify the +string. + +@comment unistd.h +@comment Unix +@deftypefun {char *} mktemp (char *@var{template}) +The @code{mktemp} function generates a unique file name by modifying +@var{template} as described above. If successful, it returns +@var{template} as modified. If @code{mktemp} cannot find a unique file +name, it makes @var{template} an empty string and returns that. If +@var{template} does not end with @samp{XXXXXX}, @code{mktemp} returns a +null pointer. +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int mkstemp (char *@var{template}) +The @code{mkstemp} function generates a unique file name just as +@code{mktemp} does, but it also opens the file for you with @code{open} +(@pxref{Opening and Closing Files}). If successful, it modifies +@var{template} in place and returns a file descriptor open on that file +for reading and writing. If @code{mkstemp} cannot create a +uniquely-named file, it makes @var{template} an empty string and returns +@code{-1}. If @var{template} does not end with @samp{XXXXXX}, +@code{mkstemp} returns @code{-1} and does not modify @var{template}. +@end deftypefun + +Unlike @code{mktemp}, @code{mkstemp} is actually guaranteed to create a +unique file that cannot possibly clash with any other program trying to +create a temporary file. This is because it works by calling +@code{open} with the @code{O_EXCL} flag bit, which says you want to +always create a new file, and get an error if the file already exists. diff --git a/manual/header.texi b/manual/header.texi new file mode 100644 index 0000000000..588d77eabf --- /dev/null +++ b/manual/header.texi @@ -0,0 +1,14 @@ +@node Library Summary, Maintenance, Language Features, Top +@appendix Summary of Library Facilities + +This appendix is a complete list of the facilities declared within the +header files supplied with the GNU C library. Each entry also lists the +standard or other source from which each facility is derived, and tells +you where in the manual you can find more information about how to use +it. + +@table @code +@comment summary.texi is generated from the other Texinfo files. +@comment See the Makefile and summary.awk for the details. +@include summary.texi +@end table diff --git a/manual/intro.texi b/manual/intro.texi new file mode 100644 index 0000000000..19f04a1474 --- /dev/null +++ b/manual/intro.texi @@ -0,0 +1,689 @@ +@node Introduction, Error Reporting, Top, Top +@chapter Introduction + +The C language provides no built-in facilities for performing such +common operations as input/output, memory management, string +manipulation, and the like. Instead, these facilities are defined +in a standard @dfn{library}, which you compile and link with your +programs. +@cindex library + +The GNU C library, described in this document, defines all of the +library functions that are specified by the ANSI C standard, as well as +additional features specific to POSIX and other derivatives of the Unix +operating system, and extensions specific to the GNU system. + +The purpose of this manual is to tell you how to use the facilities +of the GNU library. We have mentioned which features belong to which +standards to help you identify things that are potentially nonportable +to other systems. But the emphasis in this manual is not on strict +portability. + +@menu +* Getting Started:: What this manual is for and how to use it. +* Standards and Portability:: Standards and sources upon which the GNU + C library is based. +* Using the Library:: Some practical uses for the library. +* Roadmap to the Manual:: Overview of the remaining chapters in + this manual. +@end menu + +@node Getting Started, Standards and Portability, , Introduction +@section Getting Started + +This manual is written with the assumption that you are at least +somewhat familiar with the C programming language and basic programming +concepts. Specifically, familiarity with ANSI standard C +(@pxref{ANSI C}), rather than ``traditional'' pre-ANSI C dialects, is +assumed. + +The GNU C library includes several @dfn{header files}, each of which +provides definitions and declarations for a group of related facilities; +this information is used by the C compiler when processing your program. +For example, the header file @file{stdio.h} declares facilities for +performing input and output, and the header file @file{string.h} +declares string processing utilities. The organization of this manual +generally follows the same division as the header files. + +If you are reading this manual for the first time, you should read all +of the introductory material and skim the remaining chapters. There are +a @emph{lot} of functions in the GNU C library and it's not realistic to +expect that you will be able to remember exactly @emph{how} to use each +and every one of them. It's more important to become generally familiar +with the kinds of facilities that the library provides, so that when you +are writing your programs you can recognize @emph{when} to make use of +library functions, and @emph{where} in this manual you can find more +specific information about them. + + +@node Standards and Portability, Using the Library, Getting Started, Introduction +@section Standards and Portability +@cindex standards + +This section discusses the various standards and other sources that the +GNU C library is based upon. These sources include the ANSI C and +POSIX standards, and the System V and Berkeley Unix implementations. + +The primary focus of this manual is to tell you how to make effective +use of the GNU library facilities. But if you are concerned about +making your programs compatible with these standards, or portable to +operating systems other than GNU, this can affect how you use the +library. This section gives you an overview of these standards, so that +you will know what they are when they are mentioned in other parts of +the manual. + +@xref{Library Summary}, for an alphabetical list of the functions and +other symbols provided by the library. This list also states which +standards each function or symbol comes from. + +@menu +* ANSI C:: The American National Standard for the + C programming language. +* POSIX:: The IEEE 1003 standards for operating + systems. +* Berkeley Unix:: BSD and SunOS. +* SVID:: The System V Interface Description. +@end menu + +@node ANSI C, POSIX, , Standards and Portability +@subsection ANSI C +@cindex ANSI C + +The GNU C library is compatible with the C standard adopted by the +American National Standards Institute (ANSI): +@cite{American National Standard X3.159-1989---``ANSI C''}. +The header files and library facilities that make up the GNU library are +a superset of those specified by the ANSI C standard.@refill + +@pindex gcc +If you are concerned about strict adherence to the ANSI C standard, you +should use the @samp{-ansi} option when you compile your programs with +the GNU C compiler. This tells the compiler to define @emph{only} ANSI +standard features from the library header files, unless you explicitly +ask for additional features. @xref{Feature Test Macros}, for +information on how to do this. + +Being able to restrict the library to include only ANSI C features is +important because ANSI C puts limitations on what names can be defined +by the library implementation, and the GNU extensions don't fit these +limitations. @xref{Reserved Names}, for more information about these +restrictions. + +This manual does not attempt to give you complete details on the +differences between ANSI C and older dialects. It gives advice on how +to write programs to work portably under multiple C dialects, but does +not aim for completeness. + +@node POSIX, Berkeley Unix, ANSI C, Standards and Portability +@subsection POSIX (The Portable Operating System Interface) +@cindex POSIX +@cindex POSIX.1 +@cindex IEEE Std 1003.1 +@cindex POSIX.2 +@cindex IEEE Std 1003.2 + +The GNU library is also compatible with the IEEE @dfn{POSIX} family of +standards, known more formally as the @dfn{Portable Operating System +Interface for Computer Environments}. POSIX is derived mostly from +various versions of the Unix operating system. + +The library facilities specified by the POSIX standards are a superset +of those required by ANSI C; POSIX specifies additional features for +ANSI C functions, as well as specifying new additional functions. In +general, the additional requirements and functionality defined by the +POSIX standards are aimed at providing lower-level support for a +particular kind of operating system environment, rather than general +programming language support which can run in many diverse operating +system environments.@refill + +The GNU C library implements all of the functions specified in +@cite{IEEE Std 1003.1-1990, the POSIX System Application Program +Interface}, commonly referred to as POSIX.1. The primary extensions to +the ANSI C facilities specified by this standard include file system +interface primitives (@pxref{File System Interface}), device-specific +terminal control functions (@pxref{Low-Level Terminal Interface}), and +process control functions (@pxref{Processes}). + +Some facilities from @cite{IEEE Std 1003.2-1992, the POSIX Shell and +Utilities standard} (POSIX.2) are also implemented in the GNU library. +These include utilities for dealing with regular expressions and other +pattern matching facilities (@pxref{Pattern Matching}). + +@comment Roland sez: +@comment The GNU C library as it stands conforms to 1003.2 draft 11, which +@comment specifies: +@comment +@comment Several new macros in <limits.h>. +@comment popen, pclose +@comment <regex.h> (which is not yet fully implemented--wait on this) +@comment fnmatch +@comment getopt +@comment <glob.h> +@comment <wordexp.h> (not yet implemented) +@comment confstr + + +@node Berkeley Unix, SVID, POSIX, Standards and Portability +@subsection Berkeley Unix +@cindex BSD Unix +@cindex 4.@var{n} BSD Unix +@cindex Berkeley Unix +@cindex SunOS +@cindex Unix, Berkeley + +The GNU C library defines facilities from some versions of Unix which +are not formally standardized, specifically from the 4.2 BSD, 4.3 BSD, +and 4.4 BSD Unix systems (also known as @dfn{Berkeley Unix}) and from +@dfn{SunOS} (a popular 4.2 BSD derivative that includes some Unix System +V functionality). These systems support most of the ANSI and POSIX +facilities, and 4.4 BSD and newer releases of SunOS in fact support them all. + +The BSD facilities include symbolic links (@pxref{Symbolic Links}), the +@code{select} function (@pxref{Waiting for I/O}), the BSD signal +functions (@pxref{BSD Signal Handling}), and sockets (@pxref{Sockets}). + +@node SVID, , Berkeley Unix, Standards and Portability +@subsection SVID (The System V Interface Description) +@cindex SVID +@cindex System V Unix +@cindex Unix, System V + +The @dfn{System V Interface Description} (SVID) is a document describing +the AT&T Unix System V operating system. It is to some extent a +superset of the POSIX standard (@pxref{POSIX}). + +The GNU C library defines some of the facilities required by the SVID +that are not also required by the ANSI or POSIX standards, for +compatibility with System V Unix and other Unix systems (such as +SunOS) which include these facilities. However, many of the more +obscure and less generally useful facilities required by the SVID are +not included. (In fact, Unix System V itself does not provide them all.) + +@c !!! mention sysv ipc/shmem when it is there. + + +@node Using the Library, Roadmap to the Manual, Standards and Portability, Introduction +@section Using the Library + +This section describes some of the practical issues involved in using +the GNU C library. + +@menu +* Header Files:: How to include the header files in your + programs. +* Macro Definitions:: Some functions in the library may really + be implemented as macros. +* Reserved Names:: The C standard reserves some names for + the library, and some for users. +* Feature Test Macros:: How to control what names are defined. +@end menu + +@node Header Files, Macro Definitions, , Using the Library +@subsection Header Files +@cindex header files + +Libraries for use by C programs really consist of two parts: @dfn{header +files} that define types and macros and declare variables and +functions; and the actual library or @dfn{archive} that contains the +definitions of the variables and functions. + +(Recall that in C, a @dfn{declaration} merely provides information that +a function or variable exists and gives its type. For a function +declaration, information about the types of its arguments might be +provided as well. The purpose of declarations is to allow the compiler +to correctly process references to the declared variables and functions. +A @dfn{definition}, on the other hand, actually allocates storage for a +variable or says what a function does.) +@cindex definition (compared to declaration) +@cindex declaration (compared to definition) + +In order to use the facilities in the GNU C library, you should be sure +that your program source files include the appropriate header files. +This is so that the compiler has declarations of these facilities +available and can correctly process references to them. Once your +program has been compiled, the linker resolves these references to +the actual definitions provided in the archive file. + +Header files are included into a program source file by the +@samp{#include} preprocessor directive. The C language supports two +forms of this directive; the first, + +@smallexample +#include "@var{header}" +@end smallexample + +@noindent +is typically used to include a header file @var{header} that you write +yourself; this would contain definitions and declarations describing the +interfaces between the different parts of your particular application. +By contrast, + +@smallexample +#include <file.h> +@end smallexample + +@noindent +is typically used to include a header file @file{file.h} that contains +definitions and declarations for a standard library. This file would +normally be installed in a standard place by your system administrator. +You should use this second form for the C library header files. + +Typically, @samp{#include} directives are placed at the top of the C +source file, before any other code. If you begin your source files with +some comments explaining what the code in the file does (a good idea), +put the @samp{#include} directives immediately afterwards, following the +feature test macro definition (@pxref{Feature Test Macros}). + +For more information about the use of header files and @samp{#include} +directives, @pxref{Header Files,,, cpp.info, The GNU C Preprocessor +Manual}.@refill + +The GNU C library provides several header files, each of which contains +the type and macro definitions and variable and function declarations +for a group of related facilities. This means that your programs may +need to include several header files, depending on exactly which +facilities you are using. + +Some library header files include other library header files +automatically. However, as a matter of programming style, you should +not rely on this; it is better to explicitly include all the header +files required for the library facilities you are using. The GNU C +library header files have been written in such a way that it doesn't +matter if a header file is accidentally included more than once; +including a header file a second time has no effect. Likewise, if your +program needs to include multiple header files, the order in which they +are included doesn't matter. + +@strong{Compatibility Note:} Inclusion of standard header files in any +order and any number of times works in any ANSI C implementation. +However, this has traditionally not been the case in many older C +implementations. + +Strictly speaking, you don't @emph{have to} include a header file to use +a function it declares; you could declare the function explicitly +yourself, according to the specifications in this manual. But it is +usually better to include the header file because it may define types +and macros that are not otherwise available and because it may define +more efficient macro replacements for some functions. It is also a sure +way to have the correct declaration. + +@node Macro Definitions, Reserved Names, Header Files, Using the Library +@subsection Macro Definitions of Functions +@cindex shadowing functions with macros +@cindex removing macros that shadow functions +@cindex undefining macros that shadow functions + +If we describe something as a function in this manual, it may have a +macro definition as well. This normally has no effect on how your +program runs---the macro definition does the same thing as the function +would. In particular, macro equivalents for library functions evaluate +arguments exactly once, in the same way that a function call would. The +main reason for these macro definitions is that sometimes they can +produce an inline expansion that is considerably faster than an actual +function call. + +Taking the address of a library function works even if it is also +defined as a macro. This is because, in this context, the name of the +function isn't followed by the left parenthesis that is syntactically +necessary to recognize a macro call. + +You might occasionally want to avoid using the macro definition of a +function---perhaps to make your program easier to debug. There are +two ways you can do this: + +@itemize @bullet +@item +You can avoid a macro definition in a specific use by enclosing the name +of the function in parentheses. This works because the name of the +function doesn't appear in a syntactic context where it is recognizable +as a macro call. + +@item +You can suppress any macro definition for a whole source file by using +the @samp{#undef} preprocessor directive, unless otherwise stated +explicitly in the description of that facility. +@end itemize + +For example, suppose the header file @file{stdlib.h} declares a function +named @code{abs} with + +@smallexample +extern int abs (int); +@end smallexample + +@noindent +and also provides a macro definition for @code{abs}. Then, in: + +@smallexample +#include <stdlib.h> +int f (int *i) @{ return (abs (++*i)); @} +@end smallexample + +@noindent +the reference to @code{abs} might refer to either a macro or a function. +On the other hand, in each of the following examples the reference is +to a function and not a macro. + +@smallexample +#include <stdlib.h> +int g (int *i) @{ return ((abs)(++*i)); @} + +#undef abs +int h (int *i) @{ return (abs (++*i)); @} +@end smallexample + +Since macro definitions that double for a function behave in +exactly the same way as the actual function version, there is usually no +need for any of these methods. In fact, removing macro definitions usually +just makes your program slower. + + +@node Reserved Names, Feature Test Macros, Macro Definitions, Using the Library +@subsection Reserved Names +@cindex reserved names +@cindex name space + +The names of all library types, macros, variables and functions that +come from the ANSI C standard are reserved unconditionally; your program +@strong{may not} redefine these names. All other library names are +reserved if your program explicitly includes the header file that +defines or declares them. There are several reasons for these +restrictions: + +@itemize @bullet +@item +Other people reading your code could get very confused if you were using +a function named @code{exit} to do something completely different from +what the standard @code{exit} function does, for example. Preventing +this situation helps to make your programs easier to understand and +contributes to modularity and maintainability. + +@item +It avoids the possibility of a user accidentally redefining a library +function that is called by other library functions. If redefinition +were allowed, those other functions would not work properly. + +@item +It allows the compiler to do whatever special optimizations it pleases +on calls to these functions, without the possibility that they may have +been redefined by the user. Some library facilities, such as those for +dealing with variadic arguments (@pxref{Variadic Functions}) +and non-local exits (@pxref{Non-Local Exits}), actually require a +considerable amount of cooperation on the part of the C compiler, and +implementationally it might be easier for the compiler to treat these as +built-in parts of the language. +@end itemize + +In addition to the names documented in this manual, reserved names +include all external identifiers (global functions and variables) that +begin with an underscore (@samp{_}) and all identifiers regardless of +use that begin with either two underscores or an underscore followed by +a capital letter are reserved names. This is so that the library and +header files can define functions, variables, and macros for internal +purposes without risk of conflict with names in user programs. + +Some additional classes of identifier names are reserved for future +extensions to the C language or the POSIX.1 environment. While using these +names for your own purposes right now might not cause a problem, they do +raise the possibility of conflict with future versions of the C +or POSIX standards, so you should avoid these names. + +@itemize @bullet +@item +Names beginning with a capital @samp{E} followed a digit or uppercase +letter may be used for additional error code names. @xref{Error +Reporting}. + +@item +Names that begin with either @samp{is} or @samp{to} followed by a +lowercase letter may be used for additional character testing and +conversion functions. @xref{Character Handling}. + +@item +Names that begin with @samp{LC_} followed by an uppercase letter may be +used for additional macros specifying locale attributes. +@xref{Locales}. + +@item +Names of all existing mathematics functions (@pxref{Mathematics}) +suffixed with @samp{f} or @samp{l} are reserved for corresponding +functions that operate on @code{float} and @code{long double} arguments, +respectively. + +@item +Names that begin with @samp{SIG} followed by an uppercase letter are +reserved for additional signal names. @xref{Standard Signals}. + +@item +Names that begin with @samp{SIG_} followed by an uppercase letter are +reserved for additional signal actions. @xref{Basic Signal Handling}. + +@item +Names beginning with @samp{str}, @samp{mem}, or @samp{wcs} followed by a +lowercase letter are reserved for additional string and array functions. +@xref{String and Array Utilities}. + +@item +Names that end with @samp{_t} are reserved for additional type names. +@end itemize + +In addition, some individual header files reserve names beyond +those that they actually define. You only need to worry about these +restrictions if your program includes that particular header file. + +@itemize @bullet +@item +The header file @file{dirent.h} reserves names prefixed with +@samp{d_}. +@pindex dirent.h + +@item +The header file @file{fcntl.h} reserves names prefixed with +@samp{l_}, @samp{F_}, @samp{O_}, and @samp{S_}. +@pindex fcntl.h + +@item +The header file @file{grp.h} reserves names prefixed with @samp{gr_}. +@pindex grp.h + +@item +The header file @file{limits.h} reserves names suffixed with @samp{_MAX}. +@pindex limits.h + +@item +The header file @file{pwd.h} reserves names prefixed with @samp{pw_}. +@pindex pwd.h + +@item +The header file @file{signal.h} reserves names prefixed with @samp{sa_} +and @samp{SA_}. +@pindex signal.h + +@item +The header file @file{sys/stat.h} reserves names prefixed with @samp{st_} +and @samp{S_}. +@pindex sys/stat.h + +@item +The header file @file{sys/times.h} reserves names prefixed with @samp{tms_}. +@pindex sys/times.h + +@item +The header file @file{termios.h} reserves names prefixed with @samp{c_}, +@samp{V}, @samp{I}, @samp{O}, and @samp{TC}; and names prefixed with +@samp{B} followed by a digit. +@pindex termios.h +@end itemize + +@comment Include the section on Creature Nest Macros. +@comment It is in a separate file so it can be formatted into ../NOTES. +@include creature.texi + +@node Roadmap to the Manual, , Using the Library, Introduction +@section Roadmap to the Manual + +Here is an overview of the contents of the remaining chapters of +this manual. + +@itemize @bullet +@item +@ref{Error Reporting}, describes how errors detected by the library +are reported. + +@item +@ref{Language Features}, contains information about library support for +standard parts of the C language, including things like the @code{sizeof} +operator and the symbolic constant @code{NULL}, how to write functions +accepting variable numbers of arguments, and constants describing the +ranges and other properties of the numerical types. There is also a simple +debugging mechanism which allows you to put assertions in your code, and +have diagnostic messages printed if the tests fail. + +@item +@ref{Memory Allocation}, describes the GNU library's facilities for +dynamic allocation of storage. If you do not know in advance how much +storage your program needs, you can allocate it dynamically instead, +and manipulate it via pointers. + +@item +@ref{Character Handling}, contains information about character +classification functions (such as @code{isspace}) and functions for +performing case conversion. + +@item +@ref{String and Array Utilities}, has descriptions of functions for +manipulating strings (null-terminated character arrays) and general +byte arrays, including operations such as copying and comparison. + +@item +@ref{I/O Overview}, gives an overall look at the input and output +facilities in the library, and contains information about basic concepts +such as file names. + +@item +@ref{I/O on Streams}, describes I/O operations involving streams (or +@w{@code{FILE *}} objects). These are the normal C library functions +from @file{stdio.h}. + +@item +@ref{Low-Level I/O}, contains information about I/O operations +on file descriptors. File descriptors are a lower-level mechanism +specific to the Unix family of operating systems. + +@item +@ref{File System Interface}, has descriptions of operations on entire +files, such as functions for deleting and renaming them and for creating +new directories. This chapter also contains information about how you +can access the attributes of a file, such as its owner and file protection +modes. + +@item +@ref{Pipes and FIFOs}, contains information about simple interprocess +communication mechanisms. Pipes allow communication between two related +processes (such as between a parent and child), while FIFOs allow +communication between processes sharing a common file system on the same +machine. + +@item +@ref{Sockets}, describes a more complicated interprocess communication +mechanism that allows processes running on different machines to +communicate over a network. This chapter also contains information about +Internet host addressing and how to use the system network databases. + +@item +@ref{Low-Level Terminal Interface}, describes how you can change the +attributes of a terminal device. If you want to disable echo of +characters typed by the user, for example, read this chapter. + +@item +@ref{Mathematics}, contains information about the math library +functions. These include things like random-number generators and +remainder functions on integers as well as the usual trigonometric and +exponential functions on floating-point numbers. + +@item +@ref{Arithmetic,, Low-Level Arithmetic Functions}, describes functions +for simple arithmetic, analysis of floating-point values, and reading +numbers from strings. + +@item +@ref{Searching and Sorting}, contains information about functions +for searching and sorting arrays. You can use these functions on any +kind of array by providing an appropriate comparison function. + +@item +@ref{Pattern Matching}, presents functions for matching regular expressions +and shell file name patterns, and for expanding words as the shell does. + +@item +@ref{Date and Time}, describes functions for measuring both calendar time +and CPU time, as well as functions for setting alarms and timers. + +@item +@ref{Extended Characters}, contains information about manipulating +characters and strings using character sets larger than will fit in +the usual @code{char} data type. + +@item +@ref{Locales}, describes how selecting a particular country +or language affects the behavior of the library. For example, the locale +affects collation sequences for strings and how monetary values are +formatted. + +@item +@ref{Non-Local Exits}, contains descriptions of the @code{setjmp} and +@code{longjmp} functions. These functions provide a facility for +@code{goto}-like jumps which can jump from one function to another. + +@item +@ref{Signal Handling}, tells you all about signals---what they are, +how to establish a handler that is called when a particular kind of +signal is delivered, and how to prevent signals from arriving during +critical sections of your program. + +@item +@ref{Process Startup}, tells how your programs can access their +command-line arguments and environment variables. + +@item +@ref{Processes}, contains information about how to start new processes +and run programs. + +@item +@ref{Job Control}, describes functions for manipulating process groups +and the controlling terminal. This material is probably only of +interest if you are writing a shell or other program which handles job +control specially. + +@item +@ref{User Database}, and @ref{Group Database}, tell you how to access +the system user and group databases. + +@item +@ref{System Information}, describes functions for getting information +about the hardware and software configuration your program is executing +under. + +@item +@ref{System Configuration}, tells you how you can get information about +various operating system limits. Most of these parameters are provided for +compatibility with POSIX. + +@item +@ref{Library Summary}, gives a summary of all the functions, variables, and +macros in the library, with complete data types and function prototypes, +and says what standard or system each is derived from. + +@item +@ref{Maintenance}, explains how to build and install the GNU C library on +your system, how to report any bugs you might find, and how to add new +functions or port the library to a new system. +@end itemize + +If you already know the name of the facility you are interested in, you +can look it up in @ref{Library Summary}. This gives you a summary of +its syntax and a pointer to where you can find a more detailed +description. This appendix is particularly useful if you just want to +verify the order and type of arguments to a function, for example. It +also tells you what standard or system each function, variable, or macro +is derived from. diff --git a/manual/io.texi b/manual/io.texi new file mode 100644 index 0000000000..84fd0a9e44 --- /dev/null +++ b/manual/io.texi @@ -0,0 +1,396 @@ +@node I/O Overview, I/O on Streams, Pattern Matching, Top +@chapter Input/Output Overview + +Most programs need to do either input (reading data) or output (writing +data), or most frequently both, in order to do anything useful. The GNU +C library provides such a large selection of input and output functions +that the hardest part is often deciding which function is most +appropriate! + +This chapter introduces concepts and terminology relating to input +and output. Other chapters relating to the GNU I/O facilities are: + +@itemize @bullet +@item +@ref{I/O on Streams}, which covers the high-level functions +that operate on streams, including formatted input and output. + +@item +@ref{Low-Level I/O}, which covers the basic I/O and control +functions on file descriptors. + +@item +@ref{File System Interface}, which covers functions for operating on +directories and for manipulating file attributes such as access modes +and ownership. + +@item +@ref{Pipes and FIFOs}, which includes information on the basic interprocess +communication facilities. + +@item +@ref{Sockets}, which covers a more complicated interprocess communication +facility with support for networking. + +@item +@ref{Low-Level Terminal Interface}, which covers functions for changing +how input and output to terminal or other serial devices are processed. +@end itemize + + +@menu +* I/O Concepts:: Some basic information and terminology. +* File Names:: How to refer to a file. +@end menu + +@node I/O Concepts, File Names, , I/O Overview +@section Input/Output Concepts + +Before you can read or write the contents of a file, you must establish +a connection or communications channel to the file. This process is +called @dfn{opening} the file. You can open a file for reading, writing, +or both. +@cindex opening a file + +The connection to an open file is represented either as a stream or as a +file descriptor. You pass this as an argument to the functions that do +the actual read or write operations, to tell them which file to operate +on. Certain functions expect streams, and others are designed to +operate on file descriptors. + +When you have finished reading to or writing from the file, you can +terminate the connection by @dfn{closing} the file. Once you have +closed a stream or file descriptor, you cannot do any more input or +output operations on it. + +@menu +* Streams and File Descriptors:: The GNU Library provides two ways + to access the contents of files. +* File Position:: The number of bytes from the + beginning of the file. +@end menu + +@node Streams and File Descriptors, File Position, , I/O Concepts +@subsection Streams and File Descriptors + +When you want to do input or output to a file, you have a choice of two +basic mechanisms for representing the connection between your program +and the file: file descriptors and streams. File descriptors are +represented as objects of type @code{int}, while streams are represented +as @code{FILE *} objects. + +File descriptors provide a primitive, low-level interface to input and +output operations. Both file descriptors and streams can represent a +connection to a device (such as a terminal), or a pipe or socket for +communicating with another process, as well as a normal file. But, if +you want to do control operations that are specific to a particular kind +of device, you must use a file descriptor; there are no facilities to +use streams in this way. You must also use file descriptors if your +program needs to do input or output in special modes, such as +nonblocking (or polled) input (@pxref{File Status Flags}). + +Streams provide a higher-level interface, layered on top of the +primitive file descriptor facilities. The stream interface treats all +kinds of files pretty much alike---the sole exception being the three +styles of buffering that you can choose (@pxref{Stream Buffering}). + +The main advantage of using the stream interface is that the set of +functions for performing actual input and output operations (as opposed +to control operations) on streams is much richer and more powerful than +the corresponding facilities for file descriptors. The file descriptor +interface provides only simple functions for transferring blocks of +characters, but the stream interface also provides powerful formatted +input and output functions (@code{printf} and @code{scanf}) as well as +functions for character- and line-oriented input and output. +@c !!! glibc has dprintf, which lets you do printf on an fd. + +Since streams are implemented in terms of file descriptors, you can +extract the file descriptor from a stream and perform low-level +operations directly on the file descriptor. You can also initially open +a connection as a file descriptor and then make a stream associated with +that file descriptor. + +In general, you should stick with using streams rather than file +descriptors, unless there is some specific operation you want to do that +can only be done on a file descriptor. If you are a beginning +programmer and aren't sure what functions to use, we suggest that you +concentrate on the formatted input functions (@pxref{Formatted Input}) +and formatted output functions (@pxref{Formatted Output}). + +If you are concerned about portability of your programs to systems other +than GNU, you should also be aware that file descriptors are not as +portable as streams. You can expect any system running ANSI C to +support streams, but non-GNU systems may not support file descriptors at +all, or may only implement a subset of the GNU functions that operate on +file descriptors. Most of the file descriptor functions in the GNU +library are included in the POSIX.1 standard, however. + +@node File Position, , Streams and File Descriptors, I/O Concepts +@subsection File Position + +One of the attributes of an open file is its @dfn{file position} that +keeps track of where in the file the next character is to be read or +written. In the GNU system, and all POSIX.1 systems, the file position +is simply an integer representing the number of bytes from the beginning +of the file. + +The file position is normally set to the beginning of the file when it +is opened, and each time a character is read or written, the file +position is incremented. In other words, access to the file is normally +@dfn{sequential}. +@cindex file position +@cindex sequential-access files + +Ordinary files permit read or write operations at any position within +the file. Some other kinds of files may also permit this. Files which +do permit this are sometimes referred to as @dfn{random-access} files. +You can change the file position using the @code{fseek} function on a +stream (@pxref{File Positioning}) or the @code{lseek} function on a file +descriptor (@pxref{I/O Primitives}). If you try to change the file +position on a file that doesn't support random access, you get the +@code{ESPIPE} error. +@cindex random-access files + +Streams and descriptors that are opened for @dfn{append access} are +treated specially for output: output to such files is @emph{always} +appended sequentially to the @emph{end} of the file, regardless of the +file position. However, the file position is still used to control where in +the file reading is done. +@cindex append-access files + +If you think about it, you'll realize that several programs can read a +given file at the same time. In order for each program to be able to +read the file at its own pace, each program must have its own file +pointer, which is not affected by anything the other programs do. + +In fact, each opening of a file creates a separate file position. +Thus, if you open a file twice even in the same program, you get two +streams or descriptors with independent file positions. + +By contrast, if you open a descriptor and then duplicate it to get +another descriptor, these two descriptors share the same file position: +changing the file position of one descriptor will affect the other. + +@node File Names, , I/O Concepts, I/O Overview +@section File Names + +In order to open a connection to a file, or to perform other operations +such as deleting a file, you need some way to refer to the file. Nearly +all files have names that are strings---even files which are actually +devices such as tape drives or terminals. These strings are called +@dfn{file names}. You specify the file name to say which file you want +to open or operate on. + +This section describes the conventions for file names and how the +operating system works with them. +@cindex file name + +@menu +* Directories:: Directories contain entries for files. +* File Name Resolution:: A file name specifies how to look up a file. +* File Name Errors:: Error conditions relating to file names. +* File Name Portability:: File name portability and syntax issues. +@end menu + + +@node Directories, File Name Resolution, , File Names +@subsection Directories + +In order to understand the syntax of file names, you need to understand +how the file system is organized into a hierarchy of directories. + +@cindex directory +@cindex link +@cindex directory entry +A @dfn{directory} is a file that contains information to associate other +files with names; these associations are called @dfn{links} or +@dfn{directory entries}. Sometimes, people speak of ``files in a +directory'', but in reality, a directory only contains pointers to +files, not the files themselves. + +@cindex file name component +The name of a file contained in a directory entry is called a @dfn{file +name component}. In general, a file name consists of a sequence of one +or more such components, separated by the slash character (@samp{/}). A +file name which is just one component names a file with respect to its +directory. A file name with multiple components names a directory, and +then a file in that directory, and so on. + +Some other documents, such as the POSIX standard, use the term +@dfn{pathname} for what we call a file name, and either @dfn{filename} +or @dfn{pathname component} for what this manual calls a file name +component. We don't use this terminology because a ``path'' is +something completely different (a list of directories to search), and we +think that ``pathname'' used for something else will confuse users. We +always use ``file name'' and ``file name component'' (or sometimes just +``component'', where the context is obvious) in GNU documentation. Some +macros use the POSIX terminology in their names, such as +@code{PATH_MAX}. These macros are defined by the POSIX standard, so we +cannot change their names. + +You can find more detailed information about operations on directories +in @ref{File System Interface}. + +@node File Name Resolution, File Name Errors, Directories, File Names +@subsection File Name Resolution + +A file name consists of file name components separated by slash +(@samp{/}) characters. On the systems that the GNU C library supports, +multiple successive @samp{/} characters are equivalent to a single +@samp{/} character. + +@cindex file name resolution +The process of determining what file a file name refers to is called +@dfn{file name resolution}. This is performed by examining the +components that make up a file name in left-to-right order, and locating +each successive component in the directory named by the previous +component. Of course, each of the files that are referenced as +directories must actually exist, be directories instead of regular +files, and have the appropriate permissions to be accessible by the +process; otherwise the file name resolution fails. + +@cindex root directory +@cindex absolute file name +If a file name begins with a @samp{/}, the first component in the file +name is located in the @dfn{root directory} of the process (usually all +processes on the system have the same root directory). Such a file name +is called an @dfn{absolute file name}. +@c !!! xref here to chroot, if we ever document chroot. -rm + +@cindex relative file name +Otherwise, the first component in the file name is located in the +current working directory (@pxref{Working Directory}). This kind of +file name is called a @dfn{relative file name}. + +@cindex parent directory +The file name components @file{.} (``dot'') and @file{..} (``dot-dot'') +have special meanings. Every directory has entries for these file name +components. The file name component @file{.} refers to the directory +itself, while the file name component @file{..} refers to its +@dfn{parent directory} (the directory that contains the link for the +directory in question). As a special case, @file{..} in the root +directory refers to the root directory itself, since it has no parent; +thus @file{/..} is the same as @file{/}. + +Here are some examples of file names: + +@table @file +@item /a +The file named @file{a}, in the root directory. + +@item /a/b +The file named @file{b}, in the directory named @file{a} in the root directory. + +@item a +The file named @file{a}, in the current working directory. + +@item /a/./b +This is the same as @file{/a/b}. + +@item ./a +The file named @file{a}, in the current working directory. + +@item ../a +The file named @file{a}, in the parent directory of the current working +directory. +@end table + +@c An empty string may ``work'', but I think it's confusing to +@c try to describe it. It's not a useful thing for users to use--rms. +A file name that names a directory may optionally end in a @samp{/}. +You can specify a file name of @file{/} to refer to the root directory, +but the empty string is not a meaningful file name. If you want to +refer to the current working directory, use a file name of @file{.} or +@file{./}. + +Unlike some other operating systems, the GNU system doesn't have any +built-in support for file types (or extensions) or file versions as part +of its file name syntax. Many programs and utilities use conventions +for file names---for example, files containing C source code usually +have names suffixed with @samp{.c}---but there is nothing in the file +system itself that enforces this kind of convention. + +@node File Name Errors, File Name Portability, File Name Resolution, File Names +@subsection File Name Errors + +@cindex file name errors +@cindex usual file name errors + +Functions that accept file name arguments usually detect these +@code{errno} error conditions relating to the file name syntax or +trouble finding the named file. These errors are referred to throughout +this manual as the @dfn{usual file name errors}. + +@table @code +@item EACCES +The process does not have search permission for a directory component +of the file name. + +@item ENAMETOOLONG +This error is used when either the the total length of a file name is +greater than @code{PATH_MAX}, or when an individual file name component +has a length greater than @code{NAME_MAX}. @xref{Limits for Files}. + +In the GNU system, there is no imposed limit on overall file name +length, but some file systems may place limits on the length of a +component. + +@item ENOENT +This error is reported when a file referenced as a directory component +in the file name doesn't exist, or when a component is a symbolic link +whose target file does not exist. @xref{Symbolic Links}. + +@item ENOTDIR +A file that is referenced as a directory component in the file name +exists, but it isn't a directory. + +@item ELOOP +Too many symbolic links were resolved while trying to look up the file +name. The system has an arbitrary limit on the number of symbolic links +that may be resolved in looking up a single file name, as a primitive +way to detect loops. @xref{Symbolic Links}. +@end table + + +@node File Name Portability, , File Name Errors, File Names +@subsection Portability of File Names + +The rules for the syntax of file names discussed in @ref{File Names}, +are the rules normally used by the GNU system and by other POSIX +systems. However, other operating systems may use other conventions. + +There are two reasons why it can be important for you to be aware of +file name portability issues: + +@itemize @bullet +@item +If your program makes assumptions about file name syntax, or contains +embedded literal file name strings, it is more difficult to get it to +run under other operating systems that use different syntax conventions. + +@item +Even if you are not concerned about running your program on machines +that run other operating systems, it may still be possible to access +files that use different naming conventions. For example, you may be +able to access file systems on another computer running a different +operating system over a network, or read and write disks in formats used +by other operating systems. +@end itemize + +The ANSI C standard says very little about file name syntax, only that +file names are strings. In addition to varying restrictions on the +length of file names and what characters can validly appear in a file +name, different operating systems use different conventions and syntax +for concepts such as structured directories and file types or +extensions. Some concepts such as file versions might be supported in +some operating systems and not by others. + +The POSIX.1 standard allows implementations to put additional +restrictions on file name syntax, concerning what characters are +permitted in file names and on the length of file name and file name +component strings. However, in the GNU system, you do not need to worry +about these restrictions; any character except the null character is +permitted in a file name string, and there are no limits on the length +of file name strings. + + diff --git a/manual/job.texi b/manual/job.texi new file mode 100644 index 0000000000..1ac15fffc4 --- /dev/null +++ b/manual/job.texi @@ -0,0 +1,1249 @@ +@node Job Control +@chapter Job Control + +@cindex process groups +@cindex job control +@cindex job +@cindex session +@dfn{Job control} refers to the protocol for allowing a user to move +between multiple @dfn{process groups} (or @dfn{jobs}) within a single +@dfn{login session}. The job control facilities are set up so that +appropriate behavior for most programs happens automatically and they +need not do anything special about job control. So you can probably +ignore the material in this chapter unless you are writing a shell or +login program. + +You need to be familiar with concepts relating to process creation +(@pxref{Process Creation Concepts}) and signal handling (@pxref{Signal +Handling}) in order to understand this material presented in this +chapter. + +@menu +* Concepts of Job Control:: Jobs can be controlled by a shell. +* Job Control is Optional:: Not all POSIX systems support job control. +* Controlling Terminal:: How a process gets its controlling terminal. +* Access to the Terminal:: How processes share the controlling terminal. +* Orphaned Process Groups:: Jobs left after the user logs out. +* Implementing a Shell:: What a shell must do to implement job control. +* Functions for Job Control:: Functions to control process groups. +@end menu + +@node Concepts of Job Control, Job Control is Optional, , Job Control +@section Concepts of Job Control + +@cindex shell +The fundamental purpose of an interactive shell is to read +commands from the user's terminal and create processes to execute the +programs specified by those commands. It can do this using the +@code{fork} (@pxref{Creating a Process}) and @code{exec} +(@pxref{Executing a File}) functions. + +A single command may run just one process---but often one command uses +several processes. If you use the @samp{|} operator in a shell command, +you explicitly request several programs in their own processes. But +even if you run just one program, it can use multiple processes +internally. For example, a single compilation command such as @samp{cc +-c foo.c} typically uses four processes (though normally only two at any +given time). If you run @code{make}, its job is to run other programs +in separate processes. + +The processes belonging to a single command are called a @dfn{process +group} or @dfn{job}. This is so that you can operate on all of them at +once. For example, typing @kbd{C-c} sends the signal @code{SIGINT} to +terminate all the processes in the foreground process group. + +@cindex session +A @dfn{session} is a larger group of processes. Normally all the +proccesses that stem from a single login belong to the same session. + +Every process belongs to a process group. When a process is created, it +becomes a member of the same process group and session as its parent +process. You can put it in another process group using the +@code{setpgid} function, provided the process group belongs to the same +session. + +@cindex session leader +The only way to put a process in a different session is to make it the +initial process of a new session, or a @dfn{session leader}, using the +@code{setsid} function. This also puts the session leader into a new +process group, and you can't move it out of that process group again. + +Usually, new sessions are created by the system login program, and the +session leader is the process running the user's login shell. + +@cindex controlling terminal +A shell that supports job control must arrange to control which job can +use the terminal at any time. Otherwise there might be multiple jobs +trying to read from the terminal at once, and confusion about which +process should receive the input typed by the user. To prevent this, +the shell must cooperate with the terminal driver using the protocol +described in this chapter. + +@cindex foreground job +@cindex background job +The shell can give unlimited access to the controlling terminal to only +one process group at a time. This is called the @dfn{foreground job} on +that controlling terminal. Other process groups managed by the shell +that are executing without such access to the terminal are called +@dfn{background jobs}. + +@cindex stopped job +If a background job needs to read from its controlling +terminal, it is @dfn{stopped} by the terminal driver; if the +@code{TOSTOP} mode is set, likewise for writing. The user can stop +a foreground job by typing the SUSP character (@pxref{Special +Characters}) and a program can stop any job by sending it a +@code{SIGSTOP} signal. It's the responsibility of the shell to notice +when jobs stop, to notify the user about them, and to provide mechanisms +for allowing the user to interactively continue stopped jobs and switch +jobs between foreground and background. + +@xref{Access to the Terminal}, for more information about I/O to the +controlling terminal, + +@node Job Control is Optional, Controlling Terminal, Concepts of Job Control , Job Control +@section Job Control is Optional +@cindex job control is optional + +Not all operating systems support job control. The GNU system does +support job control, but if you are using the GNU library on some other +system, that system may not support job control itself. + +You can use the @code{_POSIX_JOB_CONTROL} macro to test at compile-time +whether the system supports job control. @xref{System Options}. + +If job control is not supported, then there can be only one process +group per session, which behaves as if it were always in the foreground. +The functions for creating additional process groups simply fail with +the error code @code{ENOSYS}. + +The macros naming the various job control signals (@pxref{Job Control +Signals}) are defined even if job control is not supported. However, +the system never generates these signals, and attempts to send a job +control signal or examine or specify their actions report errors or do +nothing. + + +@node Controlling Terminal, Access to the Terminal, Job Control is Optional, Job Control +@section Controlling Terminal of a Process + +One of the attributes of a process is its controlling terminal. Child +processes created with @code{fork} inherit the controlling terminal from +their parent process. In this way, all the processes in a session +inherit the controlling terminal from the session leader. A session +leader that has control of a terminal is called the @dfn{controlling +process} of that terminal. + +@cindex controlling process +You generally do not need to worry about the exact mechanism used to +allocate a controlling terminal to a session, since it is done for you +by the system when you log in. +@c ??? How does GNU system let a process get a ctl terminal. + +An individual process disconnects from its controlling terminal when it +calls @code{setsid} to become the leader of a new session. +@xref{Process Group Functions}. + +@c !!! explain how it gets a new one (by opening any terminal) +@c ??? How you get a controlling terminal is system-dependent. +@c We should document how this will work in the GNU system when it is decided. +@c What Unix does is not clean and I don't think GNU should use that. + +@node Access to the Terminal, Orphaned Process Groups, Controlling Terminal, Job Control +@section Access to the Controlling Terminal +@cindex controlling terminal, access to + +Processes in the foreground job of a controlling terminal have +unrestricted access to that terminal; background proesses do not. This +section describes in more detail what happens when a process in a +background job tries to access its controlling terminal. + +@cindex @code{SIGTTIN}, from background job +When a process in a background job tries to read from its controlling +terminal, the process group is usually sent a @code{SIGTTIN} signal. +This normally causes all of the processes in that group to stop (unless +they handle the signal and don't stop themselves). However, if the +reading process is ignoring or blocking this signal, then @code{read} +fails with an @code{EIO} error instead. + +@cindex @code{SIGTTOU}, from background job +Similarly, when a process in a background job tries to write to its +controlling terminal, the default behavior is to send a @code{SIGTTOU} +signal to the process group. However, the behavior is modified by the +@code{TOSTOP} bit of the local modes flags (@pxref{Local Modes}). If +this bit is not set (which is the default), then writing to the +controlling terminal is always permitted without sending a signal. +Writing is also permitted if the @code{SIGTTOU} signal is being ignored +or blocked by the writing process. + +Most other terminal operations that a program can do are treated as +reading or as writing. (The description of each operation should say +which.) + +For more information about the primitive @code{read} and @code{write} +functions, see @ref{I/O Primitives}. + + +@node Orphaned Process Groups, Implementing a Shell, Access to the Terminal, Job Control +@section Orphaned Process Groups +@cindex orphaned process group + +When a controlling process terminates, its terminal becomes free and a +new session can be established on it. (In fact, another user could log +in on the terminal.) This could cause a problem if any processes from +the old session are still trying to use that terminal. + +To prevent problems, process groups that continue running even after the +session leader has terminated are marked as @dfn{orphaned process +groups}. + +When a process group becomes an orphan, its processes are sent a +@code{SIGHUP} signal. Ordinarily, this causes the processes to +terminate. However, if a program ignores this signal or establishes a +handler for it (@pxref{Signal Handling}), it can continue running as in +the orphan process group even after its controlling process terminates; +but it still cannot access the terminal any more. + +@node Implementing a Shell, Functions for Job Control, Orphaned Process Groups, Job Control +@section Implementing a Job Control Shell + +This section describes what a shell must do to implement job control, by +presenting an extensive sample program to illustrate the concepts +involved. + +@iftex +@itemize @bullet +@item +@ref{Data Structures}, introduces the example and presents +its primary data structures. + +@item +@ref{Initializing the Shell}, discusses actions which the shell must +perform to prepare for job control. + +@item +@ref{Launching Jobs}, includes information about how to create jobs +to execute commands. + +@item +@ref{Foreground and Background}, discusses what the shell should +do differently when launching a job in the foreground as opposed to +a background job. + +@item +@ref{Stopped and Terminated Jobs}, discusses reporting of job status +back to the shell. + +@item +@ref{Continuing Stopped Jobs}, tells you how to continue jobs that +have been stopped. + +@item +@ref{Missing Pieces}, discusses other parts of the shell. +@end itemize +@end iftex + +@menu +* Data Structures:: Introduction to the sample shell. +* Initializing the Shell:: What the shell must do to take + responsibility for job control. +* Launching Jobs:: Creating jobs to execute commands. +* Foreground and Background:: Putting a job in foreground of background. +* Stopped and Terminated Jobs:: Reporting job status. +* Continuing Stopped Jobs:: How to continue a stopped job in + the foreground or background. +* Missing Pieces:: Other parts of the shell. +@end menu + +@node Data Structures, Initializing the Shell, , Implementing a Shell +@subsection Data Structures for the Shell + +All of the program examples included in this chapter are part of +a simple shell program. This section presents data structures +and utility functions which are used throughout the example. + +The sample shell deals mainly with two data structures. The +@code{job} type contains information about a job, which is a +set of subprocesses linked together with pipes. The @code{process} type +holds information about a single subprocess. Here are the relevant +data structure declarations: + +@smallexample +@group +/* @r{A process is a single process.} */ +typedef struct process +@{ + struct process *next; /* @r{next process in pipeline} */ + char **argv; /* @r{for exec} */ + pid_t pid; /* @r{process ID} */ + char completed; /* @r{true if process has completed} */ + char stopped; /* @r{true if process has stopped} */ + int status; /* @r{reported status value} */ +@} process; +@end group + +@group +/* @r{A job is a pipeline of processes.} */ +typedef struct job +@{ + struct job *next; /* @r{next active job} */ + char *command; /* @r{command line, used for messages} */ + process *first_process; /* @r{list of processes in this job} */ + pid_t pgid; /* @r{process group ID} */ + char notified; /* @r{true if user told about stopped job} */ + struct termios tmodes; /* @r{saved terminal modes} */ + int stdin, stdout, stderr; /* @r{standard i/o channels} */ +@} job; + +/* @r{The active jobs are linked into a list. This is its head.} */ +job *first_job = NULL; +@end group +@end smallexample + +Here are some utility functions that are used for operating on @code{job} +objects. + +@smallexample +@group +/* @r{Find the active job with the indicated @var{pgid}.} */ +job * +find_job (pid_t pgid) +@{ + job *j; + + for (j = first_job; j; j = j->next) + if (j->pgid == pgid) + return j; + return NULL; +@} +@end group + +@group +/* @r{Return true if all processes in the job have stopped or completed.} */ +int +job_is_stopped (job *j) +@{ + process *p; + + for (p = j->first_process; p; p = p->next) + if (!p->completed && !p->stopped) + return 0; + return 1; +@} +@end group + +@group +/* @r{Return true if all processes in the job have completed.} */ +int +job_is_completed (job *j) +@{ + process *p; + + for (p = j->first_process; p; p = p->next) + if (!p->completed) + return 0; + return 1; +@} +@end group +@end smallexample + + +@node Initializing the Shell, Launching Jobs, Data Structures, Implementing a Shell +@subsection Initializing the Shell +@cindex job control, enabling +@cindex subshell + +When a shell program that normally performs job control is started, it +has to be careful in case it has been invoked from another shell that is +already doing its own job control. + +A subshell that runs interactively has to ensure that it has been placed +in the foreground by its parent shell before it can enable job control +itself. It does this by getting its initial process group ID with the +@code{getpgrp} function, and comparing it to the process group ID of the +current foreground job associated with its controlling terminal (which +can be retrieved using the @code{tcgetpgrp} function). + +If the subshell is not running as a foreground job, it must stop itself +by sending a @code{SIGTTIN} signal to its own process group. It may not +arbitrarily put itself into the foreground; it must wait for the user to +tell the parent shell to do this. If the subshell is continued again, +it should repeat the check and stop itself again if it is still not in +the foreground. + +@cindex job control, enabling +Once the subshell has been placed into the foreground by its parent +shell, it can enable its own job control. It does this by calling +@code{setpgid} to put itself into its own process group, and then +calling @code{tcsetpgrp} to place this process group into the +foreground. + +When a shell enables job control, it should set itself to ignore all the +job control stop signals so that it doesn't accidentally stop itself. +You can do this by setting the action for all the stop signals to +@code{SIG_IGN}. + +A subshell that runs non-interactively cannot and should not support job +control. It must leave all processes it creates in the same process +group as the shell itself; this allows the non-interactive shell and its +child processes to be treated as a single job by the parent shell. This +is easy to do---just don't use any of the job control primitives---but +you must remember to make the shell do it. + + +Here is the initialization code for the sample shell that shows how to +do all of this. + +@smallexample +/* @r{Keep track of attributes of the shell.} */ + +#include <sys/types.h> +#include <termios.h> +#include <unistd.h> + +pid_t shell_pgid; +struct termios shell_tmodes; +int shell_terminal; +int shell_is_interactive; + + +/* @r{Make sure the shell is running interactively as the foreground job} + @r{before proceeding.} */ + +void +init_shell () +@{ + + /* @r{See if we are running interactively.} */ + shell_terminal = STDIN_FILENO; + shell_is_interactive = isatty (shell_terminal); + + if (shell_is_interactive) + @{ + /* @r{Loop until we are in the foreground.} */ + while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ())) + kill (- shell_pgid, SIGTTIN); + + /* @r{Ignore interactive and job-control signals.} */ + signal (SIGINT, SIG_IGN); + signal (SIGQUIT, SIG_IGN); + signal (SIGTSTP, SIG_IGN); + signal (SIGTTIN, SIG_IGN); + signal (SIGTTOU, SIG_IGN); + signal (SIGCHLD, SIG_IGN); + + /* @r{Put ourselves in our own process group.} */ + shell_pgid = getpid (); + if (setpgid (shell_pgid, shell_pgid) < 0) + @{ + perror ("Couldn't put the shell in its own process group"); + exit (1); + @} + + /* @r{Grab control of the terminal.} */ + tcsetpgrp (shell_terminal, shell_pgid); + + /* @r{Save default terminal attributes for shell.} */ + tcgetattr (shell_terminal, &shell_tmodes); + @} +@} +@end smallexample + + +@node Launching Jobs, Foreground and Background, Initializing the Shell, Implementing a Shell +@subsection Launching Jobs +@cindex launching jobs + +Once the shell has taken responsibility for performing job control on +its controlling terminal, it can launch jobs in response to commands +typed by the user. + +To create the processes in a process group, you use the same @code{fork} +and @code{exec} functions described in @ref{Process Creation Concepts}. +Since there are multiple child processes involved, though, things are a +little more complicated and you must be careful to do things in the +right order. Otherwise, nasty race conditions can result. + +You have two choices for how to structure the tree of parent-child +relationships among the processes. You can either make all the +processes in the process group be children of the shell process, or you +can make one process in group be the ancestor of all the other processes +in that group. The sample shell program presented in this chapter uses +the first approach because it makes bookkeeping somewhat simpler. + +@cindex process group leader +@cindex process group ID +As each process is forked, it should put itself in the new process group +by calling @code{setpgid}; see @ref{Process Group Functions}. The first +process in the new group becomes its @dfn{process group leader}, and its +process ID becomes the @dfn{process group ID} for the group. + +@cindex race conditions, relating to job control +The shell should also call @code{setpgid} to put each of its child +processes into the new process group. This is because there is a +potential timing problem: each child process must be put in the process +group before it begins executing a new program, and the shell depends on +having all the child processes in the group before it continues +executing. If both the child processes and the shell call +@code{setpgid}, this ensures that the right things happen no matter which +process gets to it first. + +If the job is being launched as a foreground job, the new process group +also needs to be put into the foreground on the controlling terminal +using @code{tcsetpgrp}. Again, this should be done by the shell as well +as by each of its child processes, to avoid race conditions. + +The next thing each child process should do is to reset its signal +actions. + +During initialization, the shell process set itself to ignore job +control signals; see @ref{Initializing the Shell}. As a result, any child +processes it creates also ignore these signals by inheritance. This is +definitely undesirable, so each child process should explicitly set the +actions for these signals back to @code{SIG_DFL} just after it is forked. + +Since shells follow this convention, applications can assume that they +inherit the correct handling of these signals from the parent process. +But every application has a responsibility not to mess up the handling +of stop signals. Applications that disable the normal interpretation of +the SUSP character should provide some other mechanism for the user to +stop the job. When the user invokes this mechanism, the program should +send a @code{SIGTSTP} signal to the process group of the process, not +just to the process itself. @xref{Signaling Another Process}. + +Finally, each child process should call @code{exec} in the normal way. +This is also the point at which redirection of the standard input and +output channels should be handled. @xref{Duplicating Descriptors}, +for an explanation of how to do this. + +Here is the function from the sample shell program that is responsible +for launching a program. The function is executed by each child process +immediately after it has been forked by the shell, and never returns. + +@smallexample +void +launch_process (process *p, pid_t pgid, + int infile, int outfile, int errfile, + int foreground) +@{ + pid_t pid; + + if (shell_is_interactive) + @{ + /* @r{Put the process into the process group and give the process group} + @r{the terminal, if appropriate.} + @r{This has to be done both by the shell and in the individual} + @r{child processes because of potential race conditions.} */ + pid = getpid (); + if (pgid == 0) pgid = pid; + setpgid (pid, pgid); + if (foreground) + tcsetpgrp (shell_terminal, pgid); + + /* @r{Set the handling for job control signals back to the default.} */ + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGTSTP, SIG_DFL); + signal (SIGTTIN, SIG_DFL); + signal (SIGTTOU, SIG_DFL); + signal (SIGCHLD, SIG_DFL); + @} + + /* @r{Set the standard input/output channels of the new process.} */ + if (infile != STDIN_FILENO) + @{ + dup2 (infile, STDIN_FILENO); + close (infile); + @} + if (outfile != STDOUT_FILENO) + @{ + dup2 (outfile, STDOUT_FILENO); + close (outfile); + @} + if (errfile != STDERR_FILENO) + @{ + dup2 (errfile, STDERR_FILENO); + close (errfile); + @} + + /* @r{Exec the new process. Make sure we exit.} */ + execvp (p->argv[0], p->argv); + perror ("execvp"); + exit (1); +@} +@end smallexample + +If the shell is not running interactively, this function does not do +anything with process groups or signals. Remember that a shell not +performing job control must keep all of its subprocesses in the same +process group as the shell itself. + +Next, here is the function that actually launches a complete job. +After creating the child processes, this function calls some other +functions to put the newly created job into the foreground or background; +these are discussed in @ref{Foreground and Background}. + +@smallexample +void +launch_job (job *j, int foreground) +@{ + process *p; + pid_t pid; + int mypipe[2], infile, outfile; + + infile = j->stdin; + for (p = j->first_process; p; p = p->next) + @{ + /* @r{Set up pipes, if necessary.} */ + if (p->next) + @{ + if (pipe (mypipe) < 0) + @{ + perror ("pipe"); + exit (1); + @} + outfile = mypipe[1]; + @} + else + outfile = j->stdout; + + /* @r{Fork the child processes.} */ + pid = fork (); + if (pid == 0) + /* @r{This is the child process.} */ + launch_process (p, j->pgid, infile, + outfile, j->stderr, foreground); + else if (pid < 0) + @{ + /* @r{The fork failed.} */ + perror ("fork"); + exit (1); + @} + else + @{ + /* @r{This is the parent process.} */ + p->pid = pid; + if (shell_is_interactive) + @{ + if (!j->pgid) + j->pgid = pid; + setpgid (pid, j->pgid); + @} + @} + + /* @r{Clean up after pipes.} */ + if (infile != j->stdin) + close (infile); + if (outfile != j->stdout) + close (outfile); + infile = mypipe[0]; + @} + + format_job_info (j, "launched"); + + if (!shell_is_interactive) + wait_for_job (j); + else if (foreground) + put_job_in_foreground (j, 0); + else + put_job_in_background (j, 0); +@} +@end smallexample + + +@node Foreground and Background, Stopped and Terminated Jobs, Launching Jobs, Implementing a Shell +@subsection Foreground and Background + +Now let's consider what actions must be taken by the shell when it +launches a job into the foreground, and how this differs from what +must be done when a background job is launched. + +@cindex foreground job, launching +When a foreground job is launched, the shell must first give it access +to the controlling terminal by calling @code{tcsetpgrp}. Then, the +shell should wait for processes in that process group to terminate or +stop. This is discussed in more detail in @ref{Stopped and Terminated +Jobs}. + +When all of the processes in the group have either completed or stopped, +the shell should regain control of the terminal for its own process +group by calling @code{tcsetpgrp} again. Since stop signals caused by +I/O from a background process or a SUSP character typed by the user +are sent to the process group, normally all the processes in the job +stop together. + +The foreground job may have left the terminal in a strange state, so the +shell should restore its own saved terminal modes before continuing. In +case the job is merely been stopped, the shell should first save the +current terminal modes so that it can restore them later if the job is +continued. The functions for dealing with terminal modes are +@code{tcgetattr} and @code{tcsetattr}; these are described in +@ref{Terminal Modes}. + +Here is the sample shell's function for doing all of this. + +@smallexample +@group +/* @r{Put job @var{j} in the foreground. If @var{cont} is nonzero,} + @r{restore the saved terminal modes and send the process group a} + @r{@code{SIGCONT} signal to wake it up before we block.} */ + +void +put_job_in_foreground (job *j, int cont) +@{ + /* @r{Put the job into the foreground.} */ + tcsetpgrp (shell_terminal, j->pgid); +@end group + +@group + /* @r{Send the job a continue signal, if necessary.} */ + if (cont) + @{ + tcsetattr (shell_terminal, TCSADRAIN, &j->tmodes); + if (kill (- j->pgid, SIGCONT) < 0) + perror ("kill (SIGCONT)"); + @} +@end group + + /* @r{Wait for it to report.} */ + wait_for_job (j); + + /* @r{Put the shell back in the foreground.} */ + tcsetpgrp (shell_terminal, shell_pgid); + +@group + /* @r{Restore the shell's terminal modes.} */ + tcgetattr (shell_terminal, &j->tmodes); + tcsetattr (shell_terminal, TCSADRAIN, &shell_tmodes); +@} +@end group +@end smallexample + +@cindex background job, launching +If the process group is launched as a background job, the shell should +remain in the foreground itself and continue to read commands from +the terminal. + +In the sample shell, there is not much that needs to be done to put +a job into the background. Here is the function it uses: + +@smallexample +/* @r{Put a job in the background. If the cont argument is true, send} + @r{the process group a @code{SIGCONT} signal to wake it up.} */ + +void +put_job_in_background (job *j, int cont) +@{ + /* @r{Send the job a continue signal, if necessary.} */ + if (cont) + if (kill (-j->pgid, SIGCONT) < 0) + perror ("kill (SIGCONT)"); +@} +@end smallexample + + +@node Stopped and Terminated Jobs, Continuing Stopped Jobs, Foreground and Background, Implementing a Shell +@subsection Stopped and Terminated Jobs + +@cindex stopped jobs, detecting +@cindex terminated jobs, detecting +When a foreground process is launched, the shell must block until all of +the processes in that job have either terminated or stopped. It can do +this by calling the @code{waitpid} function; see @ref{Process +Completion}. Use the @code{WUNTRACED} option so that status is reported +for processes that stop as well as processes that terminate. + +The shell must also check on the status of background jobs so that it +can report terminated and stopped jobs to the user; this can be done by +calling @code{waitpid} with the @code{WNOHANG} option. A good place to +put a such a check for terminated and stopped jobs is just before +prompting for a new command. + +@cindex @code{SIGCHLD}, handling of +The shell can also receive asynchronous notification that there is +status information available for a child process by establishing a +handler for @code{SIGCHLD} signals. @xref{Signal Handling}. + +In the sample shell program, the @code{SIGCHLD} signal is normally +ignored. This is to avoid reentrancy problems involving the global data +structures the shell manipulates. But at specific times when the shell +is not using these data structures---such as when it is waiting for +input on the terminal---it makes sense to enable a handler for +@code{SIGCHLD}. The same function that is used to do the synchronous +status checks (@code{do_job_notification}, in this case) can also be +called from within this handler. + +Here are the parts of the sample shell program that deal with checking +the status of jobs and reporting the information to the user. + +@smallexample +@group +/* @r{Store the status of the process @var{pid} that was returned by waitpid.} + @r{Return 0 if all went well, nonzero otherwise.} */ + +int +mark_process_status (pid_t pid, int status) +@{ + job *j; + process *p; +@end group + +@group + if (pid > 0) + @{ + /* @r{Update the record for the process.} */ + for (j = first_job; j; j = j->next) + for (p = j->first_process; p; p = p->next) + if (p->pid == pid) + @{ + p->status = status; + if (WIFSTOPPED (status)) + p->stopped = 1; + else + @{ + p->completed = 1; + if (WIFSIGNALED (status)) + fprintf (stderr, "%d: Terminated by signal %d.\n", + (int) pid, WTERMSIG (p->status)); + @} + return 0; + @} + fprintf (stderr, "No child process %d.\n", pid); + return -1; + @} +@end group +@group + else if (pid == 0 || errno == ECHILD) + /* @r{No processes ready to report.} */ + return -1; + else @{ + /* @r{Other weird errors.} */ + perror ("waitpid"); + return -1; + @} +@} +@end group + +@group +/* @r{Check for processes that have status information available,} + @r{without blocking.} */ + +void +update_status (void) +@{ + int status; + pid_t pid; + + do + pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG); + while (!mark_process_status (pid, status)); +@} +@end group + +@group +/* @r{Check for processes that have status information available,} + @r{blocking until all processes in the given job have reported.} */ + +void +wait_for_job (job *j) +@{ + int status; + pid_t pid; + + do + pid = waitpid (WAIT_ANY, &status, WUNTRACED); + while (!mark_process_status (pid, status) + && !job_is_stopped (j) + && !job_is_completed (j)); +@} +@end group + +@group +/* @r{Format information about job status for the user to look at.} */ + +void +format_job_info (job *j, const char *status) +@{ + fprintf (stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command); +@} +@end group + +@group +/* @r{Notify the user about stopped or terminated jobs.} + @r{Delete terminated jobs from the active job list.} */ + +void +do_job_notification (void) +@{ + job *j, *jlast, *jnext; + process *p; + + /* @r{Update status information for child processes.} */ + update_status (); + + jlast = NULL; + for (j = first_job; j; j = jnext) + @{ + jnext = j->next; + + /* @r{If all processes have completed, tell the user the job has} + @r{completed and delete it from the list of active jobs.} */ + if (job_is_completed (j)) @{ + format_job_info (j, "completed"); + if (jlast) + jlast->next = jnext; + else + first_job = jnext; + free_job (j); + @} + + /* @r{Notify the user about stopped jobs,} + @r{marking them so that we won't do this more than once.} */ + else if (job_is_stopped (j) && !j->notified) @{ + format_job_info (j, "stopped"); + j->notified = 1; + jlast = j; + @} + + /* @r{Don't say anything about jobs that are still running.} */ + else + jlast = j; + @} +@} +@end group +@end smallexample + +@node Continuing Stopped Jobs, Missing Pieces, Stopped and Terminated Jobs, Implementing a Shell +@subsection Continuing Stopped Jobs + +@cindex stopped jobs, continuing +The shell can continue a stopped job by sending a @code{SIGCONT} signal +to its process group. If the job is being continued in the foreground, +the shell should first invoke @code{tcsetpgrp} to give the job access to +the terminal, and restore the saved terminal settings. After continuing +a job in the foreground, the shell should wait for the job to stop or +complete, as if the job had just been launched in the foreground. + +The sample shell program handles both newly created and continued jobs +with the same pair of functions, @w{@code{put_job_in_foreground}} and +@w{@code{put_job_in_background}}. The definitions of these functions +were given in @ref{Foreground and Background}. When continuing a +stopped job, a nonzero value is passed as the @var{cont} argument to +ensure that the @code{SIGCONT} signal is sent and the terminal modes +reset, as appropriate. + +This leaves only a function for updating the shell's internal bookkeeping +about the job being continued: + +@smallexample +@group +/* @r{Mark a stopped job J as being running again.} */ + +void +mark_job_as_running (job *j) +@{ + Process *p; + + for (p = j->first_process; p; p = p->next) + p->stopped = 0; + j->notified = 0; +@} +@end group + +@group +/* @r{Continue the job J.} */ + +void +continue_job (job *j, int foreground) +@{ + mark_job_as_running (j); + if (foreground) + put_job_in_foreground (j, 1); + else + put_job_in_background (j, 1); +@} +@end group +@end smallexample + +@node Missing Pieces, , Continuing Stopped Jobs, Implementing a Shell +@subsection The Missing Pieces + +The code extracts for the sample shell included in this chapter are only +a part of the entire shell program. In particular, nothing at all has +been said about how @code{job} and @code{program} data structures are +allocated and initialized. + +Most real shells provide a complex user interface that has support for +a command language; variables; abbreviations, substitutions, and pattern +matching on file names; and the like. All of this is far too complicated +to explain here! Instead, we have concentrated on showing how to +implement the core process creation and job control functions that can +be called from such a shell. + +Here is a table summarizing the major entry points we have presented: + +@table @code +@item void init_shell (void) +Initialize the shell's internal state. @xref{Initializing the +Shell}. + +@item void launch_job (job *@var{j}, int @var{foreground}) +Launch the job @var{j} as either a foreground or background job. +@xref{Launching Jobs}. + +@item void do_job_notification (void) +Check for and report any jobs that have terminated or stopped. Can be +called synchronously or within a handler for @code{SIGCHLD} signals. +@xref{Stopped and Terminated Jobs}. + +@item void continue_job (job *@var{j}, int @var{foreground}) +Continue the job @var{j}. @xref{Continuing Stopped Jobs}. +@end table + +Of course, a real shell would also want to provide other functions for +managing jobs. For example, it would be useful to have commands to list +all active jobs or to send a signal (such as @code{SIGKILL}) to a job. + + +@node Functions for Job Control, , Implementing a Shell, Job Control +@section Functions for Job Control +@cindex process group functions +@cindex job control functions + +This section contains detailed descriptions of the functions relating +to job control. + +@menu +* Identifying the Terminal:: Determining the controlling terminal's name. +* Process Group Functions:: Functions for manipulating process groups. +* Terminal Access Functions:: Functions for controlling terminal access. +@end menu + + +@node Identifying the Terminal, Process Group Functions, , Functions for Job Control +@subsection Identifying the Controlling Terminal +@cindex controlling terminal, determining + +You can use the @code{ctermid} function to get a file name that you can +use to open the controlling terminal. In the GNU library, it returns +the same string all the time: @code{"/dev/tty"}. That is a special +``magic'' file name that refers to the controlling terminal of the +current process (if it has one). To find the name of the specific +terminal device, use @code{ttyname}; @pxref{Is It a Terminal}. + +The function @code{ctermid} is declared in the header file +@file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment POSIX.1 +@deftypefun {char *} ctermid (char *@var{string}) +The @code{ctermid} function returns a string containing the file name of +the controlling terminal for the current process. If @var{string} is +not a null pointer, it should be an array that can hold at least +@code{L_ctermid} characters; the string is returned in this array. +Otherwise, a pointer to a string in a static area is returned, which +might get overwritten on subsequent calls to this function. + +An empty string is returned if the file name cannot be determined for +any reason. Even if a file name is returned, access to the file it +represents is not guaranteed. +@end deftypefun + +@comment stdio.h +@comment POSIX.1 +@deftypevr Macro int L_ctermid +The value of this macro is an integer constant expression that +represents the size of a string large enough to hold the file name +returned by @code{ctermid}. +@end deftypevr + +See also the @code{isatty} and @code{ttyname} functions, in +@ref{Is It a Terminal}. + + +@node Process Group Functions, Terminal Access Functions, Identifying the Terminal, Functions for Job Control +@subsection Process Group Functions + +Here are descriptions of the functions for manipulating process groups. +Your program should include the header files @file{sys/types.h} and +@file{unistd.h} to use these functions. +@pindex unistd.h +@pindex sys/types.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t setsid (void) +The @code{setsid} function creates a new session. The calling process +becomes the session leader, and is put in a new process group whose +process group ID is the same as the process ID of that process. There +are initially no other processes in the new process group, and no other +process groups in the new session. + +This function also makes the calling process have no controlling terminal. + +The @code{setsid} function returns the new process group ID of the +calling process if successful. A return value of @code{-1} indicates an +error. The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EPERM +The calling process is already a process group leader, or there is +already another process group around that has the same process group ID. +@end table +@end deftypefun + +The @code{getpgrp} function has two definitions: one derived from BSD +Unix, and one from the POSIX.1 standard. The feature test macros you +have selected (@pxref{Feature Test Macros}) determine which definition +you get. Specifically, you get the BSD version if you define +@code{_BSD_SOURCE}; otherwise, you get the POSIX version if you define +@code{_POSIX_SOURCE} or @code{_GNU_SOURCE}. Programs written for old +BSD systems will not include @file{unistd.h}, which defines +@code{getpgrp} specially under @code{_BSD_SOURCE}. You must link such +programs with the @code{-lbsd-compat} option to get the BSD definition.@refill +@pindex -lbsd-compat +@pindex bsd-compat +@cindex BSD compatibility library + +@comment unistd.h +@comment POSIX.1 +@deftypefn {POSIX.1 Function} pid_t getpgrp (void) +The POSIX.1 definition of @code{getpgrp} returns the process group ID of +the calling process. +@end deftypefn + +@comment unistd.h +@comment BSD +@deftypefn {BSD Function} pid_t getpgrp (pid_t @var{pid}) +The BSD definition of @code{getpgrp} returns the process group ID of the +process @var{pid}. You can supply a value of @code{0} for the @var{pid} +argument to get information about the calling process. +@end deftypefn + +@comment unistd.h +@comment POSIX.1 +@deftypefun int setpgid (pid_t @var{pid}, pid_t @var{pgid}) +The @code{setpgid} function puts the process @var{pid} into the process +group @var{pgid}. As a special case, either @var{pid} or @var{pgid} can +be zero to indicate the process ID of the calling process. + +This function fails on a system that does not support job control. +@xref{Job Control is Optional}, for more information. + +If the operation is successful, @code{setpgid} returns zero. Otherwise +it returns @code{-1}. The following @code{errno} error conditions are +defined for this function: + +@table @code +@item EACCES +The child process named by @var{pid} has executed an @code{exec} +function since it was forked. + +@item EINVAL +The value of the @var{pgid} is not valid. + +@item ENOSYS +The system doesn't support job control. + +@item EPERM +The process indicated by the @var{pid} argument is a session leader, +or is not in the same session as the calling process, or the value of +the @var{pgid} argument doesn't match a process group ID in the same +session as the calling process. + +@item ESRCH +The process indicated by the @var{pid} argument is not the calling +process or a child of the calling process. +@end table +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int setpgrp (pid_t @var{pid}, pid_t @var{pgid}) +This is the BSD Unix name for @code{setpgid}. Both functions do exactly +the same thing. +@end deftypefun + + +@node Terminal Access Functions, , Process Group Functions, Functions for Job Control +@subsection Functions for Controlling Terminal Access + +These are the functions for reading or setting the foreground +process group of a terminal. You should include the header files +@file{sys/types.h} and @file{unistd.h} in your application to use +these functions. +@pindex unistd.h +@pindex sys/types.h + +Although these functions take a file descriptor argument to specify +the terminal device, the foreground job is associated with the terminal +file itself and not a particular open file descriptor. + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t tcgetpgrp (int @var{filedes}) +This function returns the process group ID of the foreground process +group associated with the terminal open on descriptor @var{filedes}. + +If there is no foreground process group, the return value is a number +greater than @code{1} that does not match the process group ID of any +existing process group. This can happen if all of the processes in the +job that was formerly the foreground job have terminated, and no other +job has yet been moved into the foreground. + +In case of an error, a value of @code{-1} is returned. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item ENOSYS +The system doesn't support job control. + +@item ENOTTY +The terminal file associated with the @var{filedes} argument isn't the +controlling terminal of the calling process. +@end table +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int tcsetpgrp (int @var{filedes}, pid_t @var{pgid}) +This function is used to set a terminal's foreground process group ID. +The argument @var{filedes} is a descriptor which specifies the terminal; +@var{pgid} specifies the process group. The calling process must be a +member of the same session as @var{pgid} and must have the same +controlling terminal. + +For terminal access purposes, this function is treated as output. If it +is called from a background process on its controlling terminal, +normally all processes in the process group are sent a @code{SIGTTOU} +signal. The exception is if the calling process itself is ignoring or +blocking @code{SIGTTOU} signals, in which case the operation is +performed and no signal is sent. + +If successful, @code{tcsetpgrp} returns @code{0}. A return value of +@code{-1} indicates an error. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINVAL +The @var{pgid} argument is not valid. + +@item ENOSYS +The system doesn't support job control. + +@item ENOTTY +The @var{filedes} isn't the controlling terminal of the calling process. + +@item EPERM +The @var{pgid} isn't a process group in the same session as the calling +process. +@end table +@end deftypefun diff --git a/manual/lang.texi b/manual/lang.texi new file mode 100644 index 0000000000..66d41846d2 --- /dev/null +++ b/manual/lang.texi @@ -0,0 +1,1213 @@ +@node Language Features, Library Summary, System Configuration, Top +@appendix C Language Facilities in the Library + +Some of the facilities implemented by the C library really should be +thought of as parts of the C language itself. These facilities ought to +be documented in the C Language Manual, not in the library manual; but +since we don't have the language manual yet, and documentation for these +features has been written, we are publishing it here. + +@menu +* Consistency Checking:: Using @code{assert} to abort if + something ``impossible'' happens. +* Variadic Functions:: Defining functions with varying numbers + of args. +* Null Pointer Constant:: The macro @code{NULL}. +* Important Data Types:: Data types for object sizes. +* Data Type Measurements:: Parameters of data type representations. +@end menu + +@node Consistency Checking +@section Explicitly Checking Internal Consistency +@cindex consistency checking +@cindex impossible events +@cindex assertions + +When you're writing a program, it's often a good idea to put in checks +at strategic places for ``impossible'' errors or violations of basic +assumptions. These checks are helpful in debugging problems due to +misunderstandings between different parts of the program. + +@pindex assert.h +The @code{assert} macro, defined in the header file @file{assert.h}, +provides a convenient way to abort the program while printing a message +about where in the program the error was detected. + +@vindex NDEBUG +Once you think your program is debugged, you can disable the error +checks performed by the @code{assert} macro by recompiling with the +macro @code{NDEBUG} defined. This means you don't actually have to +change the program source code to disable these checks. + +But disabling these consistency checks is undesirable unless they make +the program significantly slower. All else being equal, more error +checking is good no matter who is running the program. A wise user +would rather have a program crash, visibly, than have it return nonsense +without indicating anything might be wrong. + +@comment assert.h +@comment ANSI +@deftypefn Macro void assert (int @var{expression}) +Verify the programmer's belief that @var{expression} should be nonzero +at this point in the program. + +If @code{NDEBUG} is not defined, @code{assert} tests the value of +@var{expression}. If it is false (zero), @code{assert} aborts the +program (@pxref{Aborting a Program}) after printing a message of the +form: + +@smallexample +@file{@var{file}}:@var{linenum}: Assertion `@var{expression}' failed. +@end smallexample + +@noindent +on the standard error stream @code{stderr} (@pxref{Standard Streams}). +The filename and line number are taken from the C preprocessor macros +@code{__FILE__} and @code{__LINE__} and specify where the call to +@code{assert} was written. + +If the preprocessor macro @code{NDEBUG} is defined at the point where +@file{assert.h} is included, the @code{assert} macro is defined to do +absolutely nothing. + +@strong{Warning:} Even the argument expression @var{expression} is not +evaluated if @code{NDEBUG} is in effect. So never use @code{assert} +with arguments that involve side effects. For example, @code{assert +(++i > 0);} is a bad idea, because @code{i} will not be incremented if +@code{NDEBUG} is defined. +@end deftypefn + +@strong{Usage note:} The @code{assert} facility is designed for +detecting @emph{internal inconsistency}; it is not suitable for +reporting invalid input or improper usage by @emph{the user} of the +program. + +The information in the diagnostic messages printed by the @code{assert} +macro is intended to help you, the programmer, track down the cause of a +bug, but is not really useful for telling a user of your program why his +or her input was invalid or why a command could not be carried out. So +you can't use @code{assert} to print the error messages for these +eventualities. + +What's more, your program should not abort when given invalid input, as +@code{assert} would do---it should exit with nonzero status (@pxref{Exit +Status}) after printing its error messages, or perhaps read another +command or move on to the next input file. + +@xref{Error Messages}, for information on printing error messages for +problems that @emph{do not} represent bugs in the program. + + +@node Variadic Functions +@section Variadic Functions +@cindex variable number of arguments +@cindex variadic functions +@cindex optional arguments + +ANSI C defines a syntax for declaring a function to take a variable +number or type of arguments. (Such functions are referred to as +@dfn{varargs functions} or @dfn{variadic functions}.) However, the +language itself provides no mechanism for such functions to access their +non-required arguments; instead, you use the variable arguments macros +defined in @file{stdarg.h}. + +This section describes how to declare variadic functions, how to write +them, and how to call them properly. + +@strong{Compatibility Note:} Many older C dialects provide a similar, +but incompatible, mechanism for defining functions with variable numbers +of arguments, using @file{varargs.h}. + +@menu +* Why Variadic:: Reasons for making functions take + variable arguments. +* How Variadic:: How to define and call variadic functions. +* Variadic Example:: A complete example. +@end menu + +@node Why Variadic +@subsection Why Variadic Functions are Used + +Ordinary C functions take a fixed number of arguments. When you define +a function, you specify the data type for each argument. Every call to +the function should supply the expected number of arguments, with types +that can be converted to the specified ones. Thus, if the function +@samp{foo} is declared with @code{int foo (int, char *);} then you must +call it with two arguments, a number (any kind will do) and a string +pointer. + +But some functions perform operations that can meaningfully accept an +unlimited number of arguments. + +In some cases a function can handle any number of values by operating on +all of them as a block. For example, consider a function that allocates +a one-dimensional array with @code{malloc} to hold a specified set of +values. This operation makes sense for any number of values, as long as +the length of the array corresponds to that number. Without facilities +for variable arguments, you would have to define a separate function for +each possible array size. + +The library function @code{printf} (@pxref{Formatted Output}) is an +example of another class of function where variable arguments are +useful. This function prints its arguments (which can vary in type as +well as number) under the control of a format template string. + +These are good reasons to define a @dfn{variadic} function which can +handle as many arguments as the caller chooses to pass. + +Some functions such as @code{open} take a fixed set of arguments, but +occasionally ignore the last few. Strict adherence to ANSI C requires +these functions to be defined as variadic; in practice, however, the GNU +C compiler and most other C compilers let you define such a function to +take a fixed set of arguments---the most it can ever use---and then only +@emph{declare} the function as variadic (or not declare its arguments +at all!). + +@node How Variadic +@subsection How Variadic Functions are Defined and Used + +Defining and using a variadic function involves three steps: + +@itemize @bullet +@item +@emph{Define} the function as variadic, using an ellipsis +(@samp{@dots{}}) in the argument list, and using special macros to +access the variable arguments. @xref{Receiving Arguments}. + +@item +@emph{Declare} the function as variadic, using a prototype with an +ellipsis (@samp{@dots{}}), in all the files which call it. +@xref{Variadic Prototypes}. + +@item +@emph{Call} the function by writing the fixed arguments followed by the +additional variable arguments. @xref{Calling Variadics}. +@end itemize + +@menu +* Variadic Prototypes:: How to make a prototype for a function + with variable arguments. +* Receiving Arguments:: Steps you must follow to access the + optional argument values. +* How Many Arguments:: How to decide whether there are more arguments. +* Calling Variadics:: Things you need to know about calling + variable arguments functions. +* Argument Macros:: Detailed specification of the macros + for accessing variable arguments. +* Old Varargs:: The pre-ANSI way of defining variadic functions. +@end menu + +@node Variadic Prototypes +@subsubsection Syntax for Variable Arguments +@cindex function prototypes (variadic) +@cindex prototypes for variadic functions +@cindex variadic function prototypes + +A function that accepts a variable number of arguments must be declared +with a prototype that says so. You write the fixed arguments as usual, +and then tack on @samp{@dots{}} to indicate the possibility of +additional arguments. The syntax of ANSI C requires at least one fixed +argument before the @samp{@dots{}}. For example, + +@smallexample +int +func (const char *a, int b, @dots{}) +@{ + @dots{} +@} +@end smallexample + +@noindent +outlines a definition of a function @code{func} which returns an +@code{int} and takes two required arguments, a @code{const char *} and +an @code{int}. These are followed by any number of anonymous +arguments. + +@strong{Portability note:} For some C compilers, the last required +argument must not be declared @code{register} in the function +definition. Furthermore, this argument's type must be +@dfn{self-promoting}: that is, the default promotions must not change +its type. This rules out array and function types, as well as +@code{float}, @code{char} (whether signed or not) and @w{@code{short int}} +(whether signed or not). This is actually an ANSI C requirement. + +@node Receiving Arguments +@subsubsection Receiving the Argument Values +@cindex variadic function argument access +@cindex arguments (variadic functions) + +Ordinary fixed arguments have individual names, and you can use these +names to access their values. But optional arguments have no +names---nothing but @samp{@dots{}}. How can you access them? + +@pindex stdarg.h +The only way to access them is sequentially, in the order they were +written, and you must use special macros from @file{stdarg.h} in the +following three step process: + +@enumerate +@item +You initialize an argument pointer variable of type @code{va_list} using +@code{va_start}. The argument pointer when initialized points to the +first optional argument. + +@item +You access the optional arguments by successive calls to @code{va_arg}. +The first call to @code{va_arg} gives you the first optional argument, +the next call gives you the second, and so on. + +You can stop at any time if you wish to ignore any remaining optional +arguments. It is perfectly all right for a function to access fewer +arguments than were supplied in the call, but you will get garbage +values if you try to access too many arguments. + +@item +You indicate that you are finished with the argument pointer variable by +calling @code{va_end}. + +(In practice, with most C compilers, calling @code{va_end} does nothing +and you do not really need to call it. This is always true in the GNU C +compiler. But you might as well call @code{va_end} just in case your +program is someday compiled with a peculiar compiler.) +@end enumerate + +@xref{Argument Macros}, for the full definitions of @code{va_start}, +@code{va_arg} and @code{va_end}. + +Steps 1 and 3 must be performed in the function that accepts the +optional arguments. However, you can pass the @code{va_list} variable +as an argument to another function and perform all or part of step 2 +there. + +You can perform the entire sequence of the three steps multiple times +within a single function invocation. If you want to ignore the optional +arguments, you can do these steps zero times. + +You can have more than one argument pointer variable if you like. You +can initialize each variable with @code{va_start} when you wish, and +then you can fetch arguments with each argument pointer as you wish. +Each argument pointer variable will sequence through the same set of +argument values, but at its own pace. + +@strong{Portability note:} With some compilers, once you pass an +argument pointer value to a subroutine, you must not keep using the same +argument pointer value after that subroutine returns. For full +portability, you should just pass it to @code{va_end}. This is actually +an ANSI C requirement, but most ANSI C compilers work happily +regardless. + +@node How Many Arguments +@subsubsection How Many Arguments Were Supplied +@cindex number of arguments passed +@cindex how many arguments +@cindex arguments, how many + +There is no general way for a function to determine the number and type +of the optional arguments it was called with. So whoever designs the +function typically designs a convention for the caller to tell it how +many arguments it has, and what kind. It is up to you to define an +appropriate calling convention for each variadic function, and write all +calls accordingly. + +One kind of calling convention is to pass the number of optional +arguments as one of the fixed arguments. This convention works provided +all of the optional arguments are of the same type. + +A similar alternative is to have one of the required arguments be a bit +mask, with a bit for each possible purpose for which an optional +argument might be supplied. You would test the bits in a predefined +sequence; if the bit is set, fetch the value of the next argument, +otherwise use a default value. + +A required argument can be used as a pattern to specify both the number +and types of the optional arguments. The format string argument to +@code{printf} is one example of this (@pxref{Formatted Output Functions}). + +Another possibility is to pass an ``end marker'' value as the last +optional argument. For example, for a function that manipulates an +arbitrary number of pointer arguments, a null pointer might indicate the +end of the argument list. (This assumes that a null pointer isn't +otherwise meaningful to the function.) The @code{execl} function works +in just this way; see @ref{Executing a File}. + + +@node Calling Variadics +@subsubsection Calling Variadic Functions +@cindex variadic functions, calling +@cindex calling variadic functions +@cindex declaring variadic functions + +You don't have to write anything special when you call a variadic function. +Just write the arguments (required arguments, followed by optional ones) +inside parentheses, separated by commas, as usual. But you should prepare +by declaring the function with a prototype, and you must know how the +argument values are converted. + +In principle, functions that are @emph{defined} to be variadic must also +be @emph{declared} to be variadic using a function prototype whenever +you call them. (@xref{Variadic Prototypes}, for how.) This is because +some C compilers use a different calling convention to pass the same set +of argument values to a function depending on whether that function +takes variable arguments or fixed arguments. + +In practice, the GNU C compiler always passes a given set of argument +types in the same way regardless of whether they are optional or +required. So, as long as the argument types are self-promoting, you can +safely omit declaring them. Usually it is a good idea to declare the +argument types for variadic functions, and indeed for all functions. +But there are a few functions which it is extremely convenient not to +have to declare as variadic---for example, @code{open} and +@code{printf}. + +@cindex default argument promotions +@cindex argument promotion +Since the prototype doesn't specify types for optional arguments, in a +call to a variadic function the @dfn{default argument promotions} are +performed on the optional argument values. This means the objects of +type @code{char} or @w{@code{short int}} (whether signed or not) are +promoted to either @code{int} or @w{@code{unsigned int}}, as +appropriate; and that objects of type @code{float} are promoted to type +@code{double}. So, if the caller passes a @code{char} as an optional +argument, it is promoted to an @code{int}, and the function should get +it with @code{va_arg (@var{ap}, int)}. + +Conversion of the required arguments is controlled by the function +prototype in the usual way: the argument expression is converted to the +declared argument type as if it were being assigned to a variable of +that type. + +@node Argument Macros +@subsubsection Argument Access Macros + +Here are descriptions of the macros used to retrieve variable arguments. +These macros are defined in the header file @file{stdarg.h}. +@pindex stdarg.h + +@comment stdarg.h +@comment ANSI +@deftp {Data Type} va_list +The type @code{va_list} is used for argument pointer variables. +@end deftp + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} void va_start (va_list @var{ap}, @var{last-required}) +This macro initializes the argument pointer variable @var{ap} to point +to the first of the optional arguments of the current function; +@var{last-required} must be the last required argument to the function. + +@xref{Old Varargs}, for an alternate definition of @code{va_start} +found in the header file @file{varargs.h}. +@end deftypefn + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type}) +The @code{va_arg} macro returns the value of the next optional argument, +and modifies the value of @var{ap} to point to the subsequent argument. +Thus, successive uses of @code{va_arg} return successive optional +arguments. + +The type of the value returned by @code{va_arg} is @var{type} as +specified in the call. @var{type} must be a self-promoting type (not +@code{char} or @code{short int} or @code{float}) that matches the type +of the actual argument. +@end deftypefn + +@comment stdarg.h +@comment ANSI +@deftypefn {Macro} void va_end (va_list @var{ap}) +This ends the use of @var{ap}. After a @code{va_end} call, further +@code{va_arg} calls with the same @var{ap} may not work. You should invoke +@code{va_end} before returning from the function in which @code{va_start} +was invoked with the same @var{ap} argument. + +In the GNU C library, @code{va_end} does nothing, and you need not ever +use it except for reasons of portability. +@refill +@end deftypefn + +@node Variadic Example +@subsection Example of a Variadic Function + +Here is a complete sample function that accepts a variable number of +arguments. The first argument to the function is the count of remaining +arguments, which are added up and the result returned. While trivial, +this function is sufficient to illustrate how to use the variable +arguments facility. + +@comment Yes, this example has been tested. +@smallexample +@include add.c.texi +@end smallexample + +@node Old Varargs +@subsubsection Old-Style Variadic Functions + +@pindex varargs.h +Before ANSI C, programmers used a slightly different facility for +writing variadic functions. The GNU C compiler still supports it; +currently, it is more portable than the ANSI C facility, since support +for ANSI C is still not universal. The header file which defines the +old-fashioned variadic facility is called @file{varargs.h}. + +Using @file{varargs.h} is almost the same as using @file{stdarg.h}. +There is no difference in how you call a variadic function; +@xref{Calling Variadics}. The only difference is in how you define +them. First of all, you must use old-style non-prototype syntax, like +this: + +@smallexample +tree +build (va_alist) + va_dcl +@{ +@end smallexample + +Secondly, you must give @code{va_start} just one argument, like this: + +@smallexample + va_list p; + va_start (p); +@end smallexample + +These are the special macros used for defining old-style variadic +functions: + +@comment varargs.h +@comment Unix +@deffn Macro va_alist +This macro stands for the argument name list required in a variadic +function. +@end deffn + +@comment varargs.h +@comment Unix +@deffn Macro va_dcl +This macro declares the implicit argument or arguments for a variadic +function. +@end deffn + +@comment varargs.h +@comment Unix +@deftypefn {Macro} void va_start (va_list @var{ap}) +This macro, as defined in @file{varargs.h}, initializes the argument +pointer variable @var{ap} to point to the first argument of the current +function. +@end deftypefn + +The other argument macros, @code{va_arg} and @code{va_end}, are the same +in @file{varargs.h} as in @file{stdarg.h}; see @ref{Argument Macros} for +details. + +It does not work to include both @file{varargs.h} and @file{stdarg.h} in +the same compilation; they define @code{va_start} in conflicting ways. + +@node Null Pointer Constant +@section Null Pointer Constant +@cindex null pointer constant + +The null pointer constant is guaranteed not to point to any real object. +You can assign it to any pointer variable since it has type @code{void +*}. The preferred way to write a null pointer constant is with +@code{NULL}. + +@comment stddef.h +@comment ANSI +@deftypevr Macro {void *} NULL +This is a null pointer constant. +@end deftypevr + +You can also use @code{0} or @code{(void *)0} as a null pointer +constant, but using @code{NULL} is cleaner because it makes the purpose +of the constant more evident. + +If you use the null pointer constant as a function argument, then for +complete portability you should make sure that the function has a +prototype declaration. Otherwise, if the target machine has two +different pointer representations, the compiler won't know which +representation to use for that argument. You can avoid the problem by +explicitly casting the constant to the proper pointer type, but we +recommend instead adding a prototype for the function you are calling. + +@node Important Data Types +@section Important Data Types + +The result of subtracting two pointers in C is always an integer, but the +precise data type varies from C compiler to C compiler. Likewise, the +data type of the result of @code{sizeof} also varies between compilers. +ANSI defines standard aliases for these two types, so you can refer to +them in a portable fashion. They are defined in the header file +@file{stddef.h}. +@pindex stddef.h + +@comment stddef.h +@comment ANSI +@deftp {Data Type} ptrdiff_t +This is the signed integer type of the result of subtracting two +pointers. For example, with the declaration @code{char *p1, *p2;}, the +expression @code{p2 - p1} is of type @code{ptrdiff_t}. This will +probably be one of the standard signed integer types (@w{@code{short +int}}, @code{int} or @w{@code{long int}}), but might be a nonstandard +type that exists only for this purpose. +@end deftp + +@comment stddef.h +@comment ANSI +@deftp {Data Type} size_t +This is an unsigned integer type used to represent the sizes of objects. +The result of the @code{sizeof} operator is of this type, and functions +such as @code{malloc} (@pxref{Unconstrained Allocation}) and +@code{memcpy} (@pxref{Copying and Concatenation}) accept arguments of +this type to specify object sizes. + +@strong{Usage Note:} @code{size_t} is the preferred way to declare any +arguments or variables that hold the size of an object. +@end deftp + +In the GNU system @code{size_t} is equivalent to either +@w{@code{unsigned int}} or @w{@code{unsigned long int}}. These types +have identical properties on the GNU system, and for most purposes, you +can use them interchangeably. However, they are distinct as data types, +which makes a difference in certain contexts. + +For example, when you specify the type of a function argument in a +function prototype, it makes a difference which one you use. If the +system header files declare @code{malloc} with an argument of type +@code{size_t} and you declare @code{malloc} with an argument of type +@code{unsigned int}, you will get a compilation error if @code{size_t} +happens to be @code{unsigned long int} on your system. To avoid any +possibility of error, when a function argument or value is supposed to +have type @code{size_t}, never declare its type in any other way. + +@strong{Compatibility Note:} Implementations of C before the advent of +ANSI C generally used @code{unsigned int} for representing object sizes +and @code{int} for pointer subtraction results. They did not +necessarily define either @code{size_t} or @code{ptrdiff_t}. Unix +systems did define @code{size_t}, in @file{sys/types.h}, but the +definition was usually a signed type. + +@node Data Type Measurements +@section Data Type Measurements + +Most of the time, if you choose the proper C data type for each object +in your program, you need not be concerned with just how it is +represented or how many bits it uses. When you do need such +information, the C language itself does not provide a way to get it. +The header files @file{limits.h} and @file{float.h} contain macros +which give you this information in full detail. + +@menu +* Width of Type:: How many bits does an integer type hold? +* Range of Type:: What are the largest and smallest values + that an integer type can hold? +* Floating Type Macros:: Parameters that measure the floating point types. +* Structure Measurement:: Getting measurements on structure types. +@end menu + +@node Width of Type +@subsection Computing the Width of an Integer Data Type +@cindex integer type width +@cindex width of integer type +@cindex type measurements, integer + +The most common reason that a program needs to know how many bits are in +an integer type is for using an array of @code{long int} as a bit vector. +You can access the bit at index @var{n} with + +@smallexample +vector[@var{n} / LONGBITS] & (1 << (@var{n} % LONGBITS)) +@end smallexample + +@noindent +provided you define @code{LONGBITS} as the number of bits in a +@code{long int}. + +@pindex limits.h +There is no operator in the C language that can give you the number of +bits in an integer data type. But you can compute it from the macro +@code{CHAR_BIT}, defined in the header file @file{limits.h}. + +@table @code +@comment limits.h +@comment ANSI +@item CHAR_BIT +This is the number of bits in a @code{char}---eight, on most systems. +The value has type @code{int}. + +You can compute the number of bits in any data type @var{type} like +this: + +@smallexample +sizeof (@var{type}) * CHAR_BIT +@end smallexample +@end table + +@node Range of Type +@subsection Range of an Integer Type +@cindex integer type range +@cindex range of integer type +@cindex limits, integer types + +Suppose you need to store an integer value which can range from zero to +one million. Which is the smallest type you can use? There is no +general rule; it depends on the C compiler and target machine. You can +use the @samp{MIN} and @samp{MAX} macros in @file{limits.h} to determine +which type will work. + +Each signed integer type has a pair of macros which give the smallest +and largest values that it can hold. Each unsigned integer type has one +such macro, for the maximum value; the minimum value is, of course, +zero. + +The values of these macros are all integer constant expressions. The +@samp{MAX} and @samp{MIN} macros for @code{char} and @w{@code{short +int}} types have values of type @code{int}. The @samp{MAX} and +@samp{MIN} macros for the other types have values of the same type +described by the macro---thus, @code{ULONG_MAX} has type +@w{@code{unsigned long int}}. + +@comment Extra blank lines make it look better. +@table @code +@comment limits.h +@comment ANSI +@item SCHAR_MIN + +This is the minimum value that can be represented by a @w{@code{signed char}}. + +@comment limits.h +@comment ANSI +@item SCHAR_MAX +@comment limits.h +@comment ANSI +@itemx UCHAR_MAX + +These are the maximum values that can be represented by a +@w{@code{signed char}} and @w{@code{unsigned char}}, respectively. + +@comment limits.h +@comment ANSI +@item CHAR_MIN + +This is the minimum value that can be represented by a @code{char}. +It's equal to @code{SCHAR_MIN} if @code{char} is signed, or zero +otherwise. + +@comment limits.h +@comment ANSI +@item CHAR_MAX + +This is the maximum value that can be represented by a @code{char}. +It's equal to @code{SCHAR_MAX} if @code{char} is signed, or +@code{UCHAR_MAX} otherwise. + +@comment limits.h +@comment ANSI +@item SHRT_MIN + +This is the minimum value that can be represented by a @w{@code{signed +short int}}. On most machines that the GNU C library runs on, +@code{short} integers are 16-bit quantities. + +@comment limits.h +@comment ANSI +@item SHRT_MAX +@comment limits.h +@comment ANSI +@itemx USHRT_MAX + +These are the maximum values that can be represented by a +@w{@code{signed short int}} and @w{@code{unsigned short int}}, +respectively. + +@comment limits.h +@comment ANSI +@item INT_MIN + +This is the minimum value that can be represented by a @w{@code{signed +int}}. On most machines that the GNU C system runs on, an @code{int} is +a 32-bit quantity. + +@comment limits.h +@comment ANSI +@item INT_MAX +@comment limits.h +@comment ANSI +@itemx UINT_MAX + +These are the maximum values that can be represented by, respectively, +the type @w{@code{signed int}} and the type @w{@code{unsigned int}}. + +@comment limits.h +@comment ANSI +@item LONG_MIN + +This is the minimum value that can be represented by a @w{@code{signed +long int}}. On most machines that the GNU C system runs on, @code{long} +integers are 32-bit quantities, the same size as @code{int}. + +@comment limits.h +@comment ANSI +@item LONG_MAX +@comment limits.h +@comment ANSI +@itemx ULONG_MAX + +These are the maximum values that can be represented by a +@w{@code{signed long int}} and @code{unsigned long int}, respectively. + +@comment limits.h +@comment GNU +@item LONG_LONG_MIN + +This is the minimum value that can be represented by a @w{@code{signed +long long int}}. On most machines that the GNU C system runs on, +@w{@code{long long}} integers are 64-bit quantities. + +@comment limits.h +@comment GNU +@item LONG_LONG_MAX +@comment limits.h +@comment ANSI +@itemx ULONG_LONG_MAX + +These are the maximum values that can be represented by a @code{signed +long long int} and @code{unsigned long long int}, respectively. + +@comment limits.h +@comment GNU +@item WCHAR_MAX + +This is the maximum value that can be represented by a @code{wchar_t}. +@xref{Wide Char Intro}. +@end table + +The header file @file{limits.h} also defines some additional constants +that parameterize various operating system and file system limits. These +constants are described in @ref{System Configuration}. + +@node Floating Type Macros +@subsection Floating Type Macros +@cindex floating type measurements +@cindex measurements of floating types +@cindex type measurements, floating +@cindex limits, floating types + +The specific representation of floating point numbers varies from +machine to machine. Because floating point numbers are represented +internally as approximate quantities, algorithms for manipulating +floating point data often need to take account of the precise details of +the machine's floating point representation. + +Some of the functions in the C library itself need this information; for +example, the algorithms for printing and reading floating point numbers +(@pxref{I/O on Streams}) and for calculating trigonometric and +irrational functions (@pxref{Mathematics}) use it to avoid round-off +error and loss of accuracy. User programs that implement numerical +analysis techniques also often need this information in order to +minimize or compute error bounds. + +The header file @file{float.h} describes the format used by your +machine. + +@menu +* Floating Point Concepts:: Definitions of terminology. +* Floating Point Parameters:: Details of specific macros. +* IEEE Floating Point:: The measurements for one common + representation. +@end menu + +@node Floating Point Concepts +@subsubsection Floating Point Representation Concepts + +This section introduces the terminology for describing floating point +representations. + +You are probably already familiar with most of these concepts in terms +of scientific or exponential notation for floating point numbers. For +example, the number @code{123456.0} could be expressed in exponential +notation as @code{1.23456e+05}, a shorthand notation indicating that the +mantissa @code{1.23456} is multiplied by the base @code{10} raised to +power @code{5}. + +More formally, the internal representation of a floating point number +can be characterized in terms of the following parameters: + +@itemize @bullet +@item +@cindex sign (of floating point number) +The @dfn{sign} is either @code{-1} or @code{1}. + +@item +@cindex base (of floating point number) +@cindex radix (of floating point number) +The @dfn{base} or @dfn{radix} for exponentiation, an integer greater +than @code{1}. This is a constant for a particular representation. + +@item +@cindex exponent (of floating point number) +The @dfn{exponent} to which the base is raised. The upper and lower +bounds of the exponent value are constants for a particular +representation. + +@cindex bias (of floating point number exponent) +Sometimes, in the actual bits representing the floating point number, +the exponent is @dfn{biased} by adding a constant to it, to make it +always be represented as an unsigned quantity. This is only important +if you have some reason to pick apart the bit fields making up the +floating point number by hand, which is something for which the GNU +library provides no support. So this is ignored in the discussion that +follows. + +@item +@cindex mantissa (of floating point number) +@cindex significand (of floating point number) +The @dfn{mantissa} or @dfn{significand}, an unsigned integer which is a +part of each floating point number. + +@item +@cindex precision (of floating point number) +The @dfn{precision} of the mantissa. If the base of the representation +is @var{b}, then the precision is the number of base-@var{b} digits in +the mantissa. This is a constant for a particular representation. + +@cindex hidden bit (of floating point number mantissa) +Many floating point representations have an implicit @dfn{hidden bit} in +the mantissa. This is a bit which is present virtually in the mantissa, +but not stored in memory because its value is always 1 in a normalized +number. The precision figure (see above) includes any hidden bits. + +Again, the GNU library provides no facilities for dealing with such +low-level aspects of the representation. +@end itemize + +The mantissa of a floating point number actually represents an implicit +fraction whose denominator is the base raised to the power of the +precision. Since the largest representable mantissa is one less than +this denominator, the value of the fraction is always strictly less than +@code{1}. The mathematical value of a floating point number is then the +product of this fraction, the sign, and the base raised to the exponent. + +@cindex normalized floating point number +We say that the floating point number is @dfn{normalized} if the +fraction is at least @code{1/@var{b}}, where @var{b} is the base. In +other words, the mantissa would be too large to fit if it were +multiplied by the base. Non-normalized numbers are sometimes called +@dfn{denormal}; they contain less precision than the representation +normally can hold. + +If the number is not normalized, then you can subtract @code{1} from the +exponent while multiplying the mantissa by the base, and get another +floating point number with the same value. @dfn{Normalization} consists +of doing this repeatedly until the number is normalized. Two distinct +normalized floating point numbers cannot be equal in value. + +(There is an exception to this rule: if the mantissa is zero, it is +considered normalized. Another exception happens on certain machines +where the exponent is as small as the representation can hold. Then +it is impossible to subtract @code{1} from the exponent, so a number +may be normalized even if its fraction is less than @code{1/@var{b}}.) + +@node Floating Point Parameters +@subsubsection Floating Point Parameters + +@pindex float.h +These macro definitions can be accessed by including the header file +@file{float.h} in your program. + +Macro names starting with @samp{FLT_} refer to the @code{float} type, +while names beginning with @samp{DBL_} refer to the @code{double} type +and names beginning with @samp{LDBL_} refer to the @code{long double} +type. (Currently GCC does not support @code{long double} as a distinct +data type, so the values for the @samp{LDBL_} constants are equal to the +corresponding constants for the @code{double} type.)@refill + +Of these macros, only @code{FLT_RADIX} is guaranteed to be a constant +expression. The other macros listed here cannot be reliably used in +places that require constant expressions, such as @samp{#if} +preprocessing directives or in the dimensions of static arrays. + +Although the ANSI C standard specifies minimum and maximum values for +most of these parameters, the GNU C implementation uses whatever values +describe the floating point representation of the target machine. So in +principle GNU C actually satisfies the ANSI C requirements only if the +target machine is suitable. In practice, all the machines currently +supported are suitable. + +@table @code +@comment float.h +@comment ANSI +@item FLT_ROUNDS +This value characterizes the rounding mode for floating point addition. +The following values indicate standard rounding modes: + +@need 750 + +@table @code +@item -1 +The mode is indeterminable. +@item 0 +Rounding is towards zero. +@item 1 +Rounding is to the nearest number. +@item 2 +Rounding is towards positive infinity. +@item 3 +Rounding is towards negative infinity. +@end table + +@noindent +Any other value represents a machine-dependent nonstandard rounding +mode. + +On most machines, the value is @code{1}, in accordance with the IEEE +standard for floating point. + +Here is a table showing how certain values round for each possible value +of @code{FLT_ROUNDS}, if the other aspects of the representation match +the IEEE single-precision standard. + +@smallexample + 0 1 2 3 + 1.00000003 1.0 1.0 1.00000012 1.0 + 1.00000007 1.0 1.00000012 1.00000012 1.0 +-1.00000003 -1.0 -1.0 -1.0 -1.00000012 +-1.00000007 -1.0 -1.00000012 -1.0 -1.00000012 +@end smallexample + +@comment float.h +@comment ANSI +@item FLT_RADIX +This is the value of the base, or radix, of exponent representation. +This is guaranteed to be a constant expression, unlike the other macros +described in this section. The value is 2 on all machines we know of +except the IBM 360 and derivatives. + +@comment float.h +@comment ANSI +@item FLT_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating point +mantissa for the @code{float} data type. The following expression +yields @code{1.0} (even though mathematically it should not) due to the +limited number of mantissa digits: + +@smallexample +float radix = FLT_RADIX; + +1.0f + 1.0f / radix / radix / @dots{} / radix +@end smallexample + +@noindent +where @code{radix} appears @code{FLT_MANT_DIG} times. + +@comment float.h +@comment ANSI +@item DBL_MANT_DIG +@itemx LDBL_MANT_DIG +This is the number of base-@code{FLT_RADIX} digits in the floating point +mantissa for the data types @code{double} and @code{long double}, +respectively. + +@comment Extra blank lines make it look better. +@comment float.h +@comment ANSI +@item FLT_DIG + +This is the number of decimal digits of precision for the @code{float} +data type. Technically, if @var{p} and @var{b} are the precision and +base (respectively) for the representation, then the decimal precision +@var{q} is the maximum number of decimal digits such that any floating +point number with @var{q} base 10 digits can be rounded to a floating +point number with @var{p} base @var{b} digits and back again, without +change to the @var{q} decimal digits. + +The value of this macro is supposed to be at least @code{6}, to satisfy +ANSI C. + +@comment float.h +@comment ANSI +@item DBL_DIG +@itemx LDBL_DIG + +These are similar to @code{FLT_DIG}, but for the data types +@code{double} and @code{long double}, respectively. The values of these +macros are supposed to be at least @code{10}. + +@comment float.h +@comment ANSI +@item FLT_MIN_EXP +This is the smallest possible exponent value for type @code{float}. +More precisely, is the minimum negative integer such that the value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +normalized floating point number of type @code{float}. + +@comment float.h +@comment ANSI +@item DBL_MIN_EXP +@itemx LDBL_MIN_EXP + +These are similar to @code{FLT_MIN_EXP}, but for the data types +@code{double} and @code{long double}, respectively. + +@comment float.h +@comment ANSI +@item FLT_MIN_10_EXP +This is the minimum negative integer such that @code{10} raised to this +power minus 1 can be represented as a normalized floating point number +of type @code{float}. This is supposed to be @code{-37} or even less. + +@comment float.h +@comment ANSI +@item DBL_MIN_10_EXP +@itemx LDBL_MIN_10_EXP +These are similar to @code{FLT_MIN_10_EXP}, but for the data types +@code{double} and @code{long double}, respectively. + +@comment float.h +@comment ANSI +@item FLT_MAX_EXP +This is the largest possible exponent value for type @code{float}. More +precisely, this is the maximum positive integer such that value +@code{FLT_RADIX} raised to this power minus 1 can be represented as a +floating point number of type @code{float}. + +@comment float.h +@comment ANSI +@item DBL_MAX_EXP +@itemx LDBL_MAX_EXP +These are similar to @code{FLT_MAX_EXP}, but for the data types +@code{double} and @code{long double}, respectively. + +@comment float.h +@comment ANSI +@item FLT_MAX_10_EXP +This is the maximum positive integer such that @code{10} raised to this +power minus 1 can be represented as a normalized floating point number +of type @code{float}. This is supposed to be at least @code{37}. + +@comment float.h +@comment ANSI +@item DBL_MAX_10_EXP +@itemx LDBL_MAX_10_EXP +These are similar to @code{FLT_MAX_10_EXP}, but for the data types +@code{double} and @code{long double}, respectively. + +@comment float.h +@comment ANSI +@item FLT_MAX + +The value of this macro is the maximum number representable in type +@code{float}. It is supposed to be at least @code{1E+37}. The value +has type @code{float}. + +The smallest representable number is @code{- FLT_MAX}. + +@comment float.h +@comment ANSI +@item DBL_MAX +@itemx LDBL_MAX + +These are similar to @code{FLT_MAX}, but for the data types +@code{double} and @code{long double}, respectively. The type of the +macro's value is the same as the type it describes. + +@comment float.h +@comment ANSI +@item FLT_MIN + +The value of this macro is the minimum normalized positive floating +point number that is representable in type @code{float}. It is supposed +to be no more than @code{1E-37}. + +@comment float.h +@comment ANSI +@item DBL_MIN +@itemx LDBL_MIN + +These are similar to @code{FLT_MIN}, but for the data types +@code{double} and @code{long double}, respectively. The type of the +macro's value is the same as the type it describes. + +@comment float.h +@comment ANSI +@item FLT_EPSILON + +This is the minimum positive floating point number of type @code{float} +such that @code{1.0 + FLT_EPSILON != 1.0} is true. It's supposed to +be no greater than @code{1E-5}. + +@comment float.h +@comment ANSI +@item DBL_EPSILON +@itemx LDBL_EPSILON + +These are similar to @code{FLT_EPSILON}, but for the data types +@code{double} and @code{long double}, respectively. The type of the +macro's value is the same as the type it describes. The values are not +supposed to be greater than @code{1E-9}. +@end table + +@node IEEE Floating Point +@subsubsection IEEE Floating Point +@cindex IEEE floating point representation +@cindex floating point, IEEE + +Here is an example showing how the floating type measurements come out +for the most common floating point representation, specified by the +@cite{IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE Std +754-1985)}. Nearly all computers designed since the 1980s use this +format. + +The IEEE single-precision float representation uses a base of 2. There +is a sign bit, a mantissa with 23 bits plus one hidden bit (so the total +precision is 24 base-2 digits), and an 8-bit exponent that can represent +values in the range -125 to 128, inclusive. + +So, for an implementation that uses this representation for the +@code{float} data type, appropriate values for the corresponding +parameters are: + +@smallexample +FLT_RADIX 2 +FLT_MANT_DIG 24 +FLT_DIG 6 +FLT_MIN_EXP -125 +FLT_MIN_10_EXP -37 +FLT_MAX_EXP 128 +FLT_MAX_10_EXP +38 +FLT_MIN 1.17549435E-38F +FLT_MAX 3.40282347E+38F +FLT_EPSILON 1.19209290E-07F +@end smallexample + +Here are the values for the @code{double} data type: + +@smallexample +DBL_MANT_DIG 53 +DBL_DIG 15 +DBL_MIN_EXP -1021 +DBL_MIN_10_EXP -307 +DBL_MAX_EXP 1024 +DBL_MAX_10_EXP 308 +DBL_MAX 1.7976931348623157E+308 +DBL_MIN 2.2250738585072014E-308 +DBL_EPSILON 2.2204460492503131E-016 +@end smallexample + +@node Structure Measurement +@subsection Structure Field Offset Measurement + +You can use @code{offsetof} to measure the location within a structure +type of a particular structure member. + +@comment stddef.h +@comment ANSI +@deftypefn {Macro} size_t offsetof (@var{type}, @var{member}) +This expands to a integer constant expression that is the offset of the +structure member named @var{member} in a the structure type @var{type}. +For example, @code{offsetof (struct s, elem)} is the offset, in bytes, +of the member @code{elem} in a @code{struct s}. + +This macro won't work if @var{member} is a bit field; you get an error +from the C compiler in that case. +@end deftypefn diff --git a/manual/lgpl.texinfo b/manual/lgpl.texinfo new file mode 100644 index 0000000000..8ba7317fe0 --- /dev/null +++ b/manual/lgpl.texinfo @@ -0,0 +1,546 @@ +@setfilename lgpl.info + +@set lgpl-appendix + +@ifset lgpl-appendix +@appendix GNU LIBRARY GENERAL PUBLIC LICENSE +@end ifset +@ifclear lgpl-appendix +@unnumbered GNU LIBRARY GENERAL PUBLIC LICENSE +@end ifclear +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1991 Free Software Foundation, Inc. +675 Mass Ave, Cambridge, MA 02139, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] +@end display + +@unnumberedsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate 0 +@item +This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called ``this License''). Each licensee is +addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate a +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also compile or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate a +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate a +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and an idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU Library General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +This library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@smallexample +Yoyodyne, Inc., hereby disclaims all copyright interest in the library +`Frob' (a library for tweaking knobs) written by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end smallexample + +That's all there is to it! diff --git a/manual/libc.texinfo b/manual/libc.texinfo new file mode 100644 index 0000000000..0b455b32d2 --- /dev/null +++ b/manual/libc.texinfo @@ -0,0 +1,1007 @@ +\input texinfo @c -*- Texinfo -*- +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename libc.info +@settitle The GNU C Library +@setchapternewpage odd +@comment %**end of header (This is for running Texinfo on a region.) + +@c This tells texinfo.tex to use the real section titles in xrefs in +@c place of the node name, when no section title is explicitly given. +@set xref-automatic-section-title +@smallbook + +@c I've already told people the printed edition will be 0.06 +@set EDITION 0.06 +@set VERSION 1.09 Beta +@set UPDATED 23 December 1994 +@set ISBN 1-882114-53-1 + +@ifinfo +This file documents the GNU C library. + +This is Edition @value{EDITION}, last updated @value{UPDATED}, +of @cite{The GNU C Library Reference Manual}, for Version @value{VERSION}. + +Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU Library General Public License'' is included +exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +Library General Public License'' must be approved for accuracy by the +Foundation. +@end ifinfo + +@iftex +@shorttitlepage The GNU C Library Reference Manual +@end iftex +@titlepage +@center @titlefont{The GNU C Library} +@sp 1 +@center @titlefont{Reference Manual} +@sp 2 +@center Sandra Loosemore +@center with +@center Richard M. Stallman, Roland McGrath, and Andrew Oram +@sp 3 +@center Edition @value{EDITION} +@sp 1 +@center last updated @value{UPDATED} +@sp 1 +@center for version @value{VERSION} +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1993, 1994 Free Software Foundation, Inc. +@sp 2 +Published by the Free Software Foundation @* +675 Massachusetts Avenue, @* +Cambridge, MA 02139 USA @* +Printed copies are available for $50 each. @* +ISBN @value{ISBN} @* + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU Library General Public License'' is included +exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the text of the translation of the section entitled ``GNU +Library General Public License'' must be approved for accuracy by the +Foundation. +@end titlepage +@page + +@ifinfo +@node Top, Introduction, (dir), (dir) +@top Main Menu +This is Edition @value{EDITION}, last updated @value{UPDATED}, of +@cite{The GNU C Library Reference Manual}, for Version @value{VERSION} +of the GNU C Library. +@end ifinfo + + +@menu +* Introduction:: Purpose of the GNU C Library. +* Error Reporting:: How the GNU Library functions report + error conditions. +* Memory Allocation:: Your program can allocate memory dynamically + and manipulate it via pointers. +* Character Handling:: Character testing and conversion functions. +* String and Array Utilities:: Utilities for copying and comparing + strings and arrays. +* Extended Characters:: Support for extended character sets. +* Locales:: The country and language can affect + the behavior of library functions. +* Searching and Sorting:: General searching and sorting functions. +* Pattern Matching:: Matching wildcards and regular expressions, + and shell-style ``word expansion''. +* I/O Overview:: Introduction to the I/O facilities. +* Streams: I/O on Streams. High-level, portable I/O facilities. +* Low-Level I/O:: Low-level, less portable I/O. +* File System Interface:: Functions for manipulating files. +* Pipes and FIFOs:: A simple interprocess communication mechanism. +* Sockets:: A more complicated interprocess communication + mechanism, with support for networking. +* Low-Level Terminal Interface::How to change the characteristics + of a terminal device. +* Mathematics:: Math functions (transcendental functions, + random numbers, absolute value, etc.). +* Arithmetic:: Low-level arithmetic functions. +* Date and Time:: Functions for getting the date and time, + and for conversion between formats. +* Non-Local Exits:: The @code{setjmp} and @code{longjmp} facilities. +* Signal Handling:: All about signals; how to send them, + block them, and handle them. +* Process Startup:: Writing the beginning and end of your program. +* Processes:: How to create processes and run other programs. +* Job Control:: All about process groups and sessions. +* Users and Groups:: How users are identified and classified. +* System Information:: Getting information about the + hardware and software configuration + of the machine a program runs on. +* System Configuration:: Parameters describing operating system limits. + +Appendices + +* Language Features:: C language features provided by the library. + +* Library Summary:: A summary showing the syntax, header file, + and derivation of each library feature. +* Maintenance:: How to install and maintain the GNU C Library. +* Copying:: The GNU Library General Public License says + how you can copy and share the GNU C Library. + +Indices + +* Concept Index:: Index of concepts and names. +* Type Index:: Index of types and type qualifiers. +* Function Index:: Index of functions and function-like macros. +* Variable Index:: Index of variables and variable-like macros. +* File Index:: Index of programs and files. + + --- The Detailed Node Listing --- + +Introduction + +* Getting Started:: Getting Started +* Standards and Portability:: Standards and Portability +* Using the Library:: Using the Library +* Roadmap to the Manual:: Roadmap to the Manual + +Standards and Portability + +* ANSI C:: The American National Standard for the + C programming language. +* POSIX:: The IEEE 1003 standards for operating systems. +* Berkeley Unix:: BSD and SunOS. +* SVID:: The System V Interface Description. + +Using the Library + +* Header Files:: How to use the header files in your programs. +* Macro Definitions:: Some functions in the library may really + be implemented as macros. +* Reserved Names:: The C standard reserves some names for + the library, and some for users. +* Feature Test Macros:: How to control what names are defined. + +Error Reporting + +* Checking for Errors:: How errors are reported by library functions. +* Error Codes:: What all the error codes are. +* Error Messages:: Mapping error codes onto error messages. + +Memory Allocation + +* Memory Concepts:: An introduction to concepts and terminology. +* Dynamic Allocation and C:: How to get different kinds of allocation in C. +* Unconstrained Allocation:: The @code{malloc} facility allows fully general + dynamic allocation. +* Obstacks:: Obstacks are less general than malloc + but more efficient and convenient. +* Variable Size Automatic:: Allocation of variable-sized blocks + of automatic storage that are freed when the + calling function returns. +* Relocating Allocator:: Waste less memory, if you can tolerate + automatic relocation of the blocks you get. +* Memory Warnings:: Getting warnings when memory is nearly full. + +Unconstrained Allocation + +* Basic Allocation:: Simple use of @code{malloc}. +* Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}. +* Freeing after Malloc:: Use @code{free} to free a block you + got with @code{malloc}. +* Changing Block Size:: Use @code{realloc} to make a block + bigger or smaller. +* Allocating Cleared Space:: Use @code{calloc} to allocate a + block and clear it. +* Efficiency and Malloc:: Efficiency considerations in use of + these functions. +* Aligned Memory Blocks:: Allocating specially aligned memory: + @code{memalign} and @code{valloc}. +* Heap Consistency Checking:: Automatic checking for errors. +* Hooks for Malloc:: You can use these hooks for debugging + programs that use @code{malloc}. +* Statistics of Malloc:: Getting information about how much + memory your program is using. +* Summary of Malloc:: Summary of @code{malloc} and related functions. + +Obstacks + +* Creating Obstacks:: How to declare an obstack in your program. +* Preparing for Obstacks:: Preparations needed before you can + use obstacks. +* Allocation in an Obstack:: Allocating objects in an obstack. +* Freeing Obstack Objects:: Freeing objects in an obstack. +* Obstack Functions:: The obstack functions are both + functions and macros. +* Growing Objects:: Making an object bigger by stages. +* Extra Fast Growing:: Extra-high-efficiency (though more + complicated) growing objects. +* Status of an Obstack:: Inquiries about the status of an obstack. +* Obstacks Data Alignment:: Controlling alignment of objects in obstacks. +* Obstack Chunks:: How obstacks obtain and release chunks. + Efficiency considerations. +* Summary of Obstacks:: + +Automatic Storage with Variable Size + +* Alloca Example:: Example of using @code{alloca}. +* Advantages of Alloca:: Reasons to use @code{alloca}. +* Disadvantages of Alloca:: Reasons to avoid @code{alloca}. +* GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative + method of allocating dynamically and + freeing automatically. +Relocating Allocator + +* Relocator Concepts:: How to understand relocating allocation. +* Using Relocator:: Functions for relocating allocation. + +Character Handling + +* Classification of Characters::Testing whether characters are + letters, digits, punctuation, etc. +* Case Conversion:: Case mapping, and the like. + +String and Array Utilities + +* Representation of Strings:: Introduction to basic concepts. +* String/Array Conventions:: Whether to use a string function or an + arbitrary array function. +* String Length:: Determining the length of a string. +* Copying and Concatenation:: Functions to copy the contents of strings + and arrays. +* String/Array Comparison:: Functions for byte-wise and character-wise + comparison. +* Collation Functions:: Functions for collating strings. +* Search Functions:: Searching for a specific element or substring. +* Finding Tokens in a String:: Splitting a string into tokens by looking + for delimiters. + +Extended Characters + +* Extended Char Intro:: Multibyte codes versus wide characters. +* Locales and Extended Chars:: The locale selects the character codes. +* Multibyte Char Intro:: How multibyte codes are represented. +* Wide Char Intro:: How wide characters are represented. +* Wide String Conversion:: Converting wide strings to multibyte code + and vice versa. +* Length of Char:: how many bytes make up one multibyte char. +* Converting One Char:: Converting a string character by character. +* Example of Conversion:: Example showing why converting + one character at a time may be useful. +* Shift State:: Multibyte codes with "shift characters". + +Locales and Internationalization + +* Effects of Locale:: Actions affected by the choice of locale. +* Choosing Locale:: How the user specifies a locale. +* Locale Categories:: Different purposes for which + you can select a locale. +* Setting the Locale:: How a program specifies the locale. +* Standard Locales:: Locale names available on all systems. +* Numeric Formatting:: How to format numbers for the chosen locale. + +Searching and Sorting + +* Comparison Functions:: Defining how to compare two objects. + Since the sort and search facilities are + general, you have to specify the ordering. +* Array Search Function:: The @code{bsearch} function. +* Array Sort Function:: The @code{qsort} function. +* Search/Sort Example:: An example program. + +Pattern Matching + +* Wildcard Matching:: Matching a wildcard pattern against a single string. +* Globbing:: Finding the files that match a wildcard pattern. +* Regular Expressions:: Matching regular expressions against strings. +* Word Expansion:: Expanding shell variables, nested commands, + arithmetic, and wildcards. + This is what the shell does with shell commands. + +I/O Overview + +* I/O Concepts:: Some basic information and terminology. +* File Names:: How to refer to a file. + +I/O Concepts + +* Streams and File Descriptors:: The GNU Library provides two ways + to access the contents of files. +* File Position:: The number of bytes from the + beginning of the file. + +File Names + +* Directories:: Directories contain entries for files. +* File Name Resolution:: A file name specifies how to look up a file. +* File Name Errors:: Error conditions relating to file names. +* File Name Portability:: File name portability and syntax issues. + +I/O on Streams + +* Streams:: About the data type representing a stream. +* Standard Streams:: Streams to the standard input and output + devices are created for you. +* Opening Streams:: How to create a stream to talk to a file. +* Closing Streams:: Close a stream when you are finished with it. +* Simple Output:: Unformatted output by characters and lines. +* Character Input:: Unformatted input by characters and words. +* Line Input:: Reading a line or a record from a stream. +* Unreading:: Peeking ahead/pushing back input just read. +* Formatted Output:: @code{printf} and related functions. +* Customizing Printf:: You can define new conversion specifiers for + @code{printf} and friends. +* Formatted Input:: @code{scanf} and related functions. +* Block Input/Output:: Input and output operations on blocks of data. +* EOF and Errors:: How you can tell if an I/O error happens. +* Binary Streams:: Some systems distinguish between text files + and binary files. +* File Positioning:: About random-access streams. +* Portable Positioning:: Random access on peculiar ANSI C systems. +* Stream Buffering:: How to control buffering of streams. +* Temporary Files:: How to open a temporary file. +* Other Kinds of Streams:: Other Kinds of Streams + +Unreading + +* Unreading Idea:: An explanation of unreading with pictures. +* How Unread:: How to call @code{ungetc} to do unreading. + +Formatted Output + +* Formatted Output Basics:: Some examples to get you started. +* Output Conversion Syntax:: General syntax of conversion specifications. +* Table of Output Conversions:: Summary of output conversions, what they do. +* Integer Conversions:: Details of formatting integers. +* Floating-Point Conversions:: Details of formatting floating-point numbers. +* Other Output Conversions:: Details about formatting of strings, + characters, pointers, and the like. +* Formatted Output Functions:: Descriptions of the actual functions. +* Variable Arguments Output:: @code{vprintf} and friends. +* Parsing a Template String:: What kinds of arguments does + a given template call for? + +Customizing Printf + +* Registering New Conversions:: +* Conversion Specifier Options:: +* Defining the Output Handler:: +* Printf Extension Example:: + +Formatted Input + +* Formatted Input Basics:: Some basics to get you started. +* Input Conversion Syntax:: Syntax of conversion specifications. +* Table of Input Conversions:: Summary of input conversions and what they do. +* Numeric Input Conversions:: Details of conversions for reading numbers. +* String Input Conversions:: Details of conversions for reading strings. +* Other Input Conversions:: Details of miscellaneous other conversions. +* Formatted Input Functions:: Descriptions of the actual functions. +* Variable Arguments Input:: @code{vscanf} and friends. + +Stream Buffering + +* Buffering Concepts:: Terminology is defined here. +* Flushing Buffers:: How to ensure that output buffers are flushed. +* Controlling Buffering:: How to specify what kind of buffering to use. + +Other Kinds of Streams + +* String Streams:: +* Custom Streams:: + +Programming Your Own Custom Streams + +* Streams and Cookies:: +* Hook Functions:: + +Low-Level I/O + +* Opening and Closing Files:: How to open and close file descriptors. +* I/O Primitives:: Reading and writing data. +* File Position Primitive:: Setting a descriptor's file position. +* Descriptors and Streams:: Converting descriptor to stream or vice-versa. +* Stream/Descriptor Precautions:: Precautions needed if you use both + descriptors and streams. +* Waiting for I/O:: How to check for input or output + on multiple file descriptors. +* Control Operations:: Various other operations on file descriptors. +* Duplicating Descriptors:: Fcntl commands for duplicating descriptors. +* Descriptor Flags:: Fcntl commands for manipulating flags + associated with file descriptors. +* File Status Flags:: Fcntl commands for manipulating flags + associated with open files. +* File Locks:: Fcntl commands for implementing file locking. +* Interrupt Input:: Getting a signal when input arrives. + +File System Interface + +* Working Directory:: This is used to resolve relative file names. +* Accessing Directories:: Finding out what files a directory contains. +* Hard Links:: Adding alternate names to a file. +* Symbolic Links:: A file that ``points to'' a file name. +* Deleting Files:: How to delete a file, and what that means. +* Renaming Files:: Changing a file's name. +* Creating Directories:: A system call just for creating a directory. +* File Attributes:: Attributes of individual files. +* Making Special Files:: How to create special files. + +Accessing Directories + +* Directory Entries:: Format of one directory entry. +* Opening a Directory:: How to open a directory stream. +* Reading/Closing Directory:: How to read directory entries from the stream. +* Simple Directory Lister:: A very simple directory listing program. +* Random Access Directory:: Rereading part of the directory + already read with the same stream. + +File Attributes + +* Attribute Meanings:: The names of the file attributes, + and what their values mean. +* Reading Attributes:: How to read the attributes of a file. +* Testing File Type:: Distinguishing ordinary files, + directories, links... +* File Owner:: How ownership for new files is determined, + and how to change it. +* Permission Bits:: How information about a file's access mode + is stored. +* Access Permission:: How the system decides who can access a file. +* Setting Permissions:: How permissions for new files are assigned, + and how to change them. +* Testing File Access:: How to find out if your process can + access a file. +* File Times:: About the time attributes of a file. + +Pipes and FIFOs + +* Creating a Pipe:: Making a pipe with the @code{pipe} function. +* Pipe to a Subprocess:: Using a pipe to communicate with a child. +* FIFO Special Files:: Making a FIFO special file. + +Sockets + +* Socket Concepts:: Basic concepts you need to know about. +* Communication Styles:: Stream communication, datagrams, and others. +* Socket Addresses:: How socket names (``addresses'') work. +* File Namespace:: Details about the file namespace. +* Internet Namespace:: Details about the Internet namespace. +* Open/Close Sockets:: Creating sockets and destroying them. +* Connections:: Operations on sockets with connection state. +* Datagrams:: Operations on datagram sockets. +* Socket Options:: Miscellaneous low-level socket options. +* Networks Database:: Accessing the database of network names. + +Socket Addresses + +* Address Formats:: About @code{struct sockaddr}. +* Setting Address:: Binding an address to a socket. +* Reading Address:: Reading the address of a socket. + +Internet Domain + +* Internet Address Format:: How socket addresses are specified in the + Internet namespace. +* Host Addresses:: All about host addresses of Internet hosts. +* Protocols Database:: Referring to protocols by name. +* Services Database:: Ports may have symbolic names. +* Byte Order:: Different hosts may use different byte + ordering conventions; you need to + canonicalize host address and port number. +* Inet Example:: Putting it all together. + +Host Addresses + +* Abstract Host Addresses:: What a host number consists of. +* Data type: Host Address Data Type. Data type for a host number. +* Functions: Host Address Functions. Functions to operate on them. +* Names: Host Names. Translating host names to host numbers. + +Open/Close Sockets + +* Creating a Socket:: How to open a socket. +* Closing a Socket:: How to close a socket. +* Socket Pairs:: These are created like pipes. + +Connections + +* Connecting:: What the client program must do. +* Listening:: How a server program waits for requests. +* Accepting Connections:: What the server does when it gets a request. +* Who is Connected:: Getting the address of the + other side of a connection. +* Transferring Data:: How to send and receive data. +* Byte Stream Example:: An example client for communicating over a + byte stream socket in the Internet namespace. +* Server Example:: A corresponding server program. +* Out-of-Band Data:: This is an advanced feature. + +Transferring Data + +* Sending Data:: Sending data with @code{write}. +* Receiving Data:: Reading data with @code{read}. +* Socket Data Options:: Using @code{send} and @code{recv}. + +Datagrams + +* Sending Datagrams:: Sending packets on a datagram socket. +* Receiving Datagrams:: Receiving packets on a datagram socket. +* Datagram Example:: An example program: packets sent over a + datagram stream in the file namespace. +* Example Receiver:: Another program, that receives those packets. + +Socket Options + +* Socket Option Functions:: The basic functions for setting and getting + socket options. +* Socket-Level Options:: Details of the options at the socket level. + +Low-Level Terminal Interface + +* Is It a Terminal:: How to determine if a file is a terminal + device, and what its name is. +* I/O Queues:: About flow control and typeahead. +* Canonical or Not:: Two basic styles of input processing. +* Terminal Modes:: How to examine and modify flags controlling + terminal I/O: echoing, signals, editing. +* Line Control:: Sending break sequences, clearing buffers... +* Noncanon Example:: How to read single characters without echo. + +Terminal Modes + +* Mode Data Types:: The data type @code{struct termios} and related types. +* Mode Functions:: Functions to read and set terminal attributes. +* Setting Modes:: The right way to set attributes reliably. +* Input Modes:: Flags controlling low-level input handling. +* Output Modes:: Flags controlling low-level output handling. +* Control Modes:: Flags controlling serial port behavior. +* Local Modes:: Flags controlling high-level input handling. +* Line Speed:: How to read and set the terminal line speed. +* Special Characters:: Characters that have special effects, + and how to change them. +* Noncanonical Input:: Controlling how long to wait for input. + +Special Characters + +* Editing Characters:: +* Signal Characters:: +* Start/Stop Characters:: + +Mathematics + +* Domain and Range Errors:: How overflow conditions and the + like are reported. +* Not a Number:: Making NANs and testing for NANs. +* Trig Functions:: Sine, cosine, and tangent. +* Inverse Trig Functions:: Arc sine, arc cosine, and arc tangent. +* Exponents and Logarithms:: Also includes square root. +* Hyperbolic Functions:: Hyperbolic sine and friends. +* Pseudo-Random Numbers:: Functions for generating pseudo-random numbers. +* Absolute Value:: Absolute value functions. + +Pseudo-Random Numbers + +* ANSI Random:: @code{rand} and friends. +* BSD Random:: @code{random} and friends. + +Low-Level Arithmetic Functions + +* Normalization Functions:: Hacks for radix-2 representations. +* Rounding and Remainders:: Determinining the integer and + fractional parts of a float. +* Integer Division:: Functions for performing integer division. +* Parsing of Numbers:: Functions for ``reading'' numbers from strings. +* Predicates on Floats:: Some miscellaneous test functions. + +Parsing of Numbers + +* Parsing of Integers:: Functions for conversion of integer values. +* Parsing of Floats:: Functions for conversion of floating-point. + +Date and Time + +* Processor Time:: Measures processor time used by a program. +* Calendar Time:: Manipulation of ``real'' dates and times. +* Setting an Alarm:: Sending a signal after a specified time. +* Sleeping:: Waiting for a period of time. + +Processor Time + +* Basic CPU Time:: The @code{clock} function. +* Detailed CPU Time:: The @code{times} function. + +Calendar Time + +* Simple Calendar Time:: Facilities for manipulating calendar time. +* High-Resolution Calendar:: A time representation with greater precision. +* Broken-down Time:: Facilities for manipulating local time. +* Formatting Date and Time:: Converting times to strings. +* TZ Variable:: How users specify the time zone. +* Time Zone Functions:: Functions to examine or specify the time zone. +* Time Functions Example:: An example program showing use of some of + the time functions. + +Signal Handling + +* Concepts of Signals:: Introduction to the signal facilities. +* Standard Signals:: Particular kinds of signals with standard + names and meanings. +* Signal Actions:: Specifying what happens when a particular + signal is delivered. +* Defining Handlers:: How to write a signal handler function. +* Generating Signals:: How to send a signal to a process. +* Blocking Signals:: Making the system hold signals temporarily. +* Waiting for a Signal:: Suspending your program until a signal arrives. +* Signal Stack:: Using a Separate Signal Stack +* BSD Signal Handling:: Additional functions for backward + compatibility with BSD. + +Basic Concepts of Signals + +* Kinds of Signals:: Some examples of what can cause a signal. +* Signal Generation:: Concepts of why and how signals occur. +* Delivery of Signal:: Concepts of what a signal does to the process. + +Standard Signals + +* Program Error Signals:: Used to report serious program errors. +* Termination Signals:: Used to interrupt and/or terminate the program. +* Alarm Signals:: Used to indicate expiration of timers. +* Asynchronous I/O Signals:: Used to indicate input is available. +* Job Control Signals:: Signals used to support job control. +* Operation Error Signals:: Used to report operational system errors. +* Miscellaneous Signals:: Miscellaneous Signals. +* Signal Messages:: Printing a message describing a signal. + +Specifying Signal Actions + +* Basic Signal Handling:: The simple @code{signal} function. +* Advanced Signal Handling:: The more powerful @code{sigaction} function. +* Signal and Sigaction:: How those two functions interact. +* Sigaction Function Example:: An example of using the sigaction function. +* Flags for Sigaction:: Specifying options for signal handling. +* Initial Signal Actions:: How programs inherit signal actions. + +Defining Signal Handlers + +* Handler Returns:: +* Termination in Handler:: +* Longjmp in Handler:: +* Signals in Handler:: +* Nonreentrancy:: +* Atomic Data Access:: + +Generating Signals + +* Signaling Yourself:: Signaling Yourself +* Signaling Another Process:: Send a signal to another process. +* Permission for kill:: Permission for using @code{kill} +* Kill Example:: Using @code{kill} for Communication + +Blocking Signals + +* Why Block:: The purpose of blocking signals. +* Signal Sets:: How to specify which signals to block. +* Process Signal Mask:: Blocking delivery of signals to your + process during normal execution. +* Testing for Delivery:: Blocking to Test for Delivery of a Signal +* Blocking for Handler:: Blocking additional signals while a + handler is being run. +* Checking for Pending Signals::Checking for Pending Signals +* Remembering a Signal:: How you can get almost the same effect + as blocking a signal, by handling it + and setting a flag to be tested later. + +Waiting for a Signal + +* Using Pause:: The simple way, using @code{pause}. +* Pause Problems:: Why the simple way is often not very good. +* Sigsuspend:: Reliably waiting for a specific signal. + +BSD Signal Handling + +* BSD Handler:: BSD Function to Establish a Handler. +* Blocking in BSD:: BSD Functions for Blocking Signals + +Process Startup and Termination + +* Program Arguments:: Parsing your program's command-line arguments. +* Environment Variables:: How to access parameters inherited from + a parent process. +* Program Termination:: How to cause a process to terminate and + return status information to its parent. + +Program Arguments + +* Argument Syntax:: By convention, options start with a hyphen. +* Parsing Options:: The @code{getopt} function. +* Example of Getopt:: An example of parsing options with @code{getopt}. +* Long Options:: GNU utilities should accept long-named options. + Here is how to do that. +* Long Option Example:: An example of using @code{getopt_long}. + +Environment Variables + +* Environment Access:: How to get and set the values of + environment variables. +* Standard Environment:: These environment variables have + standard interpretations. + +Program Termination + +* Normal Termination:: If a program calls @code{exit}, a + process terminates normally. +* Exit Status:: The @code{exit status} provides information + about why the process terminated. +* Cleanups on Exit:: A process can run its own cleanup + functions upon normal termination. +* Aborting a Program:: The @code{abort} function causes + abnormal program termination. +* Termination Internals:: What happens when a process terminates. + + +Child Processes + +* Running a Command:: The easy way to run another program. +* Process Creation Concepts:: An overview of the hard way to do it. +* Process Identification:: How to get the process ID of a process. +* Creating a Process:: How to fork a child process. +* Executing a File:: How to make a child execute another program. +* Process Completion:: How to tell when a child process has completed. +* Process Completion Status:: How to interpret the status value + returned from a child process. +* BSD Wait Functions:: More functions, for backward compatibility. +* Process Creation Example:: A complete example program. + +Job Control + +* Concepts of Job Control :: Concepts of Job Control +* Job Control is Optional:: Not all POSIX systems support job control. +* Controlling Terminal:: How a process gets its controlling terminal. +* Access to the Terminal:: How processes share the controlling terminal. +* Orphaned Process Groups:: Jobs left after the user logs out. +* Implementing a Shell:: What a shell must do to implement job control. +* Functions for Job Control:: Functions to control process groups. + +Implementing a Job Control Shell + +* Data Structures:: Introduction to the sample shell. +* Initializing the Shell:: What the shell must do to take + responsibility for job control. +* Launching Jobs:: Creating jobs to execute commands. +* Foreground and Background:: Putting a job in foreground of background. +* Stopped and Terminated Jobs:: Reporting job status. +* Continuing Stopped Jobs:: How to continue a stopped job in + the foreground or background. +* Missing Pieces:: Other parts of the shell. + +Functions for Job Control + +* Identifying the Terminal:: Determining the controlling terminal's name. +* Process Group Functions:: Functions for manipulating process groups. +* Terminal Access Functions:: Functions for controlling terminal access. + +Users and Groups + +* User and Group IDs:: Each user and group has a unique numeric ID. +* Process Persona:: The user IDs and group IDs of a process. +* Why Change Persona:: Why a program might need to change + its user and/or group IDs. +* How Change Persona:: Restrictions on changing user and group IDs. +* Reading Persona:: Examining the process's user and group IDs. +* Setting User ID:: +* Setting Groups:: +* Enable/Disable Setuid:: +* Setuid Program Example:: Setuid Program Example +* Tips for Setuid:: +* Who Logged In:: Getting the name of the user who logged in, + or of the real user ID of the current process. + +* User Database:: Functions and data structures for + accessing the user database. +* Group Database:: Functions and data structures for + accessing the group database. +* Database Example:: Example program showing use of database + inquiry functions. + +User Database + +* User Data Structure:: +* Lookup User:: +* Scanning All Users:: Scanning the List of All Users +* Writing a User Entry:: + +Group Database + +* Group Data Structure:: +* Lookup Group:: +* Scanning All Groups:: Scanning the List of All Groups + +System Information + +* Host Identification:: Determining the name of the machine. +* Hardware/Software Type ID:: Determining the hardware type and + operating system type. + +System Configuration Limits + +* General Limits:: Constants and functions that describe + various process-related limits that have + one uniform value for any given machine. +* System Options:: Optional POSIX features. +* Version Supported:: Version numbers of POSIX.1 and POSIX.2. +* Sysconf:: Getting specific configuration values + of general limits and system options. +* Minimums:: Minimum values for general limits. + +* Limits for Files:: Size limitations on individual files. + These can vary between file systems + or even from file to file. +* Options for Files:: Optional features that some files may support. +* File Minimums:: Minimum values for file limits. +* Pathconf:: Getting the limit values for a particular file. + +* Utility Limits:: Capacity limits of POSIX.2 utility programs. +* Utility Minimums:: Minimum allowable values of those limits. + +* String Parameters:: Getting the default search path. + +Library Facilities that are Part of the C Language + +* Consistency Checking:: Using @code{assert} to abort + if something ``impossible'' happens. +* Variadic Functions:: Defining functions with varying + numbers of arguments. +* Null Pointer Constant:: The macro @code{NULL}. +* Important Data Types:: Data types for object sizes. +* Data Type Measurements:: Parameters of data type representations. + +Variadic Functions + +* Why Variadic:: Reasons for making functions take + variable arguments. +* How Variadic:: How to define and call variadic functions. +* Argument Macros:: Detailed specification of the macros + for accessing variable arguments. +* Variadic Example:: A complete example. + +How Variadic Functions are Defined and Used + +* Variadic Prototypes:: How to make a prototype for a function + with variable arguments. +* Receiving Arguments:: Steps you must follow to access the + optional argument values. +* How Many Arguments:: How to decide whether there are more arguments. +* Calling Variadics:: Things you need to know about calling + variable arguments functions. + +Data Type Measurements + +* Width of Type:: How many bits does an integer type hold? +* Range of Type:: What are the largest and smallest values + that an integer type can hold? +* Floating Type Macros:: Parameters that measure floating-point types. +* Structure Measurement:: Getting measurements on structure types. + +Floating Type Macros + +* Floating Point Concepts:: Definitions of terminology. +* Floating Point Parameters:: Dimensions, limits of floating point types. +* IEEE Floating Point:: How one common representation is described. + +Library Maintenance + +* Installation:: How to configure, compile and install + the GNU C library. +* Reporting Bugs:: How to report bugs (if you want to + get them fixed) and other troubles + you may have with the GNU C library. +* Porting:: How to port the GNU C library to + a new machine or operating system. +@c * Traditional C Compatibility:: Using the GNU C library with non-ANSI +@c C compilers. +* Contributors:: Who wrote what parts of the GNU C Library. + +Porting the GNU C Library + +* Hierarchy Conventions:: How the @file{sysdeps} hierarchy is + layed out. +* Porting to Unix:: Porting the library to an average + Unix-like system. +@end menu + + +@comment Includes of all the individual chapters. +@include intro.texi +@include errno.texi +@include memory.texi +@include ctype.texi +@include string.texi +@include io.texi +@include stdio.texi +@include llio.texi +@include filesys.texi +@include pipe.texi +@include socket.texi +@include terminal.texi +@include math.texi +@include arith.texi +@include search.texi +@include pattern.texi +@include time.texi +@include mbyte.texi +@include locale.texi +@include setjmp.texi +@include signal.texi +@include startup.texi +@include process.texi +@include job.texi +@include users.texi +@include sysinfo.texi +@include conf.texi + +@comment Includes of the appendices. +@include lang.texi +@include header.texi +@include maint.texi + + +@set lgpl-appendix +@node Copying, Concept Index, Maintenance, Top +@include lgpl.texinfo + + +@node Concept Index, Type Index, Copying, Top +@unnumbered Concept Index + +@printindex cp + +@node Type Index, Function Index, Concept Index, Top +@unnumbered Type Index + +@printindex tp + +@node Function Index, Variable Index, Type Index, Top +@unnumbered Function and Macro Index + +@printindex fn + +@node Variable Index, File Index, Function Index, Top +@unnumbered Variable and Constant Macro Index + +@printindex vr + +@node File Index, , Variable Index, Top +@unnumbered Program and File Index + +@printindex pg + + +@shortcontents +@contents +@bye diff --git a/manual/libcbook.texi b/manual/libcbook.texi new file mode 100644 index 0000000000..b248304ede --- /dev/null +++ b/manual/libcbook.texi @@ -0,0 +1,3 @@ +\input texinfo +@finalout +@include libc.texinfo diff --git a/manual/llio.texi b/manual/llio.texi new file mode 100644 index 0000000000..6a5a5d27e0 --- /dev/null +++ b/manual/llio.texi @@ -0,0 +1,1979 @@ +@node Low-Level I/O, File System Interface, I/O on Streams, Top +@chapter Low-Level Input/Output + +This chapter describes functions for performing low-level input/output +operations on file descriptors. These functions include the primitives +for the higher-level I/O functions described in @ref{I/O on Streams}, as +well as functions for performing low-level control operations for which +there are no equivalents on streams. + +Stream-level I/O is more flexible and usually more convenient; +therefore, programmers generally use the descriptor-level functions only +when necessary. These are some of the usual reasons: + +@itemize @bullet +@item +For reading binary files in large chunks. + +@item +For reading an entire file into core before parsing it. + +@item +To perform operations other than data transfer, which can only be done +with a descriptor. (You can use @code{fileno} to get the descriptor +corresponding to a stream.) + +@item +To pass descriptors to a child process. (The child can create its own +stream to use a descriptor that it inherits, but cannot inherit a stream +directly.) +@end itemize + +@menu +* Opening and Closing Files:: How to open and close file + descriptors. +* I/O Primitives:: Reading and writing data. +* File Position Primitive:: Setting a descriptor's file + position. +* Descriptors and Streams:: Converting descriptor to stream + or vice-versa. +* Stream/Descriptor Precautions:: Precautions needed if you use both + descriptors and streams. +* Waiting for I/O:: How to check for input or output + on multiple file descriptors. +* Control Operations:: Various other operations on file + descriptors. +* Duplicating Descriptors:: Fcntl commands for duplicating + file descriptors. +* Descriptor Flags:: Fcntl commands for manipulating + flags associated with file + descriptors. +* File Status Flags:: Fcntl commands for manipulating + flags associated with open files. +* File Locks:: Fcntl commands for implementing + file locking. +* Interrupt Input:: Getting an asynchronous signal when + input arrives. +@end menu + + +@node Opening and Closing Files +@section Opening and Closing Files + +@cindex opening a file descriptor +@cindex closing a file descriptor +This section describes the primitives for opening and closing files +using file descriptors. The @code{open} and @code{creat} functions are +declared in the header file @file{fcntl.h}, while @code{close} is +declared in @file{unistd.h}. +@pindex unistd.h +@pindex fcntl.h + +@comment fcntl.h +@comment POSIX.1 +@deftypefun int open (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}]) +The @code{open} function creates and returns a new file descriptor +for the file named by @var{filename}. Initially, the file position +indicator for the file is at the beginning of the file. The argument +@var{mode} is used only when a file is created, but it doesn't hurt +to supply the argument in any case. + +The @var{flags} argument controls how the file is to be opened. This is +a bit mask; you create the value by the bitwise OR of the appropriate +parameters (using the @samp{|} operator in C). +@xref{File Status Flags}, for the parameters available. + +The normal return value from @code{open} is a non-negative integer file +descriptor. In the case of an error, a value of @code{-1} is returned +instead. In addition to the usual file name errors (@pxref{File +Name Errors}), the following @code{errno} error conditions are defined +for this function: + +@table @code +@item EACCES +The file exists but is not readable/writable as requested by the @var{flags} +argument, the file does not exist and the directory is unwritable so +it cannot be created. + +@item EEXIST +Both @code{O_CREAT} and @code{O_EXCL} are set, and the named file already +exists. + +@item EINTR +The @code{open} operation was interrupted by a signal. +@xref{Interrupted Primitives}. + +@item EISDIR +The @var{flags} argument specified write access, and the file is a directory. + +@item EMFILE +The process has too many files open. +The maximum number of file descriptors is controlled by the +@code{RLIMIT_NOFILE} resource limit; @pxref{Limits on Resources}. + +@item ENFILE +The entire system, or perhaps the file system which contains the +directory, cannot support any additional open files at the moment. +(This problem cannot happen on the GNU system.) + +@item ENOENT +The named file does not exist, and @code{O_CREAT} is not specified. + +@item ENOSPC +The directory or file system that would contain the new file cannot be +extended, because there is no disk space left. + +@item ENXIO +@code{O_NONBLOCK} and @code{O_WRONLY} are both set in the @var{flags} +argument, the file named by @var{filename} is a FIFO (@pxref{Pipes and +FIFOs}), and no process has the file open for reading. + +@item EROFS +The file resides on a read-only file system and any of @w{@code{O_WRONLY}}, +@code{O_RDWR}, and @code{O_TRUNC} are set in the @var{flags} argument, +or @code{O_CREAT} is set and the file does not already exist. +@end table + +@c !!! umask + +The @code{open} function is the underlying primitive for the @code{fopen} +and @code{freopen} functions, that create streams. +@end deftypefun + +@comment fcntl.h +@comment POSIX.1 +@deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode}) +This function is obsolete. The call: + +@smallexample +creat (@var{filename}, @var{mode}) +@end smallexample + +@noindent +is equivalent to: + +@smallexample +open (@var{filename}, O_WRONLY | O_CREAT | O_TRUNC, @var{mode}) +@end smallexample +@end deftypefn + +@comment unistd.h +@comment POSIX.1 +@deftypefun int close (int @var{filedes}) +The function @code{close} closes the file descriptor @var{filedes}. +Closing a file has the following consequences: + +@itemize @bullet +@item +The file descriptor is deallocated. + +@item +Any record locks owned by the process on the file are unlocked. + +@item +When all file descriptors associated with a pipe or FIFO have been closed, +any unread data is discarded. +@end itemize + +The normal return value from @code{close} is @code{0}; a value of @code{-1} +is returned in case of failure. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINTR +The @code{close} call was interrupted by a signal. +@xref{Interrupted Primitives}. +Here is an example of how to handle @code{EINTR} properly: + +@smallexample +TEMP_FAILURE_RETRY (close (desc)); +@end smallexample + +@item ENOSPC +@itemx EIO +@itemx EDQUOT +When the file is accessed by NFS, these errors from @code{write} can sometimes +not be detected until @code{close}. @xref{I/O Primitives}, for details +on their meaning. +@end table +@end deftypefun + +To close a stream, call @code{fclose} (@pxref{Closing Streams}) instead +of trying to close its underlying file descriptor with @code{close}. +This flushes any buffered output and updates the stream object to +indicate that it is closed. + +@node I/O Primitives +@section Input and Output Primitives + +This section describes the functions for performing primitive input and +output operations on file descriptors: @code{read}, @code{write}, and +@code{lseek}. These functions are declared in the header file +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftp {Data Type} ssize_t +This data type is used to represent the sizes of blocks that can be +read or written in a single operation. It is similar to @code{size_t}, +but must be a signed type. +@end deftp + +@cindex reading from a file descriptor +@comment unistd.h +@comment POSIX.1 +@deftypefun ssize_t read (int @var{filedes}, void *@var{buffer}, size_t @var{size}) +The @code{read} function reads up to @var{size} bytes from the file +with descriptor @var{filedes}, storing the results in the @var{buffer}. +(This is not necessarily a character string and there is no terminating +null character added.) + +@cindex end-of-file, on a file descriptor +The return value is the number of bytes actually read. This might be +less than @var{size}; for example, if there aren't that many bytes left +in the file or if there aren't that many bytes immediately available. +The exact behavior depends on what kind of file it is. Note that +reading less than @var{size} bytes is not an error. + +A value of zero indicates end-of-file (except if the value of the +@var{size} argument is also zero). This is not considered an error. +If you keep calling @code{read} while at end-of-file, it will keep +returning zero and doing nothing else. + +If @code{read} returns at least one character, there is no way you can +tell whether end-of-file was reached. But if you did reach the end, the +next read will return zero. + +In case of an error, @code{read} returns @code{-1}. The following +@code{errno} error conditions are defined for this function: + +@table @code +@item EAGAIN +Normally, when no input is immediately available, @code{read} waits for +some input. But if the @code{O_NONBLOCK} flag is set for the file +(@pxref{File Status Flags}), @code{read} returns immediately without +reading any data, and reports this error. + +@strong{Compatibility Note:} Most versions of BSD Unix use a different +error code for this: @code{EWOULDBLOCK}. In the GNU library, +@code{EWOULDBLOCK} is an alias for @code{EAGAIN}, so it doesn't matter +which name you use. + +On some systems, reading a large amount of data from a character special +file can also fail with @code{EAGAIN} if the kernel cannot find enough +physical memory to lock down the user's pages. This is limited to +devices that transfer with direct memory access into the user's memory, +which means it does not include terminals, since they always use +separate buffers inside the kernel. This problem never happens in the +GNU system. + +Any condition that could result in @code{EAGAIN} can instead result in a +successful @code{read} which returns fewer bytes than requested. +Calling @code{read} again immediately would result in @code{EAGAIN}. + +@item EBADF +The @var{filedes} argument is not a valid file descriptor, +or is not open for reading. + +@item EINTR +@code{read} was interrupted by a signal while it was waiting for input. +@xref{Interrupted Primitives}. A signal will not necessary cause +@code{read} to return @code{EINTR}; it may instead result in a +successful @code{read} which returns fewer bytes than requested. + +@item EIO +For many devices, and for disk files, this error code indicates +a hardware error. + +@code{EIO} also occurs when a background process tries to read from the +controlling terminal, and the normal action of stopping the process by +sending it a @code{SIGTTIN} signal isn't working. This might happen if +signal is being blocked or ignored, or because the process group is +orphaned. @xref{Job Control}, for more information about job control, +and @ref{Signal Handling}, for information about signals. +@end table + +The @code{read} function is the underlying primitive for all of the +functions that read from streams, such as @code{fgetc}. +@end deftypefun + +@cindex writing to a file descriptor +@comment unistd.h +@comment POSIX.1 +@deftypefun ssize_t write (int @var{filedes}, const void *@var{buffer}, size_t @var{size}) +The @code{write} function writes up to @var{size} bytes from +@var{buffer} to the file with descriptor @var{filedes}. The data in +@var{buffer} is not necessarily a character string and a null character is +output like any other character. + +The return value is the number of bytes actually written. This may be +@var{size}, but can always be smaller. Your program should always call +@code{write} in a loop, iterating until all the data is written. + +Once @code{write} returns, the data is enqueued to be written and can be +read back right away, but it is not necessarily written out to permanent +storage immediately. You can use @code{fsync} when you need to be sure +your data has been permanently stored before continuing. (It is more +efficient for the system to batch up consecutive writes and do them all +at once when convenient. Normally they will always be written to disk +within a minute or less.) +@c !!! xref fsync +You can use the @code{O_FSYNC} open mode to make @code{write} always +store the data to disk before returning; @pxref{Operating Modes}. + +In the case of an error, @code{write} returns @code{-1}. The following +@code{errno} error conditions are defined for this function: + +@table @code +@item EAGAIN +Normally, @code{write} blocks until the write operation is complete. +But if the @code{O_NONBLOCK} flag is set for the file (@pxref{Control +Operations}), it returns immediately without writing any data, and +reports this error. An example of a situation that might cause the +process to block on output is writing to a terminal device that supports +flow control, where output has been suspended by receipt of a STOP +character. + +@strong{Compatibility Note:} Most versions of BSD Unix use a different +error code for this: @code{EWOULDBLOCK}. In the GNU library, +@code{EWOULDBLOCK} is an alias for @code{EAGAIN}, so it doesn't matter +which name you use. + +On some systems, writing a large amount of data from a character special +file can also fail with @code{EAGAIN} if the kernel cannot find enough +physical memory to lock down the user's pages. This is limited to +devices that transfer with direct memory access into the user's memory, +which means it does not include terminals, since they always use +separate buffers inside the kernel. This problem does not arise in the +GNU system. + +@item EBADF +The @var{filedes} argument is not a valid file descriptor, +or is not open for writing. + +@item EFBIG +The size of the file would become larger than the implementation can support. + +@item EINTR +The @code{write} operation was interrupted by a signal while it was +blocked waiting for completion. A signal will not necessary cause +@code{write} to return @code{EINTR}; it may instead result in a +successful @code{write} which writes fewer bytes than requested. +@xref{Interrupted Primitives}. + +@item EIO +For many devices, and for disk files, this error code indicates +a hardware error. + +@item ENOSPC +The device containing the file is full. + +@item EPIPE +This error is returned when you try to write to a pipe or FIFO that +isn't open for reading by any process. When this happens, a @code{SIGPIPE} +signal is also sent to the process; see @ref{Signal Handling}. +@end table + +Unless you have arranged to prevent @code{EINTR} failures, you should +check @code{errno} after each failing call to @code{write}, and if the +error was @code{EINTR}, you should simply repeat the call. +@xref{Interrupted Primitives}. The easy way to do this is with the +macro @code{TEMP_FAILURE_RETRY}, as follows: + +@smallexample +nbytes = TEMP_FAILURE_RETRY (write (desc, buffer, count)); +@end smallexample + +The @code{write} function is the underlying primitive for all of the +functions that write to streams, such as @code{fputc}. +@end deftypefun + +@node File Position Primitive +@section Setting the File Position of a Descriptor + +Just as you can set the file position of a stream with @code{fseek}, you +can set the file position of a descriptor with @code{lseek}. This +specifies the position in the file for the next @code{read} or +@code{write} operation. @xref{File Positioning}, for more information +on the file position and what it means. + +To read the current file position value from a descriptor, use +@code{lseek (@var{desc}, 0, SEEK_CUR)}. + +@cindex file positioning on a file descriptor +@cindex positioning a file descriptor +@cindex seeking on a file descriptor +@comment unistd.h +@comment POSIX.1 +@deftypefun off_t lseek (int @var{filedes}, off_t @var{offset}, int @var{whence}) +The @code{lseek} function is used to change the file position of the +file with descriptor @var{filedes}. + +The @var{whence} argument specifies how the @var{offset} should be +interpreted in the same way as for the @code{fseek} function, and must be +one of the symbolic constants @code{SEEK_SET}, @code{SEEK_CUR}, or +@code{SEEK_END}. + +@table @code +@item SEEK_SET +Specifies that @var{whence} is a count of characters from the beginning +of the file. + +@item SEEK_CUR +Specifies that @var{whence} is a count of characters from the current +file position. This count may be positive or negative. + +@item SEEK_END +Specifies that @var{whence} is a count of characters from the end of +the file. A negative count specifies a position within the current +extent of the file; a positive count specifies a position past the +current end. If you set the position past the current end, and +actually write data, you will extend the file with zeros up to that +position.@end table + +The return value from @code{lseek} is normally the resulting file +position, measured in bytes from the beginning of the file. +You can use this feature together with @code{SEEK_CUR} to read the +current file position. + +If you want to append to the file, setting the file position to the +current end of file with @code{SEEK_END} is not sufficient. Another +process may write more data after you seek but before you write, +extending the file so the position you write onto clobbers their data. +Instead, use the @code{O_APPEND} operating mode; @pxref{Operating Modes}. + +You can set the file position past the current end of the file. This +does not by itself make the file longer; @code{lseek} never changes the +file. But subsequent output at that position will extend the file. +Characters between the previous end of file and the new position are +filled with zeros. Extending the file in this way can create a +``hole'': the blocks of zeros are not actually allocated on disk, so the +file takes up less space than it appears so; it is then called a +``sparse file''. +@cindex sparse files +@cindex holes in files + +If the file position cannot be changed, or the operation is in some way +invalid, @code{lseek} returns a value of @code{-1}. The following +@code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} is not a valid file descriptor. + +@item EINVAL +The @var{whence} argument value is not valid, or the resulting +file offset is not valid. A file offset is invalid. + +@item ESPIPE +The @var{filedes} corresponds to an object that cannot be positioned, +such as a pipe, FIFO or terminal device. (POSIX.1 specifies this error +only for pipes and FIFOs, but in the GNU system, you always get +@code{ESPIPE} if the object is not seekable.) +@end table + +The @code{lseek} function is the underlying primitive for the +@code{fseek}, @code{ftell} and @code{rewind} functions, which operate on +streams instead of file descriptors. +@end deftypefun + +You can have multiple descriptors for the same file if you open the file +more than once, or if you duplicate a descriptor with @code{dup}. +Descriptors that come from separate calls to @code{open} have independent +file positions; using @code{lseek} on one descriptor has no effect on the +other. For example, + +@smallexample +@group +@{ + int d1, d2; + char buf[4]; + d1 = open ("foo", O_RDONLY); + d2 = open ("foo", O_RDONLY); + lseek (d1, 1024, SEEK_SET); + read (d2, buf, 4); +@} +@end group +@end smallexample + +@noindent +will read the first four characters of the file @file{foo}. (The +error-checking code necessary for a real program has been omitted here +for brevity.) + +By contrast, descriptors made by duplication share a common file +position with the original descriptor that was duplicated. Anything +which alters the file position of one of the duplicates, including +reading or writing data, affects all of them alike. Thus, for example, + +@smallexample +@{ + int d1, d2, d3; + char buf1[4], buf2[4]; + d1 = open ("foo", O_RDONLY); + d2 = dup (d1); + d3 = dup (d2); + lseek (d3, 1024, SEEK_SET); + read (d1, buf1, 4); + read (d2, buf2, 4); +@} +@end smallexample + +@noindent +will read four characters starting with the 1024'th character of +@file{foo}, and then four more characters starting with the 1028'th +character. + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} off_t +This is an arithmetic data type used to represent file sizes. +In the GNU system, this is equivalent to @code{fpos_t} or @code{long int}. +@end deftp + +These aliases for the @samp{SEEK_@dots{}} constants exist for the sake +of compatibility with older BSD systems. They are defined in two +different header files: @file{fcntl.h} and @file{sys/file.h}. + +@table @code +@item L_SET +An alias for @code{SEEK_SET}. + +@item L_INCR +An alias for @code{SEEK_CUR}. + +@item L_XTND +An alias for @code{SEEK_END}. +@end table + +@node Descriptors and Streams +@section Descriptors and Streams +@cindex streams, and file descriptors +@cindex converting file descriptor to stream +@cindex extracting file descriptor from stream + +Given an open file descriptor, you can create a stream for it with the +@code{fdopen} function. You can get the underlying file descriptor for +an existing stream with the @code{fileno} function. These functions are +declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment POSIX.1 +@deftypefun {FILE *} fdopen (int @var{filedes}, const char *@var{opentype}) +The @code{fdopen} function returns a new stream for the file descriptor +@var{filedes}. + +The @var{opentype} argument is interpreted in the same way as for the +@code{fopen} function (@pxref{Opening Streams}), except that +the @samp{b} option is not permitted; this is because GNU makes no +distinction between text and binary files. Also, @code{"w"} and +@code{"w+"} do not cause truncation of the file; these have affect only +when opening a file, and in this case the file has already been opened. +You must make sure that the @var{opentype} argument matches the actual +mode of the open file descriptor. + +The return value is the new stream. If the stream cannot be created +(for example, if the modes for the file indicated by the file descriptor +do not permit the access specified by the @var{opentype} argument), a +null pointer is returned instead. + +In some other systems, @code{fdopen} may fail to detect that the modes +for file descriptor do not permit the access specified by +@code{opentype}. The GNU C library always checks for this. +@end deftypefun + +For an example showing the use of the @code{fdopen} function, +see @ref{Creating a Pipe}. + +@comment stdio.h +@comment POSIX.1 +@deftypefun int fileno (FILE *@var{stream}) +This function returns the file descriptor associated with the stream +@var{stream}. If an error is detected (for example, if the @var{stream} +is not valid) or if @var{stream} does not do I/O to a file, +@code{fileno} returns @code{-1}. +@end deftypefun + +@cindex standard file descriptors +@cindex file descriptors, standard +There are also symbolic constants defined in @file{unistd.h} for the +file descriptors belonging to the standard streams @code{stdin}, +@code{stdout}, and @code{stderr}; see @ref{Standard Streams}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@table @code +@item STDIN_FILENO +@vindex STDIN_FILENO +This macro has value @code{0}, which is the file descriptor for +standard input. +@cindex standard input file descriptor + +@comment unistd.h +@comment POSIX.1 +@item STDOUT_FILENO +@vindex STDOUT_FILENO +This macro has value @code{1}, which is the file descriptor for +standard output. +@cindex standard output file descriptor + +@comment unistd.h +@comment POSIX.1 +@item STDERR_FILENO +@vindex STDERR_FILENO +This macro has value @code{2}, which is the file descriptor for +standard error output. +@end table +@cindex standard error file descriptor + +@node Stream/Descriptor Precautions +@section Dangers of Mixing Streams and Descriptors +@cindex channels +@cindex streams and descriptors +@cindex descriptors and streams +@cindex mixing descriptors and streams + +You can have multiple file descriptors and streams (let's call both +streams and descriptors ``channels'' for short) connected to the same +file, but you must take care to avoid confusion between channels. There +are two cases to consider: @dfn{linked} channels that share a single +file position value, and @dfn{independent} channels that have their own +file positions. + +It's best to use just one channel in your program for actual data +transfer to any given file, except when all the access is for input. +For example, if you open a pipe (something you can only do at the file +descriptor level), either do all I/O with the descriptor, or construct a +stream from the descriptor with @code{fdopen} and then do all I/O with +the stream. + +@menu +* Linked Channels:: Dealing with channels sharing a file position. +* Independent Channels:: Dealing with separately opened, unlinked channels. +* Cleaning Streams:: Cleaning a stream makes it safe to use + another channel. +@end menu + +@node Linked Channels +@subsection Linked Channels +@cindex linked channels + +Channels that come from a single opening share the same file position; +we call them @dfn{linked} channels. Linked channels result when you +make a stream from a descriptor using @code{fdopen}, when you get a +descriptor from a stream with @code{fileno}, when you copy a descriptor +with @code{dup} or @code{dup2}, and when descriptors are inherited +during @code{fork}. For files that don't support random access, such as +terminals and pipes, @emph{all} channels are effectively linked. On +random-access files, all append-type output streams are effectively +linked to each other. + +@cindex cleaning up a stream +If you have been using a stream for I/O, and you want to do I/O using +another channel (either a stream or a descriptor) that is linked to it, +you must first @dfn{clean up} the stream that you have been using. +@xref{Cleaning Streams}. + +Terminating a process, or executing a new program in the process, +destroys all the streams in the process. If descriptors linked to these +streams persist in other processes, their file positions become +undefined as a result. To prevent this, you must clean up the streams +before destroying them. + +@node Independent Channels +@subsection Independent Channels +@cindex independent channels + +When you open channels (streams or descriptors) separately on a seekable +file, each channel has its own file position. These are called +@dfn{independent channels}. + +The system handles each channel independently. Most of the time, this +is quite predictable and natural (especially for input): each channel +can read or write sequentially at its own place in the file. However, +if some of the channels are streams, you must take these precautions: + +@itemize @bullet +@item +You should clean an output stream after use, before doing anything else +that might read or write from the same part of the file. + +@item +You should clean an input stream before reading data that may have been +modified using an independent channel. Otherwise, you might read +obsolete data that had been in the stream's buffer. +@end itemize + +If you do output to one channel at the end of the file, this will +certainly leave the other independent channels positioned somewhere +before the new end. You cannot reliably set their file positions to the +new end of file before writing, because the file can always be extended +by another process between when you set the file position and when you +write the data. Instead, use an append-type descriptor or stream; they +always output at the current end of the file. In order to make the +end-of-file position accurate, you must clean the output channel you +were using, if it is a stream. + +It's impossible for two channels to have separate file pointers for a +file that doesn't support random access. Thus, channels for reading or +writing such files are always linked, never independent. Append-type +channels are also always linked. For these channels, follow the rules +for linked channels; see @ref{Linked Channels}. + +@node Cleaning Streams +@subsection Cleaning Streams + +On the GNU system, you can clean up any stream with @code{fclean}: + +@comment stdio.h +@comment GNU +@deftypefun int fclean (FILE *@var{stream}) +Clean up the stream @var{stream} so that its buffer is empty. If +@var{stream} is doing output, force it out. If @var{stream} is doing +input, give the data in the buffer back to the system, arranging to +reread it. +@end deftypefun + +On other systems, you can use @code{fflush} to clean a stream in most +cases. + +You can skip the @code{fclean} or @code{fflush} if you know the stream +is already clean. A stream is clean whenever its buffer is empty. For +example, an unbuffered stream is always clean. An input stream that is +at end-of-file is clean. A line-buffered stream is clean when the last +character output was a newline. + +There is one case in which cleaning a stream is impossible on most +systems. This is when the stream is doing input from a file that is not +random-access. Such streams typically read ahead, and when the file is +not random access, there is no way to give back the excess data already +read. When an input stream reads from a random-access file, +@code{fflush} does clean the stream, but leaves the file pointer at an +unpredictable place; you must set the file pointer before doing any +further I/O. On the GNU system, using @code{fclean} avoids both of +these problems. + +Closing an output-only stream also does @code{fflush}, so this is a +valid way of cleaning an output stream. On the GNU system, closing an +input stream does @code{fclean}. + +You need not clean a stream before using its descriptor for control +operations such as setting terminal modes; these operations don't affect +the file position and are not affected by it. You can use any +descriptor for these operations, and all channels are affected +simultaneously. However, text already ``output'' to a stream but still +buffered by the stream will be subject to the new terminal modes when +subsequently flushed. To make sure ``past'' output is covered by the +terminal settings that were in effect at the time, flush the output +streams for that terminal before setting the modes. @xref{Terminal +Modes}. + +@node Waiting for I/O +@section Waiting for Input or Output +@cindex waiting for input or output +@cindex multiplexing input +@cindex input from multiple files + +Sometimes a program needs to accept input on multiple input channels +whenever input arrives. For example, some workstations may have devices +such as a digitizing tablet, function button box, or dial box that are +connected via normal asynchronous serial interfaces; good user interface +style requires responding immediately to input on any device. Another +example is a program that acts as a server to several other processes +via pipes or sockets. + +You cannot normally use @code{read} for this purpose, because this +blocks the program until input is available on one particular file +descriptor; input on other channels won't wake it up. You could set +nonblocking mode and poll each file descriptor in turn, but this is very +inefficient. + +A better solution is to use the @code{select} function. This blocks the +program until input or output is ready on a specified set of file +descriptors, or until a timer expires, whichever comes first. This +facility is declared in the header file @file{sys/types.h}. +@pindex sys/types.h + +In the case of a server socket (@pxref{Listening}), we say that +``input'' is available when there are pending connections that could be +accepted (@pxref{Accepting Connections}). @code{accept} for server +sockets blocks and interacts with @code{select} just as @code{read} does +for normal input. + +@cindex file descriptor sets, for @code{select} +The file descriptor sets for the @code{select} function are specified +as @code{fd_set} objects. Here is the description of the data type +and some macros for manipulating these objects. + +@comment sys/types.h +@comment BSD +@deftp {Data Type} fd_set +The @code{fd_set} data type represents file descriptor sets for the +@code{select} function. It is actually a bit array. +@end deftp + +@comment sys/types.h +@comment BSD +@deftypevr Macro int FD_SETSIZE +The value of this macro is the maximum number of file descriptors that a +@code{fd_set} object can hold information about. On systems with a +fixed maximum number, @code{FD_SETSIZE} is at least that number. On +some systems, including GNU, there is no absolute limit on the number of +descriptors open, but this macro still has a constant value which +controls the number of bits in an @code{fd_set}; if you get a file +descriptor with a value as high as @code{FD_SETSIZE}, you cannot put +that descriptor into an @code{fd_set}. +@end deftypevr + +@comment sys/types.h +@comment BSD +@deftypefn Macro void FD_ZERO (fd_set *@var{set}) +This macro initializes the file descriptor set @var{set} to be the +empty set. +@end deftypefn + +@comment sys/types.h +@comment BSD +@deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set}) +This macro adds @var{filedes} to the file descriptor set @var{set}. +@end deftypefn + +@comment sys/types.h +@comment BSD +@deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set}) +This macro removes @var{filedes} from the file descriptor set @var{set}. +@end deftypefn + +@comment sys/types.h +@comment BSD +@deftypefn Macro int FD_ISSET (int @var{filedes}, fd_set *@var{set}) +This macro returns a nonzero value (true) if @var{filedes} is a member +of the the file descriptor set @var{set}, and zero (false) otherwise. +@end deftypefn + +Next, here is the description of the @code{select} function itself. + +@comment sys/types.h +@comment BSD +@deftypefun int select (int @var{nfds}, fd_set *@var{read-fds}, fd_set *@var{write-fds}, fd_set *@var{except-fds}, struct timeval *@var{timeout}) +The @code{select} function blocks the calling process until there is +activity on any of the specified sets of file descriptors, or until the +timeout period has expired. + +The file descriptors specified by the @var{read-fds} argument are +checked to see if they are ready for reading; the @var{write-fds} file +descriptors are checked to see if they are ready for writing; and the +@var{except-fds} file descriptors are checked for exceptional +conditions. You can pass a null pointer for any of these arguments if +you are not interested in checking for that kind of condition. + +A file descriptor is considered ready for reading if it is at end of +file. A server socket is considered ready for reading if there is a +pending connection which can be accepted with @code{accept}; +@pxref{Accepting Connections}. A client socket is ready for writing when +its connection is fully established; @pxref{Connecting}. + +``Exceptional conditions'' does not mean errors---errors are reported +immediately when an erroneous system call is executed, and do not +constitute a state of the descriptor. Rather, they include conditions +such as the presence of an urgent message on a socket. (@xref{Sockets}, +for information on urgent messages.) + +The @code{select} function checks only the first @var{nfds} file +descriptors. The usual thing is to pass @code{FD_SETSIZE} as the value +of this argument. + +The @var{timeout} specifies the maximum time to wait. If you pass a +null pointer for this argument, it means to block indefinitely until one +of the file descriptors is ready. Otherwise, you should provide the +time in @code{struct timeval} format; see @ref{High-Resolution +Calendar}. Specify zero as the time (a @code{struct timeval} containing +all zeros) if you want to find out which descriptors are ready without +waiting if none are ready. + +The normal return value from @code{select} is the total number of ready file +descriptors in all of the sets. Each of the argument sets is overwritten +with information about the descriptors that are ready for the corresponding +operation. Thus, to see if a particular descriptor @var{desc} has input, +use @code{FD_ISSET (@var{desc}, @var{read-fds})} after @code{select} returns. + +If @code{select} returns because the timeout period expires, it returns +a value of zero. + +Any signal will cause @code{select} to return immediately. So if your +program uses signals, you can't rely on @code{select} to keep waiting +for the full time specified. If you want to be sure of waiting for a +particular amount of time, you must check for @code{EINTR} and repeat +the @code{select} with a newly calculated timeout based on the current +time. See the example below. See also @ref{Interrupted Primitives}. + +If an error occurs, @code{select} returns @code{-1} and does not modify +the argument file descriptor sets. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EBADF +One of the file descriptor sets specified an invalid file descriptor. + +@item EINTR +The operation was interrupted by a signal. @xref{Interrupted Primitives}. + +@item EINVAL +The @var{timeout} argument is invalid; one of the components is negative +or too large. +@end table +@end deftypefun + +@strong{Portability Note:} The @code{select} function is a BSD Unix +feature. + +Here is an example showing how you can use @code{select} to establish a +timeout period for reading from a file descriptor. The @code{input_timeout} +function blocks the calling process until input is available on the +file descriptor, or until the timeout period expires. + +@smallexample +@include select.c.texi +@end smallexample + +There is another example showing the use of @code{select} to multiplex +input from multiple sockets in @ref{Server Example}. + + +@node Control Operations +@section Control Operations on Files + +@cindex control operations on files +@cindex @code{fcntl} function +This section describes how you can perform various other operations on +file descriptors, such as inquiring about or setting flags describing +the status of the file descriptor, manipulating record locks, and the +like. All of these operations are performed by the function @code{fcntl}. + +The second argument to the @code{fcntl} function is a command that +specifies which operation to perform. The function and macros that name +various flags that are used with it are declared in the header file +@file{fcntl.h}. Many of these flags are also used by the @code{open} +function; see @ref{Opening and Closing Files}. +@pindex fcntl.h + +@comment fcntl.h +@comment POSIX.1 +@deftypefun int fcntl (int @var{filedes}, int @var{command}, @dots{}) +The @code{fcntl} function performs the operation specified by +@var{command} on the file descriptor @var{filedes}. Some commands +require additional arguments to be supplied. These additional arguments +and the return value and error conditions are given in the detailed +descriptions of the individual commands. + +Briefly, here is a list of what the various commands are. + +@table @code +@item F_DUPFD +Duplicate the file descriptor (return another file descriptor pointing +to the same open file). @xref{Duplicating Descriptors}. + +@item F_GETFD +Get flags associated with the file descriptor. @xref{Descriptor Flags}. + +@item F_SETFD +Set flags associated with the file descriptor. @xref{Descriptor Flags}. + +@item F_GETFL +Get flags associated with the open file. @xref{File Status Flags}. + +@item F_SETFL +Set flags associated with the open file. @xref{File Status Flags}. + +@item F_GETLK +Get a file lock. @xref{File Locks}. + +@item F_SETLK +Set or clear a file lock. @xref{File Locks}. + +@item F_SETLKW +Like @code{F_SETLK}, but wait for completion. @xref{File Locks}. + +@item F_GETOWN +Get process or process group ID to receive @code{SIGIO} signals. +@xref{Interrupt Input}. + +@item F_SETOWN +Set process or process group ID to receive @code{SIGIO} signals. +@xref{Interrupt Input}. +@end table +@end deftypefun + + +@node Duplicating Descriptors +@section Duplicating Descriptors + +@cindex duplicating file descriptors +@cindex redirecting input and output + +You can @dfn{duplicate} a file descriptor, or allocate another file +descriptor that refers to the same open file as the original. Duplicate +descriptors share one file position and one set of file status flags +(@pxref{File Status Flags}), but each has its own set of file descriptor +flags (@pxref{Descriptor Flags}). + +The major use of duplicating a file descriptor is to implement +@dfn{redirection} of input or output: that is, to change the +file or pipe that a particular file descriptor corresponds to. + +You can perform this operation using the @code{fcntl} function with the +@code{F_DUPFD} command, but there are also convenient functions +@code{dup} and @code{dup2} for duplicating descriptors. + +@pindex unistd.h +@pindex fcntl.h +The @code{fcntl} function and flags are declared in @file{fcntl.h}, +while prototypes for @code{dup} and @code{dup2} are in the header file +@file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int dup (int @var{old}) +This function copies descriptor @var{old} to the first available +descriptor number (the first number not currently open). It is +equivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int dup2 (int @var{old}, int @var{new}) +This function copies the descriptor @var{old} to descriptor number +@var{new}. + +If @var{old} is an invalid descriptor, then @code{dup2} does nothing; it +does not close @var{new}. Otherwise, the new duplicate of @var{old} +replaces any previous meaning of descriptor @var{new}, as if @var{new} +were closed first. + +If @var{old} and @var{new} are different numbers, and @var{old} is a +valid descriptor number, then @code{dup2} is equivalent to: + +@smallexample +close (@var{new}); +fcntl (@var{old}, F_DUPFD, @var{new}) +@end smallexample + +However, @code{dup2} does this atomically; there is no instant in the +middle of calling @code{dup2} at which @var{new} is closed and not yet a +duplicate of @var{old}. +@end deftypefun + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_DUPFD +This macro is used as the @var{command} argument to @code{fcntl}, to +copy the file descriptor given as the first argument. + +The form of the call in this case is: + +@smallexample +fcntl (@var{old}, F_DUPFD, @var{next-filedes}) +@end smallexample + +The @var{next-filedes} argument is of type @code{int} and specifies that +the file descriptor returned should be the next available one greater +than or equal to this value. + +The return value from @code{fcntl} with this command is normally the value +of the new file descriptor. A return value of @code{-1} indicates an +error. The following @code{errno} error conditions are defined for +this command: + +@table @code +@item EBADF +The @var{old} argument is invalid. + +@item EINVAL +The @var{next-filedes} argument is invalid. + +@item EMFILE +There are no more file descriptors available---your program is already +using the maximum. In BSD and GNU, the maximum is controlled by a +resource limit that can be changed; @pxref{Limits on Resources}, for +more information about the @code{RLIMIT_NOFILE} limit. +@end table + +@code{ENFILE} is not a possible error code for @code{dup2} because +@code{dup2} does not create a new opening of a file; duplicate +descriptors do not count toward the limit which @code{ENFILE} +indicates. @code{EMFILE} is possible because it refers to the limit on +distinct descriptor numbers in use in one process. +@end deftypevr + +Here is an example showing how to use @code{dup2} to do redirection. +Typically, redirection of the standard streams (like @code{stdin}) is +done by a shell or shell-like program before calling one of the +@code{exec} functions (@pxref{Executing a File}) to execute a new +program in a child process. When the new program is executed, it +creates and initializes the standard streams to point to the +corresponding file descriptors, before its @code{main} function is +invoked. + +So, to redirect standard input to a file, the shell could do something +like: + +@smallexample +pid = fork (); +if (pid == 0) + @{ + char *filename; + char *program; + int file; + @dots{} + file = TEMP_FAILURE_RETRY (open (filename, O_RDONLY)); + dup2 (file, STDIN_FILENO); + TEMP_FAILURE_RETRY (close (file)); + execv (program, NULL); + @} +@end smallexample + +There is also a more detailed example showing how to implement redirection +in the context of a pipeline of processes in @ref{Launching Jobs}. + + +@node Descriptor Flags +@section File Descriptor Flags +@cindex file descriptor flags + +@dfn{File descriptor flags} are miscellaneous attributes of a file +descriptor. These flags are associated with particular file +descriptors, so that if you have created duplicate file descriptors +from a single opening of a file, each descriptor has its own set of flags. + +Currently there is just one file descriptor flag: @code{FD_CLOEXEC}, +which causes the descriptor to be closed if you use any of the +@code{exec@dots{}} functions (@pxref{Executing a File}). + +The symbols in this section are defined in the header file +@file{fcntl.h}. +@pindex fcntl.h + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_GETFD +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should return the file descriptor flags associated +with the @var{filedes} argument. + +The normal return value from @code{fcntl} with this command is a +nonnegative number which can be interpreted as the bitwise OR of the +individual flags (except that currently there is only one flag to use). + +In case of an error, @code{fcntl} returns @code{-1}. The following +@code{errno} error conditions are defined for this command: + +@table @code +@item EBADF +The @var{filedes} argument is invalid. +@end table +@end deftypevr + + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_SETFD +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should set the file descriptor flags associated with the +@var{filedes} argument. This requires a third @code{int} argument to +specify the new flags, so the form of the call is: + +@smallexample +fcntl (@var{filedes}, F_SETFD, @var{new-flags}) +@end smallexample + +The normal return value from @code{fcntl} with this command is an +unspecified value other than @code{-1}, which indicates an error. +The flags and error conditions are the same as for the @code{F_GETFD} +command. +@end deftypevr + +The following macro is defined for use as a file descriptor flag with +the @code{fcntl} function. The value is an integer constant usable +as a bit mask value. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int FD_CLOEXEC +@cindex close-on-exec (file descriptor flag) +This flag specifies that the file descriptor should be closed when +an @code{exec} function is invoked; see @ref{Executing a File}. When +a file descriptor is allocated (as with @code{open} or @code{dup}), +this bit is initially cleared on the new file descriptor, meaning that +descriptor will survive into the new program after @code{exec}. +@end deftypevr + +If you want to modify the file descriptor flags, you should get the +current flags with @code{F_GETFD} and modify the value. Don't assume +that the flags listed here are the only ones that are implemented; your +program may be run years from now and more flags may exist then. For +example, here is a function to set or clear the flag @code{FD_CLOEXEC} +without altering any other flags: + +@smallexample +/* @r{Set the @code{FD_CLOEXEC} flag of @var{desc} if @var{value} is nonzero,} + @r{or clear the flag if @var{value} is 0.} + @r{Return 0 on success, or -1 on error with @code{errno} set.} */ + +int +set_cloexec_flag (int desc, int value) +@{ + int oldflags = fcntl (desc, F_GETFD, 0); + /* @r{If reading the flags failed, return error indication now.} + if (oldflags < 0) + return oldflags; + /* @r{Set just the flag we want to set.} */ + if (value != 0) + oldflags |= FD_CLOEXEC; + else + oldflags &= ~FD_CLOEXEC; + /* @r{Store modified flag word in the descriptor.} */ + return fcntl (desc, F_SETFD, oldflags); +@} +@end smallexample + +@node File Status Flags +@section File Status Flags +@cindex file status flags + +@dfn{File status flags} are used to specify attributes of the opening of a +file. Unlike the file descriptor flags discussed in @ref{Descriptor +Flags}, the file status flags are shared by duplicated file descriptors +resulting from a single opening of the file. The file status flags are +specified with the @var{flags} argument to @code{open}; +@pxref{Opening and Closing Files}. + +File status flags fall into three categories, which are described in the +following sections. + +@itemize @bullet +@item +@ref{Access Modes}, specify what type of access is allowed to the +file: reading, writing, or both. They are set by @code{open} and are +returned by @code{fcntl}, but cannot be changed. + +@item +@ref{Open-time Flags}, control details of what @code{open} will do. +These flags are not preserved after the @code{open} call. + +@item +@ref{Operating Modes}, affect how operations such as @code{read} and +@code{write} are done. They are set by @code{open}, and can be fetched or +changed with @code{fcntl}. +@end itemize + +The symbols in this section are defined in the header file +@file{fcntl.h}. +@pindex fcntl.h + +@menu +* Access Modes:: Whether the descriptor can read or write. +* Open-time Flags:: Details of @code{open}. +* Operating Modes:: Special modes to control I/O operations. +* Getting File Status Flags:: Fetching and changing these flags. +@end menu + +@node Access Modes +@subsection File Access Modes + +The file access modes allow a file descriptor to be used for reading, +writing, or both. (In the GNU system, they can also allow none of these, +and allow execution of the file as a program.) The access modes are chosen +when the file is opened, and never change. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_RDONLY +Open the file for read access. +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_WRONLY +Open the file for write access. +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_RDWR +Open the file for both reading and writing. +@end deftypevr + +In the GNU system (and not in other systems), @code{O_RDONLY} and +@code{O_WRONLY} are independent bits that can be bitwise-ORed together, +and it is valid for either bit to be set or clear. This means that +@code{O_RDWR} is the same as @code{O_RDONLY|O_WRONLY}. A file access +mode of zero is permissible; it allows no operations that do input or +output to the file, but does allow other operations such as +@code{fchmod}. On the GNU system, since ``read-only'' or ``write-only'' +is a misnomer, @file{fcntl.h} defines additional names for the file +access modes. These names are preferred when writing GNU-specific code. +But most programs will want to be portable to other POSIX.1 systems and +should use the POSIX.1 names above instead. + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_READ +Open the file for reading. Same as @code{O_RDWR}; only defined on GNU. +@end deftypevr + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_WRITE +Open the file for reading. Same as @code{O_WRONLY}; only defined on GNU. +@end deftypevr + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_EXEC +Open the file for executing. Only defined on GNU. +@end deftypevr + +To determine the file access mode with @code{fcntl}, you must extract +the access mode bits from the retrieved file status flags. In the GNU +system, you can just test the @code{O_READ} and @code{O_WRITE} bits in +the flags word. But in other POSIX.1 systems, reading and writing +access modes are not stored as distinct bit flags. The portable way to +extract the file access mode bits is with @code{O_ACCMODE}. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_ACCMODE +This macro stands for a mask that can be bitwise-ANDed with the file +status flag value to produce a value representing the file access mode. +The mode will be @code{O_RDONLY}, @code{O_WRONLY}, or @code{O_RDWR}. +(In the GNU system it could also be zero, and it never includes the +@code{O_EXEC} bit.) +@end deftypevr + +@node Open-time Flags +@subsection Open-time Flags + +The open-time flags specify options affecting how @code{open} will behave. +These options are not preserved once the file is open. The exception to +this is @code{O_NONBLOCK}, which is also an I/O operating mode and so it +@emph{is} saved. @xref{Opening and Closing Files}, for how to call +@code{open}. + +There are two sorts of options specified by open-time flags. + +@itemize @bullet +@item +@dfn{File name translation flags} affect how @code{open} looks up the +file name to locate the file, and whether the file can be created. +@cindex file name translation flags +@cindex flags, file name translation + +@item +@dfn{Open-time action flags} specify extra operations that @code{open} will +perform on the file once it is open. +@cindex open-time action flags +@cindex flags, open-time action +@end itemize + +Here are the file name translation flags. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_CREAT +If set, the file will be created if it doesn't already exist. +@c !!! mode arg, umask +@cindex create on open (file status flag) +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_EXCL +If both @code{O_CREAT} and @code{O_EXCL} are set, then @code{open} fails +if the specified file already exists. This is guaranteed to never +clobber an existing file. +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_NONBLOCK +@cindex non-blocking open +This prevents @code{open} from blocking for a ``long time'' to open the +file. This is only meaningful for some kinds of files, usually devices +such as serial ports; when it is not meaningful, it is harmless and +ignored. Often opening a port to a modem blocks until the modem reports +carrier detection; if @code{O_NONBLOCK} is specified, @code{open} will +return immediately without a carrier. + +Note that the @code{O_NONBLOCK} flag is overloaded as both an I/O operating +mode and a file name translation flag. This means that specifying +@code{O_NONBLOCK} in @code{open} also sets nonblocking I/O mode; +@pxref{Operating Modes}. To open the file without blocking but do normal +I/O that blocks, you must call @code{open} with @code{O_NONBLOCK} set and +then call @code{fcntl} to turn the bit off. +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_NOCTTY +If the named file is a terminal device, don't make it the controlling +terminal for the process. @xref{Job Control}, for information about +what it means to be the controlling terminal. + +In the GNU system and 4.4 BSD, opening a file never makes it the +controlling terminal and @code{O_NOCTTY} is zero. However, other +systems may use a nonzero value for @code{O_NOCTTY} and set the +controlling terminal when you open a file that is a terminal device; so +to be portable, use @code{O_NOCTTY} when it is important to avoid this. +@cindex controlling terminal, setting +@end deftypevr + +The following three file name translation flags exist only in the GNU system. + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_IGNORE_CTTY +Do not recognize the named file as the controlling terminal, even if it +refers to the process's existing controlling terminal device. Operations +on the new file descriptor will never induce job control signals. +@xref{Job Control}. +@end deftypevr + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_NOLINK +If the named file is a symbolic link, open the link itself instead of +the file it refers to. (@code{fstat} on the new file descriptor will +return the information returned by @code{lstat} on the link's name.) +@cindex symbolic link, opening +@end deftypevr + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_NOTRANS +If the named file is specially translated, do not invoke the translator. +Open the bare file the translator itself sees. +@end deftypevr + + +The open-time action flags tell @code{open} to do additional operations +which are not really related to opening the file. The reason to do them +as part of @code{open} instead of in separate calls is that @code{open} +can do them @i{atomically}. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_TRUNC +Truncate the file to zero length. This option is only useful for +regular files, not special files such as directories or FIFOs. POSIX.1 +requires that you open the file for writing to use @code{O_TRUNC}. In +BSD and GNU you must have permission to write the file to truncate it, +but you need not open for write access. + +This is the only open-time action flag specified by POSIX.1. There is +no good reason for truncation to be done by @code{open}, instead of by +calling @code{ftruncate} afterwards. The @code{O_TRUNC} flag existed in +Unix before @code{ftruncate} was invented, and is retained for backward +compatibility. +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_SHLOCK +Acquire a shared lock on the file, as with @code{flock}. +@xref{File Locks}. + +If @code{O_CREAT} is specified, the locking is done atomically when +creating the file. You are guaranteed that no other process will get +the lock on the new file first. +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_EXLOCK +Acquire an exclusive lock on the file, as with @code{flock}. +@xref{File Locks}. This is atomic like @code{O_SHLOCK}. +@end deftypevr + +@node Operating Modes +@subsection I/O Operating Modes + +The operating modes affect how input and output operations using a file +descriptor work. These flags are set by @code{open} and can be fetched +and changed with @code{fcntl}. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int O_APPEND +The bit that enables append mode for the file. If set, then all +@code{write} operations write the data at the end of the file, extending +it, regardless of the current file position. This is the only reliable +way to append to a file. In append mode, you are guaranteed that the +data you write will always go to the current end of the file, regardless +of other processes writing to the file. Conversely, if you simply set +the file position to the end of file and write, then another process can +extend the file after you set the file position but before you write, +resulting in your data appearing someplace before the real end of file. +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr O_NONBLOCK +The bit that enables nonblocking mode for the file. If this bit is set, +@code{read} requests on the file can return immediately with a failure +status if there is no input immediately available, instead of blocking. +Likewise, @code{write} requests can also return immediately with a +failure status if the output can't be written immediately. + +Note that the @code{O_NONBLOCK} flag is overloaded as both an I/O +operating mode and a file name translation flag; @pxref{Open-time Flags}. +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_NDELAY +This is an obsolete name for @code{O_NONBLOCK}, provided for +compatibility with BSD. It is not defined by the POSIX.1 standard. +@end deftypevr + +The remaining operating modes are BSD and GNU extensions. They exist only +on some systems. On other systems, these macros are not defined. + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_ASYNC +The bit that enables asynchronous input mode. If set, then @code{SIGIO} +signals will be generated when input is available. @xref{Interrupt Input}. + +Asynchronous input mode is a BSD feature. +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_FSYNC +The bit that enables synchronous writing for the file. If set, each +@code{write} call will make sure the data is reliably stored on disk before +returning. @c !!! xref fsync + +Synchronous writing is a BSD feature. +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int O_SYNC +This is another name for @code{O_FSYNC}. They have the same value. +@end deftypevr + +@comment fcntl.h +@comment GNU +@deftypevr Macro int O_NOATIME +If this bit is set, @code{read} will not update the access time of the +file. @xref{File Times}. This is used by programs that do backups, so +that backing a file up does not count as reading it. +Only the owner of the file or the superuser may use this bit. + +This is a GNU extension. +@end deftypevr + +@node Getting File Status Flags +@subsection Getting and Setting File Status Flags + +The @code{fcntl} function can fetch or change file status flags. + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_GETFL +This macro is used as the @var{command} argument to @code{fcntl}, to +read the file status flags for the open file with descriptor +@var{filedes}. + +The normal return value from @code{fcntl} with this command is a +nonnegative number which can be interpreted as the bitwise OR of the +individual flags. Since the file access modes are not single-bit values, +you can mask off other bits in the returned flags with @code{O_ACCMODE} +to compare them. + +In case of an error, @code{fcntl} returns @code{-1}. The following +@code{errno} error conditions are defined for this command: + +@table @code +@item EBADF +The @var{filedes} argument is invalid. +@end table +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_SETFL +This macro is used as the @var{command} argument to @code{fcntl}, to set +the file status flags for the open file corresponding to the +@var{filedes} argument. This command requires a third @code{int} +argument to specify the new flags, so the call looks like this: + +@smallexample +fcntl (@var{filedes}, F_SETFL, @var{new-flags}) +@end smallexample + +You can't change the access mode for the file in this way; that is, +whether the file descriptor was opened for reading or writing. + +The normal return value from @code{fcntl} with this command is an +unspecified value other than @code{-1}, which indicates an error. The +error conditions are the same as for the @code{F_GETFL} command. +@end deftypevr + +If you want to modify the file status flags, you should get the current +flags with @code{F_GETFL} and modify the value. Don't assume that the +flags listed here are the only ones that are implemented; your program +may be run years from now and more flags may exist then. For example, +here is a function to set or clear the flag @code{O_NONBLOCK} without +altering any other flags: + +@smallexample +@group +/* @r{Set the @code{O_NONBLOCK} flag of @var{desc} if @var{value} is nonzero,} + @r{or clear the flag if @var{value} is 0.} + @r{Return 0 on success, or -1 on error with @code{errno} set.} */ + +int +set_nonblock_flag (int desc, int value) +@{ + int oldflags = fcntl (desc, F_GETFL, 0); + /* @r{If reading the flags failed, return error indication now.} */ + if (oldflags == -1) + return -1; + /* @r{Set just the flag we want to set.} */ + if (value != 0) + oldflags |= O_NONBLOCK; + else + oldflags &= ~O_NONBLOCK; + /* @r{Store modified flag word in the descriptor.} */ + return fcntl (desc, F_SETFL, oldflags); +@} +@end group +@end smallexample + +@node File Locks +@section File Locks + +@cindex file locks +@cindex record locking +The remaining @code{fcntl} commands are used to support @dfn{record +locking}, which permits multiple cooperating programs to prevent each +other from simultaneously accessing parts of a file in error-prone +ways. + +@cindex exclusive lock +@cindex write lock +An @dfn{exclusive} or @dfn{write} lock gives a process exclusive access +for writing to the specified part of the file. While a write lock is in +place, no other process can lock that part of the file. + +@cindex shared lock +@cindex read lock +A @dfn{shared} or @dfn{read} lock prohibits any other process from +requesting a write lock on the specified part of the file. However, +other processes can request read locks. + +The @code{read} and @code{write} functions do not actually check to see +whether there are any locks in place. If you want to implement a +locking protocol for a file shared by multiple processes, your application +must do explicit @code{fcntl} calls to request and clear locks at the +appropriate points. + +Locks are associated with processes. A process can only have one kind +of lock set for each byte of a given file. When any file descriptor for +that file is closed by the process, all of the locks that process holds +on that file are released, even if the locks were made using other +descriptors that remain open. Likewise, locks are released when a +process exits, and are not inherited by child processes created using +@code{fork} (@pxref{Creating a Process}). + +When making a lock, use a @code{struct flock} to specify what kind of +lock and where. This data type and the associated macros for the +@code{fcntl} function are declared in the header file @file{fcntl.h}. +@pindex fcntl.h + +@comment fcntl.h +@comment POSIX.1 +@deftp {Data Type} {struct flock} +This structure is used with the @code{fcntl} function to describe a file +lock. It has these members: + +@table @code +@item short int l_type +Specifies the type of the lock; one of @code{F_RDLCK}, @code{F_WRLCK}, or +@code{F_UNLCK}. + +@item short int l_whence +This corresponds to the @var{whence} argument to @code{fseek} or +@code{lseek}, and specifies what the offset is relative to. Its value +can be one of @code{SEEK_SET}, @code{SEEK_CUR}, or @code{SEEK_END}. + +@item off_t l_start +This specifies the offset of the start of the region to which the lock +applies, and is given in bytes relative to the point specified by +@code{l_whence} member. + +@item off_t l_len +This specifies the length of the region to be locked. A value of +@code{0} is treated specially; it means the region extends to the end of +the file. + +@item pid_t l_pid +This field is the process ID (@pxref{Process Creation Concepts}) of the +process holding the lock. It is filled in by calling @code{fcntl} with +the @code{F_GETLK} command, but is ignored when making a lock. +@end table +@end deftp + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_GETLK +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should get information about a lock. This command +requires a third argument of type @w{@code{struct flock *}} to be passed +to @code{fcntl}, so that the form of the call is: + +@smallexample +fcntl (@var{filedes}, F_GETLK, @var{lockp}) +@end smallexample + +If there is a lock already in place that would block the lock described +by the @var{lockp} argument, information about that lock overwrites +@code{*@var{lockp}}. Existing locks are not reported if they are +compatible with making a new lock as specified. Thus, you should +specify a lock type of @code{F_WRLCK} if you want to find out about both +read and write locks, or @code{F_RDLCK} if you want to find out about +write locks only. + +There might be more than one lock affecting the region specified by the +@var{lockp} argument, but @code{fcntl} only returns information about +one of them. The @code{l_whence} member of the @var{lockp} structure is +set to @code{SEEK_SET} and the @code{l_start} and @code{l_len} fields +set to identify the locked region. + +If no lock applies, the only change to the @var{lockp} structure is to +update the @code{l_type} to a value of @code{F_UNLCK}. + +The normal return value from @code{fcntl} with this command is an +unspecified value other than @code{-1}, which is reserved to indicate an +error. The following @code{errno} error conditions are defined for +this command: + +@table @code +@item EBADF +The @var{filedes} argument is invalid. + +@item EINVAL +Either the @var{lockp} argument doesn't specify valid lock information, +or the file associated with @var{filedes} doesn't support locks. +@end table +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_SETLK +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should set or clear a lock. This command requires a +third argument of type @w{@code{struct flock *}} to be passed to +@code{fcntl}, so that the form of the call is: + +@smallexample +fcntl (@var{filedes}, F_SETLK, @var{lockp}) +@end smallexample + +If the process already has a lock on any part of the region, the old lock +on that part is replaced with the new lock. You can remove a lock +by specifying a lock type of @code{F_UNLCK}. + +If the lock cannot be set, @code{fcntl} returns immediately with a value +of @code{-1}. This function does not block waiting for other processes +to release locks. If @code{fcntl} succeeds, it return a value other +than @code{-1}. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EAGAIN +@itemx EACCES +The lock cannot be set because it is blocked by an existing lock on the +file. Some systems use @code{EAGAIN} in this case, and other systems +use @code{EACCES}; your program should treat them alike, after +@code{F_SETLK}. (The GNU system always uses @code{EAGAIN}.) + +@item EBADF +Either: the @var{filedes} argument is invalid; you requested a read lock +but the @var{filedes} is not open for read access; or, you requested a +write lock but the @var{filedes} is not open for write access. + +@item EINVAL +Either the @var{lockp} argument doesn't specify valid lock information, +or the file associated with @var{filedes} doesn't support locks. + +@item ENOLCK +The system has run out of file lock resources; there are already too +many file locks in place. + +Well-designed file systems never report this error, because they have no +limitation on the number of locks. However, you must still take account +of the possibility of this error, as it could result from network access +to a file system on another machine. +@end table +@end deftypevr + +@comment fcntl.h +@comment POSIX.1 +@deftypevr Macro int F_SETLKW +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should set or clear a lock. It is just like the +@code{F_SETLK} command, but causes the process to block (or wait) +until the request can be specified. + +This command requires a third argument of type @code{struct flock *}, as +for the @code{F_SETLK} command. + +The @code{fcntl} return values and errors are the same as for the +@code{F_SETLK} command, but these additional @code{errno} error conditions +are defined for this command: + +@table @code +@item EINTR +The function was interrupted by a signal while it was waiting. +@xref{Interrupted Primitives}. + +@item EDEADLK +The specified region is being locked by another process. But that +process is waiting to lock a region which the current process has +locked, so waiting for the lock would result in deadlock. The system +does not guarantee that it will detect all such conditions, but it lets +you know if it notices one. +@end table +@end deftypevr + + +The following macros are defined for use as values for the @code{l_type} +member of the @code{flock} structure. The values are integer constants. + +@table @code +@comment fcntl.h +@comment POSIX.1 +@vindex F_RDLCK +@item F_RDLCK +This macro is used to specify a read (or shared) lock. + +@comment fcntl.h +@comment POSIX.1 +@vindex F_WRLCK +@item F_WRLCK +This macro is used to specify a write (or exclusive) lock. + +@comment fcntl.h +@comment POSIX.1 +@vindex F_UNLCK +@item F_UNLCK +This macro is used to specify that the region is unlocked. +@end table + +As an example of a situation where file locking is useful, consider a +program that can be run simultaneously by several different users, that +logs status information to a common file. One example of such a program +might be a game that uses a file to keep track of high scores. Another +example might be a program that records usage or accounting information +for billing purposes. + +Having multiple copies of the program simultaneously writing to the +file could cause the contents of the file to become mixed up. But +you can prevent this kind of problem by setting a write lock on the +file before actually writing to the file. + +If the program also needs to read the file and wants to make sure that +the contents of the file are in a consistent state, then it can also use +a read lock. While the read lock is set, no other process can lock +that part of the file for writing. + +@c ??? This section could use an example program. + +Remember that file locks are only a @emph{voluntary} protocol for +controlling access to a file. There is still potential for access to +the file by programs that don't use the lock protocol. + +@node Interrupt Input +@section Interrupt-Driven Input + +@cindex interrupt-driven input +If you set the @code{O_ASYNC} status flag on a file descriptor +(@pxref{File Status Flags}), a @code{SIGIO} signal is sent whenever +input or output becomes possible on that file descriptor. The process +or process group to receive the signal can be selected by using the +@code{F_SETOWN} command to the @code{fcntl} function. If the file +descriptor is a socket, this also selects the recipient of @code{SIGURG} +signals that are delivered when out-of-band data arrives on that socket; +see @ref{Out-of-Band Data}. (@code{SIGURG} is sent in any situation +where @code{select} would report the socket as having an ``exceptional +condition''. @xref{Waiting for I/O}.) + +If the file descriptor corresponds to a terminal device, then @code{SIGIO} +signals are sent to the foreground process group of the terminal. +@xref{Job Control}. + +@pindex fcntl.h +The symbols in this section are defined in the header file +@file{fcntl.h}. + +@comment fcntl.h +@comment BSD +@deftypevr Macro int F_GETOWN +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should get information about the process or process +group to which @code{SIGIO} signals are sent. (For a terminal, this is +actually the foreground process group ID, which you can get using +@code{tcgetpgrp}; see @ref{Terminal Access Functions}.) + +The return value is interpreted as a process ID; if negative, its +absolute value is the process group ID. + +The following @code{errno} error condition is defined for this command: + +@table @code +@item EBADF +The @var{filedes} argument is invalid. +@end table +@end deftypevr + +@comment fcntl.h +@comment BSD +@deftypevr Macro int F_SETOWN +This macro is used as the @var{command} argument to @code{fcntl}, to +specify that it should set the process or process group to which +@code{SIGIO} signals are sent. This command requires a third argument +of type @code{pid_t} to be passed to @code{fcntl}, so that the form of +the call is: + +@smallexample +fcntl (@var{filedes}, F_SETOWN, @var{pid}) +@end smallexample + +The @var{pid} argument should be a process ID. You can also pass a +negative number whose absolute value is a process group ID. + +The return value from @code{fcntl} with this command is @code{-1} +in case of error and some other value if successful. The following +@code{errno} error conditions are defined for this command: + +@table @code +@item EBADF +The @var{filedes} argument is invalid. + +@item ESRCH +There is no process or process group corresponding to @var{pid}. +@end table +@end deftypevr + +@c ??? This section could use an example program. diff --git a/manual/locale.texi b/manual/locale.texi new file mode 100644 index 0000000000..d2d7557ea9 --- /dev/null +++ b/manual/locale.texi @@ -0,0 +1,605 @@ +@node Locales, Searching and Sorting, Extended Characters, Top +@chapter Locales and Internationalization + +Different countries and cultures have varying conventions for how to +communicate. These conventions range from very simple ones, such as the +format for representing dates and times, to very complex ones, such as +the language spoken. + +@cindex internationalization +@cindex locales +@dfn{Internationalization} of software means programming it to be able +to adapt to the user's favorite conventions. In ANSI C, +internationalization works by means of @dfn{locales}. Each locale +specifies a collection of conventions, one convention for each purpose. +The user chooses a set of conventions by specifying a locale (via +environment variables). + +All programs inherit the chosen locale as part of their environment. +Provided the programs are written to obey the choice of locale, they +will follow the conventions preferred by the user. + +@menu +* Effects of Locale:: Actions affected by the choice of + locale. +* Choosing Locale:: How the user specifies a locale. +* Locale Categories:: Different purposes for which you can + select a locale. +* Setting the Locale:: How a program specifies the locale + with library functions. +* Standard Locales:: Locale names available on all systems. +* Numeric Formatting:: How to format numbers according to the + chosen locale. +@end menu + +@node Effects of Locale, Choosing Locale, , Locales +@section What Effects a Locale Has + +Each locale specifies conventions for several purposes, including the +following: + +@itemize @bullet +@item +What multibyte character sequences are valid, and how they are +interpreted (@pxref{Extended Characters}). + +@item +Classification of which characters in the local character set are +considered alphabetic, and upper- and lower-case conversion conventions +(@pxref{Character Handling}). + +@item +The collating sequence for the local language and character set +(@pxref{Collation Functions}). + +@item +Formatting of numbers and currency amounts (@pxref{Numeric Formatting}). + +@item +Formatting of dates and times (@pxref{Formatting Date and Time}). + +@item +What language to use for output, including error messages. +(The C library doesn't yet help you implement this.) + +@item +What language to use for user answers to yes-or-no questions. + +@item +What language to use for more complex user input. +(The C library doesn't yet help you implement this.) +@end itemize + +Some aspects of adapting to the specified locale are handled +automatically by the library subroutines. For example, all your program +needs to do in order to use the collating sequence of the chosen locale +is to use @code{strcoll} or @code{strxfrm} to compare strings. + +Other aspects of locales are beyond the comprehension of the library. +For example, the library can't automatically translate your program's +output messages into other languages. The only way you can support +output in the user's favorite language is to program this more or less +by hand. (Eventually, we hope to provide facilities to make this +easier.) + +This chapter discusses the mechanism by which you can modify the current +locale. The effects of the current locale on specific library functions +are discussed in more detail in the descriptions of those functions. + +@node Choosing Locale, Locale Categories, Effects of Locale, Locales +@section Choosing a Locale + +The simplest way for the user to choose a locale is to set the +environment variable @code{LANG}. This specifies a single locale to use +for all purposes. For example, a user could specify a hypothetical +locale named @samp{espana-castellano} to use the standard conventions of +most of Spain. + +The set of locales supported depends on the operating system you are +using, and so do their names. We can't make any promises about what +locales will exist, except for one standard locale called @samp{C} or +@samp{POSIX}. + +@cindex combining locales +A user also has the option of specifying different locales for different +purposes---in effect, choosing a mixture of multiple locales. + +For example, the user might specify the locale @samp{espana-castellano} +for most purposes, but specify the locale @samp{usa-english} for +currency formatting. This might make sense if the user is a +Spanish-speaking American, working in Spanish, but representing monetary +amounts in US dollars. + +Note that both locales @samp{espana-castellano} and @samp{usa-english}, +like all locales, would include conventions for all of the purposes to +which locales apply. However, the user can choose to use each locale +for a particular subset of those purposes. + +@node Locale Categories, Setting the Locale, Choosing Locale, Locales +@section Categories of Activities that Locales Affect +@cindex categories for locales +@cindex locale categories + +The purposes that locales serve are grouped into @dfn{categories}, so +that a user or a program can choose the locale for each category +independently. Here is a table of categories; each name is both an +environment variable that a user can set, and a macro name that you can +use as an argument to @code{setlocale}. + +@table @code +@comment locale.h +@comment ANSI +@item LC_COLLATE +@vindex LC_COLLATE +This category applies to collation of strings (functions @code{strcoll} +and @code{strxfrm}); see @ref{Collation Functions}. + +@comment locale.h +@comment ANSI +@item LC_CTYPE +@vindex LC_CTYPE +This category applies to classification and conversion of characters, +and to multibyte and wide characters; +see @ref{Character Handling} and @ref{Extended Characters}. + +@comment locale.h +@comment ANSI +@item LC_MONETARY +@vindex LC_MONETARY +This category applies to formatting monetary values; see @ref{Numeric +Formatting}. + +@comment locale.h +@comment ANSI +@item LC_NUMERIC +@vindex LC_NUMERIC +This category applies to formatting numeric values that are not +monetary; see @ref{Numeric Formatting}. + +@comment locale.h +@comment ANSI +@item LC_TIME +@vindex LC_TIME +This category applies to formatting date and time values; see +@ref{Formatting Date and Time}. + +@ignore This is apparently a feature that was in some early +draft of the POSIX.2 standard, but it's not listed in draft 11. Do we +still support this anyway? Is there a corresponding environment +variable? + +@comment locale.h +@comment GNU +@item LC_RESPONSE +@vindex LC_RESPONSE +This category applies to recognizing ``yes'' or ``no'' responses to +questions. +@end ignore + +@comment locale.h +@comment ANSI +@item LC_ALL +@vindex LC_ALL +This is not an environment variable; it is only a macro that you can use +with @code{setlocale} to set a single locale for all purposes. + +@comment locale.h +@comment ANSI +@item LANG +@vindex LANG +If this environment variable is defined, its value specifies the locale +to use for all purposes except as overridden by the variables above. +@end table + +@node Setting the Locale, Standard Locales, Locale Categories, Locales +@section How Programs Set the Locale + +A C program inherits its locale environment variables when it starts up. +This happens automatically. However, these variables do not +automatically control the locale used by the library functions, because +ANSI C says that all programs start by default in the standard @samp{C} +locale. To use the locales specified by the environment, you must call +@code{setlocale}. Call it as follows: + +@smallexample +setlocale (LC_ALL, ""); +@end smallexample + +@noindent +to select a locale based on the appropriate environment variables. + +@cindex changing the locale +@cindex locale, changing +You can also use @code{setlocale} to specify a particular locale, for +general use or for a specific category. + +@pindex locale.h +The symbols in this section are defined in the header file @file{locale.h}. + +@comment locale.h +@comment ANSI +@deftypefun {char *} setlocale (int @var{category}, const char *@var{locale}) +The function @code{setlocale} sets the current locale for +category @var{category} to @var{locale}. + +If @var{category} is @code{LC_ALL}, this specifies the locale for all +purposes. The other possible values of @var{category} specify an +individual purpose (@pxref{Locale Categories}). + +You can also use this function to find out the current locale by passing +a null pointer as the @var{locale} argument. In this case, +@code{setlocale} returns a string that is the name of the locale +currently selected for category @var{category}. + +The string returned by @code{setlocale} can be overwritten by subsequent +calls, so you should make a copy of the string (@pxref{Copying and +Concatenation}) if you want to save it past any further calls to +@code{setlocale}. (The standard library is guaranteed never to call +@code{setlocale} itself.) + +You should not modify the string returned by @code{setlocale}. +It might be the same string that was passed as an argument in a +previous call to @code{setlocale}. + +When you read the current locale for category @code{LC_ALL}, the value +encodes the entire combination of selected locales for all categories. +In this case, the value is not just a single locale name. In fact, we +don't make any promises about what it looks like. But if you specify +the same ``locale name'' with @code{LC_ALL} in a subsequent call to +@code{setlocale}, it restores the same combination of locale selections. + +When the @var{locale} argument is not a null pointer, the string returned +by @code{setlocale} reflects the newly modified locale. + +If you specify an empty string for @var{locale}, this means to read the +appropriate environment variable and use its value to select the locale +for @var{category}. + +If you specify an invalid locale name, @code{setlocale} returns a null +pointer and leaves the current locale unchanged. +@end deftypefun + +Here is an example showing how you might use @code{setlocale} to +temporarily switch to a new locale. + +@smallexample +#include <stddef.h> +#include <locale.h> +#include <stdlib.h> +#include <string.h> + +void +with_other_locale (char *new_locale, + void (*subroutine) (int), + int argument) +@{ + char *old_locale, *saved_locale; + + /* @r{Get the name of the current locale.} */ + old_locale = setlocale (LC_ALL, NULL); + + /* @r{Copy the name so it won't be clobbered by @code{setlocale}.} */ + saved_locale = strdup (old_locale); + if (old_locale == NULL) + fatal ("Out of memory"); + + /* @r{Now change the locale and do some stuff with it.} */ + setlocale (LC_ALL, new_locale); + (*subroutine) (argument); + + /* @r{Restore the original locale.} */ + setlocale (LC_ALL, saved_locale); + free (saved_locale); +@} +@end smallexample + +@strong{Portability Note:} Some ANSI C systems may define additional +locale categories. For portability, assume that any symbol beginning +with @samp{LC_} might be defined in @file{locale.h}. + +@node Standard Locales, Numeric Formatting, Setting the Locale, Locales +@section Standard Locales + +The only locale names you can count on finding on all operating systems +are these three standard ones: + +@table @code +@item "C" +This is the standard C locale. The attributes and behavior it provides +are specified in the ANSI C standard. When your program starts up, it +initially uses this locale by default. + +@item "POSIX" +This is the standard POSIX locale. Currently, it is an alias for the +standard C locale. + +@item "" +The empty name says to select a locale based on environment variables. +@xref{Locale Categories}. +@end table + +Defining and installing named locales is normally a responsibility of +the system administrator at your site (or the person who installed the +GNU C library). Some systems may allow users to create locales, but +we don't discuss that here. +@c ??? If we give the GNU system that capability, this place will have +@c ??? to be changed. + +If your program needs to use something other than the @samp{C} locale, +it will be more portable if you use whatever locale the user specifies +with the environment, rather than trying to specify some non-standard +locale explicitly by name. Remember, different machines might have +different sets of locales installed. + +@node Numeric Formatting, , Standard Locales, Locales +@section Numeric Formatting + +When you want to format a number or a currency amount using the +conventions of the current locale, you can use the function +@code{localeconv} to get the data on how to do it. The function +@code{localeconv} is declared in the header file @file{locale.h}. +@pindex locale.h +@cindex monetary value formatting +@cindex numeric value formatting + +@comment locale.h +@comment ANSI +@deftypefun {struct lconv *} localeconv (void) +The @code{localeconv} function returns a pointer to a structure whose +components contain information about how numeric and monetary values +should be formatted in the current locale. + +You shouldn't modify the structure or its contents. The structure might +be overwritten by subsequent calls to @code{localeconv}, or by calls to +@code{setlocale}, but no other function in the library overwrites this +value. +@end deftypefun + +@comment locale.h +@comment ANSI +@deftp {Data Type} {struct lconv} +This is the data type of the value returned by @code{localeconv}. +@end deftp + +If a member of the structure @code{struct lconv} has type @code{char}, +and the value is @code{CHAR_MAX}, it means that the current locale has +no value for that parameter. + +@menu +* General Numeric:: Parameters for formatting numbers and + currency amounts. +* Currency Symbol:: How to print the symbol that identifies an + amount of money (e.g. @samp{$}). +* Sign of Money Amount:: How to print the (positive or negative) sign + for a monetary amount, if one exists. +@end menu + +@node General Numeric, Currency Symbol, , Numeric Formatting +@subsection Generic Numeric Formatting Parameters + +These are the standard members of @code{struct lconv}; there may be +others. + +@table @code +@item char *decimal_point +@itemx char *mon_decimal_point +These are the decimal-point separators used in formatting non-monetary +and monetary quantities, respectively. In the @samp{C} locale, the +value of @code{decimal_point} is @code{"."}, and the value of +@code{mon_decimal_point} is @code{""}. +@cindex decimal-point separator + +@item char *thousands_sep +@itemx char *mon_thousands_sep +These are the separators used to delimit groups of digits to the left of +the decimal point in formatting non-monetary and monetary quantities, +respectively. In the @samp{C} locale, both members have a value of +@code{""} (the empty string). + +@item char *grouping +@itemx char *mon_grouping +These are strings that specify how to group the digits to the left of +the decimal point. @code{grouping} applies to non-monetary quantities +and @code{mon_grouping} applies to monetary quantities. Use either +@code{thousands_sep} or @code{mon_thousands_sep} to separate the digit +groups. +@cindex grouping of digits + +Each string is made up of decimal numbers separated by semicolons. +Successive numbers (from left to right) give the sizes of successive +groups (from right to left, starting at the decimal point). The last +number in the string is used over and over for all the remaining groups. + +If the last integer is @code{-1}, it means that there is no more +grouping---or, put another way, any remaining digits form one large +group without separators. + +For example, if @code{grouping} is @code{"4;3;2"}, the correct grouping +for the number @code{123456787654321} is @samp{12}, @samp{34}, +@samp{56}, @samp{78}, @samp{765}, @samp{4321}. This uses a group of 4 +digits at the end, preceded by a group of 3 digits, preceded by groups +of 2 digits (as many as needed). With a separator of @samp{,}, the +number would be printed as @samp{12,34,56,78,765,4321}. + +A value of @code{"3"} indicates repeated groups of three digits, as +normally used in the U.S. + +In the standard @samp{C} locale, both @code{grouping} and +@code{mon_grouping} have a value of @code{""}. This value specifies no +grouping at all. + +@item char int_frac_digits +@itemx char frac_digits +These are small integers indicating how many fractional digits (to the +right of the decimal point) should be displayed in a monetary value in +international and local formats, respectively. (Most often, both +members have the same value.) + +In the standard @samp{C} locale, both of these members have the value +@code{CHAR_MAX}, meaning ``unspecified''. The ANSI standard doesn't say +what to do when you find this the value; we recommend printing no +fractional digits. (This locale also specifies the empty string for +@code{mon_decimal_point}, so printing any fractional digits would be +confusing!) +@end table + +@node Currency Symbol, Sign of Money Amount, General Numeric, Numeric Formatting +@subsection Printing the Currency Symbol +@cindex currency symbols + +These members of the @code{struct lconv} structure specify how to print +the symbol to identify a monetary value---the international analog of +@samp{$} for US dollars. + +Each country has two standard currency symbols. The @dfn{local currency +symbol} is used commonly within the country, while the +@dfn{international currency symbol} is used internationally to refer to +that country's currency when it is necessary to indicate the country +unambiguously. + +For example, many countries use the dollar as their monetary unit, and +when dealing with international currencies it's important to specify +that one is dealing with (say) Canadian dollars instead of U.S. dollars +or Australian dollars. But when the context is known to be Canada, +there is no need to make this explicit---dollar amounts are implicitly +assumed to be in Canadian dollars. + +@table @code +@item char *currency_symbol +The local currency symbol for the selected locale. + +In the standard @samp{C} locale, this member has a value of @code{""} +(the empty string), meaning ``unspecified''. The ANSI standard doesn't +say what to do when you find this value; we recommend you simply print +the empty string as you would print any other string found in the +appropriate member. + +@item char *int_curr_symbol +The international currency symbol for the selected locale. + +The value of @code{int_curr_symbol} should normally consist of a +three-letter abbreviation determined by the international standard +@cite{ISO 4217 Codes for the Representation of Currency and Funds}, +followed by a one-character separator (often a space). + +In the standard @samp{C} locale, this member has a value of @code{""} +(the empty string), meaning ``unspecified''. We recommend you simply +print the empty string as you would print any other string found in the +appropriate member. + +@item char p_cs_precedes +@itemx char n_cs_precedes +These members are @code{1} if the @code{currency_symbol} string should +precede the value of a monetary amount, or @code{0} if the string should +follow the value. The @code{p_cs_precedes} member applies to positive +amounts (or zero), and the @code{n_cs_precedes} member applies to +negative amounts. + +In the standard @samp{C} locale, both of these members have a value of +@code{CHAR_MAX}, meaning ``unspecified''. The ANSI standard doesn't say +what to do when you find this value, but we recommend printing the +currency symbol before the amount. That's right for most countries. +In other words, treat all nonzero values alike in these members. + +The POSIX standard says that these two members apply to the +@code{int_curr_symbol} as well as the @code{currency_symbol}. The ANSI +C standard seems to imply that they should apply only to the +@code{currency_symbol}---so the @code{int_curr_symbol} should always +precede the amount. + +We can only guess which of these (if either) matches the usual +conventions for printing international currency symbols. Our guess is +that they should always preceed the amount. If we find out a reliable +answer, we will put it here. + +@item char p_sep_by_space +@itemx char n_sep_by_space +These members are @code{1} if a space should appear between the +@code{currency_symbol} string and the amount, or @code{0} if no space +should appear. The @code{p_sep_by_space} member applies to positive +amounts (or zero), and the @code{n_sep_by_space} member applies to +negative amounts. + +In the standard @samp{C} locale, both of these members have a value of +@code{CHAR_MAX}, meaning ``unspecified''. The ANSI standard doesn't say +what you should do when you find this value; we suggest you treat it as +one (print a space). In other words, treat all nonzero values alike in +these members. + +These members apply only to @code{currency_symbol}. When you use +@code{int_curr_symbol}, you never print an additional space, because +@code{int_curr_symbol} itself contains the appropriate separator. + +The POSIX standard says that these two members apply to the +@code{int_curr_symbol} as well as the @code{currency_symbol}. But an +example in the ANSI C standard clearly implies that they should apply +only to the @code{currency_symbol}---that the @code{int_curr_symbol} +contains any appropriate separator, so you should never print an +additional space. + +Based on what we know now, we recommend you ignore these members when +printing international currency symbols, and print no extra space. +@end table + +@node Sign of Money Amount, , Currency Symbol, Numeric Formatting +@subsection Printing the Sign of an Amount of Money + +These members of the @code{struct lconv} structure specify how to print +the sign (if any) in a monetary value. + +@table @code +@item char *positive_sign +@itemx char *negative_sign +These are strings used to indicate positive (or zero) and negative +(respectively) monetary quantities. + +In the standard @samp{C} locale, both of these members have a value of +@code{""} (the empty string), meaning ``unspecified''. + +The ANSI standard doesn't say what to do when you find this value; we +recommend printing @code{positive_sign} as you find it, even if it is +empty. For a negative value, print @code{negative_sign} as you find it +unless both it and @code{positive_sign} are empty, in which case print +@samp{-} instead. (Failing to indicate the sign at all seems rather +unreasonable.) + +@item char p_sign_posn +@itemx char n_sign_posn +These members have values that are small integers indicating how to +position the sign for nonnegative and negative monetary quantities, +respectively. (The string used by the sign is what was specified with +@code{positive_sign} or @code{negative_sign}.) The possible values are +as follows: + +@table @code +@item 0 +The currency symbol and quantity should be surrounded by parentheses. + +@item 1 +Print the sign string before the quantity and currency symbol. + +@item 2 +Print the sign string after the quantity and currency symbol. + +@item 3 +Print the sign string right before the currency symbol. + +@item 4 +Print the sign string right after the currency symbol. + +@item CHAR_MAX +``Unspecified''. Both members have this value in the standard +@samp{C} locale. +@end table + +The ANSI standard doesn't say what you should do when the value is +@code{CHAR_MAX}. We recommend you print the sign after the currency +symbol. +@end table + +It is not clear whether you should let these members apply to the +international currency format or not. POSIX says you should, but +intuition plus the examples in the ANSI C standard suggest you should +not. We hope that someone who knows well the conventions for formatting +monetary quantities will tell us what we should recommend. + diff --git a/manual/maint.texi b/manual/maint.texi new file mode 100644 index 0000000000..0d29d80ec9 --- /dev/null +++ b/manual/maint.texi @@ -0,0 +1,966 @@ +@c \input /gd/gnu/doc/texinfo +@c This is for making the `INSTALL' file for the distribution. +@c Makeinfo ignores it when processing the file from the include. +@setfilename INSTALL + +@node Maintenance, Copying, Library Summary, Top +@appendix Library Maintenance + +@menu +* Installation:: How to configure, compile and + install the GNU C library. +* Reporting Bugs:: How to report bugs (if you want to + get them fixed) and other troubles + you may have with the GNU C library. +* Source Layout:: How to add new functions or header files + to the GNU C library. +* Porting:: How to port the GNU C library to + a new machine or operating system. +* Contributors:: Contributors to the GNU C Library. +@end menu + +@node Installation +@appendixsec How to Install the GNU C Library +@cindex installing the library + +Installation of the GNU C library is relatively simple. + +You need the latest version of GNU @code{make}. Modifying the GNU C +Library to work with other @code{make} programs would be so hard that we +recommend you port GNU @code{make} instead. @strong{Really.}@refill + +To configure the GNU C library for your system, run the shell script +@file{configure} with @code{sh}. Use an argument which is the +conventional GNU name for your system configuration---for example, +@samp{sparc-sun-sunos4.1}, for a Sun 4 running Sunos 4.1. +@xref{Installation, Installation, Installing GNU CC, gcc.info, Using and +Porting GNU CC}, for a full description of standard GNU configuration +names. If you omit the configuration name, @file{configure} will try to +guess one for you by inspecting the system it is running on. It may or +may not be able to come up with a guess, and the its guess might be +wrong. @file{configure} will tell you the canonical name of the chosen +configuration before proceeding. + +The GNU C Library currently supports configurations that match the +following patterns: + +@smallexample +alpha-dec-osf1 +i386-@var{anything}-bsd4.3 +i386-@var{anything}-gnu +i386-@var{anything}-isc2.2 +i386-@var{anything}-isc3.@var{n} +i386-@var{anything}-sco3.2 +i386-@var{anything}-sco3.2v4 +i386-@var{anything}-sysv +i386-@var{anything}-sysv4 +i386-force_cpu386-none +i386-sequent-bsd +i960-nindy960-none +m68k-hp-bsd4.3 +m68k-mvme135-none +m68k-mvme136-none +m68k-sony-newsos3 +m68k-sony-newsos4 +m68k-sun-sunos4.@var{n} +mips-dec-ultrix4.@var{n} +mips-sgi-irix4.@var{n} +sparc-sun-solaris2.@var{n} +sparc-sun-sunos4.@var{n} +@end smallexample + +While no other configurations are supported, there are handy aliases for +these few. (These aliases work in other GNU software as well.) + +@smallexample +decstation +hp320-bsd4.3 hp300bsd +i386-sco +i386-sco3.2v4 +i386-sequent-dynix +i386-svr4 +news +sun3-sunos4.@var{n} sun3 +sun4-solaris2.@var{n} sun4-sunos5.@var{n} +sun4-sunos4.@var{n} sun4 +@end smallexample + +Here are some options that you should specify (if appropriate) when +you run @code{configure}: + +@table @samp +@item --with-gnu-ld +Use this option if you plan to use GNU @code{ld} to link programs with +the GNU C Library. (We strongly recommend that you do.) This option +enables use of features that exist only in GNU @code{ld}; so if you +configure for GNU @code{ld} you must use GNU @code{ld} @emph{every time} +you link with the GNU C Library, and when building it. + +@item --with-gnu-as +Use this option if you plan to use the GNU assembler, @code{gas}, when +building the GNU C Library. On some systems, the library may not build +properly if you do @emph{not} use @code{gas}. + +@c extra blank line makes it look better +@item --nfp + +Use this option if your computer lacks hardware floating point support. + +@item --prefix=@var{directory} +Install machine-independent data files in subdirectories of +@file{@var{directory}}. (You can also set this in @file{configparms}; +see below.) + +@item --exec-prefix=@var{directory} +Install the library and other machine-dependent files in subdirectories +of @file{@var{directory}}. (You can also set this in +@file{configparms}; see below.) +@end table + +The simplest way to run @code{configure} is to do it in the directory +that contains the library sources. This prepares to build the library +in that very directory. + +You can prepare to build the library in some other directory by going +to that other directory to run @code{configure}. In order to run +configure, you will have to specify a directory for it, like this: + +@smallexample +mkdir sun4 +cd sun4 +../configure sparc-sun-sunos4.1 +@end smallexample + +@noindent +@code{configure} looks for the sources in whatever directory you +specified for finding @code{configure} itself. It does not matter where +in the file system the source and build directories are---as long as you +specify the source directory when you run @code{configure}, you will get +the proper results. + +This feature lets you keep sources and binaries in different +directories, and that makes it easy to build the library for several +different machines from the same set of sources. Simply create a +build directory for each target machine, and run @code{configure} in +that directory specifying the target machine's configuration name. + +The library has a number of special-purpose configuration parameters. +These are defined in the file @file{Makeconfig}; see the comments in +that file for the details. + +But don't edit the file @file{Makeconfig} yourself---instead, create a +file @file{configparms} in the directory where you are building the +library, and define in that file the parameters you want to specify. +@file{configparms} should @strong{not} be an edited copy of +@file{Makeconfig}; specify only the parameters that you want to +override. To see how to set these parameters, find the section of +@file{Makeconfig} that says ``These are the configuration variables.'' +Then for each parameter that you want to change, copy the definition +from @file{Makeconfig} to your new @file{configparms} file, and change +the value as appropriate for your system. + +It is easy to configure the GNU C library for cross-compilation by +setting a few variables in @file{configparms}. Set @code{CC} to the +cross-compiler for the target you configured the library for; it is +important to use this same @code{CC} value when running +@code{configure}, like this: @samp{CC=@var{target}-gcc configure +@var{target}}. Set @code{BUILD_CC} to the compiler to use for for +programs run on the build system as part of compiling the library. You +may need to set @code{AR} and @code{RANLIB} to cross-compiling versions +of @code{ar} and @code{ranlib} if the native tools are not configured to +work with object files for the target you configured for. + +Some of the machine-dependent code for some machines uses extensions in +the GNU C compiler, so you may need to compile the library with GCC. +(In fact, all of the existing complete ports require GCC.) + +The current release of the C library contains some header files that the +compiler normally provides: @file{stddef.h}, @file{stdarg.h}, and +several files with names of the form @file{va-@var{machine}.h}. The +versions of these files that came with older releases of GCC do not work +properly with the GNU C library. The @file{stddef.h} file in release +2.2 and later of GCC is correct. If you have release 2.2 or later of +GCC, use its version of @file{stddef.h} instead of the C library's. To +do this, put the line @w{@samp{override stddef.h =}} in +@file{configparms}. The other files are corrected in release 2.3 and +later of GCC. @file{configure} will automatically detect whether the +installed @file{stdarg.h} and @file{va-@var{machine}.h} files are +compatible with the C library, and use its own if not. + +There is a potential problem with the @code{size_t} type and versions of +GCC prior to release 2.4. ANSI C requires that @code{size_t} always be +an unsigned type. For compatibility with existing systems' header +files, GCC defines @code{size_t} in @file{stddef.h} to be whatever type +the system's @file{sys/types.h} defines it to be. Most Unix systems +that define @code{size_t} in @file{sys/types.h}, define it to be a +signed type. Some code in the library depends on @code{size_t} being an +unsigned type, and will not work correctly if it is signed. + +The GNU C library code which expects @code{size_t} to be unsigned is +correct. The definition of @code{size_t} as a signed type is incorrect. +Versions 2.4 and later of GCC always define @code{size_t} as an unsigned +type, and GCC's @file{fixincludes} script massages the system's +@file{sys/types.h} so as not to conflict with this. + +In the meantime, we work around this problem by telling GCC explicitly +to use an unsigned type for @code{size_t} when compiling the GNU C +library. @file{configure} will automatically detect what type GCC uses +for @code{size_t} arrange to override it if necessary. + +To build the library, type @code{make lib}. This will produce a lot of +output, some of which looks like errors from @code{make} (but isn't). +Look for error messages from @code{make} containing @samp{***}. Those +indicate that something is really wrong. + +To build and run some test programs which exercise some of the library +facilities, type @code{make tests}. This will produce several files +with names like @file{@var{program}.out}. + +To format the @cite{GNU C Library Reference Manual} for printing, type +@w{@code{make dvi}}. To format the Info version of the manual for on +line reading with @kbd{C-h i} in Emacs or with the @code{info} program, +type @w{@code{make info}}. + +To install the library and its header files, and the Info files of the +manual, type @code{make install}, after setting the installation +directories in @file{configparms}. This will build things if necessary, +before installing them.@refill + +@node Reporting Bugs +@appendixsec Reporting Bugs +@cindex reporting bugs +@cindex bugs, reporting + +There are probably bugs in the GNU C library. There are certainly +errors and omissions in this manual. If you report them, they will get +fixed. If you don't, no one will ever know about them and they will +remain unfixed for all eternity, if not longer. + +To report a bug, first you must find it. Hopefully, this will be the +hard part. Once you've found a bug, make sure it's really a bug. A +good way to do this is to see if the GNU C library behaves the same way +some other C library does. If so, probably you are wrong and the +libraries are right (but not necessarily). If not, one of the libraries +is probably wrong. + +Once you're sure you've found a bug, try to narrow it down to the +smallest test case that reproduces the problem. In the case of a C +library, you really only need to narrow it down to one library +function call, if possible. This should not be too difficult. + +The final step when you have a simple test case is to report the bug. +When reporting a bug, send your test case, the results you got, the +results you expected, what you think the problem might be (if you've +thought of anything), your system type, and the version of the GNU C +library which you are using. Also include the files +@file{config.status} and @file{config.make} which are created by running +@file{configure}; they will be in whatever directory was current when +you ran @file{configure}. + +If you think you have found some way in which the GNU C library does not +conform to the ANSI and POSIX standards (@pxref{Standards and +Portability}), that is definitely a bug. Report it!@refill + +Send bug reports to the Internet address +@samp{bug-glibc@@prep.ai.mit.edu} or the UUCP path +@samp{mit-eddie!prep.ai.mit.edu!bug-glibc}. If you have other problems +with installation or use, please report those as well.@refill + +If you are not sure how a function should behave, and this manual +doesn't tell you, that's a bug in the manual. Report that too! If the +function's behavior disagrees with the manual, then either the library +or the manual has a bug, so report the disagreement. If you find any +errors or omissions in this manual, please report them to the Internet +address @samp{bug-glibc-manual@@prep.ai.mit.edu} or the UUCP path +@samp{mit-eddie!prep.ai.mit.edu!bug-glibc-manual}. + +@node Source Layout +@appendixsec Adding New Functions + +The process of building the library is driven by the makefiles, which +make heavy use of special features of GNU @code{make}. The makefiles +are very complex, and you probably don't want to try to understand them. +But what they do is fairly straightforward, and only requires that you +define a few variables in the right places. + +The library sources are divided into subdirectories, grouped by topic. +The @file{string} subdirectory has all the string-manipulation +functions, @file{stdio} has all the standard I/O functions, etc. + +Each subdirectory contains a simple makefile, called @file{Makefile}, +which defines a few @code{make} variables and then includes the global +makefile @file{Rules} with a line like: + +@smallexample +include ../Rules +@end smallexample + +@noindent +The basic variables that a subdirectory makefile defines are: + +@table @code +@item subdir +The name of the subdirectory, for example @file{stdio}. +This variable @strong{must} be defined. + +@item headers +The names of the header files in this section of the library, +such as @file{stdio.h}. + +@item routines +@itemx aux +The names of the modules (source files) in this section of the library. +These should be simple names, such as @samp{strlen} (rather than +complete file names, such as @file{strlen.c}). Use @code{routines} for +modules that define functions in the library, and @code{aux} for +auxiliary modules containing things like data definitions. But the +values of @code{routines} and @code{aux} are just concatenated, so there +really is no practical difference.@refill + +@item tests +The names of test programs for this section of the library. These +should be simple names, such as @samp{tester} (rather than complete file +names, such as @file{tester.c}). @w{@samp{make tests}} will build and +run all the test programs. If a test program needs input, put the test +data in a file called @file{@var{test-program}.input}; it will be given to +the test program on its standard input. If a test program wants to be +run with arguments, put the arguments (all on a single line) in a file +called @file{@var{test-program}.args}.@refill + +@item others +The names of ``other'' programs associated with this section of the +library. These are programs which are not tests per se, but are other +small programs included with the library. They are built by +@w{@samp{make others}}.@refill + +@item install-lib +@itemx install-data +@itemx install +Files to be installed by @w{@samp{make install}}. Files listed in +@samp{install-lib} are installed in the directory specified by +@samp{libdir} in @file{configparms} or @file{Makeconfig} +(@pxref{Installation}). Files listed in @code{install-data} are +installed in the directory specified by @samp{datadir} in +@file{configparms} or @file{Makeconfig}. Files listed in @code{install} +are installed in the directory specified by @samp{bindir} in +@file{configparms} or @file{Makeconfig}.@refill + +@item distribute +Other files from this subdirectory which should be put into a +distribution tar file. You need not list here the makefile itself or +the source and header files listed in the other standard variables. +Only define @code{distribute} if there are files used in an unusual way +that should go into the distribution. + +@item generated +Files which are generated by @file{Makefile} in this subdirectory. +These files will be removed by @w{@samp{make clean}}, and they will +never go into a distribution. + +@item extra-objs +Extra object files which are built by @file{Makefile} in this +subdirectory. This should be a list of file names like @file{foo.o}; +the files will actually be found in whatever directory object files are +being built in. These files will be removed by @w{@samp{make clean}}. +This variable is used for secondary object files needed to build +@code{others} or @code{tests}. +@end table + +@node Porting +@appendixsec Porting the GNU C Library + +The GNU C library is written to be easily portable to a variety of +machines and operating systems. Machine- and operating system-dependent +functions are well separated to make it easy to add implementations for +new machines or operating systems. This section describes the layout of +the library source tree and explains the mechanisms used to select +machine-dependent code to use. + +All the machine-dependent and operating system-dependent files in the +library are in the subdirectory @file{sysdeps} under the top-level +library source directory. This directory contains a hierarchy of +subdirectories (@pxref{Hierarchy Conventions}). + +Each subdirectory of @file{sysdeps} contains source files for a +particular machine or operating system, or for a class of machine or +operating system (for example, systems by a particular vendor, or all +machines that use IEEE 754 floating-point format). A configuration +specifies an ordered list of these subdirectories. Each subdirectory +implicitly appends its parent directory to the list. For example, +specifying the list @file{unix/bsd/vax} is equivalent to specifying the +list @file{unix/bsd/vax unix/bsd unix}. A subdirectory can also specify +that it implies other subdirectories which are not directly above it in +the directory hierarchy. If the file @file{Implies} exists in a +subdirectory, it lists other subdirectories of @file{sysdeps} which are +appended to the list, appearing after the subdirectory containing the +@file{Implies} file. Lines in an @file{Implies} file that begin with a +@samp{#} character are ignored as comments. For example, +@file{unix/bsd/Implies} contains:@refill +@smallexample +# BSD has Internet-related things. +unix/inet +@end smallexample +@noindent +and @file{unix/Implies} contains: +@need 300 +@smallexample +posix +@end smallexample + +@noindent +So the final list is @file{unix/bsd/vax unix/bsd unix/inet unix posix}. + +@file{sysdeps} has two ``special'' subdirectories, called @file{generic} +and @file{stub}. These two are always implicitly appended to the list +of subdirectories (in that order), so you needn't put them in an +@file{Implies} file, and you should not create any subdirectories under +them. @file{generic} is for things that can be implemented in +machine-independent C, using only other machine-independent functions in +the C library. @file{stub} is for @dfn{stub} versions of functions +which cannot be implemented on a particular machine or operating system. +The stub functions always return an error, and set @code{errno} to +@code{ENOSYS} (Function not implemented). @xref{Error Reporting}. + +A source file is known to be system-dependent by its having a version in +@file{generic} or @file{stub}; every system-dependent function should +have either a generic or stub implementation (there is no point in +having both). + +If you come across a file that is in one of the main source directories +(@file{string}, @file{stdio}, etc.), and you want to write a machine- or +operating system-dependent version of it, move the file into +@file{sysdeps/generic} and write your new implementation in the +appropriate system-specific subdirectory. Note that if a file is to be +system-dependent, it @strong{must not} appear in one of the main source +directories.@refill + +There are a few special files that may exist in each subdirectory of +@file{sysdeps}: + +@comment Blank lines after items make the table look better. +@table @file +@item Makefile + +A makefile for this machine or operating system, or class of machine or +operating system. This file is included by the library makefile +@file{Makerules}, which is used by the top-level makefile and the +subdirectory makefiles. It can change the variables set in the +including makefile or add new rules. It can use GNU @code{make} +conditional directives based on the variable @samp{subdir} (see above) to +select different sets of variables and rules for different sections of +the library. It can also set the @code{make} variable +@samp{sysdep-routines}, to specify extra modules to be included in the +library. You should use @samp{sysdep-routines} rather than adding +modules to @samp{routines} because the latter is used in determining +what to distribute for each subdirectory of the main source tree.@refill + +Each makefile in a subdirectory in the ordered list of subdirectories to +be searched is included in order. Since several system-dependent +makefiles may be included, each should append to @samp{sysdep-routines} +rather than simply setting it: + +@smallexample +sysdep-routines := $(sysdep-routines) foo bar +@end smallexample + +@need 1000 +@item Subdirs + +This file contains the names of new whole subdirectories under the +top-level library source tree that should be included for this system. +These subdirectories are treated just like the system-independent +subdirectories in the library source tree, such as @file{stdio} and +@file{math}. + +Use this when there are completely new sets of functions and header +files that should go into the library for the system this subdirectory +of @file{sysdeps} implements. For example, +@file{sysdeps/unix/inet/Subdirs} contains @file{inet}; the @file{inet} +directory contains various network-oriented operations which only make +sense to put in the library on systems that support the Internet.@refill + +@item Dist + +This file contains the names of files (relative to the subdirectory of +@file{sysdeps} in which it appears) which should be included in the +distribution. List any new files used by rules in the @file{Makefile} +in the same directory, or header files used by the source files in that +directory. You don't need to list files that are implementations +(either C or assembly source) of routines whose names are given in the +machine-independent makefiles in the main source tree. + +@item configure + +This file is a shell script fragment to be run at configuration time. +The top-level @file{configure} script uses the shell @code{.} command to +read the @file{configure} file in each system-dependent directory +chosen, in order. The @file{configure} files are often generated from +@file{configure.in} files using Autoconf. + +A system-dependent @file{configure} script will usually add things to +the shell variables @samp{DEFS} and @samp{config_vars}; see the +top-level @file{configure} script for details. The script can check for +@w{@samp{--with-@var{package}}} options that were passed to the +top-level @file{configure}. For an option +@w{@samp{--with-@var{package}=@var{value}}} @file{configure} sets the +shell variable @w{@samp{with_@var{package}}} (with any dashes in +@var{package} converted to underscores) to @var{value}; if the option is +just @w{@samp{--with-@var{package}}} (no argument), then it sets +@w{@samp{with_@var{package}}} to @samp{yes}. + +@item configure.in + +This file is an Autoconf input fragment to be processed into the file +@file{configure} in this subdirectory. @xref{Introduction,,, +autoconf.info, Autoconf: Generating Automatic Configuration Scripts}, +for a description of Autoconf. You should write either @file{configure} +or @file{configure.in}, but not both. The first line of +@file{configure.in} should invoke the @code{m4} macro +@samp{GLIBC_PROVIDES}. This macro does several @code{AC_PROVIDE} calls +for Autoconf macros which are used by the top-level @file{configure} +script; without this, those macros might be invoked again unnecessarily +by Autoconf. +@end table + +That is the general system for how system-dependencies are isolated. +@iftex +The next section explains how to decide what directories in +@file{sysdeps} to use. @ref{Porting to Unix}, has some tips on porting +the library to Unix variants. +@end iftex + +@menu +* Hierarchy Conventions:: The layout of the @file{sysdeps} hierarchy. +* Porting to Unix:: Porting the library to an average + Unix-like system. +@end menu + +@node Hierarchy Conventions +@appendixsubsec Layout of the @file{sysdeps} Directory Hierarchy + +A GNU configuration name has three parts: the CPU type, the +manufacturer's name, and the operating system. @file{configure} uses +these to pick the list of system-dependent directories to look for. If +the @samp{--nfp} option is @emph{not} passed to @file{configure}, the +directory @file{@var{machine}/fpu} is also used. The operating system +often has a @dfn{base operating system}; for example, if the operating +system is @samp{sunos4.1}, the base operating system is @samp{unix/bsd}. +The algorithm used to pick the list of directories is simple: +@file{configure} makes a list of the base operating system, +manufacturer, CPU type, and operating system, in that order. It then +concatenates all these together with slashes in between, to produce a +directory name; for example, the configuration @w{@samp{sparc-sun-sunos4.1}} +results in @file{unix/bsd/sun/sparc/sunos4.1}. @file{configure} then +tries removing each element of the list in turn, so +@file{unix/bsd/sparc} and @file{sun/sparc} are also tried, among others. +Since the precise version number of the operating system is often not +important, and it would be very inconvenient, for example, to have +identical @file{sunos4.1.1} and @file{sunos4.1.2} directories, +@file{configure} tries successively less specific operating system names +by removing trailing suffixes starting with a period. + +As an example, here is the complete list of directories that would be +tried for the configuration @w{@samp{sparc-sun-sunos4.1}} (without the +@w{@samp{--nfp}} option): + +@smallexample +sparc/fpu +unix/bsd/sun/sunos4.1/sparc +unix/bsd/sun/sunos4.1 +unix/bsd/sun/sunos4/sparc +unix/bsd/sun/sunos4 +unix/bsd/sun/sunos/sparc +unix/bsd/sun/sunos +unix/bsd/sun/sparc +unix/bsd/sun +unix/bsd/sunos4.1/sparc +unix/bsd/sunos4.1 +unix/bsd/sunos4/sparc +unix/bsd/sunos4 +unix/bsd/sunos/sparc +unix/bsd/sunos +unix/bsd/sparc +unix/bsd +unix/sun/sunos4.1/sparc +unix/sun/sunos4.1 +unix/sun/sunos4/sparc +unix/sun/sunos4 +unix/sun/sunos/sparc +unix/sun/sunos +unix/sun/sparc +unix/sun +unix/sunos4.1/sparc +unix/sunos4.1 +unix/sunos4/sparc +unix/sunos4 +unix/sunos/sparc +unix/sunos +unix/sparc +unix +sun/sunos4.1/sparc +sun/sunos4.1 +sun/sunos4/sparc +sun/sunos4 +sun/sunos/sparc +sun/sunos +sun/sparc +sun +sunos4.1/sparc +sunos4.1 +sunos4/sparc +sunos4 +sunos/sparc +sunos +sparc +@end smallexample + +Different machine architectures are conventionally subdirectories at the +top level of the @file{sysdeps} directory tree. For example, +@w{@file{sysdeps/sparc}} and @w{@file{sysdeps/m68k}}. These contain +files specific to those machine architectures, but not specific to any +particular operating system. There might be subdirectories for +specializations of those architectures, such as +@w{@file{sysdeps/m68k/68020}}. Code which is specific to the +floating-point coprocessor used with a particular machine should go in +@w{@file{sysdeps/@var{machine}/fpu}}. + +There are a few directories at the top level of the @file{sysdeps} +hierarchy that are not for particular machine architectures. + +@table @file +@item generic +@itemx stub +As described above (@pxref{Porting}), these are the two subdirectories +that every configuration implicitly uses after all others. + +@item ieee754 +This directory is for code using the IEEE 754 floating-point format, +where the C type @code{float} is IEEE 754 single-precision format, and +@code{double} is IEEE 754 double-precision format. Usually this +directory is referred to in the @file{Implies} file in a machine +architecture-specific directory, such as @file{m68k/Implies}. + +@item posix +This directory contains implementations of things in the library in +terms of @sc{POSIX.1} functions. This includes some of the @sc{POSIX.1} +functions themselves. Of course, @sc{POSIX.1} cannot be completely +implemented in terms of itself, so a configuration using just +@file{posix} cannot be complete. + +@item unix +This is the directory for Unix-like things. @xref{Porting to Unix}. +@file{unix} implies @file{posix}. There are some special-purpose +subdirectories of @file{unix}: + +@table @file +@item unix/common +This directory is for things common to both BSD and System V release 4. +Both @file{unix/bsd} and @file{unix/sysv/sysv4} imply @file{unix/common}. + +@item unix/inet +This directory is for @code{socket} and related functions on Unix systems. +The @file{inet} top-level subdirectory is enabled by @file{unix/inet/Subdirs}. +@file{unix/common} implies @file{unix/inet}. +@end table + +@item mach +This is the directory for things based on the Mach microkernel from CMU +(including the GNU operating system). Other basic operating systems +(VMS, for example) would have their own directories at the top level of +the @file{sysdeps} hierarchy, parallel to @file{unix} and @file{mach}. +@end table + +@node Porting to Unix +@appendixsubsec Porting the GNU C Library to Unix Systems + +Most Unix systems are fundamentally very similar. There are variations +between different machines, and variations in what facilities are +provided by the kernel. But the interface to the operating system +facilities is, for the most part, pretty uniform and simple. + +The code for Unix systems is in the directory @file{unix}, at the top +level of the @file{sysdeps} hierarchy. This directory contains +subdirectories (and subdirectory trees) for various Unix variants. + +The functions which are system calls in most Unix systems are +implemented in assembly code in files in @file{sysdeps/unix}. These +files are named with a suffix of @samp{.S}; for example, +@file{__open.S}. Files ending in @samp{.S} are run through the C +preprocessor before being fed to the assembler. + +These files all use a set of macros that should be defined in +@file{sysdep.h}. The @file{sysdep.h} file in @file{sysdeps/unix} +partially defines them; a @file{sysdep.h} file in another directory must +finish defining them for the particular machine and operating system +variant. See @file{sysdeps/unix/sysdep.h} and the machine-specific +@file{sysdep.h} implementations to see what these macros are and what +they should do.@refill + +The system-specific makefile for the @file{unix} directory (that is, the +file @file{sysdeps/unix/Makefile}) gives rules to generate several files +from the Unix system you are building the library on (which is assumed +to be the target system you are building the library @emph{for}). All +the generated files are put in the directory where the object files are +kept; they should not affect the source tree itself. The files +generated are @file{ioctls.h}, @file{errnos.h}, @file{sys/param.h}, and +@file{errlist.c} (for the @file{stdio} section of the library). + +@ignore +@c This section might be a good idea if it is finished, +@c but there's no point including it as it stands. --rms +@c @appendixsec Compatibility with Traditional C + +@c ??? This section is really short now. Want to keep it? --roland + +Although the GNU C library implements the ANSI C library facilities, you +@emph{can} use the GNU C library with traditional, ``pre-ANSI'' C +compilers. However, you need to be careful because the content and +organization of the GNU C library header files differs from that of +traditional C implementations. This means you may need to make changes +to your program in order to get it to compile. +@end ignore + +@node Contributors +@appendixsec Contributors to the GNU C Library + +The GNU C library was written almost entirely by Roland McGrath, who now +maintains it. Some parts of the library were contributed or worked on +by other people. + +@itemize @bullet +@item +The @code{getopt} function and related code were written by +Richard Stallman, @w{David J. MacKenzie}, and @w{Roland McGrath}. + +@item +Most of the math functions are taken from 4.4 BSD; they have been +modified only slightly to work with the GNU C library. The +Internet-related code (most of the @file{inet} subdirectory) and several +other miscellaneous functions and header files have been included with +little or no modification. + +All code incorporated from 4.4 BSD is under the following copyright: + +@quotation +@display +Copyright @copyright{} 1991 Regents of the University of California. +All rights reserved. +@end display + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +@enumerate +@item +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +@item +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +@item +All advertising materials mentioning features or use of this software +must display the following acknowledgement: +@quotation +This product includes software developed by the University of +California, Berkeley and its contributors. +@end quotation +@item +Neither the name of the University nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. +@end enumerate + +@sc{this software is provided by the regents and contributors ``as is'' and +any express or implied warranties, including, but not limited to, the +implied warranties of merchantability and fitness for a particular purpose +are disclaimed. in no event shall the regents or contributors be liable +for any direct, indirect, incidental, special, exemplary, or consequential +damages (including, but not limited to, procurement of substitute goods +or services; loss of use, data, or profits; or business interruption) +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence or otherwise) arising in any way +out of the use of this software, even if advised of the possibility of +such damage.} +@end quotation + +@item +The random number generation functions @code{random}, @code{srandom}, +@code{setstate} and @code{initstate}, which are also the basis for the +@code{rand} and @code{srand} functions, were written by Earl T. Cohen +for the University of California at Berkeley and are copyrighted by the +Regents of the University of California. They have undergone minor +changes to fit into the GNU C library and to fit the ANSI C standard, +but the functional code is Berkeley's.@refill + +@item +The merge sort function @code{qsort} was written by Michael J. Haertel. + +@item +The quick sort function used as a fallback by @code{qsort} was written +by Douglas C. Schmidt. + +@item +The memory allocation functions @code{malloc}, @code{realloc} and +@code{free} and related code were written by Michael J. Haertel. + +@comment tege's name has an umlaut. +@tex +\xdef\SETtege{Torbj\"orn Granlund} +@end tex +@ifinfo +@set tege Torbjorn Granlund +@end ifinfo +@item +Fast implementations of many of the string functions (@code{memcpy}, +@code{strlen}, etc.) were written by @value{tege}. + +@item +Some of the support code for Mach is taken from Mach 3.0 by CMU, +and is under the following copyright terms: + +@quotation +@display +Mach Operating System +Copyright @copyright{} 1991,1990,1989 Carnegie Mellon University +All Rights Reserved. +@end display + +Permission to use, copy, modify and distribute this software and its +documentation is hereby granted, provided that both the copyright +notice and this permission notice appear in all copies of the +software, derivative works or modified versions, and any portions +thereof, and that both notices appear in supporting documentation. + +@sc{carnegie mellon allows free use of this software in its ``as is'' +condition. carnegie mellon disclaims any liability of any kind for +any damages whatsoever resulting from the use of this software.} + +Carnegie Mellon requests users of this software to return to + +@display + Software Distribution Coordinator + School of Computer Science + Carnegie Mellon University + Pittsburgh PA 15213-3890 +@end display + +@noindent +or @samp{Software.Distribution@@CS.CMU.EDU} any improvements or +extensions that they make and grant Carnegie Mellon the rights to +redistribute these changes. +@end quotation + +@item +The @file{tar.h} header file was written by David J. MacKenzie. + +@item +The port to the MIPS DECStation running Ultrix 4 +(@code{mips-dec-ultrix4}) +was contributed by Brendan Kehoe and Ian Lance Taylor. + +@item +The DES encryption function @code{crypt} and related functions were +contributed by Michael Glad. + +@item +The @code{ftw} function was contributed by Ian Lance Taylor. + +@item +The code to support SunOS shared libraries was contributed by Tom Quinn. + +@item +The @code{mktime} function was contributed by Noel Cragg. + +@item +The port to the Sequent Symmetry running Dynix version 3 +(@code{i386-sequent-bsd}) was contributed by Jason Merrill. + +@item +The timezone support code is derived from the public-domain timezone +package by Arthur David Olson. + +@item +The Internet resolver code is taken directly from BIND 4.9.1, which is +under both the Berkeley copyright above and also: + +@quotation +Portions Copyright @copyright{} 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. + +@sc{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.} +@end quotation + +@item +The port to the DEC Alpha running OSF/1 (@code{alpha-dec-osf1}) was +contributed by Brendan Kehoe, using some code written by Roland McGrath. + +@item +The floating-point printing function used by @code{printf} and friends +was written by Roland McGrath and @value{tege}. The multi-precision +integer functions used in that function are taken from GNU MP, which was +contributed by @value{tege}. + +@item +The code to support Sun RPC is taken verbatim from Sun's +@w{@sc{rpcsrc-4.0}} distribution, and is covered by this copyright: + +@quotation +@display +Copyright @copyright{} 1984, Sun Microsystems, Inc. +@end display + +Sun RPC is a product of Sun Microsystems, Inc. and is provided for +unrestricted use provided that this legend is included on all tape media +and as a part of the software program in whole or part. Users may copy +or modify Sun RPC without charge, but are not authorized to license or +distribute it to anyone else except as part of a product or program +developed by the user. + +@sc{sun rpc is provided as is with no warranties of any kind including the +warranties of design, merchantibility and fitness for a particular +purpose, or arising from a course of dealing, usage or trade practice.} + +Sun RPC is provided with no support and without any obligation on the +part of Sun Microsystems, Inc. to assist in its use, correction, +modification or enhancement. + +@sc{sun microsystems, inc. shall have no liability with respect to the +infringement of copyrights, trade secrets or any patents by sun rpc +or any part thereof.} + +In no event will Sun Microsystems, Inc. be liable for any lost revenue +or profits or other special, indirect and consequential damages, even if +Sun has been advised of the possibility of such damages. + +@display +Sun Microsystems, Inc. +2550 Garcia Avenue +Mountain View, California 94043 +@end display +@end quotation + +@item +The port to SGI machines running Irix 4 (@code{mips-sgi-irix4}) was +contributed by Tom Quinn. + +@item +The port of the Mach and Hurd code to the MIPS architecture +(@code{mips-@var{anything}-gnu}) was contribued by Kazumoto Kojima. +@end itemize + +@c @bye diff --git a/manual/math.texi b/manual/math.texi new file mode 100644 index 0000000000..a97d76c2a1 --- /dev/null +++ b/manual/math.texi @@ -0,0 +1,505 @@ +@node Mathematics, Arithmetic, Low-Level Terminal Interface, Top +@chapter Mathematics + +This chapter contains information about functions for performing +mathematical computations, such as trigonometric functions. Most of +these functions have prototypes declared in the header file +@file{math.h}. +@pindex math.h + +All of the functions that operate on floating-point numbers accept +arguments and return results of type @code{double}. In the future, +there may be additional functions that operate on @code{float} and +@code{long double} values. For example, @code{cosf} and @code{cosl} +would be versions of the @code{cos} function that operate on +@code{float} and @code{long double} arguments, respectively. In the +meantime, you should avoid using these names yourself. @xref{Reserved +Names}. + +@menu +* Domain and Range Errors:: Detecting overflow conditions and the like. +* Trig Functions:: Sine, cosine, and tangent. +* Inverse Trig Functions:: Arc sine, arc cosine, and arc tangent. +* Exponents and Logarithms:: Also includes square root. +* Hyperbolic Functions:: Hyperbolic sine and friends. +* Pseudo-Random Numbers:: Functions for generating pseudo-random + numbers. +@end menu + +@node Domain and Range Errors +@section Domain and Range Errors + +@cindex domain error +Many of the functions listed in this chapter are defined mathematically +over a domain that is only a subset of real numbers. For example, the +@code{acos} function is defined over the domain between @code{-1} and +@code{1}. If you pass an argument to one of these functions that is +outside the domain over which it is defined, the function sets +@code{errno} to @code{EDOM} to indicate a @dfn{domain error}. On +machines that support IEEE floating point, functions reporting error +@code{EDOM} also return a NaN. + +Some of these functions are defined mathematically to result in a +complex value over parts of their domains. The most familiar example of +this is taking the square root of a negative number. The functions in +this chapter take only real arguments and return only real values; +therefore, if the value ought to be nonreal, this is treated as a domain +error. + +@cindex range error +A related problem is that the mathematical result of a function may not +be representable as a floating point number. If magnitude of the +correct result is too large to be represented, the function sets +@code{errno} to @code{ERANGE} to indicate a @dfn{range error}, and +returns a particular very large value (named by the macro +@code{HUGE_VAL}) or its negation (@w{@code{- HUGE_VAL}}). + +If the magnitude of the result is too small, a value of zero is returned +instead. In this case, @code{errno} might or might not be +set to @code{ERANGE}. + +The only completely reliable way to check for domain and range errors is +to set @code{errno} to @code{0} before you call the mathematical function +and test @code{errno} afterward. As a consequence of this use of +@code{errno}, use of the mathematical functions is not reentrant if you +check for errors. + +@c !!! this isn't always true at the moment.... +None of the mathematical functions ever generates signals as a result of +domain or range errors. In particular, this means that you won't see +@code{SIGFPE} signals generated within these functions. (@xref{Signal +Handling}, for more information about signals.) + +@comment math.h +@comment ANSI +@deftypevr Macro double HUGE_VAL +An expression representing a particular very large number. On machines +that use IEEE floating point format, the value is ``infinity''. On +other machines, it's typically the largest positive number that can be +represented. + +The value of this macro is used as the return value from various +mathematical functions in overflow situations. +@end deftypevr + +For more information about floating-point representations and limits, +see @ref{Floating Point Parameters}. In particular, the macro +@code{DBL_MAX} might be more appropriate than @code{HUGE_VAL} for many +uses other than testing for an error in a mathematical function. + +@node Trig Functions +@section Trigonometric Functions +@cindex trigonometric functions + +These are the familiar @code{sin}, @code{cos}, and @code{tan} functions. +The arguments to all of these functions are in units of radians; recall +that pi radians equals 180 degrees. + +@cindex pi (trigonometric constant) +The math library doesn't define a symbolic constant for pi, but you can +define your own if you need one: + +@smallexample +#define PI 3.14159265358979323846264338327 +@end smallexample + +@noindent +You can also compute the value of pi with the expression @code{acos +(-1.0)}. + + +@comment math.h +@comment ANSI +@deftypefun double sin (double @var{x}) +This function returns the sine of @var{x}, where @var{x} is given in +radians. The return value is in the range @code{-1} to @code{1}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double cos (double @var{x}) +This function returns the cosine of @var{x}, where @var{x} is given in +radians. The return value is in the range @code{-1} to @code{1}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double tan (double @var{x}) +This function returns the tangent of @var{x}, where @var{x} is given in +radians. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item ERANGE +Mathematically, the tangent function has singularities at odd multiples +of pi/2. If the argument @var{x} is too close to one of these +singularities, @code{tan} sets @code{errno} to @code{ERANGE} and returns +either positive or negative @code{HUGE_VAL}. +@end table +@end deftypefun + + +@node Inverse Trig Functions +@section Inverse Trigonometric Functions +@cindex inverse trigonmetric functions + +These are the usual arc sine, arc cosine and arc tangent functions, +which are the inverses of the sine, cosine and tangent functions, +respectively. + +@comment math.h +@comment ANSI +@deftypefun double asin (double @var{x}) +This function computes the arc sine of @var{x}---that is, the value whose +sine is @var{x}. The value is in units of radians. Mathematically, +there are infinitely many such values; the one actually returned is the +one between @code{-pi/2} and @code{pi/2} (inclusive). + +@code{asin} fails, and sets @code{errno} to @code{EDOM}, if @var{x} is +out of range. The arc sine function is defined mathematically only +over the domain @code{-1} to @code{1}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double acos (double @var{x}) +This function computes the arc cosine of @var{x}---that is, the value +whose cosine is @var{x}. The value is in units of radians. +Mathematically, there are infinitely many such values; the one actually +returned is the one between @code{0} and @code{pi} (inclusive). + +@code{acos} fails, and sets @code{errno} to @code{EDOM}, if @var{x} is +out of range. The arc cosine function is defined mathematically only +over the domain @code{-1} to @code{1}. +@end deftypefun + + +@comment math.h +@comment ANSI +@deftypefun double atan (double @var{x}) +This function computes the arc tangent of @var{x}---that is, the value +whose tangent is @var{x}. The value is in units of radians. +Mathematically, there are infinitely many such values; the one actually +returned is the one between @code{-pi/2} and @code{pi/2} +(inclusive). +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double atan2 (double @var{y}, double @var{x}) +This is the two argument arc tangent function. It is similar to computing +the arc tangent of @var{y}/@var{x}, except that the signs of both arguments +are used to determine the quadrant of the result, and @var{x} is +permitted to be zero. The return value is given in radians and is in +the range @code{-pi} to @code{pi}, inclusive. + +If @var{x} and @var{y} are coordinates of a point in the plane, +@code{atan2} returns the signed angle between the line from the origin +to that point and the x-axis. Thus, @code{atan2} is useful for +converting Cartesian coordinates to polar coordinates. (To compute the +radial coordinate, use @code{hypot}; see @ref{Exponents and +Logarithms}.) + +The function @code{atan2} sets @code{errno} to @code{EDOM} if both +@var{x} and @var{y} are zero; the return value is not defined in this +case. +@end deftypefun + + +@node Exponents and Logarithms +@section Exponentiation and Logarithms +@cindex exponentiation functions +@cindex power functions +@cindex logarithm functions + +@comment math.h +@comment ANSI +@deftypefun double exp (double @var{x}) +The @code{exp} function returns the value of e (the base of natural +logarithms) raised to power @var{x}. + +The function fails, and sets @code{errno} to @code{ERANGE}, if the +magnitude of the result is too large to be representable. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double log (double @var{x}) +This function returns the natural logarithm of @var{x}. @code{exp (log +(@var{x}))} equals @var{x}, exactly in mathematics and approximately in +C. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EDOM +The argument @var{x} is negative. The log function is defined +mathematically to return a real result only on positive arguments. + +@item ERANGE +The argument is zero. The log of zero is not defined. +@end table +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double log10 (double @var{x}) +This function returns the base-10 logarithm of @var{x}. Except for the +different base, it is similar to the @code{log} function. In fact, +@code{log10 (@var{x})} equals @code{log (@var{x}) / log (10)}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double pow (double @var{base}, double @var{power}) +This is a general exponentiation function, returning @var{base} raised +to @var{power}. + +@need 250 +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EDOM +The argument @var{base} is negative and @var{power} is not an integral +value. Mathematically, the result would be a complex number in this case. + +@item ERANGE +An underflow or overflow condition was detected in the result. +@end table +@end deftypefun + +@cindex square root function +@comment math.h +@comment ANSI +@deftypefun double sqrt (double @var{x}) +This function returns the nonnegative square root of @var{x}. + +The @code{sqrt} function fails, and sets @code{errno} to @code{EDOM}, if +@var{x} is negative. Mathematically, the square root would be a complex +number. +@end deftypefun + +@cindex cube root function +@comment math.h +@comment BSD +@deftypefun double cbrt (double @var{x}) +This function returns the cube root of @var{x}. This function cannot +fail; every representable real value has a representable real cube root. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double hypot (double @var{x}, double @var{y}) +The @code{hypot} function returns @code{sqrt (@var{x}*@var{x} + +@var{y}*@var{y})}. (This is the length of the hypotenuse of a right +triangle with sides of length @var{x} and @var{y}, or the distance +of the point (@var{x}, @var{y}) from the origin.) See also the function +@code{cabs} in @ref{Absolute Value}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double expm1 (double @var{x}) +This function returns a value equivalent to @code{exp (@var{x}) - 1}. +It is computed in a way that is accurate even if the value of @var{x} is +near zero---a case where @code{exp (@var{x}) - 1} would be inaccurate due +to subtraction of two numbers that are nearly equal. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double log1p (double @var{x}) +This function returns a value equivalent to @w{@code{log (1 + @var{x})}}. +It is computed in a way that is accurate even if the value of @var{x} is +near zero. +@end deftypefun + +@node Hyperbolic Functions +@section Hyperbolic Functions +@cindex hyperbolic functions + +The functions in this section are related to the exponential functions; +see @ref{Exponents and Logarithms}. + +@comment math.h +@comment ANSI +@deftypefun double sinh (double @var{x}) +The @code{sinh} function returns the hyperbolic sine of @var{x}, defined +mathematically as @w{@code{exp (@var{x}) - exp (-@var{x}) / 2}}. The +function fails, and sets @code{errno} to @code{ERANGE}, if the value of +@var{x} is too large; that is, if overflow occurs. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double cosh (double @var{x}) +The @code{cosh} function returns the hyperbolic cosine of @var{x}, +defined mathematically as @w{@code{exp (@var{x}) + exp (-@var{x}) / 2}}. +The function fails, and sets @code{errno} to @code{ERANGE}, if the value +of @var{x} is too large; that is, if overflow occurs. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double tanh (double @var{x}) +This function returns the hyperbolic tangent of @var{x}, whose +mathematical definition is @w{@code{sinh (@var{x}) / cosh (@var{x})}}. +@end deftypefun + +@cindex inverse hyperbolic functions + +@comment math.h +@comment BSD +@deftypefun double asinh (double @var{x}) +This function returns the inverse hyperbolic sine of @var{x}---the +value whose hyperbolic sine is @var{x}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double acosh (double @var{x}) +This function returns the inverse hyperbolic cosine of @var{x}---the +value whose hyperbolic cosine is @var{x}. If @var{x} is less than +@code{1}, @code{acosh} returns @code{HUGE_VAL}. +@end deftypefun + +@comment math.h +@comment BSD +@deftypefun double atanh (double @var{x}) +This function returns the inverse hyperbolic tangent of @var{x}---the +value whose hyperbolic tangent is @var{x}. If the absolute value of +@var{x} is greater than or equal to @code{1}, @code{atanh} returns +@code{HUGE_VAL}. +@end deftypefun + +@node Pseudo-Random Numbers +@section Pseudo-Random Numbers +@cindex random numbers +@cindex pseudo-random numbers +@cindex seed (for random numbers) + +This section describes the GNU facilities for generating a series of +pseudo-random numbers. The numbers generated are not truly random; +typically, they form a sequence that repeats periodically, with a +period so large that you can ignore it for ordinary purposes. The +random number generator works by remembering at all times a @dfn{seed} +value which it uses to compute the next random number and also to +compute a new seed. + +Although the generated numbers look unpredictable within one run of a +program, the sequence of numbers is @emph{exactly the same} from one run +to the next. This is because the initial seed is always the same. This +is convenient when you are debugging a program, but it is unhelpful if +you want the program to behave unpredictably. If you want truly random +numbers, not just pseudo-random, specify a seed based on the current +time. + +You can get repeatable sequences of numbers on a particular machine type +by specifying the same initial seed value for the random number +generator. There is no standard meaning for a particular seed value; +the same seed, used in different C libraries or on different CPU types, +will give you different random numbers. + +The GNU library supports the standard ANSI C random number functions +plus another set derived from BSD. We recommend you use the standard +ones, @code{rand} and @code{srand}. + +@menu +* ANSI Random:: @code{rand} and friends. +* BSD Random:: @code{random} and friends. +@end menu + +@node ANSI Random +@subsection ANSI C Random Number Functions + +This section describes the random number functions that are part of +the ANSI C standard. + +To use these facilities, you should include the header file +@file{stdlib.h} in your program. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int RAND_MAX +The value of this macro is an integer constant expression that +represents the maximum possible value returned by the @code{rand} +function. In the GNU library, it is @code{037777777}, which is the +largest signed integer representable in 32 bits. In other libraries, it +may be as low as @code{32767}. +@end deftypevr + +@comment stdlib.h +@comment ANSI +@deftypefun int rand () +The @code{rand} function returns the next pseudo-random number in the +series. The value is in the range from @code{0} to @code{RAND_MAX}. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun void srand (unsigned int @var{seed}) +This function establishes @var{seed} as the seed for a new series of +pseudo-random numbers. If you call @code{rand} before a seed has been +established with @code{srand}, it uses the value @code{1} as a default +seed. + +To produce truly random numbers (not just pseudo-random), do @code{srand +(time (0))}. +@end deftypefun + +@node BSD Random +@subsection BSD Random Number Functions + +This section describes a set of random number generation functions that +are derived from BSD. There is no advantage to using these functions +with the GNU C library; we support them for BSD compatibility only. + +The prototypes for these functions are in @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment BSD +@deftypefun {long int} random () +This function returns the next pseudo-random number in the sequence. +The range of values returned is from @code{0} to @code{RAND_MAX}. +@end deftypefun + +@comment stdlib.h +@comment BSD +@deftypefun void srandom (unsigned int @var{seed}) +The @code{srandom} function sets the seed for the current random number +state based on the integer @var{seed}. If you supply a @var{seed} value +of @code{1}, this will cause @code{random} to reproduce the default set +of random numbers. + +To produce truly random numbers (not just pseudo-random), do +@code{srandom (time (0))}. +@end deftypefun + +@comment stdlib.h +@comment BSD +@deftypefun {void *} initstate (unsigned int @var{seed}, void *@var{state}, size_t @var{size}) +The @code{initstate} function is used to initialize the random number +generator state. The argument @var{state} is an array of @var{size} +bytes, used to hold the state information. The size must be at least 8 +bytes, and optimal sizes are 8, 16, 32, 64, 128, and 256. The bigger +the @var{state} array, the better. + +The return value is the previous value of the state information array. +You can use this value later as an argument to @code{setstate} to +restore that state. +@end deftypefun + +@comment stdlib.h +@comment BSD +@deftypefun {void *} setstate (void *@var{state}) +The @code{setstate} function restores the random number state +information @var{state}. The argument must have been the result of +a previous call to @var{initstate} or @var{setstate}. + +The return value is the previous value of the state information array. +You can use thise value later as an argument to @code{setstate} to +restore that state. +@end deftypefun diff --git a/manual/mbyte.texi b/manual/mbyte.texi new file mode 100644 index 0000000000..c058cbfb69 --- /dev/null +++ b/manual/mbyte.texi @@ -0,0 +1,695 @@ +@node Extended Characters, Locales, String and Array Utilities, Top +@chapter Extended Characters + +A number of languages use character sets that are larger than the range +of values of type @code{char}. Japanese and Chinese are probably the +most familiar examples. + +The GNU C library includes support for two mechanisms for dealing with +extended character sets: multibyte characters and wide characters. This +chapter describes how to use these mechanisms, and the functions for +converting between them. +@cindex extended character sets + +The behavior of the functions in this chapter is affected by the current +locale for character classification---the @code{LC_CTYPE} category; see +@ref{Locale Categories}. This choice of locale selects which multibyte +code is used, and also controls the meanings and characteristics of wide +character codes. + +@menu +* Extended Char Intro:: Multibyte codes versus wide characters. +* Locales and Extended Chars:: The locale selects the character codes. +* Multibyte Char Intro:: How multibyte codes are represented. +* Wide Char Intro:: How wide characters are represented. +* Wide String Conversion:: Converting wide strings to multibyte code + and vice versa. +* Length of Char:: how many bytes make up one multibyte char. +* Converting One Char:: Converting a string character by character. +* Example of Conversion:: Example showing why converting + one character at a time may be useful. +* Shift State:: Multibyte codes with "shift characters". +@end menu + +@node Extended Char Intro, Locales and Extended Chars, , Extended Characters +@section Introduction to Extended Characters + +You can represent extended characters in either of two ways: + +@itemize @bullet +@item +As @dfn{multibyte characters} which can be embedded in an ordinary +string, an array of @code{char} objects. Their advantage is that many +programs and operating systems can handle occasional multibyte +characters scattered among ordinary ASCII characters, without any +change. + +@item +@cindex wide characters +As @dfn{wide characters}, which are like ordinary characters except that +they occupy more bits. The wide character data type, @code{wchar_t}, +has a range large enough to hold extended character codes as well as +old-fashioned ASCII codes. + +An advantage of wide characters is that each character is a single data +object, just like ordinary ASCII characters. There are a few +disadvantages: + +@itemize @bullet +@item +Each existing program must be modified and recompiled to make it use +wide characters. + +@item +Files of wide characters cannot be read by programs that expect ordinary +characters. +@end itemize +@end itemize + +Typically, you use the multibyte character representation as part of the +external program interface, such as reading or writing text to files. +However, it's usually easier to perform internal manipulations on +strings containing extended characters on arrays of @code{wchar_t} +objects, since the uniform representation makes most editing operations +easier. If you do use multibyte characters for files and wide +characters for internal operations, you need to convert between them +when you read and write data. + +If your system supports extended characters, then it supports them both +as multibyte characters and as wide characters. The library includes +functions you can use to convert between the two representations. +These functions are described in this chapter. + +@node Locales and Extended Chars, Multibyte Char Intro, Extended Char Intro, Extended Characters +@section Locales and Extended Characters + +A computer system can support more than one multibyte character code, +and more than one wide character code. The user controls the choice of +codes through the current locale for character classification +(@pxref{Locales}). Each locale specifies a particular multibyte +character code and a particular wide character code. The choice of locale +influences the behavior of the conversion functions in the library. + +Some locales support neither wide characters nor nontrivial multibyte +characters. In these locales, the library conversion functions still +work, even though what they do is basically trivial. + +If you select a new locale for character classification, the internal +shift state maintained by these functions can become confused, so it's +not a good idea to change the locale while you are in the middle of +processing a string. + +@node Multibyte Char Intro, Wide Char Intro, Locales and Extended Chars, Extended Characters +@section Multibyte Characters +@cindex multibyte characters + +In the ordinary ASCII code, a sequence of characters is a sequence of +bytes, and each character is one byte. This is very simple, but +allows for only 256 distinct characters. + +In a @dfn{multibyte character code}, a sequence of characters is a +sequence of bytes, but each character may occupy one or more consecutive +bytes of the sequence. + +@cindex basic byte sequence +There are many different ways of designing a multibyte character code; +different systems use different codes. To specify a particular code +means designating the @dfn{basic} byte sequences---those which represent +a single character---and what characters they stand for. A code that a +computer can actually use must have a finite number of these basic +sequences, and typically none of them is more than a few characters +long. + +These sequences need not all have the same length. In fact, many of +them are just one byte long. Because the basic ASCII characters in the +range from @code{0} to @code{0177} are so important, they stand for +themselves in all multibyte character codes. That is to say, a byte +whose value is @code{0} through @code{0177} is always a character in +itself. The characters which are more than one byte must always start +with a byte in the range from @code{0200} through @code{0377}. + +The byte value @code{0} can be used to terminate a string, just as it is +often used in a string of ASCII characters. + +Specifying the basic byte sequences that represent single characters +automatically gives meanings to many longer byte sequences, as more than +one character. For example, if the two byte sequence @code{0205 049} +stands for the Greek letter alpha, then @code{0205 049 065} must stand +for an alpha followed by an @samp{A} (ASCII code 065), and @code{0205 049 +0205 049} must stand for two alphas in a row. + +If any byte sequence can have more than one meaning as a sequence of +characters, then the multibyte code is ambiguous---and no good. The +codes that systems actually use are all unambiguous. + +In most codes, there are certain sequences of bytes that have no meaning +as a character or characters. These are called @dfn{invalid}. + +The simplest possible multibyte code is a trivial one: + +@quotation +The basic sequences consist of single bytes. +@end quotation + +This particular code is equivalent to not using multibyte characters at +all. It has no invalid sequences. But it can handle only 256 different +characters. + +Here is another possible code which can handle 9376 different +characters: + +@quotation +The basic sequences consist of + +@itemize @bullet +@item +single bytes with values in the range @code{0} through @code{0237}. + +@item +two-byte sequences, in which both of the bytes have values in the range +from @code{0240} through @code{0377}. +@end itemize +@end quotation + +@noindent +This code or a similar one is used on some systems to represent Japanese +characters. The invalid sequences are those which consist of an odd +number of consecutive bytes in the range from @code{0240} through +@code{0377}. + +Here is another multibyte code which can handle more distinct extended +characters---in fact, almost thirty million: + +@quotation +The basic sequences consist of + +@itemize @bullet +@item +single bytes with values in the range @code{0} through @code{0177}. + +@item +sequences of up to four bytes in which the first byte is in the range +from @code{0200} through @code{0237}, and the remaining bytes are in the +range from @code{0240} through @code{0377}. +@end itemize +@end quotation + +@noindent +In this code, any sequence that starts with a byte in the range +from @code{0240} through @code{0377} is invalid. + +And here is another variant which has the advantage that removing the +last byte or bytes from a valid character can never produce another +valid character. (This property is convenient when you want to search +strings for particular characters.) + +@quotation +The basic sequences consist of + +@itemize @bullet +@item +single bytes with values in the range @code{0} through @code{0177}. + +@item +two-byte sequences in which the first byte is in the range from +@code{0200} through @code{0207}, and the second byte is in the range +from @code{0240} through @code{0377}. + +@item +three-byte sequences in which the first byte is in the range from +@code{0210} through @code{0217}, and the other bytes are in the range +from @code{0240} through @code{0377}. + +@item +four-byte sequences in which the first byte is in the range from +@code{0220} through @code{0227}, and the other bytes are in the range +from @code{0240} through @code{0377}. +@end itemize +@end quotation + +@noindent +The list of invalid sequences for this code is long and not worth +stating in full; examples of invalid sequences include @code{0240} and +@code{0220 0300 065}. + +The number of @emph{possible} multibyte codes is astronomical. But a +given computer system will support at most a few different codes. (One +of these codes may allow for thousands of different characters.) +Another computer system may support a completely different code. The +library facilities described in this chapter are helpful because they +package up the knowledge of the details of a particular computer +system's multibyte code, so your programs need not know them. + +You can use special standard macros to find out the maximum possible +number of bytes in a character in the currently selected multibyte +code with @code{MB_CUR_MAX}, and the maximum for @emph{any} multibyte +code supported on your computer with @code{MB_LEN_MAX}. + +@comment limits.h +@comment ANSI +@deftypevr Macro int MB_LEN_MAX +This is the maximum length of a multibyte character for any supported +locale. It is defined in @file{limits.h}. +@pindex limits.h +@end deftypevr + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int MB_CUR_MAX +This macro expands into a (possibly non-constant) positive integer +expression that is the maximum number of bytes in a multibyte character +in the current locale. The value is never greater than @code{MB_LEN_MAX}. + +@pindex stdlib.h +@code{MB_CUR_MAX} is defined in @file{stdlib.h}. +@end deftypevr + +Normally, each basic sequence in a particular character code stands for +one character, the same character regardless of context. Some multibyte +character codes have a concept of @dfn{shift state}; certain codes, +called @dfn{shift sequences}, change to a different shift state, and the +meaning of some or all basic sequences varies according to the current +shift state. In fact, the set of basic sequences might even be +different depending on the current shift state. @xref{Shift State}, for +more information on handling this sort of code. + +What happens if you try to pass a string containing multibyte characters +to a function that doesn't know about them? Normally, such a function +treats a string as a sequence of bytes, and interprets certain byte +values specially; all other byte values are ``ordinary''. As long as a +multibyte character doesn't contain any of the special byte values, the +function should pass it through as if it were several ordinary +characters. + +For example, let's figure out what happens if you use multibyte +characters in a file name. The functions such as @code{open} and +@code{unlink} that operate on file names treat the name as a sequence of +byte values, with @samp{/} as the only special value. Any other byte +values are copied, or compared, in sequence, and all byte values are +treated alike. Thus, you may think of the file name as a sequence of +bytes or as a string containing multibyte characters; the same behavior +makes sense equally either way, provided no multibyte character contains +a @samp{/}. + +@node Wide Char Intro, Wide String Conversion, Multibyte Char Intro, Extended Characters +@section Wide Character Introduction + +@dfn{Wide characters} are much simpler than multibyte characters. They +are simply characters with more than eight bits, so that they have room +for more than 256 distinct codes. The wide character data type, +@code{wchar_t}, has a range large enough to hold extended character +codes as well as old-fashioned ASCII codes. + +An advantage of wide characters is that each character is a single data +object, just like ordinary ASCII characters. Wide characters also have +some disadvantages: + +@itemize @bullet +@item +A program must be modified and recompiled in order to use wide +characters at all. + +@item +Files of wide characters cannot be read by programs that expect ordinary +characters. +@end itemize + +Wide character values @code{0} through @code{0177} are always identical +in meaning to the ASCII character codes. The wide character value zero +is often used to terminate a string of wide characters, just as a single +byte with value zero often terminates a string of ordinary characters. + +@comment stddef.h +@comment ANSI +@deftp {Data Type} wchar_t +This is the ``wide character'' type, an integer type whose range is +large enough to represent all distinct values in any extended character +set in the supported locales. @xref{Locales}, for more information +about locales. This type is defined in the header file @file{stddef.h}. +@pindex stddef.h +@end deftp + +If your system supports extended characters, then each extended +character has both a wide character code and a corresponding multibyte +basic sequence. + +@cindex code, character +@cindex character code +In this chapter, the term @dfn{code} is used to refer to a single +extended character object to emphasize the distinction from the +@code{char} data type. + +@node Wide String Conversion, Length of Char, Wide Char Intro, Extended Characters +@section Conversion of Extended Strings +@cindex extended strings, converting representations +@cindex converting extended strings + +@pindex stdlib.h +The @code{mbstowcs} function converts a string of multibyte characters +to a wide character array. The @code{wcstombs} function does the +reverse. These functions are declared in the header file +@file{stdlib.h}. + +In most programs, these functions are the only ones you need for +conversion between wide strings and multibyte character strings. But +they have limitations. If your data is not null-terminated or is not +all in core at once, you probably need to use the low-level conversion +functions to convert one character at a time. @xref{Converting One +Char}. + +@comment stdlib.h +@comment ANSI +@deftypefun size_t mbstowcs (wchar_t *@var{wstring}, const char *@var{string}, size_t @var{size}) +The @code{mbstowcs} (``multibyte string to wide character string'') +function converts the null-terminated string of multibyte characters +@var{string} to an array of wide character codes, storing not more than +@var{size} wide characters into the array beginning at @var{wstring}. +The terminating null character counts towards the size, so if @var{size} +is less than the actual number of wide characters resulting from +@var{string}, no terminating null character is stored. + +The conversion of characters from @var{string} begins in the initial +shift state. + +If an invalid multibyte character sequence is found, this function +returns a value of @code{-1}. Otherwise, it returns the number of wide +characters stored in the array @var{wstring}. This number does not +include the terminating null character, which is present if the number +is less than @var{size}. + +Here is an example showing how to convert a string of multibyte +characters, allocating enough space for the result. + +@smallexample +wchar_t * +mbstowcs_alloc (const char *string) +@{ + size_t size = strlen (string) + 1; + wchar_t *buf = xmalloc (size * sizeof (wchar_t)); + + size = mbstowcs (buf, string, size); + if (size == (size_t) -1) + return NULL; + buf = xrealloc (buf, (size + 1) * sizeof (wchar_t)); + return buf; +@} +@end smallexample + +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun size_t wcstombs (char *@var{string}, const wchar_t @var{wstring}, size_t @var{size}) +The @code{wcstombs} (``wide character string to multibyte string'') +function converts the null-terminated wide character array @var{wstring} +into a string containing multibyte characters, storing not more than +@var{size} bytes starting at @var{string}, followed by a terminating +null character if there is room. The conversion of characters begins in +the initial shift state. + +The terminating null character counts towards the size, so if @var{size} +is less than or equal to the number of bytes needed in @var{wstring}, no +terminating null character is stored. + +If a code that does not correspond to a valid multibyte character is +found, this function returns a value of @code{-1}. Otherwise, the +return value is the number of bytes stored in the array @var{string}. +This number does not include the terminating null character, which is +present if the number is less than @var{size}. +@end deftypefun + +@node Length of Char, Converting One Char, Wide String Conversion, Extended Characters +@section Multibyte Character Length +@cindex multibyte character, length of +@cindex length of multibyte character + +This section describes how to scan a string containing multibyte +characters, one character at a time. The difficulty in doing this +is to know how many bytes each character contains. Your program +can use @code{mblen} to find this out. + +@comment stdlib.h +@comment ANSI +@deftypefun int mblen (const char *@var{string}, size_t @var{size}) +The @code{mblen} function with a non-null @var{string} argument returns +the number of bytes that make up the multibyte character beginning at +@var{string}, never examining more than @var{size} bytes. (The idea is +to supply for @var{size} the number of bytes of data you have in hand.) + +The return value of @code{mblen} distinguishes three possibilities: the +first @var{size} bytes at @var{string} start with valid multibyte +character, they start with an invalid byte sequence or just part of a +character, or @var{string} points to an empty string (a null character). + +For a valid multibyte character, @code{mblen} returns the number of +bytes in that character (always at least @code{1}, and never more than +@var{size}). For an invalid byte sequence, @code{mblen} returns +@code{-1}. For an empty string, it returns @code{0}. + +If the multibyte character code uses shift characters, then @code{mblen} +maintains and updates a shift state as it scans. If you call +@code{mblen} with a null pointer for @var{string}, that initializes the +shift state to its standard initial value. It also returns nonzero if +the multibyte character code in use actually has a shift state. +@xref{Shift State}. + +@pindex stdlib.h +The function @code{mblen} is declared in @file{stdlib.h}. +@end deftypefun + +@node Converting One Char, Example of Conversion, Length of Char, Extended Characters +@section Conversion of Extended Characters One by One +@cindex extended characters, converting +@cindex converting extended characters + +@pindex stdlib.h +You can convert multibyte characters one at a time to wide characters +with the @code{mbtowc} function. The @code{wctomb} function does the +reverse. These functions are declared in @file{stdlib.h}. + +@comment stdlib.h +@comment ANSI +@deftypefun int mbtowc (wchar_t *@var{result}, const char *@var{string}, size_t @var{size}) +The @code{mbtowc} (``multibyte to wide character'') function when called +with non-null @var{string} converts the first multibyte character +beginning at @var{string} to its corresponding wide character code. It +stores the result in @code{*@var{result}}. + +@code{mbtowc} never examines more than @var{size} bytes. (The idea is +to supply for @var{size} the number of bytes of data you have in hand.) + +@code{mbtowc} with non-null @var{string} distinguishes three +possibilities: the first @var{size} bytes at @var{string} start with +valid multibyte character, they start with an invalid byte sequence or +just part of a character, or @var{string} points to an empty string (a +null character). + +For a valid multibyte character, @code{mbtowc} converts it to a wide +character and stores that in @code{*@var{result}}, and returns the +number of bytes in that character (always at least @code{1}, and never +more than @var{size}). + +For an invalid byte sequence, @code{mbtowc} returns @code{-1}. For an +empty string, it returns @code{0}, also storing @code{0} in +@code{*@var{result}}. + +If the multibyte character code uses shift characters, then +@code{mbtowc} maintains and updates a shift state as it scans. If you +call @code{mbtowc} with a null pointer for @var{string}, that +initializes the shift state to its standard initial value. It also +returns nonzero if the multibyte character code in use actually has a +shift state. @xref{Shift State}. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun int wctomb (char *@var{string}, wchar_t @var{wchar}) +The @code{wctomb} (``wide character to multibyte'') function converts +the wide character code @var{wchar} to its corresponding multibyte +character sequence, and stores the result in bytes starting at +@var{string}. At most @code{MB_CUR_MAX} characters are stored. + +@code{wctomb} with non-null @var{string} distinguishes three +possibilities for @var{wchar}: a valid wide character code (one that can +be translated to a multibyte character), an invalid code, and @code{0}. + +Given a valid code, @code{wctomb} converts it to a multibyte character, +storing the bytes starting at @var{string}. Then it returns the number +of bytes in that character (always at least @code{1}, and never more +than @code{MB_CUR_MAX}). + +If @var{wchar} is an invalid wide character code, @code{wctomb} returns +@code{-1}. If @var{wchar} is @code{0}, it returns @code{0}, also +storing @code{0} in @code{*@var{string}}. + +If the multibyte character code uses shift characters, then +@code{wctomb} maintains and updates a shift state as it scans. If you +call @code{wctomb} with a null pointer for @var{string}, that +initializes the shift state to its standard initial value. It also +returns nonzero if the multibyte character code in use actually has a +shift state. @xref{Shift State}. + +Calling this function with a @var{wchar} argument of zero when +@var{string} is not null has the side-effect of reinitializing the +stored shift state @emph{as well as} storing the multibyte character +@code{0} and returning @code{0}. +@end deftypefun + +@node Example of Conversion, Shift State, Converting One Char, Extended Characters +@section Character-by-Character Conversion Example + +Here is an example that reads multibyte character text from descriptor +@code{input} and writes the corresponding wide characters to descriptor +@code{output}. We need to convert characters one by one for this +example because @code{mbstowcs} is unable to continue past a null +character, and cannot cope with an apparently invalid partial character +by reading more input. + +@smallexample +int +file_mbstowcs (int input, int output) +@{ + char buffer[BUFSIZ + MB_LEN_MAX]; + int filled = 0; + int eof = 0; + + while (!eof) + @{ + int nread; + int nwrite; + char *inp = buffer; + wchar_t outbuf[BUFSIZ]; + wchar_t *outp = outbuf; + + /* @r{Fill up the buffer from the input file.} */ + nread = read (input, buffer + filled, BUFSIZ); + if (nread < 0) + @{ + perror ("read"); + return 0; + @} + /* @r{If we reach end of file, make a note to read no more.} */ + if (nread == 0) + eof = 1; + + /* @r{@code{filled} is now the number of bytes in @code{buffer}.} */ + filled += nread; + + /* @r{Convert those bytes to wide characters--as many as we can.} */ + while (1) + @{ + int thislen = mbtowc (outp, inp, filled); + /* Stop converting at invalid character; + this can mean we have read just the first part + of a valid character. */ + if (thislen == -1) + break; + /* @r{Treat null character like any other,} + @r{but also reset shift state.} */ + if (thislen == 0) @{ + thislen = 1; + mbtowc (NULL, NULL, 0); + @} + /* @r{Advance past this character.} */ + inp += thislen; + filled -= thislen; + outp++; + @} + + /* @r{Write the wide characters we just made.} */ + nwrite = write (output, outbuf, + (outp - outbuf) * sizeof (wchar_t)); + if (nwrite < 0) + @{ + perror ("write"); + return 0; + @} + + /* @r{See if we have a @emph{real} invalid character.} */ + if ((eof && filled > 0) || filled >= MB_CUR_MAX) + @{ + error ("invalid multibyte character"); + return 0; + @} + + /* @r{If any characters must be carried forward,} + @r{put them at the beginning of @code{buffer}.} */ + if (filled > 0) + memcpy (inp, buffer, filled); + @} + @} + + return 1; +@} +@end smallexample + +@node Shift State, , Example of Conversion, Extended Characters +@section Multibyte Codes Using Shift Sequences + +In some multibyte character codes, the @emph{meaning} of any particular +byte sequence is not fixed; it depends on what other sequences have come +earlier in the same string. Typically there are just a few sequences +that can change the meaning of other sequences; these few are called +@dfn{shift sequences} and we say that they set the @dfn{shift state} for +other sequences that follow. + +To illustrate shift state and shift sequences, suppose we decide that +the sequence @code{0200} (just one byte) enters Japanese mode, in which +pairs of bytes in the range from @code{0240} to @code{0377} are single +characters, while @code{0201} enters Latin-1 mode, in which single bytes +in the range from @code{0240} to @code{0377} are characters, and +interpreted according to the ISO Latin-1 character set. This is a +multibyte code which has two alternative shift states (``Japanese mode'' +and ``Latin-1 mode''), and two shift sequences that specify particular +shift states. + +When the multibyte character code in use has shift states, then +@code{mblen}, @code{mbtowc} and @code{wctomb} must maintain and update +the current shift state as they scan the string. To make this work +properly, you must follow these rules: + +@itemize @bullet +@item +Before starting to scan a string, call the function with a null pointer +for the multibyte character address---for example, @code{mblen (NULL, +0)}. This initializes the shift state to its standard initial value. + +@item +Scan the string one character at a time, in order. Do not ``back up'' +and rescan characters already scanned, and do not intersperse the +processing of different strings. +@end itemize + +Here is an example of using @code{mblen} following these rules: + +@smallexample +void +scan_string (char *s) +@{ + int length = strlen (s); + + /* @r{Initialize shift state.} */ + mblen (NULL, 0); + + while (1) + @{ + int thischar = mblen (s, length); + /* @r{Deal with end of string and invalid characters.} */ + if (thischar == 0) + break; + if (thischar == -1) + @{ + error ("invalid multibyte character"); + break; + @} + /* @r{Advance past this character.} */ + s += thischar; + length -= thischar; + @} +@} +@end smallexample + +The functions @code{mblen}, @code{mbtowc} and @code{wctomb} are not +reentrant when using a multibyte code that uses a shift state. However, +no other library functions call these functions, so you don't have to +worry that the shift state will be changed mysteriously. diff --git a/manual/memory.texi b/manual/memory.texi new file mode 100644 index 0000000000..9269380e1d --- /dev/null +++ b/manual/memory.texi @@ -0,0 +1,1751 @@ +@comment !!! describe mmap et al (here?) +@c !!! doc brk/sbrk + +@node Memory Allocation, Character Handling, Error Reporting, Top +@chapter Memory Allocation +@cindex memory allocation +@cindex storage allocation + +The GNU system provides several methods for allocating memory space +under explicit program control. They vary in generality and in +efficiency. + +@iftex +@itemize @bullet +@item +The @code{malloc} facility allows fully general dynamic allocation. +@xref{Unconstrained Allocation}. + +@item +Obstacks are another facility, less general than @code{malloc} but more +efficient and convenient for stacklike allocation. @xref{Obstacks}. + +@item +The function @code{alloca} lets you allocate storage dynamically that +will be freed automatically. @xref{Variable Size Automatic}. +@end itemize +@end iftex + +@menu +* Memory Concepts:: An introduction to concepts and terminology. +* Dynamic Allocation and C:: How to get different kinds of allocation in C. +* Unconstrained Allocation:: The @code{malloc} facility allows fully general + dynamic allocation. +* Obstacks:: Obstacks are less general than malloc + but more efficient and convenient. +* Variable Size Automatic:: Allocation of variable-sized blocks + of automatic storage that are freed when the + calling function returns. +* Relocating Allocator:: Waste less memory, if you can tolerate + automatic relocation of the blocks you get. +* Memory Warnings:: Getting warnings when memory is nearly full. +@end menu + +@node Memory Concepts +@section Dynamic Memory Allocation Concepts +@cindex dynamic allocation +@cindex static allocation +@cindex automatic allocation + +@dfn{Dynamic memory allocation} is a technique in which programs +determine as they are running where to store some information. You need +dynamic allocation when the number of memory blocks you need, or how +long you continue to need them, depends on the data you are working on. + +For example, you may need a block to store a line read from an input file; +since there is no limit to how long a line can be, you must allocate the +storage dynamically and make it dynamically larger as you read more of the +line. + +Or, you may need a block for each record or each definition in the input +data; since you can't know in advance how many there will be, you must +allocate a new block for each record or definition as you read it. + +When you use dynamic allocation, the allocation of a block of memory is an +action that the program requests explicitly. You call a function or macro +when you want to allocate space, and specify the size with an argument. If +you want to free the space, you do so by calling another function or macro. +You can do these things whenever you want, as often as you want. + +@node Dynamic Allocation and C +@section Dynamic Allocation and C + +The C language supports two kinds of memory allocation through the variables +in C programs: + +@itemize @bullet +@item +@dfn{Static allocation} is what happens when you declare a static or +global variable. Each static or global variable defines one block of +space, of a fixed size. The space is allocated once, when your program +is started, and is never freed. + +@item +@dfn{Automatic allocation} happens when you declare an automatic +variable, such as a function argument or a local variable. The space +for an automatic variable is allocated when the compound statement +containing the declaration is entered, and is freed when that +compound statement is exited. + +In GNU C, the length of the automatic storage can be an expression +that varies. In other C implementations, it must be a constant. +@end itemize + +Dynamic allocation is not supported by C variables; there is no storage +class ``dynamic'', and there can never be a C variable whose value is +stored in dynamically allocated space. The only way to refer to +dynamically allocated space is through a pointer. Because it is less +convenient, and because the actual process of dynamic allocation +requires more computation time, programmers generally use dynamic +allocation only when neither static nor automatic allocation will serve. + +For example, if you want to allocate dynamically some space to hold a +@code{struct foobar}, you cannot declare a variable of type @code{struct +foobar} whose contents are the dynamically allocated space. But you can +declare a variable of pointer type @code{struct foobar *} and assign it the +address of the space. Then you can use the operators @samp{*} and +@samp{->} on this pointer variable to refer to the contents of the space: + +@smallexample +@{ + struct foobar *ptr + = (struct foobar *) malloc (sizeof (struct foobar)); + ptr->name = x; + ptr->next = current_foobar; + current_foobar = ptr; +@} +@end smallexample + +@node Unconstrained Allocation +@section Unconstrained Allocation +@cindex unconstrained storage allocation +@cindex @code{malloc} function +@cindex heap, dynamic allocation from + +The most general dynamic allocation facility is @code{malloc}. It +allows you to allocate blocks of memory of any size at any time, make +them bigger or smaller at any time, and free the blocks individually at +any time (or never). + +@menu +* Basic Allocation:: Simple use of @code{malloc}. +* Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}. +* Freeing after Malloc:: Use @code{free} to free a block you + got with @code{malloc}. +* Changing Block Size:: Use @code{realloc} to make a block + bigger or smaller. +* Allocating Cleared Space:: Use @code{calloc} to allocate a + block and clear it. +* Efficiency and Malloc:: Efficiency considerations in use of + these functions. +* Aligned Memory Blocks:: Allocating specially aligned memory: + @code{memalign} and @code{valloc}. +* Heap Consistency Checking:: Automatic checking for errors. +* Hooks for Malloc:: You can use these hooks for debugging + programs that use @code{malloc}. +* Statistics of Malloc:: Getting information about how much + memory your program is using. +* Summary of Malloc:: Summary of @code{malloc} and related functions. +@end menu + +@node Basic Allocation +@subsection Basic Storage Allocation +@cindex allocation of memory with @code{malloc} + +To allocate a block of memory, call @code{malloc}. The prototype for +this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} malloc (size_t @var{size}) +This function returns a pointer to a newly allocated block @var{size} +bytes long, or a null pointer if the block could not be allocated. +@end deftypefun + +The contents of the block are undefined; you must initialize it yourself +(or use @code{calloc} instead; @pxref{Allocating Cleared Space}). +Normally you would cast the value as a pointer to the kind of object +that you want to store in the block. Here we show an example of doing +so, and of initializing the space with zeros using the library function +@code{memset} (@pxref{Copying and Concatenation}): + +@smallexample +struct foo *ptr; +@dots{} +ptr = (struct foo *) malloc (sizeof (struct foo)); +if (ptr == 0) abort (); +memset (ptr, 0, sizeof (struct foo)); +@end smallexample + +You can store the result of @code{malloc} into any pointer variable +without a cast, because ANSI C automatically converts the type +@code{void *} to another type of pointer when necessary. But the cast +is necessary in contexts other than assignment operators or if you might +want your code to run in traditional C. + +Remember that when allocating space for a string, the argument to +@code{malloc} must be one plus the length of the string. This is +because a string is terminated with a null character that doesn't count +in the ``length'' of the string but does need space. For example: + +@smallexample +char *ptr; +@dots{} +ptr = (char *) malloc (length + 1); +@end smallexample + +@noindent +@xref{Representation of Strings}, for more information about this. + +@node Malloc Examples +@subsection Examples of @code{malloc} + +If no more space is available, @code{malloc} returns a null pointer. +You should check the value of @emph{every} call to @code{malloc}. It is +useful to write a subroutine that calls @code{malloc} and reports an +error if the value is a null pointer, returning only if the value is +nonzero. This function is conventionally called @code{xmalloc}. Here +it is: + +@smallexample +void * +xmalloc (size_t size) +@{ + register void *value = malloc (size); + if (value == 0) + fatal ("virtual memory exhausted"); + return value; +@} +@end smallexample + +Here is a real example of using @code{malloc} (by way of @code{xmalloc}). +The function @code{savestring} will copy a sequence of characters into +a newly allocated null-terminated string: + +@smallexample +@group +char * +savestring (const char *ptr, size_t len) +@{ + register char *value = (char *) xmalloc (len + 1); + memcpy (value, ptr, len); + value[len] = '\0'; + return value; +@} +@end group +@end smallexample + +The block that @code{malloc} gives you is guaranteed to be aligned so +that it can hold any type of data. In the GNU system, the address is +always a multiple of eight; if the size of block is 16 or more, then the +address is always a multiple of 16. Only rarely is any higher boundary +(such as a page boundary) necessary; for those cases, use +@code{memalign} or @code{valloc} (@pxref{Aligned Memory Blocks}). + +Note that the memory located after the end of the block is likely to be +in use for something else; perhaps a block already allocated by another +call to @code{malloc}. If you attempt to treat the block as longer than +you asked for it to be, you are liable to destroy the data that +@code{malloc} uses to keep track of its blocks, or you may destroy the +contents of another block. If you have already allocated a block and +discover you want it to be bigger, use @code{realloc} (@pxref{Changing +Block Size}). + +@node Freeing after Malloc +@subsection Freeing Memory Allocated with @code{malloc} +@cindex freeing memory allocated with @code{malloc} +@cindex heap, freeing memory from + +When you no longer need a block that you got with @code{malloc}, use the +function @code{free} to make the block available to be allocated again. +The prototype for this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun void free (void *@var{ptr}) +The @code{free} function deallocates the block of storage pointed at +by @var{ptr}. +@end deftypefun + +@comment stdlib.h +@comment Sun +@deftypefun void cfree (void *@var{ptr}) +This function does the same thing as @code{free}. It's provided for +backward compatibility with SunOS; you should use @code{free} instead. +@end deftypefun + +Freeing a block alters the contents of the block. @strong{Do not expect to +find any data (such as a pointer to the next block in a chain of blocks) in +the block after freeing it.} Copy whatever you need out of the block before +freeing it! Here is an example of the proper way to free all the blocks in +a chain, and the strings that they point to: + +@smallexample +struct chain + @{ + struct chain *next; + char *name; + @} + +void +free_chain (struct chain *chain) +@{ + while (chain != 0) + @{ + struct chain *next = chain->next; + free (chain->name); + free (chain); + chain = next; + @} +@} +@end smallexample + +Occasionally, @code{free} can actually return memory to the operating +system and make the process smaller. Usually, all it can do is allow a +later call to @code{malloc} to reuse the space. In the meantime, the +space remains in your program as part of a free-list used internally by +@code{malloc}. + +There is no point in freeing blocks at the end of a program, because all +of the program's space is given back to the system when the process +terminates. + +@node Changing Block Size +@subsection Changing the Size of a Block +@cindex changing the size of a block (@code{malloc}) + +Often you do not know for certain how big a block you will ultimately need +at the time you must begin to use the block. For example, the block might +be a buffer that you use to hold a line being read from a file; no matter +how long you make the buffer initially, you may encounter a line that is +longer. + +You can make the block longer by calling @code{realloc}. This function +is declared in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize}) +The @code{realloc} function changes the size of the block whose address is +@var{ptr} to be @var{newsize}. + +Since the space after the end of the block may be in use, @code{realloc} +may find it necessary to copy the block to a new address where more free +space is available. The value of @code{realloc} is the new address of the +block. If the block needs to be moved, @code{realloc} copies the old +contents. + +If you pass a null pointer for @var{ptr}, @code{realloc} behaves just +like @samp{malloc (@var{newsize})}. This can be convenient, but beware +that older implementations (before ANSI C) may not support this +behavior, and will probably crash when @code{realloc} is passed a null +pointer. +@end deftypefun + +Like @code{malloc}, @code{realloc} may return a null pointer if no +memory space is available to make the block bigger. When this happens, +the original block is untouched; it has not been modified or relocated. + +In most cases it makes no difference what happens to the original block +when @code{realloc} fails, because the application program cannot continue +when it is out of memory, and the only thing to do is to give a fatal error +message. Often it is convenient to write and use a subroutine, +conventionally called @code{xrealloc}, that takes care of the error message +as @code{xmalloc} does for @code{malloc}: + +@smallexample +void * +xrealloc (void *ptr, size_t size) +@{ + register void *value = realloc (ptr, size); + if (value == 0) + fatal ("Virtual memory exhausted"); + return value; +@} +@end smallexample + +You can also use @code{realloc} to make a block smaller. The reason you +would do this is to avoid tying up a lot of memory space when only a little +is needed. Making a block smaller sometimes necessitates copying it, so it +can fail if no other space is available. + +If the new size you specify is the same as the old size, @code{realloc} +is guaranteed to change nothing and return the same address that you gave. + +@node Allocating Cleared Space +@subsection Allocating Cleared Space + +The function @code{calloc} allocates memory and clears it to zero. It +is declared in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize}) +This function allocates a block long enough to contain a vector of +@var{count} elements, each of size @var{eltsize}. Its contents are +cleared to zero before @code{calloc} returns. +@end deftypefun + +You could define @code{calloc} as follows: + +@smallexample +void * +calloc (size_t count, size_t eltsize) +@{ + size_t size = count * eltsize; + void *value = malloc (size); + if (value != 0) + memset (value, 0, size); + return value; +@} +@end smallexample + +@node Efficiency and Malloc +@subsection Efficiency Considerations for @code{malloc} +@cindex efficiency and @code{malloc} + +To make the best use of @code{malloc}, it helps to know that the GNU +version of @code{malloc} always dispenses small amounts of memory in +blocks whose sizes are powers of two. It keeps separate pools for each +power of two. This holds for sizes up to a page size. Therefore, if +you are free to choose the size of a small block in order to make +@code{malloc} more efficient, make it a power of two. +@c !!! xref getpagesize + +Once a page is split up for a particular block size, it can't be reused +for another size unless all the blocks in it are freed. In many +programs, this is unlikely to happen. Thus, you can sometimes make a +program use memory more efficiently by using blocks of the same size for +many different purposes. + +When you ask for memory blocks of a page or larger, @code{malloc} uses a +different strategy; it rounds the size up to a multiple of a page, and +it can coalesce and split blocks as needed. + +The reason for the two strategies is that it is important to allocate +and free small blocks as fast as possible, but speed is less important +for a large block since the program normally spends a fair amount of +time using it. Also, large blocks are normally fewer in number. +Therefore, for large blocks, it makes sense to use a method which takes +more time to minimize the wasted space. + +@node Aligned Memory Blocks +@subsection Allocating Aligned Memory Blocks + +@cindex page boundary +@cindex alignment (with @code{malloc}) +@pindex stdlib.h +The address of a block returned by @code{malloc} or @code{realloc} in +the GNU system is always a multiple of eight. If you need a block whose +address is a multiple of a higher power of two than that, use +@code{memalign} or @code{valloc}. These functions are declared in +@file{stdlib.h}. + +With the GNU library, you can use @code{free} to free the blocks that +@code{memalign} and @code{valloc} return. That does not work in BSD, +however---BSD does not provide any way to free such blocks. + +@comment malloc.h stdlib.h +@comment BSD +@deftypefun {void *} memalign (size_t @var{size}, size_t @var{boundary}) +The @code{memalign} function allocates a block of @var{size} bytes whose +address is a multiple of @var{boundary}. The @var{boundary} must be a +power of two! The function @code{memalign} works by calling +@code{malloc} to allocate a somewhat larger block, and then returning an +address within the block that is on the specified boundary. +@end deftypefun + +@comment malloc.h stdlib.h +@comment BSD +@deftypefun {void *} valloc (size_t @var{size}) +Using @code{valloc} is like using @code{memalign} and passing the page size +as the value of the second argument. It is implemented like this: + +@smallexample +void * +valloc (size_t size) +@{ + return memalign (size, getpagesize ()); +@} +@end smallexample +@c !!! xref getpagesize +@end deftypefun + +@node Heap Consistency Checking +@subsection Heap Consistency Checking + +@cindex heap consistency checking +@cindex consistency checking, of heap + +You can ask @code{malloc} to check the consistency of dynamic storage by +using the @code{mcheck} function. This function is a GNU extension, +declared in @file{malloc.h}. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status})) +Calling @code{mcheck} tells @code{malloc} to perform occasional +consistency checks. These will catch things such as writing +past the end of a block that was allocated with @code{malloc}. + +The @var{abortfn} argument is the function to call when an inconsistency +is found. If you supply a null pointer, then @code{mcheck} uses a +default function which prints a message and calls @code{abort} +(@pxref{Aborting a Program}). The function you supply is called with +one argument, which says what sort of inconsistency was detected; its +type is described below. + +It is too late to begin allocation checking once you have allocated +anything with @code{malloc}. So @code{mcheck} does nothing in that +case. The function returns @code{-1} if you call it too late, and +@code{0} otherwise (when it is successful). + +The easiest way to arrange to call @code{mcheck} early enough is to use +the option @samp{-lmcheck} when you link your program; then you don't +need to modify your program source at all. +@end deftypefun + +@deftypefun {enum mcheck_status} mprobe (void *@var{pointer}) +The @code{mprobe} function lets you explicitly check for inconsistencies +in a particular allocated block. You must have already called +@code{mcheck} at the beginning of the program, to do its occasional +checks; calling @code{mprobe} requests an additional consistency check +to be done at the time of the call. + +The argument @var{pointer} must be a pointer returned by @code{malloc} +or @code{realloc}. @code{mprobe} returns a value that says what +inconsistency, if any, was found. The values are described below. +@end deftypefun + +@deftp {Data Type} {enum mcheck_status} +This enumerated type describes what kind of inconsistency was detected +in an allocated block, if any. Here are the possible values: + +@table @code +@item MCHECK_DISABLED +@code{mcheck} was not called before the first allocation. +No consistency checking can be done. +@item MCHECK_OK +No inconsistency detected. +@item MCHECK_HEAD +The data immediately before the block was modified. +This commonly happens when an array index or pointer +is decremented too far. +@item MCHECK_TAIL +The data immediately after the block was modified. +This commonly happens when an array index or pointer +is incremented too far. +@item MCHECK_FREE +The block was already freed. +@end table +@end deftp + +@node Hooks for Malloc +@subsection Storage Allocation Hooks +@cindex allocation hooks, for @code{malloc} + +The GNU C library lets you modify the behavior of @code{malloc}, +@code{realloc}, and @code{free} by specifying appropriate hook +functions. You can use these hooks to help you debug programs that use +dynamic storage allocation, for example. + +The hook variables are declared in @file{malloc.h}. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@defvar __malloc_hook +The value of this variable is a pointer to function that @code{malloc} +uses whenever it is called. You should define this function to look +like @code{malloc}; that is, like: + +@smallexample +void *@var{function} (size_t @var{size}) +@end smallexample +@end defvar + +@comment malloc.h +@comment GNU +@defvar __realloc_hook +The value of this variable is a pointer to function that @code{realloc} +uses whenever it is called. You should define this function to look +like @code{realloc}; that is, like: + +@smallexample +void *@var{function} (void *@var{ptr}, size_t @var{size}) +@end smallexample +@end defvar + +@comment malloc.h +@comment GNU +@defvar __free_hook +The value of this variable is a pointer to function that @code{free} +uses whenever it is called. You should define this function to look +like @code{free}; that is, like: + +@smallexample +void @var{function} (void *@var{ptr}) +@end smallexample +@end defvar + +You must make sure that the function you install as a hook for one of +these functions does not call that function recursively without restoring +the old value of the hook first! Otherwise, your program will get stuck +in an infinite recursion. + +Here is an example showing how to use @code{__malloc_hook} properly. It +installs a function that prints out information every time @code{malloc} +is called. + +@smallexample +static void *(*old_malloc_hook) (size_t); +static void * +my_malloc_hook (size_t size) +@{ + void *result; + __malloc_hook = old_malloc_hook; + result = malloc (size); + /* @r{@code{printf} might call @code{malloc}, so protect it too.} */ + printf ("malloc (%u) returns %p\n", (unsigned int) size, result); + __malloc_hook = my_malloc_hook; + return result; +@} + +main () +@{ + ... + old_malloc_hook = __malloc_hook; + __malloc_hook = my_malloc_hook; + ... +@} +@end smallexample + +The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by +installing such hooks. + +@c __morecore, __after_morecore_hook are undocumented +@c It's not clear whether to document them. + +@node Statistics of Malloc +@subsection Statistics for Storage Allocation with @code{malloc} + +@cindex allocation statistics +You can get information about dynamic storage allocation by calling the +@code{mstats} function. This function and its associated data type are +declared in @file{malloc.h}; they are a GNU extension. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@deftp {Data Type} {struct mstats} +This structure type is used to return information about the dynamic +storage allocator. It contains the following members: + +@table @code +@item size_t bytes_total +This is the total size of memory managed by @code{malloc}, in bytes. + +@item size_t chunks_used +This is the number of chunks in use. (The storage allocator internally +gets chunks of memory from the operating system, and then carves them up +to satisfy individual @code{malloc} requests; see @ref{Efficiency and +Malloc}.) + +@item size_t bytes_used +This is the number of bytes in use. + +@item size_t chunks_free +This is the number of chunks which are free -- that is, that have been +allocated by the operating system to your program, but which are not +now being used. + +@item size_t bytes_free +This is the number of bytes which are free. +@end table +@end deftp + +@comment malloc.h +@comment GNU +@deftypefun {struct mstats} mstats (void) +This function returns information about the current dynamic memory usage +in a structure of type @code{struct mstats}. +@end deftypefun + +@node Summary of Malloc +@subsection Summary of @code{malloc}-Related Functions + +Here is a summary of the functions that work with @code{malloc}: + +@table @code +@item void *malloc (size_t @var{size}) +Allocate a block of @var{size} bytes. @xref{Basic Allocation}. + +@item void free (void *@var{addr}) +Free a block previously allocated by @code{malloc}. @xref{Freeing after +Malloc}. + +@item void *realloc (void *@var{addr}, size_t @var{size}) +Make a block previously allocated by @code{malloc} larger or smaller, +possibly by copying it to a new location. @xref{Changing Block Size}. + +@item void *calloc (size_t @var{count}, size_t @var{eltsize}) +Allocate a block of @var{count} * @var{eltsize} bytes using +@code{malloc}, and set its contents to zero. @xref{Allocating Cleared +Space}. + +@item void *valloc (size_t @var{size}) +Allocate a block of @var{size} bytes, starting on a page boundary. +@xref{Aligned Memory Blocks}. + +@item void *memalign (size_t @var{size}, size_t @var{boundary}) +Allocate a block of @var{size} bytes, starting on an address that is a +multiple of @var{boundary}. @xref{Aligned Memory Blocks}. + +@item int mcheck (void (*@var{abortfn}) (void)) +Tell @code{malloc} to perform occasional consistency checks on +dynamically allocated memory, and to call @var{abortfn} when an +inconsistency is found. @xref{Heap Consistency Checking}. + +@item void *(*__malloc_hook) (size_t @var{size}) +A pointer to a function that @code{malloc} uses whenever it is called. + +@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}) +A pointer to a function that @code{realloc} uses whenever it is called. + +@item void (*__free_hook) (void *@var{ptr}) +A pointer to a function that @code{free} uses whenever it is called. + +@item struct mstats mstats (void) +Return information about the current dynamic memory usage. +@xref{Statistics of Malloc}. +@end table + +@node Obstacks +@section Obstacks +@cindex obstacks + +An @dfn{obstack} is a pool of memory containing a stack of objects. You +can create any number of separate obstacks, and then allocate objects in +specified obstacks. Within each obstack, the last object allocated must +always be the first one freed, but distinct obstacks are independent of +each other. + +Aside from this one constraint of order of freeing, obstacks are totally +general: an obstack can contain any number of objects of any size. They +are implemented with macros, so allocation is usually very fast as long as +the objects are usually small. And the only space overhead per object is +the padding needed to start each object on a suitable boundary. + +@menu +* Creating Obstacks:: How to declare an obstack in your program. +* Preparing for Obstacks:: Preparations needed before you can + use obstacks. +* Allocation in an Obstack:: Allocating objects in an obstack. +* Freeing Obstack Objects:: Freeing objects in an obstack. +* Obstack Functions:: The obstack functions are both + functions and macros. +* Growing Objects:: Making an object bigger by stages. +* Extra Fast Growing:: Extra-high-efficiency (though more + complicated) growing objects. +* Status of an Obstack:: Inquiries about the status of an obstack. +* Obstacks Data Alignment:: Controlling alignment of objects in obstacks. +* Obstack Chunks:: How obstacks obtain and release chunks; + efficiency considerations. +* Summary of Obstacks:: +@end menu + +@node Creating Obstacks +@subsection Creating Obstacks + +The utilities for manipulating obstacks are declared in the header +file @file{obstack.h}. +@pindex obstack.h + +@comment obstack.h +@comment GNU +@deftp {Data Type} {struct obstack} +An obstack is represented by a data structure of type @code{struct +obstack}. This structure has a small fixed size; it records the status +of the obstack and how to find the space in which objects are allocated. +It does not contain any of the objects themselves. You should not try +to access the contents of the structure directly; use only the functions +described in this chapter. +@end deftp + +You can declare variables of type @code{struct obstack} and use them as +obstacks, or you can allocate obstacks dynamically like any other kind +of object. Dynamic allocation of obstacks allows your program to have a +variable number of different stacks. (You can even allocate an +obstack structure in another obstack, but this is rarely useful.) + +All the functions that work with obstacks require you to specify which +obstack to use. You do this with a pointer of type @code{struct obstack +*}. In the following, we often say ``an obstack'' when strictly +speaking the object at hand is such a pointer. + +The objects in the obstack are packed into large blocks called +@dfn{chunks}. The @code{struct obstack} structure points to a chain of +the chunks currently in use. + +The obstack library obtains a new chunk whenever you allocate an object +that won't fit in the previous chunk. Since the obstack library manages +chunks automatically, you don't need to pay much attention to them, but +you do need to supply a function which the obstack library should use to +get a chunk. Usually you supply a function which uses @code{malloc} +directly or indirectly. You must also supply a function to free a chunk. +These matters are described in the following section. + +@node Preparing for Obstacks +@subsection Preparing for Using Obstacks + +Each source file in which you plan to use the obstack functions +must include the header file @file{obstack.h}, like this: + +@smallexample +#include <obstack.h> +@end smallexample + +@findex obstack_chunk_alloc +@findex obstack_chunk_free +Also, if the source file uses the macro @code{obstack_init}, it must +declare or define two functions or macros that will be called by the +obstack library. One, @code{obstack_chunk_alloc}, is used to allocate +the chunks of memory into which objects are packed. The other, +@code{obstack_chunk_free}, is used to return chunks when the objects in +them are freed. These macros should appear before any use of obstacks +in the source file. + +Usually these are defined to use @code{malloc} via the intermediary +@code{xmalloc} (@pxref{Unconstrained Allocation}). This is done with +the following pair of macro definitions: + +@smallexample +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free +@end smallexample + +@noindent +Though the storage you get using obstacks really comes from @code{malloc}, +using obstacks is faster because @code{malloc} is called less often, for +larger blocks of memory. @xref{Obstack Chunks}, for full details. + +At run time, before the program can use a @code{struct obstack} object +as an obstack, it must initialize the obstack by calling +@code{obstack_init}. + +@comment obstack.h +@comment GNU +@deftypefun int obstack_init (struct obstack *@var{obstack-ptr}) +Initialize obstack @var{obstack-ptr} for allocation of objects. This +function calls the obstack's @code{obstack_chunk_alloc} function. It +returns 0 if @code{obstack_chunk_alloc} returns a null pointer, meaning +that it is out of memory. Otherwise, it returns 1. If you supply an +@code{obstack_chunk_alloc} function that calls @code{exit} +(@pxref{Program Termination}) or @code{longjmp} (@pxref{Non-Local +Exits}) when out of memory, you can safely ignore the value that +@code{obstack_init} returns. +@end deftypefun + +Here are two examples of how to allocate the space for an obstack and +initialize it. First, an obstack that is a static variable: + +@smallexample +static struct obstack myobstack; +@dots{} +obstack_init (&myobstack); +@end smallexample + +@noindent +Second, an obstack that is itself dynamically allocated: + +@smallexample +struct obstack *myobstack_ptr + = (struct obstack *) xmalloc (sizeof (struct obstack)); + +obstack_init (myobstack_ptr); +@end smallexample + +@node Allocation in an Obstack +@subsection Allocation in an Obstack +@cindex allocation (obstacks) + +The most direct way to allocate an object in an obstack is with +@code{obstack_alloc}, which is invoked almost like @code{malloc}. + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size}) +This allocates an uninitialized block of @var{size} bytes in an obstack +and returns its address. Here @var{obstack-ptr} specifies which obstack +to allocate the block in; it is the address of the @code{struct obstack} +object which represents the obstack. Each obstack function or macro +requires you to specify an @var{obstack-ptr} as the first argument. + +This function calls the obstack's @code{obstack_chunk_alloc} function if +it needs to allocate a new chunk of memory; it returns a null pointer if +@code{obstack_chunk_alloc} returns one. In that case, it has not +changed the amount of memory allocated in the obstack. If you supply an +@code{obstack_chunk_alloc} function that calls @code{exit} +(@pxref{Program Termination}) or @code{longjmp} (@pxref{Non-Local +Exits}) when out of memory, then @code{obstack_alloc} will never return +a null pointer. +@end deftypefun + +For example, here is a function that allocates a copy of a string @var{str} +in a specific obstack, which is in the variable @code{string_obstack}: + +@smallexample +struct obstack string_obstack; + +char * +copystring (char *string) +@{ + char *s = (char *) obstack_alloc (&string_obstack, + strlen (string) + 1); + memcpy (s, string, strlen (string)); + return s; +@} +@end smallexample + +To allocate a block with specified contents, use the function +@code{obstack_copy}, declared like this: + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +This allocates a block and initializes it by copying @var{size} +bytes of data starting at @var{address}. It can return a null pointer +under the same conditions as @code{obstack_alloc}. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +Like @code{obstack_copy}, but appends an extra byte containing a null +character. This extra byte is not counted in the argument @var{size}. +@end deftypefun + +The @code{obstack_copy0} function is convenient for copying a sequence +of characters into an obstack as a null-terminated string. Here is an +example of its use: + +@smallexample +char * +obstack_savestring (char *addr, int size) +@{ + return obstack_copy0 (&myobstack, addr, size); +@} +@end smallexample + +@noindent +Contrast this with the previous example of @code{savestring} using +@code{malloc} (@pxref{Basic Allocation}). + +@node Freeing Obstack Objects +@subsection Freeing Objects in an Obstack +@cindex freeing (obstacks) + +To free an object allocated in an obstack, use the function +@code{obstack_free}. Since the obstack is a stack of objects, freeing +one object automatically frees all other objects allocated more recently +in the same obstack. + +@comment obstack.h +@comment GNU +@deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object}) +If @var{object} is a null pointer, everything allocated in the obstack +is freed. Otherwise, @var{object} must be the address of an object +allocated in the obstack. Then @var{object} is freed, along with +everything allocated in @var{obstack} since @var{object}. +@end deftypefun + +Note that if @var{object} is a null pointer, the result is an +uninitialized obstack. To free all storage in an obstack but leave it +valid for further allocation, call @code{obstack_free} with the address +of the first object allocated on the obstack: + +@smallexample +obstack_free (obstack_ptr, first_object_allocated_ptr); +@end smallexample + +Recall that the objects in an obstack are grouped into chunks. When all +the objects in a chunk become free, the obstack library automatically +frees the chunk (@pxref{Preparing for Obstacks}). Then other +obstacks, or non-obstack allocation, can reuse the space of the chunk. + +@node Obstack Functions +@subsection Obstack Functions and Macros +@cindex macros + +The interfaces for using obstacks may be defined either as functions or +as macros, depending on the compiler. The obstack facility works with +all C compilers, including both ANSI C and traditional C, but there are +precautions you must take if you plan to use compilers other than GNU C. + +If you are using an old-fashioned non-ANSI C compiler, all the obstack +``functions'' are actually defined only as macros. You can call these +macros like functions, but you cannot use them in any other way (for +example, you cannot take their address). + +Calling the macros requires a special precaution: namely, the first +operand (the obstack pointer) may not contain any side effects, because +it may be computed more than once. For example, if you write this: + +@smallexample +obstack_alloc (get_obstack (), 4); +@end smallexample + +@noindent +you will find that @code{get_obstack} may be called several times. +If you use @code{*obstack_list_ptr++} as the obstack pointer argument, +you will get very strange results since the incrementation may occur +several times. + +In ANSI C, each function has both a macro definition and a function +definition. The function definition is used if you take the address of the +function without calling it. An ordinary call uses the macro definition by +default, but you can request the function definition instead by writing the +function name in parentheses, as shown here: + +@smallexample +char *x; +void *(*funcp) (); +/* @r{Use the macro}. */ +x = (char *) obstack_alloc (obptr, size); +/* @r{Call the function}. */ +x = (char *) (obstack_alloc) (obptr, size); +/* @r{Take the address of the function}. */ +funcp = obstack_alloc; +@end smallexample + +@noindent +This is the same situation that exists in ANSI C for the standard library +functions. @xref{Macro Definitions}. + +@strong{Warning:} When you do use the macros, you must observe the +precaution of avoiding side effects in the first operand, even in ANSI +C. + +If you use the GNU C compiler, this precaution is not necessary, because +various language extensions in GNU C permit defining the macros so as to +compute each argument only once. + +@node Growing Objects +@subsection Growing Objects +@cindex growing objects (in obstacks) +@cindex changing the size of a block (obstacks) + +Because storage in obstack chunks is used sequentially, it is possible to +build up an object step by step, adding one or more bytes at a time to the +end of the object. With this technique, you do not need to know how much +data you will put in the object until you come to the end of it. We call +this the technique of @dfn{growing objects}. The special functions +for adding data to the growing object are described in this section. + +You don't need to do anything special when you start to grow an object. +Using one of the functions to add data to the object automatically +starts it. However, it is necessary to say explicitly when the object is +finished. This is done with the function @code{obstack_finish}. + +The actual address of the object thus built up is not known until the +object is finished. Until then, it always remains possible that you will +add so much data that the object must be copied into a new chunk. + +While the obstack is in use for a growing object, you cannot use it for +ordinary allocation of another object. If you try to do so, the space +already added to the growing object will become part of the other object. + +@comment obstack.h +@comment GNU +@deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size}) +The most basic function for adding to a growing object is +@code{obstack_blank}, which adds space without initializing it. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) +To add a block of initialized space, use @code{obstack_grow}, which is +the growing-object analogue of @code{obstack_copy}. It adds @var{size} +bytes of data to the growing object, copying the contents from +@var{data}. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) +This is the growing-object analogue of @code{obstack_copy0}. It adds +@var{size} bytes copied from @var{data}, followed by an additional null +character. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c}) +To add one character at a time, use the function @code{obstack_1grow}. +It adds a single byte containing @var{c} to the growing object. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr}) +When you are finished growing the object, use the function +@code{obstack_finish} to close it off and return its final address. + +Once you have finished the object, the obstack is available for ordinary +allocation or for growing another object. + +This function can return a null pointer under the same conditions as +@code{obstack_alloc} (@pxref{Allocation in an Obstack}). +@end deftypefun + +When you build an object by growing it, you will probably need to know +afterward how long it became. You need not keep track of this as you grow +the object, because you can find out the length from the obstack just +before finishing the object with the function @code{obstack_object_size}, +declared as follows: + +@comment obstack.h +@comment GNU +@deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) +This function returns the current size of the growing object, in bytes. +Remember to call this function @emph{before} finishing the object. +After it is finished, @code{obstack_object_size} will return zero. +@end deftypefun + +If you have started growing an object and wish to cancel it, you should +finish it and then free it, like this: + +@smallexample +obstack_free (obstack_ptr, obstack_finish (obstack_ptr)); +@end smallexample + +@noindent +This has no effect if no object was growing. + +@cindex shrinking objects +You can use @code{obstack_blank} with a negative size argument to make +the current object smaller. Just don't try to shrink it beyond zero +length---there's no telling what will happen if you do that. + +@node Extra Fast Growing +@subsection Extra Fast Growing Objects +@cindex efficiency and obstacks + +The usual functions for growing objects incur overhead for checking +whether there is room for the new growth in the current chunk. If you +are frequently constructing objects in small steps of growth, this +overhead can be significant. + +You can reduce the overhead by using special ``fast growth'' +functions that grow the object without checking. In order to have a +robust program, you must do the checking yourself. If you do this checking +in the simplest way each time you are about to add data to the object, you +have not saved anything, because that is what the ordinary growth +functions do. But if you can arrange to check less often, or check +more efficiently, then you make the program faster. + +The function @code{obstack_room} returns the amount of room available +in the current chunk. It is declared as follows: + +@comment obstack.h +@comment GNU +@deftypefun int obstack_room (struct obstack *@var{obstack-ptr}) +This returns the number of bytes that can be added safely to the current +growing object (or to an object about to be started) in obstack +@var{obstack} using the fast growth functions. +@end deftypefun + +While you know there is room, you can use these fast growth functions +for adding data to a growing object: + +@comment obstack.h +@comment GNU +@deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c}) +The function @code{obstack_1grow_fast} adds one byte containing the +character @var{c} to the growing object in obstack @var{obstack-ptr}. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size}) +The function @code{obstack_blank_fast} adds @var{size} bytes to the +growing object in obstack @var{obstack-ptr} without initializing them. +@end deftypefun + +When you check for space using @code{obstack_room} and there is not +enough room for what you want to add, the fast growth functions +are not safe. In this case, simply use the corresponding ordinary +growth function instead. Very soon this will copy the object to a +new chunk; then there will be lots of room available again. + +So, each time you use an ordinary growth function, check afterward for +sufficient space using @code{obstack_room}. Once the object is copied +to a new chunk, there will be plenty of space again, so the program will +start using the fast growth functions again. + +Here is an example: + +@smallexample +@group +void +add_string (struct obstack *obstack, const char *ptr, int len) +@{ + while (len > 0) + @{ + int room = obstack_room (obstack); + if (room == 0) + @{ + /* @r{Not enough room. Add one character slowly,} + @r{which may copy to a new chunk and make room.} */ + obstack_1grow (obstack, *ptr++); + len--; + @} + else + @{ + if (room > len) + room = len; + /* @r{Add fast as much as we have room for.} */ + len -= room; + while (room-- > 0) + obstack_1grow_fast (obstack, *ptr++); + @} + @} +@} +@end group +@end smallexample + +@node Status of an Obstack +@subsection Status of an Obstack +@cindex obstack status +@cindex status of obstack + +Here are functions that provide information on the current status of +allocation in an obstack. You can use them to learn about an object while +still growing it. + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr}) +This function returns the tentative address of the beginning of the +currently growing object in @var{obstack-ptr}. If you finish the object +immediately, it will have that address. If you make it larger first, it +may outgrow the current chunk---then its address will change! + +If no object is growing, this value says where the next object you +allocate will start (once again assuming it fits in the current +chunk). +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr}) +This function returns the address of the first free byte in the current +chunk of obstack @var{obstack-ptr}. This is the end of the currently +growing object. If no object is growing, @code{obstack_next_free} +returns the same value as @code{obstack_base}. +@end deftypefun + +@comment obstack.h +@comment GNU +@deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) +This function returns the size in bytes of the currently growing object. +This is equivalent to + +@smallexample +obstack_next_free (@var{obstack-ptr}) - obstack_base (@var{obstack-ptr}) +@end smallexample +@end deftypefun + +@node Obstacks Data Alignment +@subsection Alignment of Data in Obstacks +@cindex alignment (in obstacks) + +Each obstack has an @dfn{alignment boundary}; each object allocated in +the obstack automatically starts on an address that is a multiple of the +specified boundary. By default, this boundary is 4 bytes. + +To access an obstack's alignment boundary, use the macro +@code{obstack_alignment_mask}, whose function prototype looks like +this: + +@comment obstack.h +@comment GNU +@deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr}) +The value is a bit mask; a bit that is 1 indicates that the corresponding +bit in the address of an object should be 0. The mask value should be one +less than a power of 2; the effect is that all object addresses are +multiples of that power of 2. The default value of the mask is 3, so that +addresses are multiples of 4. A mask value of 0 means an object can start +on any multiple of 1 (that is, no alignment is required). + +The expansion of the macro @code{obstack_alignment_mask} is an lvalue, +so you can alter the mask by assignment. For example, this statement: + +@smallexample +obstack_alignment_mask (obstack_ptr) = 0; +@end smallexample + +@noindent +has the effect of turning off alignment processing in the specified obstack. +@end deftypefn + +Note that a change in alignment mask does not take effect until +@emph{after} the next time an object is allocated or finished in the +obstack. If you are not growing an object, you can make the new +alignment mask take effect immediately by calling @code{obstack_finish}. +This will finish a zero-length object and then do proper alignment for +the next object. + +@node Obstack Chunks +@subsection Obstack Chunks +@cindex efficiency of chunks +@cindex chunks + +Obstacks work by allocating space for themselves in large chunks, and +then parceling out space in the chunks to satisfy your requests. Chunks +are normally 4096 bytes long unless you specify a different chunk size. +The chunk size includes 8 bytes of overhead that are not actually used +for storing objects. Regardless of the specified size, longer chunks +will be allocated when necessary for long objects. + +The obstack library allocates chunks by calling the function +@code{obstack_chunk_alloc}, which you must define. When a chunk is no +longer needed because you have freed all the objects in it, the obstack +library frees the chunk by calling @code{obstack_chunk_free}, which you +must also define. + +These two must be defined (as macros) or declared (as functions) in each +source file that uses @code{obstack_init} (@pxref{Creating Obstacks}). +Most often they are defined as macros like this: + +@smallexample +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free +@end smallexample + +Note that these are simple macros (no arguments). Macro definitions with +arguments will not work! It is necessary that @code{obstack_chunk_alloc} +or @code{obstack_chunk_free}, alone, expand into a function name if it is +not itself a function name. + +If you allocate chunks with @code{malloc}, the chunk size should be a +power of 2. The default chunk size, 4096, was chosen because it is long +enough to satisfy many typical requests on the obstack yet short enough +not to waste too much memory in the portion of the last chunk not yet used. + +@comment obstack.h +@comment GNU +@deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr}) +This returns the chunk size of the given obstack. +@end deftypefn + +Since this macro expands to an lvalue, you can specify a new chunk size by +assigning it a new value. Doing so does not affect the chunks already +allocated, but will change the size of chunks allocated for that particular +obstack in the future. It is unlikely to be useful to make the chunk size +smaller, but making it larger might improve efficiency if you are +allocating many objects whose size is comparable to the chunk size. Here +is how to do so cleanly: + +@smallexample +if (obstack_chunk_size (obstack_ptr) < @var{new-chunk-size}) + obstack_chunk_size (obstack_ptr) = @var{new-chunk-size}; +@end smallexample + +@node Summary of Obstacks +@subsection Summary of Obstack Functions + +Here is a summary of all the functions associated with obstacks. Each +takes the address of an obstack (@code{struct obstack *}) as its first +argument. + +@table @code +@item void obstack_init (struct obstack *@var{obstack-ptr}) +Initialize use of an obstack. @xref{Creating Obstacks}. + +@item void *obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size}) +Allocate an object of @var{size} uninitialized bytes. +@xref{Allocation in an Obstack}. + +@item void *obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +Allocate an object of @var{size} bytes, with contents copied from +@var{address}. @xref{Allocation in an Obstack}. + +@item void *obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +Allocate an object of @var{size}+1 bytes, with @var{size} of them copied +from @var{address}, followed by a null character at the end. +@xref{Allocation in an Obstack}. + +@item void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object}) +Free @var{object} (and everything allocated in the specified obstack +more recently than @var{object}). @xref{Freeing Obstack Objects}. + +@item void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size}) +Add @var{size} uninitialized bytes to a growing object. +@xref{Growing Objects}. + +@item void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +Add @var{size} bytes, copied from @var{address}, to a growing object. +@xref{Growing Objects}. + +@item void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) +Add @var{size} bytes, copied from @var{address}, to a growing object, +and then add another byte containing a null character. @xref{Growing +Objects}. + +@item void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{data-char}) +Add one byte containing @var{data-char} to a growing object. +@xref{Growing Objects}. + +@item void *obstack_finish (struct obstack *@var{obstack-ptr}) +Finalize the object that is growing and return its permanent address. +@xref{Growing Objects}. + +@item int obstack_object_size (struct obstack *@var{obstack-ptr}) +Get the current size of the currently growing object. @xref{Growing +Objects}. + +@item void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size}) +Add @var{size} uninitialized bytes to a growing object without checking +that there is enough room. @xref{Extra Fast Growing}. + +@item void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{data-char}) +Add one byte containing @var{data-char} to a growing object without +checking that there is enough room. @xref{Extra Fast Growing}. + +@item int obstack_room (struct obstack *@var{obstack-ptr}) +Get the amount of room now available for growing the current object. +@xref{Extra Fast Growing}. + +@item int obstack_alignment_mask (struct obstack *@var{obstack-ptr}) +The mask used for aligning the beginning of an object. This is an +lvalue. @xref{Obstacks Data Alignment}. + +@item int obstack_chunk_size (struct obstack *@var{obstack-ptr}) +The size for allocating chunks. This is an lvalue. @xref{Obstack Chunks}. + +@item void *obstack_base (struct obstack *@var{obstack-ptr}) +Tentative starting address of the currently growing object. +@xref{Status of an Obstack}. + +@item void *obstack_next_free (struct obstack *@var{obstack-ptr}) +Address just after the end of the currently growing object. +@xref{Status of an Obstack}. +@end table + +@node Variable Size Automatic +@section Automatic Storage with Variable Size +@cindex automatic freeing +@cindex @code{alloca} function +@cindex automatic storage with variable size + +The function @code{alloca} supports a kind of half-dynamic allocation in +which blocks are allocated dynamically but freed automatically. + +Allocating a block with @code{alloca} is an explicit action; you can +allocate as many blocks as you wish, and compute the size at run time. But +all the blocks are freed when you exit the function that @code{alloca} was +called from, just as if they were automatic variables declared in that +function. There is no way to free the space explicitly. + +The prototype for @code{alloca} is in @file{stdlib.h}. This function is +a BSD extension. +@pindex stdlib.h + +@comment stdlib.h +@comment GNU, BSD +@deftypefun {void *} alloca (size_t @var{size}); +The return value of @code{alloca} is the address of a block of @var{size} +bytes of storage, allocated in the stack frame of the calling function. +@end deftypefun + +Do not use @code{alloca} inside the arguments of a function call---you +will get unpredictable results, because the stack space for the +@code{alloca} would appear on the stack in the middle of the space for +the function arguments. An example of what to avoid is @code{foo (x, +alloca (4), y)}. +@c This might get fixed in future versions of GCC, but that won't make +@c it safe with compilers generally. + +@menu +* Alloca Example:: Example of using @code{alloca}. +* Advantages of Alloca:: Reasons to use @code{alloca}. +* Disadvantages of Alloca:: Reasons to avoid @code{alloca}. +* GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative + method of allocating dynamically and + freeing automatically. +@end menu + +@node Alloca Example +@subsection @code{alloca} Example + +As an example of use of @code{alloca}, here is a function that opens a file +name made from concatenating two argument strings, and returns a file +descriptor or minus one signifying failure: + +@smallexample +int +open2 (char *str1, char *str2, int flags, int mode) +@{ + char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1); + strcpy (name, str1); + strcat (name, str2); + return open (name, flags, mode); +@} +@end smallexample + +@noindent +Here is how you would get the same results with @code{malloc} and +@code{free}: + +@smallexample +int +open2 (char *str1, char *str2, int flags, int mode) +@{ + char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1); + int desc; + if (name == 0) + fatal ("virtual memory exceeded"); + strcpy (name, str1); + strcat (name, str2); + desc = open (name, flags, mode); + free (name); + return desc; +@} +@end smallexample + +As you can see, it is simpler with @code{alloca}. But @code{alloca} has +other, more important advantages, and some disadvantages. + +@node Advantages of Alloca +@subsection Advantages of @code{alloca} + +Here are the reasons why @code{alloca} may be preferable to @code{malloc}: + +@itemize @bullet +@item +Using @code{alloca} wastes very little space and is very fast. (It is +open-coded by the GNU C compiler.) + +@item +Since @code{alloca} does not have separate pools for different sizes of +block, space used for any size block can be reused for any other size. +@code{alloca} does not cause storage fragmentation. + +@item +@cindex longjmp +Nonlocal exits done with @code{longjmp} (@pxref{Non-Local Exits}) +automatically free the space allocated with @code{alloca} when they exit +through the function that called @code{alloca}. This is the most +important reason to use @code{alloca}. + +To illustrate this, suppose you have a function +@code{open_or_report_error} which returns a descriptor, like +@code{open}, if it succeeds, but does not return to its caller if it +fails. If the file cannot be opened, it prints an error message and +jumps out to the command level of your program using @code{longjmp}. +Let's change @code{open2} (@pxref{Alloca Example}) to use this +subroutine:@refill + +@smallexample +int +open2 (char *str1, char *str2, int flags, int mode) +@{ + char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1); + strcpy (name, str1); + strcat (name, str2); + return open_or_report_error (name, flags, mode); +@} +@end smallexample + +@noindent +Because of the way @code{alloca} works, the storage it allocates is +freed even when an error occurs, with no special effort required. + +By contrast, the previous definition of @code{open2} (which uses +@code{malloc} and @code{free}) would develop a storage leak if it were +changed in this way. Even if you are willing to make more changes to +fix it, there is no easy way to do so. +@end itemize + +@node Disadvantages of Alloca +@subsection Disadvantages of @code{alloca} + +@cindex @code{alloca} disadvantages +@cindex disadvantages of @code{alloca} +These are the disadvantages of @code{alloca} in comparison with +@code{malloc}: + +@itemize @bullet +@item +If you try to allocate more storage than the machine can provide, you +don't get a clean error message. Instead you get a fatal signal like +the one you would get from an infinite recursion; probably a +segmentation violation (@pxref{Program Error Signals}). + +@item +Some non-GNU systems fail to support @code{alloca}, so it is less +portable. However, a slower emulation of @code{alloca} written in C +is available for use on systems with this deficiency. +@end itemize + +@node GNU C Variable-Size Arrays +@subsection GNU C Variable-Size Arrays +@cindex variable-sized arrays + +In GNU C, you can replace most uses of @code{alloca} with an array of +variable size. Here is how @code{open2} would look then: + +@smallexample +int open2 (char *str1, char *str2, int flags, int mode) +@{ + char name[strlen (str1) + strlen (str2) + 1]; + strcpy (name, str1); + strcat (name, str2); + return open (name, flags, mode); +@} +@end smallexample + +But @code{alloca} is not always equivalent to a variable-sized array, for +several reasons: + +@itemize @bullet +@item +A variable size array's space is freed at the end of the scope of the +name of the array. The space allocated with @code{alloca} +remains until the end of the function. + +@item +It is possible to use @code{alloca} within a loop, allocating an +additional block on each iteration. This is impossible with +variable-sized arrays. +@end itemize + +@strong{Note:} If you mix use of @code{alloca} and variable-sized arrays +within one function, exiting a scope in which a variable-sized array was +declared frees all blocks allocated with @code{alloca} during the +execution of that scope. + + +@node Relocating Allocator +@section Relocating Allocator + +@cindex relocating memory allocator +Any system of dynamic memory allocation has overhead: the amount of +space it uses is more than the amount the program asks for. The +@dfn{relocating memory allocator} achieves very low overhead by moving +blocks in memory as necessary, on its own initiative. + +@menu +* Relocator Concepts:: How to understand relocating allocation. +* Using Relocator:: Functions for relocating allocation. +@end menu + +@node Relocator Concepts +@subsection Concepts of Relocating Allocation + +@ifinfo +The @dfn{relocating memory allocator} achieves very low overhead by +moving blocks in memory as necessary, on its own initiative. +@end ifinfo + +When you allocate a block with @code{malloc}, the address of the block +never changes unless you use @code{realloc} to change its size. Thus, +you can safely store the address in various places, temporarily or +permanently, as you like. This is not safe when you use the relocating +memory allocator, because any and all relocatable blocks can move +whenever you allocate memory in any fashion. Even calling @code{malloc} +or @code{realloc} can move the relocatable blocks. + +@cindex handle +For each relocatable block, you must make a @dfn{handle}---a pointer +object in memory, designated to store the address of that block. The +relocating allocator knows where each block's handle is, and updates the +address stored there whenever it moves the block, so that the handle +always points to the block. Each time you access the contents of the +block, you should fetch its address anew from the handle. + +To call any of the relocating allocator functions from a signal handler +is almost certainly incorrect, because the signal could happen at any +time and relocate all the blocks. The only way to make this safe is to +block the signal around any access to the contents of any relocatable +block---not a convenient mode of operation. @xref{Nonreentrancy}. + +@node Using Relocator +@subsection Allocating and Freeing Relocatable Blocks + +@pindex malloc.h +In the descriptions below, @var{handleptr} designates the address of the +handle. All the functions are declared in @file{malloc.h}; all are GNU +extensions. + +@comment malloc.h +@comment GNU +@deftypefun {void *} r_alloc (void **@var{handleptr}, size_t @var{size}) +This function allocates a relocatable block of size @var{size}. It +stores the block's address in @code{*@var{handleptr}} and returns +a non-null pointer to indicate success. + +If @code{r_alloc} can't get the space needed, it stores a null pointer +in @code{*@var{handleptr}}, and returns a null pointer. +@end deftypefun + +@comment malloc.h +@comment GNU +@deftypefun void r_alloc_free (void **@var{handleptr}) +This function is the way to free a relocatable block. It frees the +block that @code{*@var{handleptr}} points to, and stores a null pointer +in @code{*@var{handleptr}} to show it doesn't point to an allocated +block any more. +@end deftypefun + +@comment malloc.h +@comment GNU +@deftypefun {void *} r_re_alloc (void **@var{handleptr}, size_t @var{size}) +The function @code{r_re_alloc} adjusts the size of the block that +@code{*@var{handleptr}} points to, making it @var{size} bytes long. It +stores the address of the resized block in @code{*@var{handleptr}} and +returns a non-null pointer to indicate success. + +If enough memory is not available, this function returns a null pointer +and does not modify @code{*@var{handleptr}}. +@end deftypefun + +@node Memory Warnings +@section Memory Usage Warnings +@cindex memory usage warnings +@cindex warnings of memory almost full + +@pindex malloc.c +You can ask for warnings as the program approaches running out of memory +space, by calling @code{memory_warnings}. This tells @code{malloc} to +check memory usage every time it asks for more memory from the operating +system. This is a GNU extension declared in @file{malloc.h}. + +@comment malloc.h +@comment GNU +@deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *)) +Call this function to request warnings for nearing exhaustion of virtual +memory. + +The argument @var{start} says where data space begins, in memory. The +allocator compares this against the last address used and against the +limit of data space, to determine the fraction of available memory in +use. If you supply zero for @var{start}, then a default value is used +which is right in most circumstances. + +For @var{warn-func}, supply a function that @code{malloc} can call to +warn you. It is called with a string (a warning message) as argument. +Normally it ought to display the string for the user to read. +@end deftypefun + +The warnings come when memory becomes 75% full, when it becomes 85% +full, and when it becomes 95% full. Above 95% you get another warning +each time memory usage increases. + diff --git a/manual/pattern.texi b/manual/pattern.texi new file mode 100644 index 0000000000..903aa48073 --- /dev/null +++ b/manual/pattern.texi @@ -0,0 +1,1189 @@ +@node Pattern Matching, I/O Overview, Searching and Sorting, Top +@chapter Pattern Matching + +The GNU C Library provides pattern matching facilities for two kinds of +patterns: regular expressions and file-name wildcards. The library also +provides a facility for expanding variable and command references and +parsing text into words in the way the shell does. + +@menu +* Wildcard Matching:: Matching a wildcard pattern against a single string. +* Globbing:: Finding the files that match a wildcard pattern. +* Regular Expressions:: Matching regular expressions against strings. +* Word Expansion:: Expanding shell variables, nested commands, + arithmetic, and wildcards. + This is what the shell does with shell commands. +@end menu + +@node Wildcard Matching +@section Wildcard Matching + +@pindex fnmatch.h +This section describes how to match a wildcard pattern against a +particular string. The result is a yes or no answer: does the +string fit the pattern or not. The symbols described here are all +declared in @file{fnmatch.h}. + +@comment fnmatch.h +@comment POSIX.2 +@deftypefun int fnmatch (const char *@var{pattern}, const char *@var{string}, int @var{flags}) +This function tests whether the string @var{string} matches the pattern +@var{pattern}. It returns @code{0} if they do match; otherwise, it +returns the nonzero value @code{FNM_NOMATCH}. The arguments +@var{pattern} and @var{string} are both strings. + +The argument @var{flags} is a combination of flag bits that alter the +details of matching. See below for a list of the defined flags. + +In the GNU C Library, @code{fnmatch} cannot experience an ``error''---it +always returns an answer for whether the match succeeds. However, other +implementations of @code{fnmatch} might sometimes report ``errors''. +They would do so by returning nonzero values that are not equal to +@code{FNM_NOMATCH}. +@end deftypefun + +These are the available flags for the @var{flags} argument: + +@table @code +@comment fnmatch.h +@comment GNU +@item FNM_FILE_NAME +Treat the @samp{/} character specially, for matching file names. If +this flag is set, wildcard constructs in @var{pattern} cannot match +@samp{/} in @var{string}. Thus, the only way to match @samp{/} is with +an explicit @samp{/} in @var{pattern}. + +@comment fnmatch.h +@comment POSIX.2 +@item FNM_PATHNAME +This is an alias for @code{FNM_FILE_NAME}; it comes from POSIX.2. We +don't recommend this name because we don't use the term ``pathname'' for +file names. + +@comment fnmatch.h +@comment POSIX.2 +@item FNM_PERIOD +Treat the @samp{.} character specially if it appears at the beginning of +@var{string}. If this flag is set, wildcard constructs in @var{pattern} +cannot match @samp{.} as the first character of @var{string}. + +If you set both @code{FNM_PERIOD} and @code{FNM_FILE_NAME}, then the +special treatment applies to @samp{.} following @samp{/} as well as to +@samp{.} at the beginning of @var{string}. (The shell uses the +@code{FNM_PERIOD} and @code{FNM_FILE_NAME} falgs together for matching +file names.) + +@comment fnmatch.h +@comment POSIX.2 +@item FNM_NOESCAPE +Don't treat the @samp{\} character specially in patterns. Normally, +@samp{\} quotes the following character, turning off its special meaning +(if any) so that it matches only itself. When quoting is enabled, the +pattern @samp{\?} matches only the string @samp{?}, because the question +mark in the pattern acts like an ordinary character. + +If you use @code{FNM_NOESCAPE}, then @samp{\} is an ordinary character. + +@comment fnmatch.h +@comment GNU +@item FNM_LEADING_DIR +Ignore a trailing sequence of characters starting with a @samp{/} in +@var{string}; that is to say, test whether @var{string} starts with a +directory name that @var{pattern} matches. + +If this flag is set, either @samp{foo*} or @samp{foobar} as a pattern +would match the string @samp{foobar/frobozz}. + +@comment fnmatch.h +@comment GNU +@item FNM_CASEFOLD +Ignore case in comparing @var{string} to @var{pattern}. +@end table + +@node Globbing +@section Globbing + +@cindex globbing +The archetypal use of wildcards is for matching against the files in a +directory, and making a list of all the matches. This is called +@dfn{globbing}. + +You could do this using @code{fnmatch}, by reading the directory entries +one by one and testing each one with @code{fnmatch}. But that would be +slow (and complex, since you would have to handle subdirectories by +hand). + +The library provides a function @code{glob} to make this particular use +of wildcards convenient. @code{glob} and the other symbols in this +section are declared in @file{glob.h}. + +@menu +* Calling Glob:: Basic use of @code{glob}. +* Flags for Globbing:: Flags that enable various options in @code{glob}. +@end menu + +@node Calling Glob +@subsection Calling @code{glob} + +The result of globbing is a vector of file names (strings). To return +this vector, @code{glob} uses a special data type, @code{glob_t}, which +is a structure. You pass @code{glob} the address of the structure, and +it fills in the structure's fields to tell you about the results. + +@comment glob.h +@comment POSIX.2 +@deftp {Data Type} glob_t +This data type holds a pointer to a word vector. More precisely, it +records both the address of the word vector and its size. + +@table @code +@item gl_pathc +The number of elements in the vector. + +@item gl_pathv +The address of the vector. This field has type @w{@code{char **}}. + +@item gl_offs +The offset of the first real element of the vector, from its nominal +address in the @code{gl_pathv} field. Unlike the other fields, this +is always an input to @code{glob}, rather than an output from it. + +If you use a nonzero offset, then that many elements at the beginning of +the vector are left empty. (The @code{glob} function fills them with +null pointers.) + +The @code{gl_offs} field is meaningful only if you use the +@code{GLOB_DOOFFS} flag. Otherwise, the offset is always zero +regardless of what is in this field, and the first real element comes at +the beginning of the vector. +@end table +@end deftp + +@comment glob.h +@comment POSIX.2 +@deftypefun int glob (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob_t *@var{vector-ptr}) +The function @code{glob} does globbing using the pattern @var{pattern} +in the current directory. It puts the result in a newly allocated +vector, and stores the size and address of this vector into +@code{*@var{vector-ptr}}. The argument @var{flags} is a combination of +bit flags; see @ref{Flags for Globbing}, for details of the flags. + +The result of globbing is a sequence of file names. The function +@code{glob} allocates a string for each resulting word, then +allocates a vector of type @code{char **} to store the addresses of +these strings. The last element of the vector is a null pointer. +This vector is called the @dfn{word vector}. + +To return this vector, @code{glob} stores both its address and its +length (number of elements, not counting the terminating null pointer) +into @code{*@var{vector-ptr}}. + +Normally, @code{glob} sorts the file names alphabetically before +returning them. You can turn this off with the flag @code{GLOB_NOSORT} +if you want to get the information as fast as possible. Usually it's +a good idea to let @code{glob} sort them---if you process the files in +alphabetical order, the users will have a feel for the rate of progress +that your application is making. + +If @code{glob} succeeds, it returns 0. Otherwise, it returns one +of these error codes: + +@table @code +@comment glob.h +@comment POSIX.2 +@item GLOB_ABORTED +There was an error opening a directory, and you used the flag +@code{GLOB_ERR} or your specified @var{errfunc} returned a nonzero +value. +@iftex +See below +@end iftex +@ifinfo +@xref{Flags for Globbing}, +@end ifinfo +for an explanation of the @code{GLOB_ERR} flag and @var{errfunc}. + +@comment glob.h +@comment POSIX.2 +@item GLOB_NOMATCH +The pattern didn't match any existing files. If you use the +@code{GLOB_NOCHECK} flag, then you never get this error code, because +that flag tells @code{glob} to @emph{pretend} that the pattern matched +at least one file. + +@comment glob.h +@comment POSIX.2 +@item GLOB_NOSPACE +It was impossible to allocate memory to hold the result. +@end table + +In the event of an error, @code{glob} stores information in +@code{*@var{vector-ptr}} about all the matches it has found so far. +@end deftypefun + +@node Flags for Globbing +@subsection Flags for Globbing + +This section describes the flags that you can specify in the +@var{flags} argument to @code{glob}. Choose the flags you want, +and combine them with the C bitwise OR operator @code{|}. + +@table @code +@comment glob.h +@comment POSIX.2 +@item GLOB_APPEND +Append the words from this expansion to the vector of words produced by +previous calls to @code{glob}. This way you can effectively expand +several words as if they were concatenated with spaces between them. + +In order for appending to work, you must not modify the contents of the +word vector structure between calls to @code{glob}. And, if you set +@code{GLOB_DOOFFS} in the first call to @code{glob}, you must also +set it when you append to the results. + +Note that the pointer stored in @code{gl_pathv} may no longer be valid +after you call @code{glob} the second time, because @code{glob} might +have relocated the vector. So always fetch @code{gl_pathv} from the +@code{glob_t} structure after each @code{glob} call; @strong{never} save +the pointer across calls. + +@comment glob.h +@comment POSIX.2 +@item GLOB_DOOFFS +Leave blank slots at the beginning of the vector of words. +The @code{gl_offs} field says how many slots to leave. +The blank slots contain null pointers. + +@comment glob.h +@comment POSIX.2 +@item GLOB_ERR +Give up right away and report an error if there is any difficulty +reading the directories that must be read in order to expand @var{pattern} +fully. Such difficulties might include a directory in which you don't +have the requisite access. Normally, @code{glob} tries its best to keep +on going despite any errors, reading whatever directories it can. + +You can exercise even more control than this by specifying an +error-handler function @var{errfunc} when you call @code{glob}. If +@var{errfunc} is not a null pointer, then @code{glob} doesn't give up +right away when it can't read a directory; instead, it calls +@var{errfunc} with two arguments, like this: + +@smallexample +(*@var{errfunc}) (@var{filename}, @var{error-code}) +@end smallexample + +@noindent +The argument @var{filename} is the name of the directory that +@code{glob} couldn't open or couldn't read, and @var{error-code} is the +@code{errno} value that was reported to @code{glob}. + +If the error handler function returns nonzero, then @code{glob} gives up +right away. Otherwise, it continues. + +@comment glob.h +@comment POSIX.2 +@item GLOB_MARK +If the pattern matches the name of a directory, append @samp{/} to the +directory's name when returning it. + +@comment glob.h +@comment POSIX.2 +@item GLOB_NOCHECK +If the pattern doesn't match any file names, return the pattern itself +as if it were a file name that had been matched. (Normally, when the +pattern doesn't match anything, @code{glob} returns that there were no +matches.) + +@comment glob.h +@comment POSIX.2 +@item GLOB_NOSORT +Don't sort the file names; return them in no particular order. +(In practice, the order will depend on the order of the entries in +the directory.) The only reason @emph{not} to sort is to save time. + +@comment glob.h +@comment POSIX.2 +@item GLOB_NOESCAPE +Don't treat the @samp{\} character specially in patterns. Normally, +@samp{\} quotes the following character, turning off its special meaning +(if any) so that it matches only itself. When quoting is enabled, the +pattern @samp{\?} matches only the string @samp{?}, because the question +mark in the pattern acts like an ordinary character. + +If you use @code{GLOB_NOESCAPE}, then @samp{\} is an ordinary character. + +@code{glob} does its work by calling the function @code{fnmatch} +repeatedly. It handles the flag @code{GLOB_NOESCAPE} by turning on the +@code{FNM_NOESCAPE} flag in calls to @code{fnmatch}. +@end table + +@node Regular Expressions +@section Regular Expression Matching + +The GNU C library supports two interfaces for matching regular +expressions. One is the standard POSIX.2 interface, and the other is +what the GNU system has had for many years. + +Both interfaces are declared in the header file @file{regex.h}. +If you define @w{@code{_POSIX_C_SOURCE}}, then only the POSIX.2 +functions, structures, and constants are declared. +@c !!! we only document the POSIX.2 interface here!! + +@menu +* POSIX Regexp Compilation:: Using @code{regcomp} to prepare to match. +* Flags for POSIX Regexps:: Syntax variations for @code{regcomp}. +* Matching POSIX Regexps:: Using @code{regexec} to match the compiled + pattern that you get from @code{regcomp}. +* Regexp Subexpressions:: Finding which parts of the string were matched. +* Subexpression Complications:: Find points of which parts were matched. +* Regexp Cleanup:: Freeing storage; reporting errors. +@end menu + +@node POSIX Regexp Compilation +@subsection POSIX Regular Expression Compilation + +Before you can actually match a regular expression, you must +@dfn{compile} it. This is not true compilation---it produces a special +data structure, not machine instructions. But it is like ordinary +compilation in that its purpose is to enable you to ``execute'' the +pattern fast. (@xref{Matching POSIX Regexps}, for how to use the +compiled regular expression for matching.) + +There is a special data type for compiled regular expressions: + +@comment regex.h +@comment POSIX.2 +@deftp {Data Type} regex_t +This type of object holds a compiled regular expression. +It is actually a structure. It has just one field that your programs +should look at: + +@table @code +@item re_nsub +This field holds the number of parenthetical subexpressions in the +regular expression that was compiled. +@end table + +There are several other fields, but we don't describe them here, because +only the functions in the library should use them. +@end deftp + +After you create a @code{regex_t} object, you can compile a regular +expression into it by calling @code{regcomp}. + +@comment regex.h +@comment POSIX.2 +@deftypefun int regcomp (regex_t *@var{compiled}, const char *@var{pattern}, int @var{cflags}) +The function @code{regcomp} ``compiles'' a regular expression into a +data structure that you can use with @code{regexec} to match against a +string. The compiled regular expression format is designed for +efficient matching. @code{regcomp} stores it into @code{*@var{compiled}}. + +It's up to you to allocate an object of type @code{regex_t} and pass its +address to @code{regcomp}. + +The argument @var{cflags} lets you specify various options that control +the syntax and semantics of regular expressions. @xref{Flags for POSIX +Regexps}. + +If you use the flag @code{REG_NOSUB}, then @code{regcomp} omits from +the compiled regular expression the information necessary to record +how subexpressions actually match. In this case, you might as well +pass @code{0} for the @var{matchptr} and @var{nmatch} arguments when +you call @code{regexec}. + +If you don't use @code{REG_NOSUB}, then the compiled regular expression +does have the capacity to record how subexpressions match. Also, +@code{regcomp} tells you how many subexpressions @var{pattern} has, by +storing the number in @code{@var{compiled}->re_nsub}. You can use that +value to decide how long an array to allocate to hold information about +subexpression matches. + +@code{regcomp} returns @code{0} if it succeeds in compiling the regular +expression; otherwise, it returns a nonzero error code (see the table +below). You can use @code{regerror} to produce an error message string +describing the reason for a nonzero value; see @ref{Regexp Cleanup}. + +@end deftypefun + +Here are the possible nonzero values that @code{regcomp} can return: + +@table @code +@comment regex.h +@comment POSIX.2 +@item REG_BADBR +There was an invalid @samp{\@{@dots{}\@}} construct in the regular +expression. A valid @samp{\@{@dots{}\@}} construct must contain either +a single number, or two numbers in increasing order separated by a +comma. + +@comment regex.h +@comment POSIX.2 +@item REG_BADPAT +There was a syntax error in the regular expression. + +@comment regex.h +@comment POSIX.2 +@item REG_BADRPT +A repetition operator such as @samp{?} or @samp{*} appeared in a bad +position (with no preceding subexpression to act on). + +@comment regex.h +@comment POSIX.2 +@item REG_ECOLLATE +The regular expression referred to an invalid collating element (one not +defined in the current locale for string collation). @xref{Locale +Categories}. + +@comment regex.h +@comment POSIX.2 +@item REG_ECTYPE +The regular expression referred to an invalid character class name. + +@comment regex.h +@comment POSIX.2 +@item REG_EESCAPE +The regular expression ended with @samp{\}. + +@comment regex.h +@comment POSIX.2 +@item REG_ESUBREG +There was an invalid number in the @samp{\@var{digit}} construct. + +@comment regex.h +@comment POSIX.2 +@item REG_EBRACK +There were unbalanced square brackets in the regular expression. + +@comment regex.h +@comment POSIX.2 +@item REG_EPAREN +An extended regular expression had unbalanced parentheses, +or a basic regular expression had unbalanced @samp{\(} and @samp{\)}. + +@comment regex.h +@comment POSIX.2 +@item REG_EBRACE +The regular expression had unbalanced @samp{\@{} and @samp{\@}}. + +@comment regex.h +@comment POSIX.2 +@item REG_ERANGE +One of the endpoints in a range expression was invalid. + +@comment regex.h +@comment POSIX.2 +@item REG_ESPACE +@code{regcomp} ran out of memory. +@end table + +@node Flags for POSIX Regexps +@subsection Flags for POSIX Regular Expressions + +These are the bit flags that you can use in the @var{cflags} operand when +compiling a regular expression with @code{regcomp}. + +@table @code +@comment regex.h +@comment POSIX.2 +@item REG_EXTENDED +Treat the pattern as an extended regular expression, rather than as a +basic regular expression. + +@comment regex.h +@comment POSIX.2 +@item REG_ICASE +Ignore case when matching letters. + +@comment regex.h +@comment POSIX.2 +@item REG_NOSUB +Don't bother storing the contents of the @var{matches-ptr} array. + +@comment regex.h +@comment POSIX.2 +@item REG_NEWLINE +Treat a newline in @var{string} as dividing @var{string} into multiple +lines, so that @samp{$} can match before the newline and @samp{^} can +match after. Also, don't permit @samp{.} to match a newline, and don't +permit @samp{[^@dots{}]} to match a newline. + +Otherwise, newline acts like any other ordinary character. +@end table + +@node Matching POSIX Regexps +@subsection Matching a Compiled POSIX Regular Expression + +Once you have compiled a regular expression, as described in @ref{POSIX +Regexp Compilation}, you can match it against strings using +@code{regexec}. A match anywhere inside the string counts as success, +unless the regular expression contains anchor characters (@samp{^} or +@samp{$}). + +@comment regex.h +@comment POSIX.2 +@deftypefun int regexec (regex_t *@var{compiled}, char *@var{string}, size_t @var{nmatch}, regmatch_t @var{matchptr} @t{[]}, int @var{eflags}) +This function tries to match the compiled regular expression +@code{*@var{compiled}} against @var{string}. + +@code{regexec} returns @code{0} if the regular expression matches; +otherwise, it returns a nonzero value. See the table below for +what nonzero values mean. You can use @code{regerror} to produce an +error message string describing the reason for a nonzero value; +see @ref{Regexp Cleanup}. + +The argument @var{eflags} is a word of bit flags that enable various +options. + +If you want to get information about what part of @var{string} actually +matched the regular expression or its subexpressions, use the arguments +@var{matchptr} and @var{nmatch}. Otherwise, pass @code{0} for +@var{nmatch}, and @code{NULL} for @var{matchptr}. @xref{Regexp +Subexpressions}. +@end deftypefun + +You must match the regular expression with the same set of current +locales that were in effect when you compiled the regular expression. + +The function @code{regexec} accepts the following flags in the +@var{eflags} argument: + +@table @code +@comment regex.h +@comment POSIX.2 +@item REG_NOTBOL +Do not regard the beginning of the specified string as the beginning of +a line; more generally, don't make any assumptions about what text might +precede it. + +@comment regex.h +@comment POSIX.2 +@item REG_NOTEOL +Do not regard the end of the specified string as the end of a line; more +generally, don't make any assumptions about what text might follow it. +@end table + +Here are the possible nonzero values that @code{regexec} can return: + +@table @code +@comment regex.h +@comment POSIX.2 +@item REG_NOMATCH +The pattern didn't match the string. This isn't really an error. + +@comment regex.h +@comment POSIX.2 +@item REG_ESPACE +@code{regexec} ran out of memory. +@end table + +@node Regexp Subexpressions +@subsection Match Results with Subexpressions + +When @code{regexec} matches parenthetical subexpressions of +@var{pattern}, it records which parts of @var{string} they match. It +returns that information by storing the offsets into an array whose +elements are structures of type @code{regmatch_t}. The first element of +the array (index @code{0}) records the part of the string that matched +the entire regular expression. Each other element of the array records +the beginning and end of the part that matched a single parenthetical +subexpression. + +@comment regex.h +@comment POSIX.2 +@deftp {Data Type} regmatch_t +This is the data type of the @var{matcharray} array that you pass to +@code{regexec}. It containes two structure fields, as follows: + +@table @code +@item rm_so +The offset in @var{string} of the beginning of a substring. Add this +value to @var{string} to get the address of that part. + +@item rm_eo +The offset in @var{string} of the end of the substring. +@end table +@end deftp + +@comment regex.h +@comment POSIX.2 +@deftp {Data Type} regoff_t +@code{regoff_t} is an alias for another signed integer type. +The fields of @code{regmatch_t} have type @code{regoff_t}. +@end deftp + +The @code{regmatch_t} elements correspond to subexpressions +positionally; the first element (index @code{1}) records where the first +subexpression matched, the second element records the second +subexpression, and so on. The order of the subexpressions is the order +in which they begin. + +When you call @code{regexec}, you specify how long the @var{matchptr} +array is, with the @var{nmatch} argument. This tells @code{regexec} how +many elements to store. If the actual regular expression has more than +@var{nmatch} subexpressions, then you won't get offset information about +the rest of them. But this doesn't alter whether the pattern matches a +particular string or not. + +If you don't want @code{regexec} to return any information about where +the subexpressions matched, you can either supply @code{0} for +@var{nmatch}, or use the flag @code{REG_NOSUB} when you compile the +pattern with @code{regcomp}. + +@node Subexpression Complications +@subsection Complications in Subexpression Matching + +Sometimes a subexpression matches a substring of no characters. This +happens when @samp{f\(o*\)} matches the string @samp{fum}. (It really +matches just the @samp{f}.) In this case, both of the offsets identify +the point in the string where the null substring was found. In this +example, the offsets are both @code{1}. + +Sometimes the entire regular expression can match without using some of +its subexpressions at all---for example, when @samp{ba\(na\)*} matches the +string @samp{ba}, the parenthetical subexpression is not used. When +this happens, @code{regexec} stores @code{-1} in both fields of the +element for that subexpression. + +Sometimes matching the entire regular expression can match a particular +subexpression more than once---for example, when @samp{ba\(na\)*} +matches the string @samp{bananana}, the parenthetical subexpression +matches three times. When this happens, @code{regexec} usually stores +the offsets of the last part of the string that matched the +subexpression. In the case of @samp{bananana}, these offsets are +@code{6} and @code{8}. + +But the last match is not always the one that is chosen. It's more +accurate to say that the last @emph{opportunity} to match is the one +that takes precedence. What this means is that when one subexpression +appears within another, then the results reported for the inner +subexpression reflect whatever happened on the last match of the outer +subexpression. For an example, consider @samp{\(ba\(na\)*s \)*} matching +the string @samp{bananas bas }. The last time the inner expression +actually matches is near the end of the first word. But it is +@emph{considered} again in the second word, and fails to match there. +@code{regexec} reports nonuse of the ``na'' subexpression. + +Another place where this rule applies is when the regular expression +@w{@samp{\(ba\(na\)*s \|nefer\(ti\)* \)*}} matches @samp{bananas nefertiti}. +The ``na'' subexpression does match in the first word, but it doesn't +match in the second word because the other alternative is used there. +Once again, the second repetition of the outer subexpression overrides +the first, and within that second repetition, the ``na'' subexpression +is not used. So @code{regexec} reports nonuse of the ``na'' +subexpression. + +@node Regexp Cleanup +@subsection POSIX Regexp Matching Cleanup + +When you are finished using a compiled regular expression, you can +free the storage it uses by calling @code{regfree}. + +@comment regex.h +@comment POSIX.2 +@deftypefun void regfree (regex_t *@var{compiled}) +Calling @code{regfree} frees all the storage that @code{*@var{compiled}} +points to. This includes various internal fields of the @code{regex_t} +structure that aren't documented in this manual. + +@code{regfree} does not free the object @code{*@var{compiled}} itself. +@end deftypefun + +You should always free the space in a @code{regex_t} structure with +@code{regfree} before using the structure to compile another regular +expression. + +When @code{regcomp} or @code{regexec} reports an error, you can use +the function @code{regerror} to turn it into an error message string. + +@comment regex.h +@comment POSIX.2 +@deftypefun size_t regerror (int @var{errcode}, regex_t *@var{compiled}, char *@var{buffer}, size_t @var{length}) +This function produces an error message string for the error code +@var{errcode}, and stores the string in @var{length} bytes of memory +starting at @var{buffer}. For the @var{compiled} argument, supply the +same compiled regular expression structure that @code{regcomp} or +@code{regexec} was working with when it got the error. Alternatively, +you can supply @code{NULL} for @var{compiled}; you will still get a +meaningful error message, but it might not be as detailed. + +If the error message can't fit in @var{length} bytes (including a +terminating null character), then @code{regerror} truncates it. +The string that @code{regerror} stores is always null-terminated +even if it has been truncated. + +The return value of @code{regerror} is the minimum length needed to +store the entire error message. If this is less than @var{length}, then +the error message was not truncated, and you can use it. Otherwise, you +should call @code{regerror} again with a larger buffer. + +Here is a function which uses @code{regerror}, but always dynamically +allocates a buffer for the error message: + +@smallexample +char *get_regerror (int errcode, regex_t *compiled) +@{ + size_t length = regerror (errcode, compiled, NULL, 0); + char *buffer = xmalloc (length); + (void) regerror (errcode, compiled, buffer, length); + return buffer; +@} +@end smallexample +@end deftypefun + +@c !!!! this is not actually in the library.... +@node Word Expansion +@section Shell-Style Word Expansion +@cindex word expansion +@cindex expansion of shell words + +@dfn{Word expansion} means the process of splitting a string into +@dfn{words} and substituting for variables, commands, and wildcards +just as the shell does. + +For example, when you write @samp{ls -l foo.c}, this string is split +into three separate words---@samp{ls}, @samp{-l} and @samp{foo.c}. +This is the most basic function of word expansion. + +When you write @samp{ls *.c}, this can become many words, because +the word @samp{*.c} can be replaced with any number of file names. +This is called @dfn{wildcard expansion}, and it is also a part of +word expansion. + +When you use @samp{echo $PATH} to print your path, you are taking +advantage of @dfn{variable substitution}, which is also part of word +expansion. + +Ordinary programs can perform word expansion just like the shell by +calling the library function @code{wordexp}. + +@menu +* Expansion Stages:: What word expansion does to a string. +* Calling Wordexp:: How to call @code{wordexp}. +* Flags for Wordexp:: Options you can enable in @code{wordexp}. +* Wordexp Example:: A sample program that does word expansion. +@end menu + +@node Expansion Stages +@subsection The Stages of Word Expansion + +When word expansion is applied to a sequence of words, it performs the +following transformations in the order shown here: + +@enumerate +@item +@cindex tilde expansion +@dfn{Tilde expansion}: Replacement of @samp{~foo} with the name of +the home directory of @samp{foo}. + +@item +Next, three different transformations are applied in the same step, +from left to right: + +@itemize @bullet +@item +@cindex variable substitution +@cindex substitution of variables and commands +@dfn{Variable substitution}: Environment variables are substituted for +references such as @samp{$foo}. + +@item +@cindex command substitution +@dfn{Command substitution}: Constructs such as @w{@samp{`cat foo`}} and +the equivalent @w{@samp{$(cat foo)}} are replaced with the output from +the inner command. + +@item +@cindex arithmetic expansion +@dfn{Arithmetic expansion}: Constructs such as @samp{$(($x-1))} are +replaced with the result of the arithmetic computation. +@end itemize + +@item +@cindex field splitting +@dfn{Field splitting}: subdivision of the text into @dfn{words}. + +@item +@cindex wildcard expansion +@dfn{Wildcard expansion}: The replacement of a construct such as @samp{*.c} +with a list of @samp{.c} file names. Wildcard expansion applies to an +entire word at a time, and replaces that word with 0 or more file names +that are themselves words. + +@item +@cindex quote removal +@cindex removal of quotes +@dfn{Quote removal}: The deletion of string-quotes, now that they have +done their job by inhibiting the above transformations when appropriate. +@end enumerate + +For the details of these transformations, and how to write the constructs +that use them, see @w{@cite{The BASH Manual}} (to appear). + +@node Calling Wordexp +@subsection Calling @code{wordexp} + +All the functions, constants and data types for word expansion are +declared in the header file @file{wordexp.h}. + +Word expansion produces a vector of words (strings). To return this +vector, @code{wordexp} uses a special data type, @code{wordexp_t}, which +is a structure. You pass @code{wordexp} the address of the structure, +and it fills in the structure's fields to tell you about the results. + +@comment wordexp.h +@comment POSIX.2 +@deftp {Data Type} {wordexp_t} +This data type holds a pointer to a word vector. More precisely, it +records both the address of the word vector and its size. + +@table @code +@item we_wordc +The number of elements in the vector. + +@item we_wordv +The address of the vector. This field has type @w{@code{char **}}. + +@item we_offs +The offset of the first real element of the vector, from its nominal +address in the @code{we_wordv} field. Unlike the other fields, this +is always an input to @code{wordexp}, rather than an output from it. + +If you use a nonzero offset, then that many elements at the beginning of +the vector are left empty. (The @code{wordexp} function fills them with +null pointers.) + +The @code{we_offs} field is meaningful only if you use the +@code{WRDE_DOOFFS} flag. Otherwise, the offset is always zero +regardless of what is in this field, and the first real element comes at +the beginning of the vector. +@end table +@end deftp + +@comment wordexp.h +@comment POSIX.2 +@deftypefun int wordexp (const char *@var{words}, wordexp_t *@var{word-vector-ptr}, int @var{flags}) +Perform word expansion on the string @var{words}, putting the result in +a newly allocated vector, and store the size and address of this vector +into @code{*@var{word-vector-ptr}}. The argument @var{flags} is a +combination of bit flags; see @ref{Flags for Wordexp}, for details of +the flags. + +You shouldn't use any of the characters @samp{|&;<>} in the string +@var{words} unless they are quoted; likewise for newline. If you use +these characters unquoted, you will get the @code{WRDE_BADCHAR} error +code. Don't use parentheses or braces unless they are quoted or part of +a word expansion construct. If you use quotation characters @samp{'"`}, +they should come in pairs that balance. + +The results of word expansion are a sequence of words. The function +@code{wordexp} allocates a string for each resulting word, then +allocates a vector of type @code{char **} to store the addresses of +these strings. The last element of the vector is a null pointer. +This vector is called the @dfn{word vector}. + +To return this vector, @code{wordexp} stores both its address and its +length (number of elements, not counting the terminating null pointer) +into @code{*@var{word-vector-ptr}}. + +If @code{wordexp} succeeds, it returns 0. Otherwise, it returns one +of these error codes: + +@table @code +@comment wordexp.h +@comment POSIX.2 +@item WRDE_BADCHAR +The input string @var{words} contains an unquoted invalid character such +as @samp{|}. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_BADVAL +The input string refers to an undefined shell variable, and you used the flag +@code{WRDE_UNDEF} to forbid such references. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_CMDSUB +The input string uses command substitution, and you used the flag +@code{WRDE_NOCMD} to forbid command substitution. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_NOSPACE +It was impossible to allocate memory to hold the result. In this case, +@code{wordexp} can store part of the results---as much as it could +allocate room for. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_SYNTAX +There was a syntax error in the input string. For example, an unmatched +quoting character is a syntax error. +@end table +@end deftypefun + +@comment wordexp.h +@comment POSIX.2 +@deftypefun void wordfree (wordexp_t *@var{word-vector-ptr}) +Free the storage used for the word-strings and vector that +@code{*@var{word-vector-ptr}} points to. This does not free the +structure @code{*@var{word-vector-ptr}} itself---only the other +data it points to. +@end deftypefun + +@node Flags for Wordexp +@subsection Flags for Word Expansion + +This section describes the flags that you can specify in the +@var{flags} argument to @code{wordexp}. Choose the flags you want, +and combine them with the C operator @code{|}. + +@table @code +@comment wordexp.h +@comment POSIX.2 +@item WRDE_APPEND +Append the words from this expansion to the vector of words produced by +previous calls to @code{wordexp}. This way you can effectively expand +several words as if they were concatenated with spaces between them. + +In order for appending to work, you must not modify the contents of the +word vector structure between calls to @code{wordexp}. And, if you set +@code{WRDE_DOOFFS} in the first call to @code{wordexp}, you must also +set it when you append to the results. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_DOOFFS +Leave blank slots at the beginning of the vector of words. +The @code{we_offs} field says how many slots to leave. +The blank slots contain null pointers. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_NOCMD +Don't do command substitution; if the input requests command substitution, +report an error. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_REUSE +Reuse a word vector made by a previous call to @code{wordexp}. +Instead of allocating a new vector of words, this call to @code{wordexp} +will use the vector that already exists (making it larger if necessary). + +Note that the vector may move, so it is not safe to save an old pointer +and use it again after calling @code{wordexp}. You must fetch +@code{we_pathv} anew after each call. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_SHOWERR +Do show any error messages printed by commands run by command substitution. +More precisely, allow these commands to inherit the standard error output +stream of the current process. By default, @code{wordexp} gives these +commands a standard error stream that discards all output. + +@comment wordexp.h +@comment POSIX.2 +@item WRDE_UNDEF +If the input refers to a shell variable that is not defined, report an +error. +@end table + +@node Wordexp Example +@subsection @code{wordexp} Example + +Here is an example of using @code{wordexp} to expand several strings +and use the results to run a shell command. It also shows the use of +@code{WRDE_APPEND} to concatenate the expansions and of @code{wordfree} +to free the space allocated by @code{wordexp}. + +@smallexample +int +expand_and_execute (const char *program, const char *options) +@{ + wordexp_t result; + pid_t pid + int status, i; + + /* @r{Expand the string for the program to run.} */ + switch (wordexp (program, &result, 0)) + @{ + case 0: /* @r{Successful}. */ + break; + case WRDE_NOSPACE: + /* @r{If the error was @code{WRDE_NOSPACE},} + @r{then perhaps part of the result was allocated.} */ + wordfree (&result); + default: /* @r{Some other error.} */ + return -1; + @} + + /* @r{Expand the strings specified for the arguments.} */ + for (i = 0; args[i]; i++) + @{ + if (wordexp (options, &result, WRDE_APPEND)) + @{ + wordfree (&result); + return -1; + @} + @} + + pid = fork (); + if (pid == 0) + @{ + /* @r{This is the child process. Execute the command.} */ + execv (result.we_wordv[0], result.we_wordv); + exit (EXIT_FAILURE); + @} + else if (pid < 0) + /* @r{The fork failed. Report failure.} */ + status = -1; + else + /* @r{This is the parent process. Wait for the child to complete.} */ + if (waitpid (pid, &status, 0) != pid) + status = -1; + + wordfree (&result); + return status; +@} +@end smallexample + +In practice, since @code{wordexp} is executed by running a subshell, it +would be faster to do this by concatenating the strings with spaces +between them and running that as a shell command using @samp{sh -c}. + +@c No sense finishing this for here. +@ignore +@node Tilde Expansion +@subsection Details of Tilde Expansion + +It's a standard part of shell syntax that you can use @samp{~} at the +beginning of a file name to stand for your own home directory. You +can use @samp{~@var{user}} to stand for @var{user}'s home directory. + +@dfn{Tilde expansion} is the process of converting these abbreviations +to the directory names that they stand for. + +Tilde expansion applies to the @samp{~} plus all following characters up +to whitespace or a slash. It takes place only at the beginning of a +word, and only if none of the characters to be transformed is quoted in +any way. + +Plain @samp{~} uses the value of the environment variable @code{HOME} +as the proper home directory name. @samp{~} followed by a user name +uses @code{getpwname} to look up that user in the user database, and +uses whatever directory is recorded there. Thus, @samp{~} followed +by your own name can give different results from plain @samp{~}, if +the value of @code{HOME} is not really your home directory. + +@node Variable Substitution +@subsection Details of Variable Substitution + +Part of ordinary shell syntax is the use of @samp{$@var{variable}} to +substitute the value of a shell variable into a command. This is called +@dfn{variable substitution}, and it is one part of doing word expansion. + +There are two basic ways you can write a variable reference for +substitution: + +@table @code +@item $@{@var{variable}@} +If you write braces around the variable name, then it is completely +unambiguous where the variable name ends. You can concatenate +additional letters onto the end of the variable value by writing them +immediately after the close brace. For example, @samp{$@{foo@}s} +expands into @samp{tractors}. + +@item $@var{variable} +If you do not put braces around the variable name, then the variable +name consists of all the alphanumeric characters and underscores that +follow the @samp{$}. The next punctuation character ends the variable +name. Thus, @samp{$foo-bar} refers to the variable @code{foo} and expands +into @samp{tractor-bar}. +@end table + +When you use braces, you can also use various constructs to modify the +value that is substituted, or test it in various ways. + +@table @code +@item $@{@var{variable}:-@var{default}@} +Substitute the value of @var{variable}, but if that is empty or +undefined, use @var{default} instead. + +@item $@{@var{variable}:=@var{default}@} +Substitute the value of @var{variable}, but if that is empty or +undefined, use @var{default} instead and set the variable to +@var{default}. + +@item $@{@var{variable}:?@var{message}@} +If @var{variable} is defined and not empty, substitute its value. + +Otherwise, print @var{message} as an error message on the standard error +stream, and consider word expansion a failure. + +@c ??? How does wordexp report such an error? + +@item $@{@var{variable}:+@var{replacement}@} +Substitute @var{replacement}, but only if @var{variable} is defined and +nonempty. Otherwise, substitute nothing for this construct. +@end table + +@table @code +@item $@{#@var{variable}@} +Substitute a numeral which expresses in base ten the number of +characters in the value of @var{variable}. @samp{$@{#foo@}} stands for +@samp{7}, because @samp{tractor} is seven characters. +@end table + +These variants of variable substitution let you remove part of the +variable's value before substituting it. The @var{prefix} and +@var{suffix} are not mere strings; they are wildcard patterns, just +like the patterns that you use to match multiple file names. But +in this context, they match against parts of the variable value +rather than against file names. + +@table @code +@item $@{@var{variable}%%@var{suffix}@} +Substitute the value of @var{variable}, but first discard from that +variable any portion at the end that matches the pattern @var{suffix}. + +If there is more than one alternative for how to match against +@var{suffix}, this construct uses the longest possible match. + +Thus, @samp{$@{foo%%r*@}} substitutes @samp{t}, because the largest +match for @samp{r*} at the end of @samp{tractor} is @samp{ractor}. + +@item $@{@var{variable}%@var{suffix}@} +Substitute the value of @var{variable}, but first discard from that +variable any portion at the end that matches the pattern @var{suffix}. + +If there is more than one alternative for how to match against +@var{suffix}, this construct uses the shortest possible alternative. + +Thus, @samp{$@{foo%%r*@}} substitutes @samp{tracto}, because the shortest +match for @samp{r*} at the end of @samp{tractor} is just @samp{r}. + +@item $@{@var{variable}##@var{prefix}@} +Substitute the value of @var{variable}, but first discard from that +variable any portion at the beginning that matches the pattern @var{prefix}. + +If there is more than one alternative for how to match against +@var{prefix}, this construct uses the longest possible match. + +Thus, @samp{$@{foo%%r*@}} substitutes @samp{t}, because the largest +match for @samp{r*} at the end of @samp{tractor} is @samp{ractor}. + +@item $@{@var{variable}#@var{prefix}@} +Substitute the value of @var{variable}, but first discard from that +variable any portion at the beginning that matches the pattern @var{prefix}. + +If there is more than one alternative for how to match against +@var{prefix}, this construct uses the shortest possible alternative. + +Thus, @samp{$@{foo%%r*@}} substitutes @samp{tracto}, because the shortest +match for @samp{r*} at the end of @samp{tractor} is just @samp{r}. + +@end ignore diff --git a/manual/pipe.texi b/manual/pipe.texi new file mode 100644 index 0000000000..773dc4aac8 --- /dev/null +++ b/manual/pipe.texi @@ -0,0 +1,208 @@ +@node Pipes and FIFOs, Sockets, File System Interface, Top +@chapter Pipes and FIFOs + +@cindex pipe +A @dfn{pipe} is a mechanism for interprocess communication; data written +to the pipe by one process can be read by another process. The data is +handled in a first-in, first-out (FIFO) order. The pipe has no name; it +is created for one use and both ends must be inherited from the single +process which created the pipe. + +@cindex FIFO special file +A @dfn{FIFO special file} is similar to a pipe, but instead of being an +anonymous, temporary connection, a FIFO has a name or names like any +other file. Processes open the FIFO by name in order to communicate +through it. + +A pipe or FIFO has to be open at both ends simultaneously. If you read +from a pipe or FIFO file that doesn't have any processes writing to it +(perhaps because they have all closed the file, or exited), the read +returns end-of-file. Writing to a pipe or FIFO that doesn't have a +reading process is treated as an error condition; it generates a +@code{SIGPIPE} signal, and fails with error code @code{EPIPE} if the +signal is handled or blocked. + +Neither pipes nor FIFO special files allow file positioning. Both +reading and writing operations happen sequentially; reading from the +beginning of the file and writing at the end. + +@menu +* Creating a Pipe:: Making a pipe with the @code{pipe} function. +* Pipe to a Subprocess:: Using a pipe to communicate with a + child process. +* FIFO Special Files:: Making a FIFO special file. +* Pipe Atomicity:: When pipe (or FIFO) I/O is atomic. +@end menu + +@node Creating a Pipe +@section Creating a Pipe +@cindex creating a pipe +@cindex opening a pipe +@cindex interprocess communication, with pipes + +The primitive for creating a pipe is the @code{pipe} function. This +creates both the reading and writing ends of the pipe. It is not very +useful for a single process to use a pipe to talk to itself. In typical +use, a process creates a pipe just before it forks one or more child +processes (@pxref{Creating a Process}). The pipe is then used for +communication either between the parent or child processes, or between +two sibling processes. + +The @code{pipe} function is declared in the header file +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun int pipe (int @var{filedes}@t{[2]}) +The @code{pipe} function creates a pipe and puts the file descriptors +for the reading and writing ends of the pipe (respectively) into +@code{@var{filedes}[0]} and @code{@var{filedes}[1]}. + +An easy way to remember that the input end comes first is that file +descriptor @code{0} is standard input, and file descriptor @code{1} is +standard output. + +If successful, @code{pipe} returns a value of @code{0}. On failure, +@code{-1} is returned. The following @code{errno} error conditions are +defined for this function: + +@table @code +@item EMFILE +The process has too many files open. + +@item ENFILE +There are too many open files in the entire system. @xref{Error Codes}, +for more information about @code{ENFILE}. This error never occurs in +the GNU system. +@end table +@end deftypefun + +Here is an example of a simple program that creates a pipe. This program +uses the @code{fork} function (@pxref{Creating a Process}) to create +a child process. The parent process writes data to the pipe, which is +read by the child process. + +@smallexample +@include pipe.c.texi +@end smallexample + +@node Pipe to a Subprocess +@section Pipe to a Subprocess +@cindex creating a pipe to a subprocess +@cindex pipe to a subprocess +@cindex filtering i/o through subprocess + +A common use of pipes is to send data to or receive data from a program +being run as subprocess. One way of doing this is by using a combination of +@code{pipe} (to create the pipe), @code{fork} (to create the subprocess), +@code{dup2} (to force the subprocess to use the pipe as its standard input +or output channel), and @code{exec} (to execute the new program). Or, +you can use @code{popen} and @code{pclose}. + +The advantage of using @code{popen} and @code{pclose} is that the +interface is much simpler and easier to use. But it doesn't offer as +much flexibility as using the low-level functions directly. + +@comment stdio.h +@comment POSIX.2, SVID, BSD +@deftypefun {FILE *} popen (const char *@var{command}, const char *@var{mode}) +The @code{popen} function is closely related to the @code{system} +function; see @ref{Running a Command}. It executes the shell command +@var{command} as a subprocess. However, instead of waiting for the +command to complete, it creates a pipe to the subprocess and returns a +stream that corresponds to that pipe. + +If you specify a @var{mode} argument of @code{"r"}, you can read from the +stream to retrieve data from the standard output channel of the subprocess. +The subprocess inherits its standard input channel from the parent process. + +Similarly, if you specify a @var{mode} argument of @code{"w"}, you can +write to the stream to send data to the standard input channel of the +subprocess. The subprocess inherits its standard output channel from +the parent process. + +In the event of an error, @code{popen} returns a null pointer. This +might happen if the pipe or stream cannot be created, if the subprocess +cannot be forked, or if the program cannot be executed. +@end deftypefun + +@comment stdio.h +@comment POSIX.2, SVID, BSD +@deftypefun int pclose (FILE *@var{stream}) +The @code{pclose} function is used to close a stream created by @code{popen}. +It waits for the child process to terminate and returns its status value, +as for the @code{system} function. +@end deftypefun + +Here is an example showing how to use @code{popen} and @code{pclose} to +filter output through another program, in this case the paging program +@code{more}. + +@smallexample +@include popen.c.texi +@end smallexample + +@node FIFO Special Files +@section FIFO Special Files +@cindex creating a FIFO special file +@cindex interprocess communication, with FIFO + +A FIFO special file is similar to a pipe, except that it is created in a +different way. Instead of being an anonymous communications channel, a +FIFO special file is entered into the file system by calling +@code{mkfifo}. + +Once you have created a FIFO special file in this way, any process can +open it for reading or writing, in the same way as an ordinary file. +However, it has to be open at both ends simultaneously before you can +proceed to do any input or output operations on it. Opening a FIFO for +reading normally blocks until some other process opens the same FIFO for +writing, and vice versa. + +The @code{mkfifo} function is declared in the header file +@file{sys/stat.h}. +@pindex sys/stat.h + +@comment sys/stat.h +@comment POSIX.1 +@deftypefun int mkfifo (const char *@var{filename}, mode_t @var{mode}) +The @code{mkfifo} function makes a FIFO special file with name +@var{filename}. The @var{mode} argument is used to set the file's +permissions; see @ref{Setting Permissions}. + +The normal, successful return value from @code{mkfifo} is @code{0}. In +the case of an error, @code{-1} is returned. In addition to the usual +file name errors (@pxref{File Name Errors}), the following +@code{errno} error conditions are defined for this function: + +@table @code +@item EEXIST +The named file already exists. + +@item ENOSPC +The directory or file system cannot be extended. + +@item EROFS +The directory that would contain the file resides on a read-only file +system. +@end table +@end deftypefun + +@node Pipe Atomicity +@section Atomicity of Pipe I/O + +Reading or writing pipe data is @dfn{atomic} if the size of data written +is less than @code{PIPE_BUF}. This means that the data transfer seems +to be an instantaneous unit, in that nothing else in the system can +observe a state in which it is partially complete. Atomic I/O may not +begin right away (it may need to wait for buffer space or for data), but +once it does begin, it finishes immediately. + +Reading or writing a larger amount of data may not be atomic; for +example, output data from other processes sharing the descriptor may be +interspersed. Also, once @code{PIPE_BUF} characters have been written, +further writes will block until some characters are read. + +@xref{Limits for Files}, for information about the @code{PIPE_BUF} +parameter. diff --git a/manual/process.texi b/manual/process.texi new file mode 100644 index 0000000000..2f5ba65af5 --- /dev/null +++ b/manual/process.texi @@ -0,0 +1,775 @@ +@node Processes +@chapter Processes + +@cindex process +@dfn{Processes} are the primitive units for allocation of system +resources. Each process has its own address space and (usually) one +thread of control. A process executes a program; you can have multiple +processes executing the same program, but each process has its own copy +of the program within its own address space and executes it +independently of the other copies. + +@cindex child process +@cindex parent process +Processes are organized hierarchically. Each process has a @dfn{parent +process} which explicitly arranged to create it. The processes created +by a given parent are called its @dfn{child processes}. A child +inherits many of its attributes from the parent process. + +This chapter describes how a program can create, terminate, and control +child processes. Actually, there are three distinct operations +involved: creating a new child process, causing the new process to +execute a program, and coordinating the completion of the child process +with the original program. + +The @code{system} function provides a simple, portable mechanism for +running another program; it does all three steps automatically. If you +need more control over the details of how this is done, you can use the +primitive functions to do each step individually instead. + +@menu +* Running a Command:: The easy way to run another program. +* Process Creation Concepts:: An overview of the hard way to do it. +* Process Identification:: How to get the process ID of a process. +* Creating a Process:: How to fork a child process. +* Executing a File:: How to make a process execute another program. +* Process Completion:: How to tell when a child process has completed. +* Process Completion Status:: How to interpret the status value + returned from a child process. +* BSD Wait Functions:: More functions, for backward compatibility. +* Process Creation Example:: A complete example program. +@end menu + + +@node Running a Command +@section Running a Command +@cindex running a command + +The easy way to run another program is to use the @code{system} +function. This function does all the work of running a subprogram, but +it doesn't give you much control over the details: you have to wait +until the subprogram terminates before you can do anything else. + +@comment stdlib.h +@comment ANSI +@deftypefun int system (const char *@var{command}) +@pindex sh +This function executes @var{command} as a shell command. In the GNU C +library, it always uses the default shell @code{sh} to run the command. +In particular, it searches the directories in @code{PATH} to find +programs to execute. The return value is @code{-1} if it wasn't +possible to create the shell process, and otherwise is the status of the +shell process. @xref{Process Completion}, for details on how this +status code can be interpreted. + +@pindex stdlib.h +The @code{system} function is declared in the header file +@file{stdlib.h}. +@end deftypefun + +@strong{Portability Note:} Some C implementations may not have any +notion of a command processor that can execute other programs. You can +determine whether a command processor exists by executing +@w{@code{system (NULL)}}; if the return value is nonzero, a command +processor is available. + +The @code{popen} and @code{pclose} functions (@pxref{Pipe to a +Subprocess}) are closely related to the @code{system} function. They +allow the parent process to communicate with the standard input and +output channels of the command being executed. + +@node Process Creation Concepts +@section Process Creation Concepts + +This section gives an overview of processes and of the steps involved in +creating a process and making it run another program. + +@cindex process ID +@cindex process lifetime +Each process is named by a @dfn{process ID} number. A unique process ID +is allocated to each process when it is created. The @dfn{lifetime} of +a process ends when its termination is reported to its parent process; +at that time, all of the process resources, including its process ID, +are freed. + +@cindex creating a process +@cindex forking a process +@cindex child process +@cindex parent process +Processes are created with the @code{fork} system call (so the operation +of creating a new process is sometimes called @dfn{forking} a process). +The @dfn{child process} created by @code{fork} is a copy of the original +@dfn{parent process}, except that it has its own process ID. + +After forking a child process, both the parent and child processes +continue to execute normally. If you want your program to wait for a +child process to finish executing before continuing, you must do this +explicitly after the fork operation, by calling @code{wait} or +@code{waitpid} (@pxref{Process Completion}). These functions give you +limited information about why the child terminated---for example, its +exit status code. + +A newly forked child process continues to execute the same program as +its parent process, at the point where the @code{fork} call returns. +You can use the return value from @code{fork} to tell whether the program +is running in the parent process or the child. + +@cindex process image +Having several processes run the same program is only occasionally +useful. But the child can execute another program using one of the +@code{exec} functions; see @ref{Executing a File}. The program that the +process is executing is called its @dfn{process image}. Starting +execution of a new program causes the process to forget all about its +previous process image; when the new program exits, the process exits +too, instead of returning to the previous process image. + +@node Process Identification +@section Process Identification + +The @code{pid_t} data type represents process IDs. You can get the +process ID of a process by calling @code{getpid}. The function +@code{getppid} returns the process ID of the parent of the current +process (this is also known as the @dfn{parent process ID}). Your +program should include the header files @file{unistd.h} and +@file{sys/types.h} to use these functions. +@pindex sys/types.h +@pindex unistd.h + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} pid_t +The @code{pid_t} data type is a signed integer type which is capable +of representing a process ID. In the GNU library, this is an @code{int}. +@end deftp + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t getpid (void) +The @code{getpid} function returns the process ID of the current process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t getppid (void) +The @code{getppid} function returns the process ID of the parent of the +current process. +@end deftypefun + +@node Creating a Process +@section Creating a Process + +The @code{fork} function is the primitive for creating a process. +It is declared in the header file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun pid_t fork (void) +The @code{fork} function creates a new process. + +If the operation is successful, there are then both parent and child +processes and both see @code{fork} return, but with different values: it +returns a value of @code{0} in the child process and returns the child's +process ID in the parent process. + +If process creation failed, @code{fork} returns a value of @code{-1} in +the parent process. The following @code{errno} error conditions are +defined for @code{fork}: + +@table @code +@item EAGAIN +There aren't enough system resources to create another process, or the +user already has too many processes running. This means exceeding the +@code{RLIMIT_NPROC} resource limit, which can usually be increased; +@pxref{Limits on Resources}. + +@item ENOMEM +The process requires more space than the system can supply. +@end table +@end deftypefun + +The specific attributes of the child process that differ from the +parent process are: + +@itemize @bullet +@item +The child process has its own unique process ID. + +@item +The parent process ID of the child process is the process ID of its +parent process. + +@item +The child process gets its own copies of the parent process's open file +descriptors. Subsequently changing attributes of the file descriptors +in the parent process won't affect the file descriptors in the child, +and vice versa. @xref{Control Operations}. However, the file position +associated with each descriptor is shared by both processes; +@pxref{File Position}. + +@item +The elapsed processor times for the child process are set to zero; +see @ref{Processor Time}. + +@item +The child doesn't inherit file locks set by the parent process. +@c !!! flock locks shared +@xref{Control Operations}. + +@item +The child doesn't inherit alarms set by the parent process. +@xref{Setting an Alarm}. + +@item +The set of pending signals (@pxref{Delivery of Signal}) for the child +process is cleared. (The child process inherits its mask of blocked +signals and signal actions from the parent process.) +@end itemize + + +@comment unistd.h +@comment BSD +@deftypefun pid_t vfork (void) +The @code{vfork} function is similar to @code{fork} but on systems it +is more efficient; however, there are restrictions you must follow to +use it safely. + +While @code{fork} makes a complete copy of the calling process's +address space and allows both the parent and child to execute +independently, @code{vfork} does not make this copy. Instead, the +child process created with @code{vfork} shares its parent's address +space until it calls exits or one of the @code{exec} functions. In the +meantime, the parent process suspends execution. + +You must be very careful not to allow the child process created with +@code{vfork} to modify any global data or even local variables shared +with the parent. Furthermore, the child process cannot return from (or +do a long jump out of) the function that called @code{vfork}! This +would leave the parent process's control information very confused. If +in doubt, use @code{fork} instead. + +Some operating systems don't really implement @code{vfork}. The GNU C +library permits you to use @code{vfork} on all systems, but actually +executes @code{fork} if @code{vfork} isn't available. If you follow +the proper precautions for using @code{vfork}, your program will still +work even if the system uses @code{fork} instead. +@end deftypefun + +@node Executing a File +@section Executing a File +@cindex executing a file +@cindex @code{exec} functions + +This section describes the @code{exec} family of functions, for executing +a file as a process image. You can use these functions to make a child +process execute a new program after it has been forked. + +@pindex unistd.h +The functions in this family differ in how you specify the arguments, +but otherwise they all do the same thing. They are declared in the +header file @file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]}) +The @code{execv} function executes the file named by @var{filename} as a +new process image. + +The @var{argv} argument is an array of null-terminated strings that is +used to provide a value for the @code{argv} argument to the @code{main} +function of the program to be executed. The last element of this array +must be a null pointer. By convention, the first element of this array +is the file name of the program sans directory names. @xref{Program +Arguments}, for full details on how programs can access these arguments. + +The environment for the new process image is taken from the +@code{environ} variable of the current process image; see +@ref{Environment Variables}, for information about environments. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{}) +This is similar to @code{execv}, but the @var{argv} strings are +specified individually instead of as an array. A null pointer must be +passed as the last such argument. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]}) +This is similar to @code{execv}, but permits you to specify the environment +for the new program explicitly as the @var{env} argument. This should +be an array of strings in the same format as for the @code{environ} +variable; see @ref{Environment Access}. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, char *const @var{env}@t{[]}, @dots{}) +This is similar to @code{execl}, but permits you to specify the +environment for the new program explicitly. The environment argument is +passed following the null pointer that marks the last @var{argv} +argument, and should be an array of strings in the same format as for +the @code{environ} variable. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]}) +The @code{execvp} function is similar to @code{execv}, except that it +searches the directories listed in the @code{PATH} environment variable +(@pxref{Standard Environment}) to find the full file name of a +file from @var{filename} if @var{filename} does not contain a slash. + +This function is useful for executing system utility programs, because +it looks for them in the places that the user has chosen. Shells use it +to run the commands that users type. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{}) +This function is like @code{execl}, except that it performs the same +file name searching as the @code{execvp} function. +@end deftypefun + +The size of the argument list and environment list taken together must +not be greater than @code{ARG_MAX} bytes. @xref{General Limits}. In +the GNU system, the size (which compares against @code{ARG_MAX}) +includes, for each string, the number of characters in the string, plus +the size of a @code{char *}, plus one, rounded up to a multiple of the +size of a @code{char *}. Other systems may have somewhat different +rules for counting. + +These functions normally don't return, since execution of a new program +causes the currently executing program to go away completely. A value +of @code{-1} is returned in the event of a failure. In addition to the +usual file name errors (@pxref{File Name Errors}), the following +@code{errno} error conditions are defined for these functions: + +@table @code +@item E2BIG +The combined size of the new program's argument list and environment +list is larger than @code{ARG_MAX} bytes. The GNU system has no +specific limit on the argument list size, so this error code cannot +result, but you may get @code{ENOMEM} instead if the arguments are too +big for available memory. + +@item ENOEXEC +The specified file can't be executed because it isn't in the right format. + +@item ENOMEM +Executing the specified file requires more storage than is available. +@end table + +If execution of the new file succeeds, it updates the access time field +of the file as if the file had been read. @xref{File Times}, for more +details about access times of files. + +The point at which the file is closed again is not specified, but +is at some point before the process exits or before another process +image is executed. + +Executing a new process image completely changes the contents of memory, +copying only the argument and environment strings to new locations. But +many other attributes of the process are unchanged: + +@itemize @bullet +@item +The process ID and the parent process ID. @xref{Process Creation Concepts}. + +@item +Session and process group membership. @xref{Concepts of Job Control}. + +@item +Real user ID and group ID, and supplementary group IDs. @xref{Process +Persona}. + +@item +Pending alarms. @xref{Setting an Alarm}. + +@item +Current working directory and root directory. @xref{Working +Directory}. In the GNU system, the root directory is not copied when +executing a setuid program; instead the system default root directory +is used for the new program. + +@item +File mode creation mask. @xref{Setting Permissions}. + +@item +Process signal mask; see @ref{Process Signal Mask}. + +@item +Pending signals; see @ref{Blocking Signals}. + +@item +Elapsed processor time associated with the process; see @ref{Processor Time}. +@end itemize + +If the set-user-ID and set-group-ID mode bits of the process image file +are set, this affects the effective user ID and effective group ID +(respectively) of the process. These concepts are discussed in detail +in @ref{Process Persona}. + +Signals that are set to be ignored in the existing process image are +also set to be ignored in the new process image. All other signals are +set to the default action in the new process image. For more +information about signals, see @ref{Signal Handling}. + +File descriptors open in the existing process image remain open in the +new process image, unless they have the @code{FD_CLOEXEC} +(close-on-exec) flag set. The files that remain open inherit all +attributes of the open file description from the existing process image, +including file locks. File descriptors are discussed in @ref{Low-Level I/O}. + +Streams, by contrast, cannot survive through @code{exec} functions, +because they are located in the memory of the process itself. The new +process image has no streams except those it creates afresh. Each of +the streams in the pre-@code{exec} process image has a descriptor inside +it, and these descriptors do survive through @code{exec} (provided that +they do not have @code{FD_CLOEXEC} set). The new process image can +reconnect these to new streams using @code{fdopen} (@pxref{Descriptors +and Streams}). + +@node Process Completion +@section Process Completion +@cindex process completion +@cindex waiting for completion of child process +@cindex testing exit status of child process + +The functions described in this section are used to wait for a child +process to terminate or stop, and determine its status. These functions +are declared in the header file @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment POSIX.1 +@deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}) +The @code{waitpid} function is used to request status information from a +child process whose process ID is @var{pid}. Normally, the calling +process is suspended until the child process makes status information +available by terminating. + +Other values for the @var{pid} argument have special interpretations. A +value of @code{-1} or @code{WAIT_ANY} requests status information for +any child process; a value of @code{0} or @code{WAIT_MYPGRP} requests +information for any child process in the same process group as the +calling process; and any other negative value @minus{} @var{pgid} +requests information for any child process whose process group ID is +@var{pgid}. + +If status information for a child process is available immediately, this +function returns immediately without waiting. If more than one eligible +child process has status information available, one of them is chosen +randomly, and its status is returned immediately. To get the status +from the other eligible child processes, you need to call @code{waitpid} +again. + +The @var{options} argument is a bit mask. Its value should be the +bitwise OR (that is, the @samp{|} operator) of zero or more of the +@code{WNOHANG} and @code{WUNTRACED} flags. You can use the +@code{WNOHANG} flag to indicate that the parent process shouldn't wait; +and the @code{WUNTRACED} flag to request status information from stopped +processes as well as processes that have terminated. + +The status information from the child process is stored in the object +that @var{status-ptr} points to, unless @var{status-ptr} is a null pointer. + +The return value is normally the process ID of the child process whose +status is reported. If the @code{WNOHANG} option was specified and no +child process is waiting to be noticed, the value is zero. A value of +@code{-1} is returned in case of error. The following @code{errno} +error conditions are defined for this function: + +@table @code +@item EINTR +The function was interrupted by delivery of a signal to the calling +process. @xref{Interrupted Primitives}. + +@item ECHILD +There are no child processes to wait for, or the specified @var{pid} +is not a child of the calling process. + +@item EINVAL +An invalid value was provided for the @var{options} argument. +@end table +@end deftypefun + +These symbolic constants are defined as values for the @var{pid} argument +to the @code{waitpid} function. + +@comment Extra blank lines make it look better. +@table @code +@item WAIT_ANY + +This constant macro (whose value is @code{-1}) specifies that +@code{waitpid} should return status information about any child process. + + +@item WAIT_MYPGRP +This constant (with value @code{0}) specifies that @code{waitpid} should +return status information about any child process in the same process +group as the calling process. +@end table + +These symbolic constants are defined as flags for the @var{options} +argument to the @code{waitpid} function. You can bitwise-OR the flags +together to obtain a value to use as the argument. + +@table @code +@item WNOHANG + +This flag specifies that @code{waitpid} should return immediately +instead of waiting, if there is no child process ready to be noticed. + +@item WUNTRACED + +This flag specifies that @code{waitpid} should report the status of any +child processes that have been stopped as well as those that have +terminated. +@end table + +@comment sys/wait.h +@comment POSIX.1 +@deftypefun pid_t wait (int *@var{status-ptr}) +This is a simplified version of @code{waitpid}, and is used to wait +until any one child process terminates. The call: + +@smallexample +wait (&status) +@end smallexample + +@noindent +is exactly equivalent to: + +@smallexample +waitpid (-1, &status, 0) +@end smallexample +@end deftypefun + +@comment sys/wait.h +@comment BSD +@deftypefun pid_t wait4 (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage}) +If @var{usage} is a null pointer, @code{wait4} is equivalent to +@code{waitpid (@var{pid}, @var{status-ptr}, @var{options})}. + +If @var{usage} is not null, @code{wait4} stores usage figures for the +child process in @code{*@var{rusage}} (but only if the child has +terminated, not if it has stopped). @xref{Resource Usage}. + +This function is a BSD extension. +@end deftypefun + +Here's an example of how to use @code{waitpid} to get the status from +all child processes that have terminated, without ever waiting. This +function is designed to be a handler for @code{SIGCHLD}, the signal that +indicates that at least one child process has terminated. + +@smallexample +@group +void +sigchld_handler (int signum) +@{ + int pid; + int status; + while (1) + @{ + pid = waitpid (WAIT_ANY, &status, WNOHANG); + if (pid < 0) + @{ + perror ("waitpid"); + break; + @} + if (pid == 0) + break; + notice_termination (pid, status); + @} +@} +@end group +@end smallexample + +@node Process Completion Status +@section Process Completion Status + +If the exit status value (@pxref{Program Termination}) of the child +process is zero, then the status value reported by @code{waitpid} or +@code{wait} is also zero. You can test for other kinds of information +encoded in the returned status value using the following macros. +These macros are defined in the header file @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFEXITED (int @var{status}) +This macro returns a nonzero value if the child process terminated +normally with @code{exit} or @code{_exit}. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WEXITSTATUS (int @var{status}) +If @code{WIFEXITED} is true of @var{status}, this macro returns the +low-order 8 bits of the exit status value from the child process. +@xref{Exit Status}. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFSIGNALED (int @var{status}) +This macro returns a nonzero value if the child process terminated +because it received a signal that was not handled. +@xref{Signal Handling}. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WTERMSIG (int @var{status}) +If @code{WIFSIGNALED} is true of @var{status}, this macro returns the +signal number of the signal that terminated the child process. +@end deftypefn + +@comment sys/wait.h +@comment BSD +@deftypefn Macro int WCOREDUMP (int @var{status}) +This macro returns a nonzero value if the child process terminated +and produced a core dump. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WIFSTOPPED (int @var{status}) +This macro returns a nonzero value if the child process is stopped. +@end deftypefn + +@comment sys/wait.h +@comment POSIX.1 +@deftypefn Macro int WSTOPSIG (int @var{status}) +If @code{WIFSTOPPED} is true of @var{status}, this macro returns the +signal number of the signal that caused the child process to stop. +@end deftypefn + + +@node BSD Wait Functions +@section BSD Process Wait Functions + +The GNU library also provides these related facilities for compatibility +with BSD Unix. BSD uses the @code{union wait} data type to represent +status values rather than an @code{int}. The two representations are +actually interchangeable; they describe the same bit patterns. The GNU +C Library defines macros such as @code{WEXITSTATUS} so that they will +work on either kind of object, and the @code{wait} function is defined +to accept either type of pointer as its @var{status-ptr} argument. + +These functions are declared in @file{sys/wait.h}. +@pindex sys/wait.h + +@comment sys/wait.h +@comment BSD +@deftp {Data Type} {union wait} +This data type represents program termination status values. It has +the following members: + +@table @code +@item int w_termsig +The value of this member is the same as the result of the +@code{WTERMSIG} macro. + +@item int w_coredump +The value of this member is the same as the result of the +@code{WCOREDUMP} macro. + +@item int w_retcode +The value of this member is the same as the result of the +@code{WEXITSTATUS} macro. + +@item int w_stopsig +The value of this member is the same as the result of the +@code{WSTOPSIG} macro. +@end table + +Instead of accessing these members directly, you should use the +equivalent macros. +@end deftp + +The @code{wait3} function is the predecessor to @code{wait4}, which is +more flexible. @code{wait3} is now obsolete. + +@comment sys/wait.h +@comment BSD +@deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage}) +If @var{usage} is a null pointer, @code{wait3} is equivalent to +@code{waitpid (-1, @var{status-ptr}, @var{options})}. + +If @var{usage} is not null, @code{wait3} stores usage figures for the +child process in @code{*@var{rusage}} (but only if the child has +terminated, not if it has stopped). @xref{Resource Usage}. +@end deftypefun + +@node Process Creation Example +@section Process Creation Example + +Here is an example program showing how you might write a function +similar to the built-in @code{system}. It executes its @var{command} +argument using the equivalent of @samp{sh -c @var{command}}. + +@smallexample +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> + +/* @r{Execute the command using this shell program.} */ +#define SHELL "/bin/sh" + +@group +int +my_system (const char *command) +@{ + int status; + pid_t pid; +@end group + + pid = fork (); + if (pid == 0) + @{ + /* @r{This is the child process. Execute the shell command.} */ + execl (SHELL, SHELL, "-c", command, NULL); + _exit (EXIT_FAILURE); + @} + else if (pid < 0) + /* @r{The fork failed. Report failure.} */ + status = -1; + else + /* @r{This is the parent process. Wait for the child to complete.} */ + if (waitpid (pid, &status, 0) != pid) + status = -1; + return status; +@} +@end smallexample + +@comment Yes, this example has been tested. + +There are a couple of things you should pay attention to in this +example. + +Remember that the first @code{argv} argument supplied to the program +represents the name of the program being executed. That is why, in the +call to @code{execl}, @code{SHELL} is supplied once to name the program +to execute and a second time to supply a value for @code{argv[0]}. + +The @code{execl} call in the child process doesn't return if it is +successful. If it fails, you must do something to make the child +process terminate. Just returning a bad status code with @code{return} +would leave two processes running the original program. Instead, the +right behavior is for the child process to report failure to its parent +process. + +Call @code{_exit} to accomplish this. The reason for using @code{_exit} +instead of @code{exit} is to avoid flushing fully buffered streams such +as @code{stdout}. The buffers of these streams probably contain data +that was copied from the parent process by the @code{fork}, data that +will be output eventually by the parent process. Calling @code{exit} in +the child would output the data twice. @xref{Termination Internals}. diff --git a/manual/search.texi b/manual/search.texi new file mode 100644 index 0000000000..d914135297 --- /dev/null +++ b/manual/search.texi @@ -0,0 +1,195 @@ +@node Searching and Sorting, Pattern Matching, Locales, Top +@chapter Searching and Sorting + +This chapter describes functions for searching and sorting arrays of +arbitrary objects. You pass the appropriate comparison function to be +applied as an argument, along with the size of the objects in the array +and the total number of elements. + +@menu +* Comparison Functions:: Defining how to compare two objects. + Since the sort and search facilities + are general, you have to specify the + ordering. +* Array Search Function:: The @code{bsearch} function. +* Array Sort Function:: The @code{qsort} function. +* Search/Sort Example:: An example program. +@end menu + +@node Comparison Functions, Array Search Function, , Searching and Sorting +@section Defining the Comparison Function +@cindex Comparison Function + +In order to use the sorted array library functions, you have to describe +how to compare the elements of the array. + +To do this, you supply a comparison function to compare two elements of +the array. The library will call this function, passing as arguments +pointers to two array elements to be compared. Your comparison function +should return a value the way @code{strcmp} (@pxref{String/Array +Comparison}) does: negative if the first argument is ``less'' than the +second, zero if they are ``equal'', and positive if the first argument +is ``greater''. + +Here is an example of a comparison function which works with an array of +numbers of type @code{double}: + +@smallexample +int +compare_doubles (const double *a, const double *b) +@{ + return (int) (*a - *b); +@} +@end smallexample + +The header file @file{stdlib.h} defines a name for the data type of +comparison functions. This type is a GNU extension. + +@comment stdlib.h +@comment GNU +@tindex comparison_fn_t +@smallexample +int comparison_fn_t (const void *, const void *); +@end smallexample + +@node Array Search Function, Array Sort Function, Comparison Functions, Searching and Sorting +@section Array Search Function +@cindex search function (for arrays) +@cindex binary search function (for arrays) +@cindex array search function + +To search a sorted array for an element matching the key, use the +@code{bsearch} function. The prototype for this function is in +the header file @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun {void *} bsearch (const void *@var{key}, const void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) +The @code{bsearch} function searches the sorted array @var{array} for an object +that is equivalent to @var{key}. The array contains @var{count} elements, +each of which is of size @var{size} bytes. + +The @var{compare} function is used to perform the comparison. This +function is called with two pointer arguments and should return an +integer less than, equal to, or greater than zero corresponding to +whether its first argument is considered less than, equal to, or greater +than its second argument. The elements of the @var{array} must already +be sorted in ascending order according to this comparison function. + +The return value is a pointer to the matching array element, or a null +pointer if no match is found. If the array contains more than one element +that matches, the one that is returned is unspecified. + +This function derives its name from the fact that it is implemented +using the binary search algorithm. +@end deftypefun + +@node Array Sort Function, Search/Sort Example, Array Search Function, Searching and Sorting +@section Array Sort Function +@cindex sort function (for arrays) +@cindex quick sort function (for arrays) +@cindex array sort function + +To sort an array using an arbitrary comparison function, use the +@code{qsort} function. The prototype for this function is in +@file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) +The @var{qsort} function sorts the array @var{array}. The array contains +@var{count} elements, each of which is of size @var{size}. + +The @var{compare} function is used to perform the comparison on the +array elements. This function is called with two pointer arguments and +should return an integer less than, equal to, or greater than zero +corresponding to whether its first argument is considered less than, +equal to, or greater than its second argument. + +@cindex stable sorting +@strong{Warning:} If two objects compare as equal, their order after +sorting is unpredictable. That is to say, the sorting is not stable. +This can make a difference when the comparison considers only part of +the elements. Two elements with the same sort key may differ in other +respects. + +If you want the effect of a stable sort, you can get this result by +writing the comparison function so that, lacking other reason +distinguish between two elements, it compares them by their addresses. +Note that doing this may make the sorting algorithm less efficient, so +do it only if necessary. + +Here is a simple example of sorting an array of doubles in numerical +order, using the comparison function defined above (@pxref{Comparison +Functions}): + +@smallexample +@{ + double *array; + int size; + @dots{} + qsort (array, size, sizeof (double), compare_doubles); +@} +@end smallexample + +The @code{qsort} function derives its name from the fact that it was +originally implemented using the ``quick sort'' algorithm. +@end deftypefun + +@node Search/Sort Example, , Array Sort Function, Searching and Sorting +@section Searching and Sorting Example + +Here is an example showing the use of @code{qsort} and @code{bsearch} +with an array of structures. The objects in the array are sorted +by comparing their @code{name} fields with the @code{strcmp} function. +Then, we can look up individual objects based on their names. + +@comment This example is dedicated to the memory of Jim Henson. RIP. +@smallexample +@include search.c.texi +@end smallexample + +@cindex Kermit the frog +The output from this program looks like: + +@smallexample +Kermit, the frog +Piggy, the pig +Gonzo, the whatever +Fozzie, the bear +Sam, the eagle +Robin, the frog +Animal, the animal +Camilla, the chicken +Sweetums, the monster +Dr. Strangepork, the pig +Link Hogthrob, the pig +Zoot, the human +Dr. Bunsen Honeydew, the human +Beaker, the human +Swedish Chef, the human + +Animal, the animal +Beaker, the human +Camilla, the chicken +Dr. Bunsen Honeydew, the human +Dr. Strangepork, the pig +Fozzie, the bear +Gonzo, the whatever +Kermit, the frog +Link Hogthrob, the pig +Piggy, the pig +Robin, the frog +Sam, the eagle +Swedish Chef, the human +Sweetums, the monster +Zoot, the human + +Kermit, the frog +Gonzo, the whatever +Couldn't find Janice. +@end smallexample + + diff --git a/manual/setjmp.texi b/manual/setjmp.texi new file mode 100644 index 0000000000..dfdac1c4cd --- /dev/null +++ b/manual/setjmp.texi @@ -0,0 +1,213 @@ +@node Non-Local Exits, Signal Handling, Date and Time, Top +@chapter Non-Local Exits +@cindex non-local exits +@cindex long jumps + +Sometimes when your program detects an unusual situation inside a deeply +nested set of function calls, you would like to be able to immediately +return to an outer level of control. This section describes how you can +do such @dfn{non-local exits} using the @code{setjmp} and @code{longjmp} +functions. + +@menu +* Intro: Non-Local Intro. When and how to use these facilities. +* Details: Non-Local Details. Functions for nonlocal exits. +* Non-Local Exits and Signals:: Portability issues. +@end menu + +@node Non-Local Intro, Non-Local Details, , Non-Local Exits +@section Introduction to Non-Local Exits + +As an example of a situation where a non-local exit can be useful, +suppose you have an interactive program that has a ``main loop'' that +prompts for and executes commands. Suppose the ``read'' command reads +input from a file, doing some lexical analysis and parsing of the input +while processing it. If a low-level input error is detected, it would +be useful to be able to return immediately to the ``main loop'' instead +of having to make each of the lexical analysis, parsing, and processing +phases all have to explicitly deal with error situations initially +detected by nested calls. + +(On the other hand, if each of these phases has to do a substantial +amount of cleanup when it exits---such as closing files, deallocating +buffers or other data structures, and the like---then it can be more +appropriate to do a normal return and have each phase do its own +cleanup, because a non-local exit would bypass the intervening phases and +their associated cleanup code entirely. Alternatively, you could use a +non-local exit but do the cleanup explicitly either before or after +returning to the ``main loop''.) + +In some ways, a non-local exit is similar to using the @samp{return} +statement to return from a function. But while @samp{return} abandons +only a single function call, transferring control back to the point at +which it was called, a non-local exit can potentially abandon many +levels of nested function calls. + +You identify return points for non-local exits calling the function +@code{setjmp}. This function saves information about the execution +environment in which the call to @code{setjmp} appears in an object of +type @code{jmp_buf}. Execution of the program continues normally after +the call to @code{setjmp}, but if a exit is later made to this return +point by calling @code{longjmp} with the corresponding @w{@code{jmp_buf}} +object, control is transferred back to the point where @code{setjmp} was +called. The return value from @code{setjmp} is used to distinguish +between an ordinary return and a return made by a call to +@code{longjmp}, so calls to @code{setjmp} usually appear in an @samp{if} +statement. + +Here is how the example program described above might be set up: + +@smallexample +@include setjmp.c.texi +@end smallexample + +The function @code{abort_to_main_loop} causes an immediate transfer of +control back to the main loop of the program, no matter where it is +called from. + +The flow of control inside the @code{main} function may appear a little +mysterious at first, but it is actually a common idiom with +@code{setjmp}. A normal call to @code{setjmp} returns zero, so the +``else'' clause of the conditional is executed. If +@code{abort_to_main_loop} is called somewhere within the execution of +@code{do_command}, then it actually appears as if the @emph{same} call +to @code{setjmp} in @code{main} were returning a second time with a value +of @code{-1}. + +@need 250 +So, the general pattern for using @code{setjmp} looks something like: + +@smallexample +if (setjmp (@var{buffer})) + /* @r{Code to clean up after premature return.} */ + @dots{} +else + /* @r{Code to be executed normally after setting up the return point.} */ + @dots{} +@end smallexample + +@node Non-Local Details, Non-Local Exits and Signals, Non-Local Intro, Non-Local Exits +@section Details of Non-Local Exits + +Here are the details on the functions and data structures used for +performing non-local exits. These facilities are declared in +@file{setjmp.h}. +@pindex setjmp.h + +@comment setjmp.h +@comment ANSI +@deftp {Data Type} jmp_buf +Objects of type @code{jmp_buf} hold the state information to +be restored by a non-local exit. The contents of a @code{jmp_buf} +identify a specific place to return to. +@end deftp + +@comment setjmp.h +@comment ANSI +@deftypefn Macro int setjmp (jmp_buf @var{state}) +When called normally, @code{setjmp} stores information about the +execution state of the program in @var{state} and returns zero. If +@code{longjmp} is later used to perform a non-local exit to this +@var{state}, @code{setjmp} returns a nonzero value. +@end deftypefn + +@comment setjmp.h +@comment ANSI +@deftypefun void longjmp (jmp_buf @var{state}, int @var{value}) +This function restores current execution to the state saved in +@var{state}, and continues execution from the call to @code{setjmp} that +established that return point. Returning from @code{setjmp} by means of +@code{longjmp} returns the @var{value} argument that was passed to +@code{longjmp}, rather than @code{0}. (But if @var{value} is given as +@code{0}, @code{setjmp} returns @code{1}).@refill +@end deftypefun + +There are a lot of obscure but important restrictions on the use of +@code{setjmp} and @code{longjmp}. Most of these restrictions are +present because non-local exits require a fair amount of magic on the +part of the C compiler and can interact with other parts of the language +in strange ways. + +The @code{setjmp} function is actually a macro without an actual +function definition, so you shouldn't try to @samp{#undef} it or take +its address. In addition, calls to @code{setjmp} are safe in only the +following contexts: + +@itemize @bullet +@item +As the test expression of a selection or iteration +statement (such as @samp{if}, @samp{switch}, or @samp{while}). + +@item +As one operand of a equality or comparison operator that appears as the +test expression of a selection or iteration statement. The other +operand must be an integer constant expression. + +@item +As the operand of a unary @samp{!} operator, that appears as the +test expression of a selection or iteration statement. + +@item +By itself as an expression statement. +@end itemize + +Return points are valid only during the dynamic extent of the function +that called @code{setjmp} to establish them. If you @code{longjmp} to +a return point that was established in a function that has already +returned, unpredictable and disastrous things are likely to happen. + +You should use a nonzero @var{value} argument to @code{longjmp}. While +@code{longjmp} refuses to pass back a zero argument as the return value +from @code{setjmp}, this is intended as a safety net against accidental +misuse and is not really good programming style. + +When you perform a non-local exit, accessible objects generally retain +whatever values they had at the time @code{longjmp} was called. The +exception is that the values of automatic variables local to the +function containing the @code{setjmp} call that have been changed since +the call to @code{setjmp} are indeterminate, unless you have declared +them @code{volatile}. + +@node Non-Local Exits and Signals,, Non-Local Details, Non-Local Exits +@section Non-Local Exits and Signals + +In BSD Unix systems, @code{setjmp} and @code{longjmp} also save and +restore the set of blocked signals; see @ref{Blocking Signals}. However, +the POSIX.1 standard requires @code{setjmp} and @code{longjmp} not to +change the set of blocked signals, and provides an additional pair of +functions (@code{sigsetjmp} and @code{sigsetjmp}) to get the BSD +behavior. + +The behavior of @code{setjmp} and @code{longjmp} in the GNU library is +controlled by feature test macros; see @ref{Feature Test Macros}. The +default in the GNU system is the POSIX.1 behavior rather than the BSD +behavior. + +The facilities in this section are declared in the header file +@file{setjmp.h}. +@pindex setjmp.h + +@comment setjmp.h +@comment POSIX.1 +@deftp {Data Type} sigjmp_buf +This is similar to @code{jmp_buf}, except that it can also store state +information about the set of blocked signals. +@end deftp + +@comment setjmp.h +@comment POSIX.1 +@deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs}) +This is similar to @code{setjmp}. If @var{savesigs} is nonzero, the set +of blocked signals is saved in @var{state} and will be restored if a +@code{siglongjmp} is later performed with this @var{state}. +@end deftypefun + +@comment setjmp.h +@comment POSIX.1 +@deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value}) +This is similar to @code{longjmp} except for the type of its @var{state} +argument. If the @code{sigsetjmp} call that set this @var{state} used a +nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of +blocked signals. +@end deftypefun + diff --git a/manual/signal.texi b/manual/signal.texi new file mode 100644 index 0000000000..bca02c528b --- /dev/null +++ b/manual/signal.texi @@ -0,0 +1,3316 @@ +@node Signal Handling, Process Startup, Non-Local Exits, Top +@chapter Signal Handling + +@cindex signal +A @dfn{signal} is a software interrupt delivered to a process. The +operating system uses signals to report exceptional situations to an +executing program. Some signals report errors such as references to +invalid memory addresses; others report asynchronous events, such as +disconnection of a phone line. + +The GNU C library defines a variety of signal types, each for a +particular kind of event. Some kinds of events make it inadvisable or +impossible for the program to proceed as usual, and the corresponding +signals normally abort the program. Other kinds of signals that report +harmless events are ignored by default. + +If you anticipate an event that causes signals, you can define a handler +function and tell the operating system to run it when that particular +type of signal arrives. + +Finally, one process can send a signal to another process; this allows a +parent process to abort a child, or two related processes to communicate +and synchronize. + +@menu +* Concepts of Signals:: Introduction to the signal facilities. +* Standard Signals:: Particular kinds of signals with + standard names and meanings. +* Signal Actions:: Specifying what happens when a + particular signal is delivered. +* Defining Handlers:: How to write a signal handler function. +* Interrupted Primitives:: Signal handlers affect use of @code{open}, + @code{read}, @code{write} and other functions. +* Generating Signals:: How to send a signal to a process. +* Blocking Signals:: Making the system hold signals temporarily. +* Waiting for a Signal:: Suspending your program until a signal + arrives. +* Signal Stack:: Using a Separate Signal Stack. +* BSD Signal Handling:: Additional functions for backward + compatibility with BSD. +@end menu + +@node Concepts of Signals +@section Basic Concepts of Signals + +This section explains basic concepts of how signals are generated, what +happens after a signal is delivered, and how programs can handle +signals. + +@menu +* Kinds of Signals:: Some examples of what can cause a signal. +* Signal Generation:: Concepts of why and how signals occur. +* Delivery of Signal:: Concepts of what a signal does to the + process. +@end menu + +@node Kinds of Signals +@subsection Some Kinds of Signals + +A signal reports the occurrence of an exceptional event. These are some +of the events that can cause (or @dfn{generate}, or @dfn{raise}) a +signal: + +@itemize @bullet +@item +A program error such as dividing by zero or issuing an address outside +the valid range. + +@item +A user request to interrupt or terminate the program. Most environments +are set up to let a user suspend the program by typing @kbd{C-z}, or +terminate it with @kbd{C-c}. Whatever key sequence is used, the +operating system sends the proper signal to interrupt the process. + +@item +The termination of a child process. + +@item +Expiration of a timer or alarm. + +@item +A call to @code{kill} or @code{raise} by the same process. + +@item +A call to @code{kill} from another process. Signals are a limited but +useful form of interprocess communication. + +@item +An attempt to perform an I/O operation that cannot be done. Examples +are reading from a pipe that has no writer (@pxref{Pipes and FIFOs}), +and reading or writing to a terminal in certain situations (@pxref{Job +Control}). +@end itemize + +Each of these kinds of events (excepting explicit calls to @code{kill} +and @code{raise}) generates its own particular kind of signal. The +various kinds of signals are listed and described in detail in +@ref{Standard Signals}. + +@node Signal Generation +@subsection Concepts of Signal Generation +@cindex generation of signals + +In general, the events that generate signals fall into three major +categories: errors, external events, and explicit requests. + +An error means that a program has done something invalid and cannot +continue execution. But not all kinds of errors generate signals---in +fact, most do not. For example, opening a nonexistent file is an error, +but it does not raise a signal; instead, @code{open} returns @code{-1}. +In general, errors that are necessarily associated with certain library +functions are reported by returning a value that indicates an error. +The errors which raise signals are those which can happen anywhere in +the program, not just in library calls. These include division by zero +and invalid memory addresses. + +An external event generally has to do with I/O or other processes. +These include the arrival of input, the expiration of a timer, and the +termination of a child process. + +An explicit request means the use of a library function such as +@code{kill} whose purpose is specifically to generate a signal. + +Signals may be generated @dfn{synchronously} or @dfn{asynchronously}. A +synchronous signal pertains to a specific action in the program, and is +delivered (unless blocked) during that action. Most errors generate +signals synchronously, and so do explicit requests by a process to +generate a signal for that same process. On some machines, certain +kinds of hardware errors (usually floating-point exceptions) are not +reported completely synchronously, but may arrive a few instructions +later. + +Asynchronous signals are generated by events outside the control of the +process that receives them. These signals arrive at unpredictable times +during execution. External events generate signals asynchronously, and +so do explicit requests that apply to some other process. + +A given type of signal is either typically synchrous or typically +asynchronous. For example, signals for errors are typically synchronous +because errors generate signals synchronously. But any type of signal +can be generated synchronously or asynchronously with an explicit +request. + +@node Delivery of Signal +@subsection How Signals Are Delivered +@cindex delivery of signals +@cindex pending signals +@cindex blocked signals + +When a signal is generated, it becomes @dfn{pending}. Normally it +remains pending for just a short period of time and then is +@dfn{delivered} to the process that was signaled. However, if that kind +of signal is currently @dfn{blocked}, it may remain pending +indefinitely---until signals of that kind are @dfn{unblocked}. Once +unblocked, it will be delivered immediately. @xref{Blocking Signals}. + +@cindex specified action (for a signal) +@cindex default action (for a signal) +@cindex signal action +@cindex catching signals +When the signal is delivered, whether right away or after a long delay, +the @dfn{specified action} for that signal is taken. For certain +signals, such as @code{SIGKILL} and @code{SIGSTOP}, the action is fixed, +but for most signals, the program has a choice: ignore the signal, +specify a @dfn{handler function}, or accept the @dfn{default action} for +that kind of signal. The program specifies its choice using functions +such as @code{signal} or @code{sigaction} (@pxref{Signal Actions}). We +sometimes say that a handler @dfn{catches} the signal. While the +handler is running, that particular signal is normally blocked. + +If the specified action for a kind of signal is to ignore it, then any +such signal which is generated is discarded immediately. This happens +even if the signal is also blocked at the time. A signal discarded in +this way will never be delivered, not even if the program subsequently +specifies a different action for that kind of signal and then unblocks +it. + +If a signal arrives which the program has neither handled nor ignored, +its @dfn{default action} takes place. Each kind of signal has its own +default action, documented below (@pxref{Standard Signals}). For most kinds +of signals, the default action is to terminate the process. For certain +kinds of signals that represent ``harmless'' events, the default action +is to do nothing. + +When a signal terminates a process, its parent process can determine the +cause of termination by examining the termination status code reported +by the @code{wait} or @code{waitpid} functions. (This is discussed in +more detail in @ref{Process Completion}.) The information it can get +includes the fact that termination was due to a signal, and the kind of +signal involved. If a program you run from a shell is terminated by a +signal, the shell typically prints some kind of error message. + +The signals that normally represent program errors have a special +property: when one of these signals terminates the process, it also +writes a @dfn{core dump file} which records the state of the process at +the time of termination. You can examine the core dump with a debugger +to investigate what caused the error. + +If you raise a ``program error'' signal by explicit request, and this +terminates the process, it makes a core dump file just as if the signal +had been due directly to an error. + +@node Standard Signals +@section Standard Signals +@cindex signal names +@cindex names of signals + +@pindex signal.h +@cindex signal number +This section lists the names for various standard kinds of signals and +describes what kind of event they mean. Each signal name is a macro +which stands for a positive integer---the @dfn{signal number} for that +kind of signal. Your programs should never make assumptions about the +numeric code for a particular kind of signal, but rather refer to them +always by the names defined here. This is because the number for a +given kind of signal can vary from system to system, but the meanings of +the names are standardized and fairly uniform. + +The signal names are defined in the header file @file{signal.h}. + +@comment signal.h +@comment BSD +@deftypevr Macro int NSIG +The value of this symbolic constant is the total number of signals +defined. Since the signal numbers are allocated consecutively, +@code{NSIG} is also one greater than the largest defined signal number. +@end deftypevr + +@menu +* Program Error Signals:: Used to report serious program errors. +* Termination Signals:: Used to interrupt and/or terminate the + program. +* Alarm Signals:: Used to indicate expiration of timers. +* Asynchronous I/O Signals:: Used to indicate input is available. +* Job Control Signals:: Signals used to support job control. +* Operation Error Signals:: Used to report operational system errors. +* Miscellaneous Signals:: Miscellaneous Signals. +* Signal Messages:: Printing a message describing a signal. +@end menu + +@node Program Error Signals +@subsection Program Error Signals +@cindex program error signals + +The following signals are generated when a serious program error is +detected by the operating system or the computer itself. In general, +all of these signals are indications that your program is seriously +broken in some way, and there's usually no way to continue the +computation which encountered the error. + +Some programs handle program error signals in order to tidy up before +terminating; for example, programs that turn off echoing of terminal +input should handle program error signals in order to turn echoing back +on. The handler should end by specifying the default action for the +signal that happened and then reraising it; this will cause the program +to terminate with that signal, as if it had not had a handler. +(@xref{Termination in Handler}.) + +Termination is the sensible ultimate outcome from a program error in +most programs. However, programming systems such as Lisp that can load +compiled user programs might need to keep executing even if a user +program incurs an error. These programs have handlers which use +@code{longjmp} to return control to the command level. + +The default action for all of these signals is to cause the process to +terminate. If you block or ignore these signals or establish handlers +for them that return normally, your program will probably break horribly +when such signals happen, unless they are generated by @code{raise} or +@code{kill} instead of a real error. + +@vindex COREFILE +When one of these program error signals terminates a process, it also +writes a @dfn{core dump file} which records the state of the process at +the time of termination. The core dump file is named @file{core} and is +written in whichever directory is current in the process at the time. +(On the GNU system, you can specify the file name for core dumps with +the environment variable @code{COREFILE}.) The purpose of core dump +files is so that you can examine them with a debugger to investigate +what caused the error. + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGFPE +The @code{SIGFPE} signal reports a fatal arithmetic error. Although the +name is derived from ``floating-point exception'', this signal actually +covers all arithmetic errors, including division by zero and overflow. +If a program stores integer data in a location which is then used in a +floating-point operation, this often causes an ``invalid operation'' +exception, because the processor cannot recognize the data as a +floating-point number. +@cindex exception +@cindex floating-point exception + +Actual floating-point exceptions are a complicated subject because there +are many types of exceptions with subtly different meanings, and the +@code{SIGFPE} signal doesn't distinguish between them. The @cite{IEEE +Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)} +defines various floating-point exceptions and requires conforming +computer systems to report their occurrences. However, this standard +does not specify how the exceptions are reported, or what kinds of +handling and control the operating system can offer to the programmer. +@end deftypevr + +BSD systems provide the @code{SIGFPE} handler with an extra argument +that distinguishes various causes of the exception. In order to access +this argument, you must define the handler to accept two arguments, +which means you must cast it to a one-argument function type in order to +establish the handler. The GNU library does provide this extra +argument, but the value is meaningful only on operating systems that +provide the information (BSD systems and GNU systems). + +@table @code +@comment signal.h +@comment BSD +@item FPE_INTOVF_TRAP +@vindex FPE_INTOVF_TRAP +Integer overflow (impossible in a C program unless you enable overflow +trapping in a hardware-specific fashion). +@comment signal.h +@comment BSD +@item FPE_INTDIV_TRAP +@vindex FPE_INTDIV_TRAP +Integer division by zero. +@comment signal.h +@comment BSD +@item FPE_SUBRNG_TRAP +@vindex FPE_SUBRNG_TRAP +Subscript-range (something that C programs never check for). +@comment signal.h +@comment BSD +@item FPE_FLTOVF_TRAP +@vindex FPE_FLTOVF_TRAP +Floating overflow trap. +@comment signal.h +@comment BSD +@item FPE_FLTDIV_TRAP +@vindex FPE_FLTDIV_TRAP +Floating/decimal division by zero. +@comment signal.h +@comment BSD +@item FPE_FLTUND_TRAP +@vindex FPE_FLTUND_TRAP +Floating underflow trap. (Trapping on floating underflow is not +normally enabled.) +@comment signal.h +@comment BSD +@item FPE_DECOVF_TRAP +@vindex FPE_DECOVF_TRAP +Decimal overflow trap. (Only a few machines have decimal arithmetic and +C never uses it.) +@ignore @c These seem redundant +@comment signal.h +@comment BSD +@item FPE_FLTOVF_FAULT +@vindex FPE_FLTOVF_FAULT +Floating overflow fault. +@comment signal.h +@comment BSD +@item FPE_FLTDIV_FAULT +@vindex FPE_FLTDIV_FAULT +Floating divide by zero fault. +@comment signal.h +@comment BSD +@item FPE_FLTUND_FAULT +@vindex FPE_FLTUND_FAULT +Floating underflow fault. +@end ignore +@end table + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGILL +The name of this signal is derived from ``illegal instruction''; it +usually means your program is trying to execute garbage or a privileged +instruction. Since the C compiler generates only valid instructions, +@code{SIGILL} typically indicates that the executable file is corrupted, +or that you are trying to execute data. Some common ways of getting +into the latter situation are by passing an invalid object where a +pointer to a function was expected, or by writing past the end of an +automatic array (or similar problems with pointers to automatic +variables) and corrupting other data on the stack such as the return +address of a stack frame. + +@code{SIGILL} can also be generated when the stack overflows, or when +the system has trouble running the handler for a signal. +@end deftypevr +@cindex illegal instruction + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGSEGV +@cindex segmentation violation +This signal is generated when a program tries to read or write outside +the memory that is allocated for it, or to write memory that can only be +read. (Actually, the signals only occur when the program goes far +enough outside to be detected by the system's memory protection +mechanism.) The name is an abbreviation for ``segmentation violation''. + +Common ways of getting a @code{SIGSEGV} condition include dereferencing +a null or uninitialized pointer, or when you use a pointer to step +through an array, but fail to check for the end of the array. It varies +among systems whether dereferencing a null pointer generates +@code{SIGSEGV} or @code{SIGBUS}. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGBUS +This signal is generated when an invalid pointer is dereferenced. Like +@code{SIGSEGV}, this signal is typically the result of dereferencing an +uninitialized pointer. The difference between the two is that +@code{SIGSEGV} indicates an invalid access to valid memory, while +@code{SIGBUS} indicates an access to an invalid address. In particular, +@code{SIGBUS} signals often result from dereferencing a misaligned +pointer, such as referring to a four-word integer at an address not +divisible by four. (Each kind of computer has its own requirements for +address alignment.) + +The name of this signal is an abbreviation for ``bus error''. +@end deftypevr +@cindex bus error + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGABRT +@cindex abort signal +This signal indicates an error detected by the program itself and +reported by calling @code{abort}. @xref{Aborting a Program}. +@end deftypevr + +@comment signal.h +@comment Unix +@deftypevr Macro int SIGIOT +Generated by the PDP-11 ``iot'' instruction. On most machines, this is +just another name for @code{SIGABRT}. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGTRAP +Generated by the machine's breakpoint instruction, and possibly other +trap instructions. This signal is used by debuggers. Your program will +probably only see @code{SIGTRAP} if it is somehow executing bad +instructions. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGEMT +Emulator trap; this results from certain unimplemented instructions +which might be emulated in software, or the operating system's +failure to properly emulate them. +@end deftypevr + +@comment signal.h +@comment Unix +@deftypevr Macro int SIGSYS +Bad system call; that is to say, the instruction to trap to the +operating system was executed, but the code number for the system call +to perform was invalid. +@end deftypevr + +@node Termination Signals +@subsection Termination Signals +@cindex program termination signals + +These signals are all used to tell a process to terminate, in one way +or another. They have different names because they're used for slightly +different purposes, and programs might want to handle them differently. + +The reason for handling these signals is usually so your program can +tidy up as appropriate before actually terminating. For example, you +might want to save state information, delete temporary files, or restore +the previous terminal modes. Such a handler should end by specifying +the default action for the signal that happened and then reraising it; +this will cause the program to terminate with that signal, as if it had +not had a handler. (@xref{Termination in Handler}.) + +The (obvious) default action for all of these signals is to cause the +process to terminate. + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGTERM +@cindex termination signal +The @code{SIGTERM} signal is a generic signal used to cause program +termination. Unlike @code{SIGKILL}, this signal can be blocked, +handled, and ignored. It is the normal way to politely ask a program to +terminate. + +The shell command @code{kill} generates @code{SIGTERM} by default. +@pindex kill +@end deftypevr + +@comment signal.h +@comment ANSI +@deftypevr Macro int SIGINT +@cindex interrupt signal +The @code{SIGINT} (``program interrupt'') signal is sent when the user +types the INTR character (normally @kbd{C-c}). @xref{Special +Characters}, for information about terminal driver support for +@kbd{C-c}. +@end deftypevr + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGQUIT +@cindex quit signal +@cindex quit signal +The @code{SIGQUIT} signal is similar to @code{SIGINT}, except that it's +controlled by a different key---the QUIT character, usually +@kbd{C-\}---and produces a core dump when it terminates the process, +just like a program error signal. You can think of this as a +program error condition ``detected'' by the user. + +@xref{Program Error Signals}, for information about core dumps. +@xref{Special Characters}, for information about terminal driver +support. + +Certain kinds of cleanups are best omitted in handling @code{SIGQUIT}. +For example, if the program creates temporary files, it should handle +the other termination requests by deleting the temporary files. But it +is better for @code{SIGQUIT} not to delete them, so that the user can +examine them in conjunction with the core dump. +@end deftypevr + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGKILL +The @code{SIGKILL} signal is used to cause immediate program termination. +It cannot be handled or ignored, and is therefore always fatal. It is +also not possible to block this signal. + +This signal is usually generated only by explicit request. Since it +cannot be handled, you should generate it only as a last resort, after +first trying a less drastic method such as @kbd{C-c} or @code{SIGTERM}. +If a process does not respond to any other termination signals, sending +it a @code{SIGKILL} signal will almost always cause it to go away. + +In fact, if @code{SIGKILL} fails to terminate a process, that by itself +constitutes an operating system bug which you should report. + +The system will generate @code{SIGKILL} for a process itself under some +unusual conditions where the program cannot possible continue to run +(even to run a signal handler). +@end deftypevr +@cindex kill signal + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGHUP +@cindex hangup signal +The @code{SIGHUP} (``hang-up'') signal is used to report that the user's +terminal is disconnected, perhaps because a network or telephone +connection was broken. For more information about this, see @ref{Control +Modes}. + +This signal is also used to report the termination of the controlling +process on a terminal to jobs associated with that session; this +termination effectively disconnects all processes in the session from +the controlling terminal. For more information, see @ref{Termination +Internals}. +@end deftypevr + +@node Alarm Signals +@subsection Alarm Signals + +These signals are used to indicate the expiration of timers. +@xref{Setting an Alarm}, for information about functions that cause +these signals to be sent. + +The default behavior for these signals is to cause program termination. +This default is rarely useful, but no other default would be useful; +most of the ways of using these signals would require handler functions +in any case. + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGALRM +This signal typically indicates expiration of a timer that measures real +or clock time. It is used by the @code{alarm} function, for example. +@end deftypevr +@cindex alarm signal + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGVTALRM +This signal typically indicates expiration of a timer that measures CPU +time used by the current process. The name is an abbreviation for +``virtual time alarm''. +@end deftypevr +@cindex virtual time alarm signal + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGPROF +This signal is typically indicates expiration of a timer that measures +both CPU time used by the current process, and CPU time expended on +behalf of the process by the system. Such a timer is used to implement +code profiling facilities, hence the name of this signal. +@end deftypevr +@cindex profiling alarm signal + + +@node Asynchronous I/O Signals +@subsection Asynchronous I/O Signals + +The signals listed in this section are used in conjunction with +asynchronous I/O facilities. You have to take explicit action by +calling @code{fcntl} to enable a particular file descriptior to generate +these signals (@pxref{Interrupt Input}). The default action for these +signals is to ignore them. + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGIO +@cindex input available signal +@cindex output possible signal +This signal is sent when a file descriptor is ready to perform input +or output. + +On most operating systems, terminals and sockets are the only kinds of +files that can generate @code{SIGIO}; other kinds, including ordinary +files, never generate @code{SIGIO} even if you ask them to. + +In the GNU system @code{SIGIO} will always be generated properly +if you successfully set asynchronous mode with @code{fcntl}. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGURG +@cindex urgent data signal +This signal is sent when ``urgent'' or out-of-band data arrives on a +socket. @xref{Out-of-Band Data}. +@end deftypevr + +@comment signal.h +@comment SVID +@deftypevr Macro int SIGPOLL +This is a System V signal name, more or less similar to @code{SIGIO}. +It is defined only for compatibility. +@end deftypevr + +@node Job Control Signals +@subsection Job Control Signals +@cindex job control signals + +These signals are used to support job control. If your system +doesn't support job control, then these macros are defined but the +signals themselves can't be raised or handled. + +You should generally leave these signals alone unless you really +understand how job control works. @xref{Job Control}. + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGCHLD +@cindex child process signal +This signal is sent to a parent process whenever one of its child +processes terminates or stops. + +The default action for this signal is to ignore it. If you establish a +handler for this signal while there are child processes that have +terminated but not reported their status via @code{wait} or +@code{waitpid} (@pxref{Process Completion}), whether your new handler +applies to those processes or not depends on the particular operating +system. +@end deftypevr + +@comment signal.h +@comment SVID +@deftypevr Macro int SIGCLD +This is an obsolete name for @code{SIGCHLD}. +@end deftypevr + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGCONT +@cindex continue signal +You can send a @code{SIGCONT} signal to a process to make it continue. +This signal is special---it always makes the process continue if it is +stopped, before the signal is delivered. The default behavior is to do +nothing else. You cannot block this signal. You can set a handler, but +@code{SIGCONT} always makes the process continue regardless. + +Most programs have no reason to handle @code{SIGCONT}; they simply +resume execution without realizing they were ever stopped. You can use +a handler for @code{SIGCONT} to make a program do something special when +it is stopped and continued---for example, to reprint a prompt when it +is suspended while waiting for input. +@end deftypevr + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGSTOP +The @code{SIGSTOP} signal stops the process. It cannot be handled, +ignored, or blocked. +@end deftypevr +@cindex stop signal + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGTSTP +The @code{SIGTSTP} signal is an interactive stop signal. Unlike +@code{SIGSTOP}, this signal can be handled and ignored. + +Your program should handle this signal if you have a special need to +leave files or system tables in a secure state when a process is +stopped. For example, programs that turn off echoing should handle +@code{SIGTSTP} so they can turn echoing back on before stopping. + +This signal is generated when the user types the SUSP character +(normally @kbd{C-z}). For more information about terminal driver +support, see @ref{Special Characters}. +@end deftypevr +@cindex interactive stop signal + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGTTIN +A process cannot read from the the user's terminal while it is running +as a background job. When any process in a background job tries to +read from the terminal, all of the processes in the job are sent a +@code{SIGTTIN} signal. The default action for this signal is to +stop the process. For more information about how this interacts with +the terminal driver, see @ref{Access to the Terminal}. +@end deftypevr +@cindex terminal input signal + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGTTOU +This is similar to @code{SIGTTIN}, but is generated when a process in a +background job attempts to write to the terminal or set its modes. +Again, the default action is to stop the process. @code{SIGTTOU} is +only generated for an attempt to write to the terminal if the +@code{TOSTOP} output mode is set; @pxref{Output Modes}. +@end deftypevr +@cindex terminal output signal + +While a process is stopped, no more signals can be delivered to it until +it is continued, except @code{SIGKILL} signals and (obviously) +@code{SIGCONT} signals. The signals are marked as pending, but not +delivered until the process is continued. The @code{SIGKILL} signal +always causes termination of the process and can't be blocked, handled +or ignored. You can ignore @code{SIGCONT}, but it always causes the +process to be continued anyway if it is stopped. Sending a +@code{SIGCONT} signal to a process causes any pending stop signals for +that process to be discarded. Likewise, any pending @code{SIGCONT} +signals for a process are discarded when it receives a stop signal. + +When a process in an orphaned process group (@pxref{Orphaned Process +Groups}) receives a @code{SIGTSTP}, @code{SIGTTIN}, or @code{SIGTTOU} +signal and does not handle it, the process does not stop. Stopping the +process would probably not be very useful, since there is no shell +program that will notice it stop and allow the user to continue it. +What happens instead depends on the operating system you are using. +Some systems may do nothing; others may deliver another signal instead, +such as @code{SIGKILL} or @code{SIGHUP}. In the GNU system, the process +dies with @code{SIGKILL}; this avoids the problem of many stopped, +orphaned processes lying around the system. + +@ignore +On the GNU system, it is possible to reattach to the orphaned process +group and continue it, so stop signals do stop the process as usual on +a GNU system unless you have requested POSIX compatibility ``till it +hurts.'' +@end ignore + +@node Operation Error Signals +@subsection Operation Error Signals + +These signals are used to report various errors generated by an +operation done by the program. They do not necessarily indicate a +programming error in the program, but an error that prevents an +operating system call from completing. The default action for all of +them is to cause the process to terminate. + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGPIPE +@cindex pipe signal +@cindex broken pipe signal +Broken pipe. If you use pipes or FIFOs, you have to design your +application so that one process opens the pipe for reading before +another starts writing. If the reading process never starts, or +terminates unexpectedly, writing to the pipe or FIFO raises a +@code{SIGPIPE} signal. If @code{SIGPIPE} is blocked, handled or +ignored, the offending call fails with @code{EPIPE} instead. + +Pipes and FIFO special files are discussed in more detail in @ref{Pipes +and FIFOs}. + +Another cause of @code{SIGPIPE} is when you try to output to a socket +that isn't connected. @xref{Sending Data}. +@end deftypevr + +@comment signal.h +@comment GNU +@deftypevr Macro int SIGLOST +@cindex lost resource signal +Resource lost. This signal is generated when you have an advisory lock +on an NFS file, and the NFS server reboots and forgets about your lock. + +In the GNU system, @code{SIGLOST} is generated when any server program +dies unexpectedly. It is usually fine to ignore the signal; whatever +call was made to the server that died just returns an error. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGXCPU +CPU time limit exceeded. This signal is generated when the process +exceeds its soft resource limit on CPU time. @xref{Limits on Resources}. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGXFSZ +File size limit exceeded. This signal is generated when the process +attempts to extend a file so it exceeds the process's soft resource +limit on file size. @xref{Limits on Resources}. +@end deftypevr + +@node Miscellaneous Signals +@subsection Miscellaneous Signals + +These signals are used for various other purposes. In general, they +will not affect your program unless it explicitly uses them for something. + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGUSR1 +@end deftypevr +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SIGUSR2 +@cindex user signals +The @code{SIGUSR1} and @code{SIGUSR2} signals are set aside for you to +use any way you want. They're useful for simple interprocess +communication, if you write a signal handler for them in the program +that receives the signal. + +There is an example showing the use of @code{SIGUSR1} and @code{SIGUSR2} +in @ref{Signaling Another Process}. + +The default action is to terminate the process. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGWINCH +Window size change. This is generated on some systems (including GNU) +when the terminal driver's record of the number of rows and columns on +the screen is changed. The default action is to ignore it. + +If a program does full-screen display, it should handle @code{SIGWINCH}. +When the signal arrives, it should fetch the new screen size and +reformat its display accordingly. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SIGINFO +Information request. In 4.4 BSD and the GNU system, this signal is sent +to all the processes in the foreground process group of the controlling +terminal when the user types the STATUS character in canonical mode; +@pxref{Signal Characters}. + +If the process is the leader of the process group, the default action is +to print some status information about the system and what the process +is doing. Otherwise the default is to do nothing. +@end deftypevr + +@node Signal Messages +@subsection Signal Messages +@cindex signal messages + +We mentioned above that the shell prints a message describing the signal +that terminated a child process. The clean way to print a message +describing a signal is to use the functions @code{strsignal} and +@code{psignal}. These functions use a signal number to specify which +kind of signal to describe. The signal number may come from the +termination status of a child process (@pxref{Process Completion}) or it +may come from a signal handler in the same process. + +@comment string.h +@comment GNU +@deftypefun {char *} strsignal (int @var{signum}) +This function returns a pointer to a statically-allocated string +containing a message describing the signal @var{signum}. You +should not modify the contents of this string; and, since it can be +rewritten on subsequent calls, you should save a copy of it if you need +to reference it later. + +@pindex string.h +This function is a GNU extension, declared in the header file +@file{string.h}. +@end deftypefun + +@comment signal.h +@comment BSD +@deftypefun void psignal (int @var{signum}, const char *@var{message}) +This function prints a message describing the signal @var{signum} to the +standard error output stream @code{stderr}; see @ref{Standard Streams}. + +If you call @code{psignal} with a @var{message} that is either a null +pointer or an empty string, @code{psignal} just prints the message +corresponding to @var{signum}, adding a trailing newline. + +If you supply a non-null @var{message} argument, then @code{psignal} +prefixes its output with this string. It adds a colon and a space +character to separate the @var{message} from the string corresponding +to @var{signum}. + +@pindex stdio.h +This function is a BSD feature, declared in the header file @file{signal.h}. +@end deftypefun + +@vindex sys_siglist +There is also an array @code{sys_siglist} which contains the messages +for the various signal codes. This array exists on BSD systems, unlike +@code{strsignal}. + +@node Signal Actions +@section Specifying Signal Actions +@cindex signal actions +@cindex establishing a handler + +The simplest way to change the action for a signal is to use the +@code{signal} function. You can specify a built-in action (such as to +ignore the signal), or you can @dfn{establish a handler}. + +The GNU library also implements the more versatile @code{sigaction} +facility. This section describes both facilities and gives suggestions +on which to use when. + +@menu +* Basic Signal Handling:: The simple @code{signal} function. +* Advanced Signal Handling:: The more powerful @code{sigaction} function. +* Signal and Sigaction:: How those two functions interact. +* Sigaction Function Example:: An example of using the sigaction function. +* Flags for Sigaction:: Specifying options for signal handling. +* Initial Signal Actions:: How programs inherit signal actions. +@end menu + +@node Basic Signal Handling +@subsection Basic Signal Handling +@cindex @code{signal} function + +The @code{signal} function provides a simple interface for establishing +an action for a particular signal. The function and associated macros +are declared in the header file @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment GNU +@deftp {Data Type} sighandler_t +This is the type of signal handler functions. Signal handlers take one +integer argument specifying the signal number, and have return type +@code{void}. So, you should define handler functions like this: + +@smallexample +void @var{handler} (int @code{signum}) @{ @dots{} @} +@end smallexample + +The name @code{sighandler_t} for this data type is a GNU extension. +@end deftp + +@comment signal.h +@comment ANSI +@deftypefun sighandler_t signal (int @var{signum}, sighandler_t @var{action}) +The @code{signal} function establishes @var{action} as the action for +the signal @var{signum}. + +The first argument, @var{signum}, identifies the signal whose behavior +you want to control, and should be a signal number. The proper way to +specify a signal number is with one of the symbolic signal names +described in @ref{Standard Signals}---don't use an explicit number, because +the numerical code for a given kind of signal may vary from operating +system to operating system. + +The second argument, @var{action}, specifies the action to use for the +signal @var{signum}. This can be one of the following: + +@table @code +@item SIG_DFL +@vindex SIG_DFL +@cindex default action for a signal +@code{SIG_DFL} specifies the default action for the particular signal. +The default actions for various kinds of signals are stated in +@ref{Standard Signals}. + +@item SIG_IGN +@vindex SIG_IGN +@cindex ignore action for a signal +@code{SIG_IGN} specifies that the signal should be ignored. + +Your program generally should not ignore signals that represent serious +events or that are normally used to request termination. You cannot +ignore the @code{SIGKILL} or @code{SIGSTOP} signals at all. You can +ignore program error signals like @code{SIGSEGV}, but ignoring the error +won't enable the program to continue executing meaningfully. Ignoring +user requests such as @code{SIGINT}, @code{SIGQUIT}, and @code{SIGTSTP} +is unfriendly. + +When you do not wish signals to be delivered during a certain part of +the program, the thing to do is to block them, not ignore them. +@xref{Blocking Signals}. + +@item @var{handler} +Supply the address of a handler function in your program, to specify +running this handler as the way to deliver the signal. + +For more information about defining signal handler functions, +see @ref{Defining Handlers}. +@end table + +If you set the action for a signal to @code{SIG_IGN}, or if you set it +to @code{SIG_DFL} and the default action is to ignore that signal, then +any pending signals of that type are discarded (even if they are +blocked). Discarding the pending signals means that they will never be +delivered, not even if you subsequently specify another action and +unblock this kind of signal. + +The @code{signal} function returns the action that was previously in +effect for the specified @var{signum}. You can save this value and +restore it later by calling @code{signal} again. + +If @code{signal} can't honor the request, it returns @code{SIG_ERR} +instead. The following @code{errno} error conditions are defined for +this function: + +@table @code +@item EINVAL +You specified an invalid @var{signum}; or you tried to ignore or provide +a handler for @code{SIGKILL} or @code{SIGSTOP}. +@end table +@end deftypefun + +Here is a simple example of setting up a handler to delete temporary +files when certain fatal signals happen: + +@smallexample +#include <signal.h> + +void +termination_handler (int signum) +@{ + struct temp_file *p; + + for (p = temp_file_list; p; p = p->next) + unlink (p->name); +@} + +int +main (void) +@{ + @dots{} + if (signal (SIGINT, termination_handler) == SIG_IGN) + signal (SIGINT, SIG_IGN); + if (signal (SIGHUP, termination_handler) == SIG_IGN) + signal (SIGHUP, SIG_IGN); + if (signal (SIGTERM, termination_handler) == SIG_IGN) + signal (SIGTERM, SIG_IGN); + @dots{} +@} +@end smallexample + +@noindent +Note how if a given signal was previously set to be ignored, this code +avoids altering that setting. This is because non-job-control shells +often ignore certain signals when starting children, and it is important +for the children to respect this. + +We do not handle @code{SIGQUIT} or the program error signals in this +example because these are designed to provide information for debugging +(a core dump), and the temporary files may give useful information. + +@comment signal.h +@comment SVID +@deftypefun sighandler_t ssignal (int @var{signum}, sighandler_t @var{action}) +The @code{ssignal} function does the same thing as @code{signal}; it is +provided only for compatibility with SVID. +@end deftypefun + +@comment signal.h +@comment ANSI +@deftypevr Macro sighandler_t SIG_ERR +The value of this macro is used as the return value from @code{signal} +to indicate an error. +@end deftypevr + +@ignore +@comment RMS says that ``we don't do this''. +Implementations might define additional macros for built-in signal +actions that are suitable as a @var{action} argument to @code{signal}, +besides @code{SIG_IGN} and @code{SIG_DFL}. Identifiers whose names +begin with @samp{SIG_} followed by an uppercase letter are reserved for +this purpose. +@end ignore + + +@node Advanced Signal Handling +@subsection Advanced Signal Handling +@cindex @code{sigaction} function + +The @code{sigaction} function has the same basic effect as +@code{signal}: to specify how a signal should be handled by the process. +However, @code{sigaction} offers more control, at the expense of more +complexity. In particular, @code{sigaction} allows you to specify +additional flags to control when the signal is generated and how the +handler is invoked. + +The @code{sigaction} function is declared in @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment POSIX.1 +@deftp {Data Type} {struct sigaction} +Structures of type @code{struct sigaction} are used in the +@code{sigaction} function to specify all the information about how to +handle a particular signal. This structure contains at least the +following members: + +@table @code +@item sighandler_t sa_handler +This is used in the same way as the @var{action} argument to the +@code{signal} function. The value can be @code{SIG_DFL}, +@code{SIG_IGN}, or a function pointer. @xref{Basic Signal Handling}. + +@item sigset_t sa_mask +This specifies a set of signals to be blocked while the handler runs. +Blocking is explained in @ref{Blocking for Handler}. Note that the +signal that was delivered is automatically blocked by default before its +handler is started; this is true regardless of the value in +@code{sa_mask}. If you want that signal not to be blocked within its +handler, you must write code in the handler to unblock it. + +@item int sa_flags +This specifies various flags which can affect the behavior of +the signal. These are described in more detail in @ref{Flags for Sigaction}. +@end table +@end deftp + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigaction (int @var{signum}, const struct sigaction *@var{action}, struct sigaction *@var{old-action}) +The @var{action} argument is used to set up a new action for the signal +@var{signum}, while the @var{old-action} argument is used to return +information about the action previously associated with this symbol. +(In other words, @var{old-action} has the same purpose as the +@code{signal} function's return value---you can check to see what the +old action in effect for the signal was, and restore it later if you +want.) + +Either @var{action} or @var{old-action} can be a null pointer. If +@var{old-action} is a null pointer, this simply suppresses the return +of information about the old action. If @var{action} is a null pointer, +the action associated with the signal @var{signum} is unchanged; this +allows you to inquire about how a signal is being handled without changing +that handling. + +The return value from @code{sigaction} is zero if it succeeds, and +@code{-1} on failure. The following @code{errno} error conditions are +defined for this function: + +@table @code +@item EINVAL +The @var{signum} argument is not valid, or you are trying to +trap or ignore @code{SIGKILL} or @code{SIGSTOP}. +@end table +@end deftypefun + +@node Signal and Sigaction +@subsection Interaction of @code{signal} and @code{sigaction} + +It's possible to use both the @code{signal} and @code{sigaction} +functions within a single program, but you have to be careful because +they can interact in slightly strange ways. + +The @code{sigaction} function specifies more information than the +@code{signal} function, so the return value from @code{signal} cannot +express the full range of @code{sigaction} possibilities. Therefore, if +you use @code{signal} to save and later reestablish an action, it may +not be able to reestablish properly a handler that was established with +@code{sigaction}. + +To avoid having problems as a result, always use @code{sigaction} to +save and restore a handler if your program uses @code{sigaction} at all. +Since @code{sigaction} is more general, it can properly save and +reestablish any action, regardless of whether it was established +originally with @code{signal} or @code{sigaction}. + +On some systems if you establish an action with @code{signal} and then +examine it with @code{sigaction}, the handler address that you get may +not be the same as what you specified with @code{signal}. It may not +even be suitable for use as an action argument with @code{signal}. But +you can rely on using it as an argument to @code{sigaction}. This +problem never happens on the GNU system. + +So, you're better off using one or the other of the mechanisms +consistently within a single program. + +@strong{Portability Note:} The basic @code{signal} function is a feature +of ANSI C, while @code{sigaction} is part of the POSIX.1 standard. If +you are concerned about portability to non-POSIX systems, then you +should use the @code{signal} function instead. + +@node Sigaction Function Example +@subsection @code{sigaction} Function Example + +In @ref{Basic Signal Handling}, we gave an example of establishing a +simple handler for termination signals using @code{signal}. Here is an +equivalent example using @code{sigaction}: + +@smallexample +#include <signal.h> + +void +termination_handler (int signum) +@{ + struct temp_file *p; + + for (p = temp_file_list; p; p = p->next) + unlink (p->name); +@} + +int +main (void) +@{ + @dots{} + struct sigaction new_action, old_action; + + /* @r{Set up the structure to specify the new action.} */ + new_action.sa_handler = termination_handler; + sigemptyset (&new_action.sa_mask); + new_action.sa_flags = 0; + + sigaction (SIGINT, NULL, &old_action); + if (old_action.sa_handler != SIG_IGN) + sigaction (SIGINT, &new_action, NULL); + sigaction (SIGHUP, NULL, &old_action); + if (old_action.sa_handler != SIG_IGN) + sigaction (SIGHUP, &new_action, NULL); + sigaction (SIGTERM, NULL, &old_action); + if (old_action.sa_handler != SIG_IGN) + sigaction (SIGTERM, &new_action, NULL); + @dots{} +@} +@end smallexample + +The program just loads the @code{new_action} structure with the desired +parameters and passes it in the @code{sigaction} call. The usage of +@code{sigemptyset} is described later; see @ref{Blocking Signals}. + +As in the example using @code{signal}, we avoid handling signals +previously set to be ignored. Here we can avoid altering the signal +handler even momentarily, by using the feature of @code{sigaction} that +lets us examine the current action without specifying a new one. + +Here is another example. It retrieves information about the current +action for @code{SIGINT} without changing that action. + +@smallexample +struct sigaction query_action; + +if (sigaction (SIGINT, NULL, &query_action) < 0) + /* @r{@code{sigaction} returns -1 in case of error.} */ +else if (query_action.sa_handler == SIG_DFL) + /* @r{@code{SIGINT} is handled in the default, fatal manner.} */ +else if (query_action.sa_handler == SIG_IGN) + /* @r{@code{SIGINT} is ignored.} */ +else + /* @r{A programmer-defined signal handler is in effect.} */ +@end smallexample + +@node Flags for Sigaction +@subsection Flags for @code{sigaction} +@cindex signal flags +@cindex flags for @code{sigaction} +@cindex @code{sigaction} flags + +The @code{sa_flags} member of the @code{sigaction} structure is a +catch-all for special features. Most of the time, @code{SA_RESTART} is +a good value to use for this field. + +The value of @code{sa_flags} is interpreted as a bit mask. Thus, you +should choose the flags you want to set, @sc{or} those flags together, +and store the result in the @code{sa_flags} member of your +@code{sigaction} structure. + +Each signal number has its own set of flags. Each call to +@code{sigaction} affects one particular signal number, and the flags +that you specify apply only to that particular signal. + +In the GNU C library, establishing a handler with @code{signal} sets all +the flags to zero except for @code{SA_RESTART}, whose value depends on +the settings you have made with @code{siginterrupt}. @xref{Interrupted +Primitives}, to see what this is about. + +@pindex signal.h +These macros are defined in the header file @file{signal.h}. + +@comment signal.h +@comment POSIX.1 +@deftypevr Macro int SA_NOCLDSTOP +This flag is meaningful only for the @code{SIGCHLD} signal. When the +flag is set, the system delivers the signal for a terminated child +process but not for one that is stopped. By default, @code{SIGCHLD} is +delivered for both terminated children and stopped children. + +Setting this flag for a signal other than @code{SIGCHLD} has no effect. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SA_ONSTACK +If this flag is set for a particular signal number, the system uses the +signal stack when delivering that kind of signal. @xref{Signal Stack}. +If a signal with this flag arrives and you have not set a signal stack, +the system terminates the program with @code{SIGILL}. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SA_RESTART +This flag controls what happens when a signal is delivered during +certain primitives (such as @code{open}, @code{read} or @code{write}), +and the signal handler returns normally. There are two alternatives: +the library function can resume, or it can return failure with error +code @code{EINTR}. + +The choice is controlled by the @code{SA_RESTART} flag for the +particular kind of signal that was delivered. If the flag is set, +returning from a handler resumes the library function. If the flag is +clear, returning from a handler makes the function fail. +@xref{Interrupted Primitives}. +@end deftypevr + +@node Initial Signal Actions +@subsection Initial Signal Actions +@cindex initial signal actions + +When a new process is created (@pxref{Creating a Process}), it inherits +handling of signals from its parent process. However, when you load a +new process image using the @code{exec} function (@pxref{Executing a +File}), any signals that you've defined your own handlers for revert to +their @code{SIG_DFL} handling. (If you think about it a little, this +makes sense; the handler functions from the old program are specific to +that program, and aren't even present in the address space of the new +program image.) Of course, the new program can establish its own +handlers. + +When a program is run by a shell, the shell normally sets the initial +actions for the child process to @code{SIG_DFL} or @code{SIG_IGN}, as +appropriate. It's a good idea to check to make sure that the shell has +not set up an initial action of @code{SIG_IGN} before you establish your +own signal handlers. + +Here is an example of how to establish a handler for @code{SIGHUP}, but +not if @code{SIGHUP} is currently ignored: + +@smallexample +@group +@dots{} +struct sigaction temp; + +sigaction (SIGHUP, NULL, &temp); + +if (temp.sa_handler != SIG_IGN) + @{ + temp.sa_handler = handle_sighup; + sigemptyset (&temp.sa_mask); + sigaction (SIGHUP, &temp, NULL); + @} +@end group +@end smallexample + +@node Defining Handlers +@section Defining Signal Handlers +@cindex signal handler function + +This section describes how to write a signal handler function that can +be established with the @code{signal} or @code{sigaction} functions. + +A signal handler is just a function that you compile together with the +rest of the program. Instead of directly invoking the function, you use +@code{signal} or @code{sigaction} to tell the operating system to call +it when a signal arrives. This is known as @dfn{establishing} the +handler. @xref{Signal Actions}. + +There are two basic strategies you can use in signal handler functions: + +@itemize @bullet +@item +You can have the handler function note that the signal arrived by +tweaking some global data structures, and then return normally. + +@item +You can have the handler function terminate the program or transfer +control to a point where it can recover from the situation that caused +the signal. +@end itemize + +You need to take special care in writing handler functions because they +can be called asynchronously. That is, a handler might be called at any +point in the program, unpredictably. If two signals arrive during a +very short interval, one handler can run within another. This section +describes what your handler should do, and what you should avoid. + +@menu +* Handler Returns:: Handlers that return normally, and what + this means. +* Termination in Handler:: How handler functions terminate a program. +* Longjmp in Handler:: Nonlocal transfer of control out of a + signal handler. +* Signals in Handler:: What happens when signals arrive while + the handler is already occupied. +* Merged Signals:: When a second signal arrives before the + first is handled. +* Nonreentrancy:: Do not call any functions unless you know they + are reentrant with respect to signals. +* Atomic Data Access:: A single handler can run in the middle of + reading or writing a single object. +@end menu + +@node Handler Returns +@subsection Signal Handlers that Return + +Handlers which return normally are usually used for signals such as +@code{SIGALRM} and the I/O and interprocess communication signals. But +a handler for @code{SIGINT} might also return normally after setting a +flag that tells the program to exit at a convenient time. + +It is not safe to return normally from the handler for a program error +signal, because the behavior of the program when the handler function +returns is not defined after a program error. @xref{Program Error +Signals}. + +Handlers that return normally must modify some global variable in order +to have any effect. Typically, the variable is one that is examined +periodically by the program during normal operation. Its data type +should be @code{sig_atomic_t} for reasons described in @ref{Atomic +Data Access}. + +Here is a simple example of such a program. It executes the body of +the loop until it has noticed that a @code{SIGALRM} signal has arrived. +This technique is useful because it allows the iteration in progress +when the signal arrives to complete before the loop exits. + +@smallexample +@include sigh1.c.texi +@end smallexample + +@node Termination in Handler +@subsection Handlers That Terminate the Process + +Handler functions that terminate the program are typically used to cause +orderly cleanup or recovery from program error signals and interactive +interrupts. + +The cleanest way for a handler to terminate the process is to raise the +same signal that ran the handler in the first place. Here is how to do +this: + +@smallexample +volatile sig_atomic_t fatal_error_in_progress = 0; + +void +fatal_error_signal (int sig) +@{ +@group + /* @r{Since this handler is established for more than one kind of signal, } + @r{it might still get invoked recursively by delivery of some other kind} + @r{of signal. Use a static variable to keep track of that.} */ + if (fatal_error_in_progress) + raise (sig); + fatal_error_in_progress = 1; +@end group + +@group + /* @r{Now do the clean up actions:} + @r{- reset terminal modes} + @r{- kill child processes} + @r{- remove lock files} */ + @dots{} +@end group + +@group + /* @r{Now reraise the signal. Since the signal is blocked,} + @r{it will receive its default handling, which is} + @r{to terminate the process. We could just call} + @r{@code{exit} or @code{abort}, but reraising the signal} + @r{sets the return status from the process correctly.} */ + raise (sig); +@} +@end group +@end smallexample + +@node Longjmp in Handler +@subsection Nonlocal Control Transfer in Handlers +@cindex non-local exit, from signal handler + +You can do a nonlocal transfer of control out of a signal handler using +the @code{setjmp} and @code{longjmp} facilities (@pxref{Non-Local +Exits}). + +When the handler does a nonlocal control transfer, the part of the +program that was running will not continue. If this part of the program +was in the middle of updating an important data structure, the data +structure will remain inconsistent. Since the program does not +terminate, the inconsistency is likely to be noticed later on. + +There are two ways to avoid this problem. One is to block the signal +for the parts of the program that update important data structures. +Blocking the signal delays its delivery until it is unblocked, once the +critical updating is finished. @xref{Blocking Signals}. + +The other way to re-initialize the crucial data structures in the signal +handler, or make their values consistent. + +Here is a rather schematic example showing the reinitialization of one +global variable. + +@smallexample +@group +#include <signal.h> +#include <setjmp.h> + +jmp_buf return_to_top_level; + +volatile sig_atomic_t waiting_for_input; + +void +handle_sigint (int signum) +@{ + /* @r{We may have been waiting for input when the signal arrived,} + @r{but we are no longer waiting once we transfer control.} */ + waiting_for_input = 0; + longjmp (return_to_top_level, 1); +@} +@end group + +@group +int +main (void) +@{ + @dots{} + signal (SIGINT, sigint_handler); + @dots{} + while (1) @{ + prepare_for_command (); + if (setjmp (return_to_top_level) == 0) + read_and_execute_command (); + @} +@} +@end group + +@group +/* @r{Imagine this is a subroutine used by various commands.} */ +char * +read_data () +@{ + if (input_from_terminal) @{ + waiting_for_input = 1; + @dots{} + waiting_for_input = 0; + @} else @{ + @dots{} + @} +@} +@end group +@end smallexample + + +@node Signals in Handler +@subsection Signals Arriving While a Handler Runs +@cindex race conditions, relating to signals + +What happens if another signal arrives while your signal handler +function is running? + +When the handler for a particular signal is invoked, that signal is +automatically blocked until the handler returns. That means that if two +signals of the same kind arrive close together, the second one will be +held until the first has been handled. (The handler can explicitly +unblock the signal using @code{sigprocmask}, if you want to allow more +signals of this type to arrive; see @ref{Process Signal Mask}.) + +However, your handler can still be interrupted by delivery of another +kind of signal. To avoid this, you can use the @code{sa_mask} member of +the action structure passed to @code{sigaction} to explicitly specify +which signals should be blocked while the signal handler runs. These +signals are in addition to the signal for which the handler was invoked, +and any other signals that are normally blocked by the process. +@xref{Blocking for Handler}. + +When the handler returns, the set of blocked signals is restored to the +value it had before the handler ran. So using @code{sigprocmask} inside +the handler only affects what signals can arrive during the execution of +the handler itself, not what signals can arrive once the handler returns. + +@strong{Portability Note:} Always use @code{sigaction} to establish a +handler for a signal that you expect to receive asynchronously, if you +want your program to work properly on System V Unix. On this system, +the handling of a signal whose handler was established with +@code{signal} automatically sets the signal's action back to +@code{SIG_DFL}, and the handler must re-establish itself each time it +runs. This practice, while inconvenient, does work when signals cannot +arrive in succession. However, if another signal can arrive right away, +it may arrive before the handler can re-establish itself. Then the +second signal would receive the default handling, which could terminate +the process. + +@node Merged Signals +@subsection Signals Close Together Merge into One +@cindex handling multiple signals +@cindex successive signals +@cindex merging of signals + +If multiple signals of the same type are delivered to your process +before your signal handler has a chance to be invoked at all, the +handler may only be invoked once, as if only a single signal had +arrived. In effect, the signals merge into one. This situation can +arise when the signal is blocked, or in a multiprocessing environment +where the system is busy running some other processes while the signals +are delivered. This means, for example, that you cannot reliably use a +signal handler to count signals. The only distinction you can reliably +make is whether at least one signal has arrived since a given time in +the past. + +Here is an example of a handler for @code{SIGCHLD} that compensates for +the fact that the number of signals recieved may not equal the number of +child processes generate them. It assumes that the program keeps track +of all the child processes with a chain of structures as follows: + +@smallexample +struct process +@{ + struct process *next; + /* @r{The process ID of this child.} */ + int pid; + /* @r{The descriptor of the pipe or pseudo terminal} + @r{on which output comes from this child.} */ + int input_descriptor; + /* @r{Nonzero if this process has stopped or terminated.} */ + sig_atomic_t have_status; + /* @r{The status of this child; 0 if running,} + @r{otherwise a status value from @code{waitpid}.} */ + int status; +@}; + +struct process *process_list; +@end smallexample + +This example also uses a flag to indicate whether signals have arrived +since some time in the past---whenever the program last cleared it to +zero. + +@smallexample +/* @r{Nonzero means some child's status has changed} + @r{so look at @code{process_list} for the details.} */ +int process_status_change; +@end smallexample + +Here is the handler itself: + +@smallexample +void +sigchld_handler (int signo) +@{ + int old_errno = errno; + + while (1) @{ + register int pid; + int w; + struct process *p; + + /* @r{Keep asking for a status until we get a definitive result.} */ + do + @{ + errno = 0; + pid = waitpid (WAIT_ANY, &w, WNOHANG | WUNTRACED); + @} + while (pid <= 0 && errno == EINTR); + + if (pid <= 0) @{ + /* @r{A real failure means there are no more} + @r{stopped or terminated child processes, so return.} */ + errno = old_errno; + return; + @} + + /* @r{Find the process that signaled us, and record its status.} */ + + for (p = process_list; p; p = p->next) + if (p->pid == pid) @{ + p->status = w; + /* @r{Indicate that the @code{status} field} + @r{has data to look at. We do this only after storing it.} */ + p->have_status = 1; + + /* @r{If process has terminated, stop waiting for its output.} */ + if (WIFSIGNALED (w) || WIFEXITED (w)) + if (p->input_descriptor) + FD_CLR (p->input_descriptor, &input_wait_mask); + + /* @r{The program should check this flag from time to time} + @r{to see if there is any news in @code{process_list}.} */ + ++process_status_change; + @} + + /* @r{Loop around to handle all the processes} + @r{that have something to tell us.} */ + @} +@} +@end smallexample + +Here is the proper way to check the flag @code{process_status_change}: + +@smallexample +if (process_status_change) @{ + struct process *p; + process_status_change = 0; + for (p = process_list; p; p = p->next) + if (p->have_status) @{ + @dots{} @r{Examine @code{p->status}} @dots{} + @} +@} +@end smallexample + +@noindent +It is vital to clear the flag before examining the list; otherwise, if a +signal were delivered just before the clearing of the flag, and after +the appropriate element of the process list had been checked, the status +change would go unnoticed until the next signal arrived to set the flag +again. You could, of course, avoid this problem by blocking the signal +while scanning the list, but it is much more elegant to guarantee +correctness by doing things in the right order. + +The loop which checks process status avoids examining @code{p->status} +until it sees that status has been validly stored. This is to make sure +that the status cannot change in the middle of accessing it. Once +@code{p->have_status} is set, it means that the child process is stopped +or terminated, and in either case, it cannot stop or terminate again +until the program has taken notice. @xref{Atomic Usage}, for more +information about coping with interruptions during accessings of a +variable. + +Here is another way you can test whether the handler has run since the +last time you checked. This technique uses a counter which is never +changed outside the handler. Instead of clearing the count, the program +remembers the previous value and sees whether it has changed since the +previous check. The advantage of this method is that different parts of +the program can check independently, each part checking whether there +has been a signal since that part last checked. + +@smallexample +sig_atomic_t process_status_change; + +sig_atomic_t last_process_status_change; + +@dots{} +@{ + sig_atomic_t prev = last_process_status_change; + last_process_status_change = process_status_change; + if (last_process_status_change != prev) @{ + struct process *p; + for (p = process_list; p; p = p->next) + if (p->have_status) @{ + @dots{} @r{Examine @code{p->status}} @dots{} + @} + @} +@} +@end smallexample + +@node Nonreentrancy +@subsection Signal Handling and Nonreentrant Functions +@cindex restrictions on signal handler functions + +Handler functions usually don't do very much. The best practice is to +write a handler that does nothing but set an external variable that the +program checks regularly, and leave all serious work to the program. +This is best because the handler can be called at asynchronously, at +unpredictable times---perhaps in the middle of a primitive function, or +even between the beginning and the end of a C operator that requires +multiple instructions. The data structures being manipulated might +therefore be in an inconsistent state when the handler function is +invoked. Even copying one @code{int} variable into another can take two +instructions on most machines. + +This means you have to be very careful about what you do in a signal +handler. + +@itemize @bullet +@item +@cindex @code{volatile} declarations +If your handler needs to access any global variables from your program, +declare those variables @code{volatile}. This tells the compiler that +the value of the variable might change asynchronously, and inhibits +certain optimizations that would be invalidated by such modifications. + +@item +@cindex reentrant functions +If you call a function in the handler, make sure it is @dfn{reentrant} +with respect to signals, or else make sure that the signal cannot +interrupt a call to a related function. +@end itemize + +A function can be non-reentrant if it uses memory that is not on the +stack. + +@itemize @bullet +@item +If a function uses a static variable or a global variable, or a +dynamically-allocated object that it finds for itself, then it is +non-reentrant and any two calls to the function can interfere. + +For example, suppose that the signal handler uses @code{gethostbyname}. +This function returns its value in a static object, reusing the same +object each time. If the signal happens to arrive during a call to +@code{gethostbyname}, or even after one (while the program is still +using the value), it will clobber the value that the program asked for. + +However, if the program does not use @code{gethostbyname} or any other +function that returns information in the same object, or if it always +blocks signals around each use, then you are safe. + +There are a large number of library functions that return values in a +fixed object, always reusing the same object in this fashion, and all of +them cause the same problem. The description of a function in this +manual always mentions this behavior. + +@item +If a function uses and modifies an object that you supply, then it is +potentially non-reentrant; two calls can interfere if they use the same +object. + +This case arises when you do I/O using streams. Suppose that the +signal handler prints a message with @code{fprintf}. Suppose that the +program was in the middle of an @code{fprintf} call using the same +stream when the signal was delivered. Both the signal handler's message +and the program's data could be corrupted, because both calls operate on +the same data structure---the stream itself. + +However, if you know that the stream that the handler uses cannot +possibly be used by the program at a time when signals can arrive, then +you are safe. It is no problem if the program uses some other stream. + +@item +On most systems, @code{malloc} and @code{free} are not reentrant, +because they use a static data structure which records what memory +blocks are free. As a result, no library functions that allocate or +free memory are reentrant. This includes functions that allocate space +to store a result. + +The best way to avoid the need to allocate memory in a handler is to +allocate in advance space for signal handlers to use. + +The best way to avoid freeing memory in a handler is to flag or record +the objects to be freed, and have the program check from time to time +whether anything is waiting to be freed. But this must be done with +care, because placing an object on a chain is not atomic, and if it is +interrupted by another signal handler that does the same thing, you +could ``lose'' one of the objects. + +@ignore +!!! not true +On the GNU system, @code{malloc} and @code{free} are safe to use in +signal handlers because they block signals. As a result, the library +functions that allocate space for a result are also safe in signal +handlers. The obstack allocation functions are safe as long as you +don't use the same obstack both inside and outside of a signal handler. +@end ignore + +The relocating allocation functions (@pxref{Relocating Allocator}) +are certainly not safe to use in a signal handler. + +@item +Any function that modifies @code{errno} is non-reentrant, but you can +correct for this: in the handler, save the original value of +@code{errno} and restore it before returning normally. This prevents +errors that occur within the signal handler from being confused with +errors from system calls at the point the program is interrupted to run +the handler. + +This technique is generally applicable; if you want to call in a handler +a function that modifies a particular object in memory, you can make +this safe by saving and restoring that object. + +@item +Merely reading from a memory object is safe provided that you can deal +with any of the values that might appear in the object at a time when +the signal can be delivered. Keep in mind that assignment to some data +types requires more than one instruction, which means that the handler +could run ``in the middle of'' an assignment to the variable if its type +is not atomic. @xref{Atomic Data Access}. + +@item +Merely writing into a memory object is safe as long as a sudden change +in the value, at any time when the handler might run, will not disturb +anything. +@end itemize + +@node Atomic Data Access +@subsection Atomic Data Access and Signal Handling + +Whether the data in your application concerns atoms, or mere text, you +have to be careful about the fact that access to a single datum is not +necessarily @dfn{atomic}. This means that it can take more than one +instruction to read or write a single object. In such cases, a signal +handler might in the middle of reading or writing the object. + +There are three ways you can cope with this problem. You can use data +types that are always accessed atomically; you can carefully arrange +that nothing untoward happens if an access is interrupted, or you can +block all signals around any access that had better not be interrupted +(@pxref{Blocking Signals}). + +@menu +* Non-atomic Example:: A program illustrating interrupted access. +* Types: Atomic Types. Data types that guarantee no interruption. +* Usage: Atomic Usage. Proving that interruption is harmless. +@end menu + +@node Non-atomic Example +@subsubsection Problems with Non-Atomic Access + +Here is an example which shows what can happen if a signal handler runs +in the middle of modifying a variable. (Interrupting the reading of a +variable can also lead to paradoxical results, but here we only show +writing.) + +@smallexample +#include <signal.h> +#include <stdio.h> + +struct two_words @{ int a, b; @} memory; + +void +handler(int signum) +@{ + printf ("%d,%d\n", memory.a, memory.b); + alarm (1); +@} + +@group +int +main (void) +@{ + static struct two_words zeros = @{ 0, 0 @}, ones = @{ 1, 1 @}; + signal (SIGALRM, handler); + memory = zeros; + alarm (1); + while (1) + @{ + memory = zeros; + memory = ones; + @} +@} +@end group +@end smallexample + +This program fills @code{memory} with zeros, ones, zeros, ones, +alternating forever; meanwhile, once per second, the alarm signal handler +prints the current contents. (Calling @code{printf} in the handler is +safe in this program because it is certainly not being called outside +the handler when the signal happens.) + +Clearly, this program can print a pair of zeros or a pair of ones. But +that's not all it can do! On most machines, it takes several +instructions to store a new value in @code{memory}, and the value is +stored one word at a time. If the signal is delivered in between these +instructions, the handler might find that @code{memory.a} is zero and +@code{memory.b} is one (or vice versa). + +On some machines it may be possible to store a new value in +@code{memory} with just one instruction that cannot be interrupted. On +these machines, the handler will always print two zeros or two ones. + +@node Atomic Types +@subsubsection Atomic Types + +To avoid uncertainty about interrupting access to a variable, you can +use a particular data type for which access is always atomic: +@code{sig_atomic_t}. Reading and writing this data type is guaranteed +to happen in a single instruction, so there's no way for a handler to +run ``in the middle'' of an access. + +The type @code{sig_atomic_t} is always an integer data type, but which +one it is, and how many bits it contains, may vary from machine to +machine. + +@comment signal.h +@comment ANSI +@deftp {Data Type} sig_atomic_t +This is an integer data type. Objects of this type are always accessed +atomically. +@end deftp + +In practice, you can assume that @code{int} and other integer types no +longer than @code{int} are atomic. You can also assume that pointer +types are atomic; that is very convenient. Both of these are true on +all of the machines that the GNU C library supports, and on all POSIX +systems we know of. +@c ??? This might fail on a 386 that uses 64-bit pointers. + +@node Atomic Usage +@subsubsection Atomic Usage Patterns + +Certain patterns of access avoid any problem even if an access is +interrupted. For example, a flag which is set by the handler, and +tested and cleared by the main program from time to time, is always safe +even if access actually requires two instructions. To show that this is +so, we must consider each access that could be interrupted, and show +that there is no problem if it is interrupted. + +An interrupt in the middle of testing the flag is safe because either it's +recognized to be nonzero, in which case the precise value doesn't +matter, or it will be seen to be nonzero the next time it's tested. + +An interrupt in the middle of clearing the flag is no problem because +either the value ends up zero, which is what happens if a signal comes +in just before the flag is cleared, or the value ends up nonzero, and +subsequent events occur as if the signal had come in just after the flag +was cleared. As long as the code handles both of these cases properly, +it can also handle a signal in the middle of clearing the flag. (This +is an example of the sort of reasoning you need to do to figure out +whether non-atomic usage is safe.) + +Sometimes you can insure uninterrupted access to one object by +protecting its use with another object, perhaps one whose type +guarantees atomicity. @xref{Merged Signals}, for an example. + +@node Interrupted Primitives +@section Primitives Interrupted by Signals + +A signal can arrive and be handled while an I/O primitive such as +@code{open} or @code{read} is waiting for an I/O device. If the signal +handler returns, the system faces the question: what should happen next? + +POSIX specifies one approach: make the primitive fail right away. The +error code for this kind of failure is @code{EINTR}. This is flexible, +but usually inconvenient. Typically, POSIX applications that use signal +handlers must check for @code{EINTR} after each library function that +can return it, in order to try the call again. Often programmers forget +to check, which is a common source of error. + +The GNU library provides a convenient way to retry a call after a +temporary failure, with the macro @code{TEMP_FAILURE_RETRY}: + +@comment unistd.h +@comment GNU +@defmac TEMP_FAILURE_RETRY (@var{expression}) +This macro evaluates @var{expression} once. If it fails and reports +error code @code{EINTR}, @code{TEMP_FAILURE_RETRY} evaluates it again, +and over and over until the result is not a temporary failure. + +The value returned by @code{TEMP_FAILURE_RETRY} is whatever value +@var{expression} produced. +@end defmac + +BSD avoids @code{EINTR} entirely and provides a more convenient +approach: to restart the interrupted primitive, instead of making it +fail. If you choose this approach, you need not be concerned with +@code{EINTR}. + +You can choose either approach with the GNU library. If you use +@code{sigaction} to establish a signal handler, you can specify how that +handler should behave. If you specify the @code{SA_RESTART} flag, +return from that handler will resume a primitive; otherwise, return from +that handler will cause @code{EINTR}. @xref{Flags for Sigaction}. + +Another way to specify the choice is with the @code{siginterrupt} +function. @xref{BSD Handler}. + +@c !!! not true now about _BSD_SOURCE +When you don't specify with @code{sigaction} or @code{siginterrupt} what +a particular handler should do, it uses a default choice. The default +choice in the GNU library depends on the feature test macros you have +defined. If you define @code{_BSD_SOURCE} or @code{_GNU_SOURCE} before +calling @code{signal}, the default is to resume primitives; otherwise, +the default is to make them fail with @code{EINTR}. (The library +contains alternate versions of the @code{signal} function, and the +feature test macros determine which one you really call.) @xref{Feature +Test Macros}. +@cindex EINTR, and restarting interrupted primitives +@cindex restarting interrupted primitives +@cindex interrupting primitives +@cindex primitives, interrupting +@c !!! want to have @cindex system calls @i{see} primitives [no page #] + +The description of each primitive affected by this issue +lists @code{EINTR} among the error codes it can return. + +There is one situation where resumption never happens no matter which +choice you make: when a data-transfer function such as @code{read} or +@code{write} is interrupted by a signal after transferring part of the +data. In this case, the function returns the number of bytes already +transferred, indicating partial success. + +This might at first appear to cause unreliable behavior on +record-oriented devices (including datagram sockets; @pxref{Datagrams}), +where splitting one @code{read} or @code{write} into two would read or +write two records. Actually, there is no problem, because interruption +after a partial transfer cannot happen on such devices; they always +transfer an entire record in one burst, with no waiting once data +transfer has started. + +@node Generating Signals +@section Generating Signals +@cindex sending signals +@cindex raising signals +@cindex signals, generating + +Besides signals that are generated as a result of a hardware trap or +interrupt, your program can explicitly send signals to itself or to +another process. + +@menu +* Signaling Yourself:: A process can send a signal to itself. +* Signaling Another Process:: Send a signal to another process. +* Permission for kill:: Permission for using @code{kill}. +* Kill Example:: Using @code{kill} for Communication. +@end menu + +@node Signaling Yourself +@subsection Signaling Yourself + +A process can send itself a signal with the @code{raise} function. This +function is declared in @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment ANSI +@deftypefun int raise (int @var{signum}) +The @code{raise} function sends the signal @var{signum} to the calling +process. It returns zero if successful and a nonzero value if it fails. +About the only reason for failure would be if the value of @var{signum} +is invalid. +@end deftypefun + +@comment signal.h +@comment SVID +@deftypefun int gsignal (int @var{signum}) +The @code{gsignal} function does the same thing as @code{raise}; it is +provided only for compatibility with SVID. +@end deftypefun + +One convenient use for @code{raise} is to reproduce the default behavior +of a signal that you have trapped. For instance, suppose a user of your +program types the SUSP character (usually @kbd{C-z}; @pxref{Special +Characters}) to send it an interactive stop stop signal +(@code{SIGTSTP}), and you want to clean up some internal data buffers +before stopping. You might set this up like this: + +@comment RMS suggested getting rid of the handler for SIGCONT in this function. +@comment But that would require that the handler for SIGTSTP unblock the +@comment signal before doing the call to raise. We haven't covered that +@comment topic yet, and I don't want to distract from the main point of +@comment the example with a digression to explain what is going on. As +@comment the example is written, the signal that is raise'd will be delivered +@comment as soon as the SIGTSTP handler returns, which is fine. + +@smallexample +#include <signal.h> + +/* @r{When a stop signal arrives, set the action back to the default + and then resend the signal after doing cleanup actions.} */ + +void +tstp_handler (int sig) +@{ + signal (SIGTSTP, SIG_DFL); + /* @r{Do cleanup actions here.} */ + @dots{} + raise (SIGTSTP); +@} + +/* @r{When the process is continued again, restore the signal handler.} */ + +void +cont_handler (int sig) +@{ + signal (SIGCONT, cont_handler); + signal (SIGTSTP, tstp_handler); +@} + +@group +/* @r{Enable both handlers during program initialization.} */ + +int +main (void) +@{ + signal (SIGCONT, cont_handler); + signal (SIGTSTP, tstp_handler); + @dots{} +@} +@end group +@end smallexample + +@strong{Portability note:} @code{raise} was invented by the ANSI C +committee. Older systems may not support it, so using @code{kill} may +be more portable. @xref{Signaling Another Process}. + +@node Signaling Another Process +@subsection Signaling Another Process + +@cindex killing a process +The @code{kill} function can be used to send a signal to another process. +In spite of its name, it can be used for a lot of things other than +causing a process to terminate. Some examples of situations where you +might want to send signals between processes are: + +@itemize @bullet +@item +A parent process starts a child to perform a task---perhaps having the +child running an infinite loop---and then terminates the child when the +task is no longer needed. + +@item +A process executes as part of a group, and needs to terminate or notify +the other processes in the group when an error or other event occurs. + +@item +Two processes need to synchronize while working together. +@end itemize + +This section assumes that you know a little bit about how processes +work. For more information on this subject, see @ref{Processes}. + +The @code{kill} function is declared in @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment POSIX.1 +@deftypefun int kill (pid_t @var{pid}, int @var{signum}) +The @code{kill} function sends the signal @var{signum} to the process +or process group specified by @var{pid}. Besides the signals listed in +@ref{Standard Signals}, @var{signum} can also have a value of zero to +check the validity of the @var{pid}. + +The @var{pid} specifies the process or process group to receive the +signal: + +@table @code +@item @var{pid} > 0 +The process whose identifier is @var{pid}. + +@item @var{pid} == 0 +All processes in the same process group as the sender. + +@item @var{pid} < -1 +The process group whose identifier is @minus{}@var{pid}. + +@item @var{pid} == -1 +If the process is privileged, send the signal to all processes except +for some special system processes. Otherwise, send the signal to all +processes with the same effective user ID. +@end table + +A process can send a signal @var{signum} to itself with a call like +@w{@code{kill (getpid(), @var{signum})}}. If @code{kill} is used by a +process to send a signal to itself, and the signal is not blocked, then +@code{kill} delivers at least one signal (which might be some other +pending unblocked signal instead of the signal @var{signum}) to that +process before it returns. + +The return value from @code{kill} is zero if the signal can be sent +successfully. Otherwise, no signal is sent, and a value of @code{-1} is +returned. If @var{pid} specifies sending a signal to several processes, +@code{kill} succeeds if it can send the signal to at least one of them. +There's no way you can tell which of the processes got the signal +or whether all of them did. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The @var{signum} argument is an invalid or unsupported number. + +@item EPERM +You do not have the privilege to send a signal to the process or any of +the processes in the process group named by @var{pid}. + +@item ESCRH +The @var{pid} argument does not refer to an existing process or group. +@end table +@end deftypefun + +@comment signal.h +@comment BSD +@deftypefun int killpg (int @var{pgid}, int @var{signum}) +This is similar to @code{kill}, but sends signal @var{signum} to the +process group @var{pgid}. This function is provided for compatibility +with BSD; using @code{kill} to do this is more portable. +@end deftypefun + +As a simple example of @code{kill}, the call @w{@code{kill (getpid (), +@var{sig})}} has the same effect as @w{@code{raise (@var{sig})}}. + +@node Permission for kill +@subsection Permission for using @code{kill} + +There are restrictions that prevent you from using @code{kill} to send +signals to any random process. These are intended to prevent antisocial +behavior such as arbitrarily killing off processes belonging to another +user. In typical use, @code{kill} is used to pass signals between +parent, child, and sibling processes, and in these situations you +normally do have permission to send signals. The only common execption +is when you run a setuid program in a child process; if the program +changes its real UID as well as its effective UID, you may not have +permission to send a signal. The @code{su} program does this. + +Whether a process has permission to send a signal to another process +is determined by the user IDs of the two processes. This concept is +discussed in detail in @ref{Process Persona}. + +Generally, for a process to be able to send a signal to another process, +either the sending process must belong to a privileged user (like +@samp{root}), or the real or effective user ID of the sending process +must match the real or effective user ID of the receiving process. If +the receiving process has changed its effective user ID from the +set-user-ID mode bit on its process image file, then the owner of the +process image file is used in place of its current effective user ID. +In some implementations, a parent process might be able to send signals +to a child process even if the user ID's don't match, and other +implementations might enforce other restrictions. + +The @code{SIGCONT} signal is a special case. It can be sent if the +sender is part of the same session as the receiver, regardless of +user IDs. + +@node Kill Example +@subsection Using @code{kill} for Communication +@cindex interprocess communication, with signals +Here is a longer example showing how signals can be used for +interprocess communication. This is what the @code{SIGUSR1} and +@code{SIGUSR2} signals are provided for. Since these signals are fatal +by default, the process that is supposed to receive them must trap them +through @code{signal} or @code{sigaction}. + +In this example, a parent process forks a child process and then waits +for the child to complete its initialization. The child process tells +the parent when it is ready by sending it a @code{SIGUSR1} signal, using +the @code{kill} function. + +@smallexample +@include sigusr.c.texi +@end smallexample + +This example uses a busy wait, which is bad, because it wastes CPU +cycles that other programs could otherwise use. It is better to ask the +system to wait until the signal arrives. See the example in +@ref{Waiting for a Signal}. + +@node Blocking Signals +@section Blocking Signals +@cindex blocking signals + +Blocking a signal means telling the operating system to hold it and +deliver it later. Generally, a program does not block signals +indefinitely---it might as well ignore them by setting their actions to +@code{SIG_IGN}. But it is useful to block signals briefly, to prevent +them from interrupting sensitive operations. For instance: + +@itemize @bullet +@item +You can use the @code{sigprocmask} function to block signals while you +modify global variables that are also modified by the handlers for these +signals. + +@item +You can set @code{sa_mask} in your @code{sigaction} call to block +certain signals while a particular signal handler runs. This way, the +signal handler can run without being interrupted itself by signals. +@end itemize + +@menu +* Why Block:: The purpose of blocking signals. +* Signal Sets:: How to specify which signals to + block. +* Process Signal Mask:: Blocking delivery of signals to your + process during normal execution. +* Testing for Delivery:: Blocking to Test for Delivery of + a Signal. +* Blocking for Handler:: Blocking additional signals while a + handler is being run. +* Checking for Pending Signals:: Checking for Pending Signals +* Remembering a Signal:: How you can get almost the same + effect as blocking a signal, by + handling it and setting a flag + to be tested later. +@end menu + +@node Why Block +@subsection Why Blocking Signals is Useful + +Temporary blocking of signals with @code{sigprocmask} gives you a way to +prevent interrupts during critical parts of your code. If signals +arrive in that part of the program, they are delivered later, after you +unblock them. + +One example where this is useful is for sharing data between a signal +handler and the rest of the program. If the type of the data is not +@code{sig_atomic_t} (@pxref{Atomic Data Access}), then the signal +handler could run when the rest of the program has only half finished +reading or writing the data. This would lead to confusing consequences. + +To make the program reliable, you can prevent the signal handler from +running while the rest of the program is examining or modifying that +data---by blocking the appropriate signal around the parts of the +program that touch the data. + +Blocking signals is also necessary when you want to perform a certain +action only if a signal has not arrived. Suppose that the handler for +the signal sets a flag of type @code{sig_atomic_t}; you would like to +test the flag and perform the action if the flag is not set. This is +unreliable. Suppose the signal is delivered immediately after you test +the flag, but before the consequent action: then the program will +perform the action even though the signal has arrived. + +The only way to test reliably for whether a signal has yet arrived is to +test while the signal is blocked. + +@node Signal Sets +@subsection Signal Sets + +All of the signal blocking functions use a data structure called a +@dfn{signal set} to specify what signals are affected. Thus, every +activity involves two stages: creating the signal set, and then passing +it as an argument to a library function. +@cindex signal set + +These facilities are declared in the header file @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment POSIX.1 +@deftp {Data Type} sigset_t +The @code{sigset_t} data type is used to represent a signal set. +Internally, it may be implemented as either an integer or structure +type. + +For portability, use only the functions described in this section to +initialize, change, and retrieve information from @code{sigset_t} +objects---don't try to manipulate them directly. +@end deftp + +There are two ways to initialize a signal set. You can initially +specify it to be empty with @code{sigemptyset} and then add specified +signals individually. Or you can specify it to be full with +@code{sigfillset} and then delete specified signals individually. + +You must always initialize the signal set with one of these two +functions before using it in any other way. Don't try to set all the +signals explicitly because the @code{sigset_t} object might include some +other information (like a version field) that needs to be initialized as +well. (In addition, it's not wise to put into your program an +assumption that the system has no signals aside from the ones you know +about.) + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigemptyset (sigset_t *@var{set}) +This function initializes the signal set @var{set} to exclude all of the +defined signals. It always returns @code{0}. +@end deftypefun + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigfillset (sigset_t *@var{set}) +This function initializes the signal set @var{set} to include +all of the defined signals. Again, the return value is @code{0}. +@end deftypefun + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigaddset (sigset_t *@var{set}, int @var{signum}) +This function adds the signal @var{signum} to the signal set @var{set}. +All @code{sigaddset} does is modify @var{set}; it does not block or +unblock any signals. + +The return value is @code{0} on success and @code{-1} on failure. +The following @code{errno} error condition is defined for this function: + +@table @code +@item EINVAL +The @var{signum} argument doesn't specify a valid signal. +@end table +@end deftypefun + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigdelset (sigset_t *@var{set}, int @var{signum}) +This function removes the signal @var{signum} from the signal set +@var{set}. All @code{sigdelset} does is modify @var{set}; it does not +block or unblock any signals. The return value and error conditions are +the same as for @code{sigaddset}. +@end deftypefun + +Finally, there is a function to test what signals are in a signal set: + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigismember (const sigset_t *@var{set}, int @var{signum}) +The @code{sigismember} function tests whether the signal @var{signum} is +a member of the signal set @var{set}. It returns @code{1} if the signal +is in the set, @code{0} if not, and @code{-1} if there is an error. + +The following @code{errno} error condition is defined for this function: + +@table @code +@item EINVAL +The @var{signum} argument doesn't specify a valid signal. +@end table +@end deftypefun + +@node Process Signal Mask +@subsection Process Signal Mask +@cindex signal mask +@cindex process signal mask + +The collection of signals that are currently blocked is called the +@dfn{signal mask}. Each process has its own signal mask. When you +create a new process (@pxref{Creating a Process}), it inherits its +parent's mask. You can block or unblock signals with total flexibility +by modifying the signal mask. + +The prototype for the @code{sigprocmask} function is in @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigprocmask (int @var{how}, const sigset_t *@var{set}, sigset_t *@var{oldset}) +The @code{sigprocmask} function is used to examine or change the calling +process's signal mask. The @var{how} argument determines how the signal +mask is changed, and must be one of the following values: + +@table @code +@comment signal.h +@comment POSIX.1 +@vindex SIG_BLOCK +@item SIG_BLOCK +Block the signals in @code{set}---add them to the existing mask. In +other words, the new mask is the union of the existing mask and +@var{set}. + +@comment signal.h +@comment POSIX.1 +@vindex SIG_UNBLOCK +@item SIG_UNBLOCK +Unblock the signals in @var{set}---remove them from the existing mask. + +@comment signal.h +@comment POSIX.1 +@vindex SIG_SETMASK +@item SIG_SETMASK +Use @var{set} for the mask; ignore the previous value of the mask. +@end table + +The last argument, @var{oldset}, is used to return information about the +old process signal mask. If you just want to change the mask without +looking at it, pass a null pointer as the @var{oldset} argument. +Similarly, if you want to know what's in the mask without changing it, +pass a null pointer for @var{set} (in this case the @var{how} argument +is not significant). The @var{oldset} argument is often used to +remember the previous signal mask in order to restore it later. (Since +the signal mask is inherited over @code{fork} and @code{exec} calls, you +can't predict what its contents are when your program starts running.) + +If invoking @code{sigprocmask} causes any pending signals to be +unblocked, at least one of those signals is delivered to the process +before @code{sigprocmask} returns. The order in which pending signals +are delivered is not specified, but you can control the order explicitly +by making multiple @code{sigprocmask} calls to unblock various signals +one at a time. + +The @code{sigprocmask} function returns @code{0} if successful, and @code{-1} +to indicate an error. The following @code{errno} error conditions are +defined for this function: + +@table @code +@item EINVAL +The @var{how} argument is invalid. +@end table + +You can't block the @code{SIGKILL} and @code{SIGSTOP} signals, but +if the signal set includes these, @code{sigprocmask} just ignores +them instead of returning an error status. + +Remember, too, that blocking program error signals such as @code{SIGFPE} +leads to undesirable results for signals generated by an actual program +error (as opposed to signals sent with @code{raise} or @code{kill}). +This is because your program may be too broken to be able to continue +executing to a point where the signal is unblocked again. +@xref{Program Error Signals}. +@end deftypefun + +@node Testing for Delivery +@subsection Blocking to Test for Delivery of a Signal + +Now for a simple example. Suppose you establish a handler for +@code{SIGALRM} signals that sets a flag whenever a signal arrives, and +your main program checks this flag from time to time and then resets it. +You can prevent additional @code{SIGALRM} signals from arriving in the +meantime by wrapping the critical part of the code with calls to +@code{sigprocmask}, like this: + +@smallexample +/* @r{This variable is set by the SIGALRM signal handler.} */ +volatile sig_atomic_t flag = 0; + +int +main (void) +@{ + sigset_t block_alarm; + + @dots{} + + /* @r{Initialize the signal mask.} */ + sigemptyset (&block_alarm); + sigaddset (&block_alarm, SIGALRM); + +@group + while (1) + @{ + /* @r{Check if a signal has arrived; if so, reset the flag.} */ + sigprocmask (SIG_BLOCK, &block_alarm, NULL); + if (flag) + @{ + @var{actions-if-not-arrived} + flag = 0; + @} + sigprocmask (SIG_UNBLOCK, &block_alarm, NULL); + + @dots{} + @} +@} +@end group +@end smallexample + +@node Blocking for Handler +@subsection Blocking Signals for a Handler +@cindex blocking signals, in a handler + +When a signal handler is invoked, you usually want it to be able to +finish without being interrupted by another signal. From the moment the +handler starts until the moment it finishes, you must block signals that +might confuse it or corrupt its data. + +When a handler function is invoked on a signal, that signal is +automatically blocked (in addition to any other signals that are already +in the process's signal mask) during the time the handler is running. +If you set up a handler for @code{SIGTSTP}, for instance, then the +arrival of that signal forces further @code{SIGTSTP} signals to wait +during the execution of the handler. + +However, by default, other kinds of signals are not blocked; they can +arrive during handler execution. + +The reliable way to block other kinds of signals during the execution of +the handler is to use the @code{sa_mask} member of the @code{sigaction} +structure. + +Here is an example: + +@smallexample +#include <signal.h> +#include <stddef.h> + +void catch_stop (); + +void +install_handler (void) +@{ + struct sigaction setup_action; + sigset_t block_mask; + + sigemptyset (&block_mask); + /* @r{Block other terminal-generated signals while handler runs.} */ + sigaddset (&block_mask, SIGINT); + sigaddset (&block_mask, SIGQUIT); + setup_action.sa_handler = catch_stop; + setup_action.sa_mask = block_mask; + setup_action.sa_flags = 0; + sigaction (SIGTSTP, &setup_action, NULL); +@} +@end smallexample + +This is more reliable than blocking the other signals explicitly in the +code for the handler. If you block signals explicity in the handler, +you can't avoid at least a short interval at the beginning of the +handler where they are not yet blocked. + +You cannot remove signals from the process's current mask using this +mechanism. However, you can make calls to @code{sigprocmask} within +your handler to block or unblock signals as you wish. + +In any case, when the handler returns, the system restores the mask that +was in place before the handler was entered. If any signals that become +unblocked by this restoration are pending, the process will receive +those signals immediately, before returning to the code that was +interrupted. + +@node Checking for Pending Signals +@subsection Checking for Pending Signals +@cindex pending signals, checking for +@cindex blocked signals, checking for +@cindex checking for pending signals + +You can find out which signals are pending at any time by calling +@code{sigpending}. This function is declared in @file{signal.h}. +@pindex signal.h + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigpending (sigset_t *@var{set}) +The @code{sigpending} function stores information about pending signals +in @var{set}. If there is a pending signal that is blocked from +delivery, then that signal is a member of the returned set. (You can +test whether a particular signal is a member of this set using +@code{sigismember}; see @ref{Signal Sets}.) + +The return value is @code{0} if successful, and @code{-1} on failure. +@end deftypefun + +Testing whether a signal is pending is not often useful. Testing when +that signal is not blocked is almost certainly bad design. + +Here is an example. + +@smallexample +#include <signal.h> +#include <stddef.h> + +sigset_t base_mask, waiting_mask; + +sigemptyset (&base_mask); +sigaddset (&base_mask, SIGINT); +sigaddset (&base_mask, SIGTSTP); + +/* @r{Block user interrupts while doing other processing.} */ +sigprocmask (SIG_SETMASK, &base_mask, NULL); +@dots{} + +/* @r{After a while, check to see whether any signals are pending.} */ +sigpending (&waiting_mask); +if (sigismember (&waiting_mask, SIGINT)) @{ + /* @r{User has tried to kill the process.} */ +@} +else if (sigismember (&waiting_mask, SIGTSTP)) @{ + /* @r{User has tried to stop the process.} */ +@} +@end smallexample + +Remember that if there is a particular signal pending for your process, +additional signals of that same type that arrive in the meantime might +be discarded. For example, if a @code{SIGINT} signal is pending when +another @code{SIGINT} signal arrives, your program will probably only +see one of them when you unblock this signal. + +@strong{Portability Note:} The @code{sigpending} function is new in +POSIX.1. Older systems have no equivalent facility. + +@node Remembering a Signal +@subsection Remembering a Signal to Act On Later + +Instead of blocking a signal using the library facilities, you can get +almost the same results by making the handler set a flag to be tested +later, when you ``unblock''. Here is an example: + +@smallexample +/* @r{If this flag is nonzero, don't handle the signal right away.} */ +volatile sig_atomic_t signal_pending; + +/* @r{This is nonzero if a signal arrived and was not handled.} */ +volatile sig_atomic_t defer_signal; + +void +handler (int signum) +@{ + if (defer_signal) + signal_pending = signum; + else + @dots{} /* @r{``Really'' handle the signal.} */ +@} + +@dots{} + +void +update_mumble (int frob) +@{ + /* @r{Prevent signals from having immediate effect.} */ + defer_signal++; + /* @r{Now update @code{mumble}, without worrying about interruption.} */ + mumble.a = 1; + mumble.b = hack (); + mumble.c = frob; + /* @r{We have updated @code{mumble}. Handle any signal that came in.} */ + defer_signal--; + if (defer_signal == 0 && signal_pending != 0) + raise (signal_pending); +@} +@end smallexample + +Note how the particular signal that arrives is stored in +@code{signal_pending}. That way, we can handle several types of +inconvenient signals with the same mechanism. + +We increment and decrement @code{defer_signal} so that nested critical +sections will work properly; thus, if @code{update_mumble} were called +with @code{signal_pending} already nonzero, signals would be deferred +not only within @code{update_mumble}, but also within the caller. This +is also why we do not check @code{signal_pending} if @code{defer_signal} +is still nonzero. + +The incrementing and decrementing of @code{defer_signal} require more +than one instruction; it is possible for a signal to happen in the +middle. But that does not cause any problem. If the signal happens +early enough to see the value from before the increment or decrement, +that is equivalent to a signal which came before the beginning of the +increment or decrement, which is a case that works properly. + +It is absolutely vital to decrement @code{defer_signal} before testing +@code{signal_pending}, because this avoids a subtle bug. If we did +these things in the other order, like this, + +@smallexample + if (defer_signal == 1 && signal_pending != 0) + raise (signal_pending); + defer_signal--; +@end smallexample + +@noindent +then a signal arriving in between the @code{if} statement and the decrement +would be effetively ``lost'' for an indefinite amount of time. The +handler would merely set @code{defer_signal}, but the program having +already tested this variable, it would not test the variable again. + +@cindex timing error in signal handling +Bugs like these are called @dfn{timing errors}. They are especially bad +because they happen only rarely and are nearly impossible to reproduce. +You can't expect to find them with a debugger as you would find a +reproducible bug. So it is worth being especially careful to avoid +them. + +(You would not be tempted to write the code in this order, given the use +of @code{defer_signal} as a counter which must be tested along with +@code{signal_pending}. After all, testing for zero is cleaner than +testing for one. But if you did not use @code{defer_signal} as a +counter, and gave it values of zero and one only, then either order +might seem equally simple. This is a further advantage of using a +counter for @code{defer_signal}: it will reduce the chance you will +write the code in the wrong order and create a subtle bug.) + +@node Waiting for a Signal +@section Waiting for a Signal +@cindex waiting for a signal +@cindex @code{pause} function + +If your program is driven by external events, or uses signals for +synchronization, then when it has nothing to do it should probably wait +until a signal arrives. + +@menu +* Using Pause:: The simple way, using @code{pause}. +* Pause Problems:: Why the simple way is often not very good. +* Sigsuspend:: Reliably waiting for a specific signal. +@end menu + +@node Using Pause +@subsection Using @code{pause} + +The simple way to wait until a signal arrives is to call @code{pause}. +Please read about its disadvantages, in the following section, before +you use it. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int pause () +The @code{pause} function suspends program execution until a signal +arrives whose action is either to execute a handler function, or to +terminate the process. + +If the signal causes a handler function to be executed, then +@code{pause} returns. This is considered an unsuccessful return (since +``successful'' behavior would be to suspend the program forever), so the +return value is @code{-1}. Even if you specify that other primitives +should resume when a system handler returns (@pxref{Interrupted +Primitives}), this has no effect on @code{pause}; it always fails when a +signal is handled. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EINTR +The function was interrupted by delivery of a signal. +@end table + +If the signal causes program termination, @code{pause} doesn't return +(obviously). + +The @code{pause} function is declared in @file{unistd.h}. +@end deftypefun + +@node Pause Problems +@subsection Problems with @code{pause} + +The simplicity of @code{pause} can conceal serious timing errors that +can make a program hang mysteriously. + +It is safe to use @code{pause} if the real work of your program is done +by the signal handlers themselves, and the ``main program'' does nothing +but call @code{pause}. Each time a signal is delivered, the handler +will do the next batch of work that is to be done, and then return, so +that the main loop of the program can call @code{pause} again. + +You can't safely use @code{pause} to wait until one more signal arrives, +and then resume real work. Even if you arrange for the signal handler +to cooperate by setting a flag, you still can't use @code{pause} +reliably. Here is an example of this problem: + +@smallexample +/* @r{@code{usr_interrupt} is set by the signal handler.} */ +if (!usr_interrupt) + pause (); + +/* @r{Do work once the signal arrives.} */ +@dots{} +@end smallexample + +@noindent +This has a bug: the signal could arrive after the variable +@code{usr_interrupt} is checked, but before the call to @code{pause}. +If no further signals arrive, the process would never wake up again. + +You can put an upper limit on the excess waiting by using @code{sleep} +in a loop, instead of using @code{pause}. (@xref{Sleeping}, for more +about @code{sleep}.) Here is what this looks like: + +@smallexample +/* @r{@code{usr_interrupt} is set by the signal handler.} +while (!usr_interrupt) + sleep (1); + +/* @r{Do work once the signal arrives.} */ +@dots{} +@end smallexample + +For some purposes, that is good enough. But with a little more +complexity, you can wait reliably until a particular signal handler is +run, using @code{sigsuspend}. +@ifinfo +@xref{Sigsuspend}. +@end ifinfo + +@node Sigsuspend +@subsection Using @code{sigsuspend} + +The clean and reliable way to wait for a signal to arrive is to block it +and then use @code{sigsuspend}. By using @code{sigsuspend} in a loop, +you can wait for certain kinds of signals, while letting other kinds of +signals be handled by their handlers. + +@comment signal.h +@comment POSIX.1 +@deftypefun int sigsuspend (const sigset_t *@var{set}) +This function replaces the process's signal mask with @var{set} and then +suspends the process until a signal is delivered whose action is either +to terminate the process or invoke a signal handling function. In other +words, the program is effectively suspended until one of the signals that +is not a member of @var{set} arrives. + +If the process is woken up by deliver of a signal that invokes a handler +function, and the handler function returns, then @code{sigsuspend} also +returns. + +The mask remains @var{set} only as long as @code{sigsuspend} is waiting. +The function @code{sigsuspend} always restores the previous signal mask +when it returns. + +The return value and error conditions are the same as for @code{pause}. +@end deftypefun + +With @code{sigsuspend}, you can replace the @code{pause} or @code{sleep} +loop in the previous section with something completely reliable: + +@smallexample +sigset_t mask, oldmask; + +@dots{} + +/* @r{Set up the mask of signals to temporarily block.} */ +sigemptyset (&mask); +sigaddset (&mask, SIGUSR1); + +@dots{} + +/* @r{Wait for a signal to arrive.} */ +sigprocmask (SIG_BLOCK, &mask, &oldmask); +while (!usr_interrupt) + sigsuspend (&oldmask); +sigprocmask (SIG_UNBLOCK, &mask, NULL); +@end smallexample + +This last piece of code is a little tricky. The key point to remember +here is that when @code{sigsuspend} returns, it resets the process's +signal mask to the original value, the value from before the call to +@code{sigsuspend}---in this case, the @code{SIGUSR1} signal is once +again blocked. The second call to @code{sigprocmask} is +necessary to explicitly unblock this signal. + +One other point: you may be wondering why the @code{while} loop is +necessary at all, since the program is apparently only waiting for one +@code{SIGUSR1} signal. The answer is that the mask passed to +@code{sigsuspend} permits the process to be woken up by the delivery of +other kinds of signals, as well---for example, job control signals. If +the process is woken up by a signal that doesn't set +@code{usr_interrupt}, it just suspends itself again until the ``right'' +kind of signal eventually arrives. + +This technique takes a few more lines of preparation, but that is needed +just once for each kind of wait criterion you want to use. The code +that actually waits is just four lines. + +@node Signal Stack +@section Using a Separate Signal Stack + +A signal stack is a special area of memory to be used as the execution +stack during signal handlers. It should be fairly large, to avoid any +danger that it will overflow in turn; the macro @code{SIGSTKSZ} is +defined to a canonical size for signal stacks. You can use +@code{malloc} to allocate the space for the stack. Then call +@code{sigaltstack} or @code{sigstack} to tell the system to use that +space for the signal stack. + +You don't need to write signal handlers differently in order to use a +signal stack. Switching from one stack to the other happens +automatically. (Some non-GNU debuggers on some machines may get +confused if you examine a stack trace while a handler that uses the +signal stack is running.) + +There are two interfaces for telling the system to use a separate signal +stack. @code{sigstack} is the older interface, which comes from 4.2 +BSD. @code{sigaltstack} is the newer interface, and comes from 4.4 +BSD. The @code{sigaltstack} interface has the advantage that it does +not require your program to know which direction the stack grows, which +depends on the specific machine and operating system. + +@comment signal.h +@comment BSD +@deftp {Data Type} {struct sigaltstack} +This structure describes a signal stack. It contains the following members: + +@table @code +@item void *ss_sp +This points to the base of the signal stack. + +@item size_t ss_size +This is the size (in bytes) of the signal stack which @samp{ss_sp} points to. +You should set this to however much space you allocated for the stack. + +There are two macros defined in @file{signal.h} that you should use in +calculating this size: + +@vtable @code +@item SIGSTKSZ +This is the canonical size for a signal stack. It is judged to be +sufficient for normal uses. + +@item MINSIGSTKSZ +This is the amount of signal stack space the operating system needs just +to implement signal delivery. The size of a signal stack @strong{must} +be greater than this. + +For most cases, just using @code{SIGSTKSZ} for @code{ss_size} is +sufficient. But if you know how much stack space your program's signal +handlers will need, you may want to use a different size. In this case, +you should allocate @code{MINSIGSTKSZ} additional bytes for the signal +stack and increase @code{ss_size} accordinly. +@end vtable + +@item int ss_flags +This field contains the bitwise @sc{or} of these flags: + +@vtable @code +@item SA_DISABLE +This tells the system that it should not use the signal stack. + +@item SA_ONSTACK +This is set by the system, and indicates that the signal stack is +currently in use. If this bit is not set, then signals will be +delivered on the normal user stack. +@end vtable +@end table +@end deftp + +@comment signal.h +@comment BSD +@deftypefun int sigaltstack (const struct sigaltstack *@var{stack}, struct sigaltstack *@var{oldstack}) +The @code{sigaltstack} function specifies an alternate stack for use +during signal handling. When a signal is received by the process and +its action indicates that the signal stack is used, the system arranges +a switch to the currently installed signal stack while the handler for +that signal is executed. + +If @var{oldstack} is not a null pointer, information about the currently +installed signal stack is returned in the location it points to. If +@var{stack} is not a null pointer, then this is installed as the new +stack for use by signal handlers. + +The return value is @code{0} on success and @code{-1} on failure. If +@code{sigaltstack} fails, it sets @code{errno} to one of these values: + +@table @code +@item +@item EINVAL +You tried to disable a stack that was in fact currently in use. + +@item ENOMEM +The size of the alternate stack was too small. +It must be greater than @code{MINSIGSTKSZ}. +@end table +@end deftypefun + +Here is the older @code{sigstack} interface. You should use +@code{sigaltstack} instead on systems that have it. + +@comment signal.h +@comment BSD +@deftp {Data Type} {struct sigstack} +This structure describes a signal stack. It contains the following members: + +@table @code +@item void *ss_sp +This is the stack pointer. If the stack grows downwards on your +machine, this should point to the top of the area you allocated. If the +stack grows upwards, it should point to the bottom. + +@item int ss_onstack +This field is true if the process is currently using this stack. +@end table +@end deftp + +@comment signal.h +@comment BSD +@deftypefun int sigstack (const struct sigstack *@var{stack}, struct sigstack *@var{oldstack}) +The @code{sigstack} function specifies an alternate stack for use during +signal handling. When a signal is received by the process and its +action indicates that the signal stack is used, the system arranges a +switch to the currently installed signal stack while the handler for +that signal is executed. + +If @var{oldstack} is not a null pointer, information about the currently +installed signal stack is returned in the location it points to. If +@var{stack} is not a null pointer, then this is installed as the new +stack for use by signal handlers. + +The return value is @code{0} on success and @code{-1} on failure. +@end deftypefun + +@node BSD Signal Handling +@section BSD Signal Handling + +This section describes alternative signal handling functions derived +from BSD Unix. These facilities were an advance, in their time; today, +they are mostly obsolete, and supported mainly for compatibility with +BSD Unix. + +There are many similarities between the BSD and POSIX signal handling +facilities, because the POSIX facilities were inspired by the BSD +facilities. Besides having different names for all the functions to +avoid conflicts, the main differences between the two are: + +@itemize @bullet +@item +BSD Unix represents signal masks as an @code{int} bit mask, rather than +as a @code{sigset_t} object. + +@item +The BSD facilities use a different default for whether an interrupted +primitive should fail or resume. The POSIX facilities make system +calls fail unless you specify that they should resume. With the BSD +facility, the default is to make system calls resume unless you say they +should fail. @xref{Interrupted Primitives}. +@end itemize + +The BSD facilities are declared in @file{signal.h}. +@pindex signal.h + +@menu +* BSD Handler:: BSD Function to Establish a Handler. +* Blocking in BSD:: BSD Functions for Blocking Signals. +@end menu + +@node BSD Handler +@subsection BSD Function to Establish a Handler + +@comment signal.h +@comment BSD +@deftp {Data Type} {struct sigvec} +This data type is the BSD equivalent of @code{struct sigaction} +(@pxref{Advanced Signal Handling}); it is used to specify signal actions +to the @code{sigvec} function. It contains the following members: + +@table @code +@item sighandler_t sv_handler +This is the handler function. + +@item int sv_mask +This is the mask of additional signals to be blocked while the handler +function is being called. + +@item int sv_flags +This is a bit mask used to specify various flags which affect the +behavior of the signal. You can also refer to this field as +@code{sv_onstack}. +@end table +@end deftp + +These symbolic constants can be used to provide values for the +@code{sv_flags} field of a @code{sigvec} structure. This field is a bit +mask value, so you bitwise-OR the flags of interest to you together. + +@comment signal.h +@comment BSD +@deftypevr Macro int SV_ONSTACK +If this bit is set in the @code{sv_flags} field of a @code{sigvec} +structure, it means to use the signal stack when delivering the signal. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypevr Macro int SV_INTERRUPT +If this bit is set in the @code{sv_flags} field of a @code{sigvec} +structure, it means that system calls interrupted by this kind of signal +should not be restarted if the handler returns; instead, the system +calls should return with a @code{EINTR} error status. @xref{Interrupted +Primitives}. +@end deftypevr + +@comment signal.h +@comment Sun +@deftypevr Macro int SV_RESETHAND +If this bit is set in the @code{sv_flags} field of a @code{sigvec} +structure, it means to reset the action for the signal back to +@code{SIG_DFL} when the signal is received. +@end deftypevr + +@comment signal.h +@comment BSD +@deftypefun int sigvec (int @var{signum}, const struct sigvec *@var{action},struct sigvec *@var{old-action}) +This function is the equivalent of @code{sigaction} (@pxref{Advanced Signal +Handling}); it installs the action @var{action} for the signal @var{signum}, +returning information about the previous action in effect for that signal +in @var{old-action}. +@end deftypefun + +@comment signal.h +@comment BSD +@deftypefun int siginterrupt (int @var{signum}, int @var{failflag}) +This function specifies which approach to use when certain primitives +are interrupted by handling signal @var{signum}. If @var{failflag} is +false, signal @var{signum} restarts primitives. If @var{failflag} is +true, handling @var{signum} causes these primitives to fail with error +code @code{EINTR}. @xref{Interrupted Primitives}. +@end deftypefun + +@node Blocking in BSD +@subsection BSD Functions for Blocking Signals + +@comment signal.h +@comment BSD +@deftypefn Macro int sigmask (int @var{signum}) +This macro returns a signal mask that has the bit for signal @var{signum} +set. You can bitwise-OR the results of several calls to @code{sigmask} +together to specify more than one signal. For example, + +@smallexample +(sigmask (SIGTSTP) | sigmask (SIGSTOP) + | sigmask (SIGTTIN) | sigmask (SIGTTOU)) +@end smallexample + +@noindent +specifies a mask that includes all the job-control stop signals. +@end deftypefn + +@comment signal.h +@comment BSD +@deftypefun int sigblock (int @var{mask}) +This function is equivalent to @code{sigprocmask} (@pxref{Process Signal +Mask}) with a @var{how} argument of @code{SIG_BLOCK}: it adds the +signals specified by @var{mask} to the calling process's set of blocked +signals. The return value is the previous set of blocked signals. +@end deftypefun + +@comment signal.h +@comment BSD +@deftypefun int sigsetmask (int @var{mask}) +This function equivalent to @code{sigprocmask} (@pxref{Process +Signal Mask}) with a @var{how} argument of @code{SIG_SETMASK}: it sets +the calling process's signal mask to @var{mask}. The return value is +the previous set of blocked signals. +@end deftypefun + +@comment signal.h +@comment BSD +@deftypefun int sigpause (int @var{mask}) +This function is the equivalent of @code{sigsuspend} (@pxref{Waiting +for a Signal}): it sets the calling process's signal mask to @var{mask}, +and waits for a signal to arrive. On return the previous set of blocked +signals is restored. +@end deftypefun diff --git a/manual/socket.texi b/manual/socket.texi new file mode 100644 index 0000000000..0b338fca82 --- /dev/null +++ b/manual/socket.texi @@ -0,0 +1,2748 @@ +@node Sockets, Low-Level Terminal Interface, Pipes and FIFOs, Top +@chapter Sockets + +This chapter describes the GNU facilities for interprocess +communication using sockets. + +@cindex socket +@cindex interprocess communication, with sockets +A @dfn{socket} is a generalized interprocess communication channel. +Like a pipe, a socket is represented as a file descriptor. But, +unlike pipes, sockets support communication between unrelated +processes, and even between processes running on different machines +that communicate over a network. Sockets are the primary means of +communicating with other machines; @code{telnet}, @code{rlogin}, +@code{ftp}, @code{talk}, and the other familiar network programs use +sockets. + +Not all operating systems support sockets. In the GNU library, the +header file @file{sys/socket.h} exists regardless of the operating +system, and the socket functions always exist, but if the system does +not really support sockets, these functions always fail. + +@strong{Incomplete:} We do not currently document the facilities for +broadcast messages or for configuring Internet interfaces. + +@menu +* Socket Concepts:: Basic concepts you need to know about. +* Communication Styles::Stream communication, datagrams, and other styles. +* Socket Addresses:: How socket names (``addresses'') work. +* File Namespace:: Details about the file namespace. +* Internet Namespace:: Details about the Internet namespace. +* Misc Namespaces:: Other namespaces not documented fully here. +* Open/Close Sockets:: Creating sockets and destroying them. +* Connections:: Operations on sockets with connection state. +* Datagrams:: Operations on datagram sockets. +* Inetd:: Inetd is a daemon that starts servers on request. + The most convenient way to write a server + is to make it work with Inetd. +* Socket Options:: Miscellaneous low-level socket options. +* Networks Database:: Accessing the database of network names. +@end menu + +@node Socket Concepts +@section Socket Concepts + +@cindex communication style (of a socket) +@cindex style of communication (of a socket) +When you create a socket, you must specify the style of communication +you want to use and the type of protocol that should implement it. +The @dfn{communication style} of a socket defines the user-level +semantics of sending and receiving data on the socket. Choosing a +communication style specifies the answers to questions such as these: + +@itemize @bullet +@item +@cindex packet +@cindex byte stream +@cindex stream (sockets) +@strong{What are the units of data transmission?} Some communication +styles regard the data as a sequence of bytes, with no larger +structure; others group the bytes into records (which are known in +this context as @dfn{packets}). + +@item +@cindex loss of data on sockets +@cindex data loss on sockets +@strong{Can data be lost during normal operation?} Some communication +styles guarantee that all the data sent arrives in the order it was +sent (barring system or network crashes); other styles occasionally +lose data as a normal part of operation, and may sometimes deliver +packets more than once or in the wrong order. + +Designing a program to use unreliable communication styles usually +involves taking precautions to detect lost or misordered packets and +to retransmit data as needed. + +@item +@strong{Is communication entirely with one partner?} Some +communication styles are like a telephone call---you make a +@dfn{connection} with one remote socket, and then exchange data +freely. Other styles are like mailing letters---you specify a +destination address for each message you send. +@end itemize + +@cindex namespace (of socket) +@cindex domain (of socket) +@cindex socket namespace +@cindex socket domain +You must also choose a @dfn{namespace} for naming the socket. A socket +name (``address'') is meaningful only in the context of a particular +namespace. In fact, even the data type to use for a socket name may +depend on the namespace. Namespaces are also called ``domains'', but we +avoid that word as it can be confused with other usage of the same +term. Each namespace has a symbolic name that starts with @samp{PF_}. +A corresponding symbolic name starting with @samp{AF_} designates the +address format for that namespace. + +@cindex network protocol +@cindex protocol (of socket) +@cindex socket protocol +@cindex protocol family +Finally you must choose the @dfn{protocol} to carry out the +communication. The protocol determines what low-level mechanism is used +to transmit and receive data. Each protocol is valid for a particular +namespace and communication style; a namespace is sometimes called a +@dfn{protocol family} because of this, which is why the namespace names +start with @samp{PF_}. + +The rules of a protocol apply to the data passing between two programs, +perhaps on different computers; most of these rules are handled by the +operating system, and you need not know about them. What you do need to +know about protocols is this: + +@itemize @bullet +@item +In order to have communication between two sockets, they must specify +the @emph{same} protocol. + +@item +Each protocol is meaningful with particular style/namespace +combinations and cannot be used with inappropriate combinations. For +example, the TCP protocol fits only the byte stream style of +communication and the Internet namespace. + +@item +For each combination of style and namespace, there is a @dfn{default +protocol} which you can request by specifying 0 as the protocol +number. And that's what you should normally do---use the default. +@end itemize + +@node Communication Styles +@section Communication Styles + +The GNU library includes support for several different kinds of sockets, +each with different characteristics. This section describes the +supported socket types. The symbolic constants listed here are +defined in @file{sys/socket.h}. +@pindex sys/socket.h + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int SOCK_STREAM +The @code{SOCK_STREAM} style is like a pipe (@pxref{Pipes and FIFOs}); +it operates over a connection with a particular remote socket, and +transmits data reliably as a stream of bytes. + +Use of this style is covered in detail in @ref{Connections}. +@end deftypevr + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int SOCK_DGRAM +The @code{SOCK_DGRAM} style is used for sending +individually-addressed packets, unreliably. +It is the diametrical opposite of @code{SOCK_STREAM}. + +Each time you write data to a socket of this kind, that data becomes +one packet. Since @code{SOCK_DGRAM} sockets do not have connections, +you must specify the recipient address with each packet. + +The only guarantee that the system makes about your requests to +transmit data is that it will try its best to deliver each packet you +send. It may succeed with the sixth packet after failing with the +fourth and fifth packets; the seventh packet may arrive before the +sixth, and may arrive a second time after the sixth. + +The typical use for @code{SOCK_DGRAM} is in situations where it is +acceptable to simply resend a packet if no response is seen in a +reasonable amount of time. + +@xref{Datagrams}, for detailed information about how to use datagram +sockets. +@end deftypevr + +@ignore +@c This appears to be only for the NS domain, which we aren't +@c discussing and probably won't support either. +@comment sys/socket.h +@comment BSD +@deftypevr Macro int SOCK_SEQPACKET +This style is like @code{SOCK_STREAM} except that the data is +structured into packets. + +A program that receives data over a @code{SOCK_SEQPACKET} socket +should be prepared to read the entire message packet in a single call +to @code{read}; if it only reads part of the message, the remainder of +the message is simply discarded instead of being available for +subsequent calls to @code{read}. + +Many protocols do not support this communication style. +@end deftypevr +@end ignore + +@ignore +@comment sys/socket.h +@comment BSD +@deftypevr Macro int SOCK_RDM +This style is a reliable version of @code{SOCK_DGRAM}: it sends +individually addressed packets, but guarantees that each packet sent +arrives exactly once. + +@strong{Warning:} It is not clear this is actually supported +by any operating system. +@end deftypevr +@end ignore + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int SOCK_RAW +This style provides access to low-level network protocols and +interfaces. Ordinary user programs usually have no need to use this +style. +@end deftypevr + +@node Socket Addresses +@section Socket Addresses + +@cindex address of socket +@cindex name of socket +@cindex binding a socket address +@cindex socket address (name) binding +The name of a socket is normally called an @dfn{address}. The +functions and symbols for dealing with socket addresses were named +inconsistently, sometimes using the term ``name'' and sometimes using +``address''. You can regard these terms as synonymous where sockets +are concerned. + +A socket newly created with the @code{socket} function has no +address. Other processes can find it for communication only if you +give it an address. We call this @dfn{binding} the address to the +socket, and the way to do it is with the @code{bind} function. + +You need be concerned with the address of a socket if other processes +are to find it and start communicating with it. You can specify an +address for other sockets, but this is usually pointless; the first time +you send data from a socket, or use it to initiate a connection, the +system assigns an address automatically if you have not specified one. + +Occasionally a client needs to specify an address because the server +discriminates based on addresses; for example, the rsh and rlogin +protocols look at the client's socket address and don't bypass password +checking unless it is less than @code{IPPORT_RESERVED} (@pxref{Ports}). + +The details of socket addresses vary depending on what namespace you are +using. @xref{File Namespace}, or @ref{Internet Namespace}, for specific +information. + +Regardless of the namespace, you use the same functions @code{bind} and +@code{getsockname} to set and examine a socket's address. These +functions use a phony data type, @code{struct sockaddr *}, to accept the +address. In practice, the address lives in a structure of some other +data type appropriate to the address format you are using, but you cast +its address to @code{struct sockaddr *} when you pass it to +@code{bind}. + +@menu +* Address Formats:: About @code{struct sockaddr}. +* Setting Address:: Binding an address to a socket. +* Reading Address:: Reading the address of a socket. +@end menu + +@node Address Formats +@subsection Address Formats + +The functions @code{bind} and @code{getsockname} use the generic data +type @code{struct sockaddr *} to represent a pointer to a socket +address. You can't use this data type effectively to interpret an +address or construct one; for that, you must use the proper data type +for the socket's namespace. + +Thus, the usual practice is to construct an address in the proper +namespace-specific type, then cast a pointer to @code{struct sockaddr *} +when you call @code{bind} or @code{getsockname}. + +The one piece of information that you can get from the @code{struct +sockaddr} data type is the @dfn{address format} designator which tells +you which data type to use to understand the address fully. + +@pindex sys/socket.h +The symbols in this section are defined in the header file +@file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftp {Date Type} {struct sockaddr} +The @code{struct sockaddr} type itself has the following members: + +@table @code +@item short int sa_family +This is the code for the address format of this address. It +identifies the format of the data which follows. + +@item char sa_data[14] +This is the actual socket address data, which is format-dependent. Its +length also depends on the format, and may well be more than 14. The +length 14 of @code{sa_data} is essentially arbitrary. +@end table +@end deftp + +Each address format has a symbolic name which starts with @samp{AF_}. +Each of them corresponds to a @samp{PF_} symbol which designates the +corresponding namespace. Here is a list of address format names: + +@table @code +@comment sys/socket.h +@comment GNU +@item AF_FILE +@vindex AF_FILE +This designates the address format that goes with the file namespace. +(@code{PF_FILE} is the name of that namespace.) @xref{File Namespace +Details}, for information about this address format. + +@comment sys/socket.h +@comment BSD +@item AF_UNIX +@vindex AF_UNIX +This is a synonym for @code{AF_FILE}, for compatibility. +(@code{PF_UNIX} is likewise a synonym for @code{PF_FILE}.) + +@comment sys/socket.h +@comment BSD +@item AF_INET +@vindex AF_INET +This designates the address format that goes with the Internet +namespace. (@code{PF_INET} is the name of that namespace.) +@xref{Internet Address Format}. + +@comment sys/socket.h +@comment BSD +@item AF_UNSPEC +@vindex AF_UNSPEC +This designates no particular address format. It is used only in rare +cases, such as to clear out the default destination address of a +``connected'' datagram socket. @xref{Sending Datagrams}. + +The corresponding namespace designator symbol @code{PF_UNSPEC} exists +for completeness, but there is no reason to use it in a program. +@end table + +@file{sys/socket.h} defines symbols starting with @samp{AF_} for many +different kinds of networks, all or most of which are not actually +implemented. We will document those that really work, as we receive +information about how to use them. + +@node Setting Address +@subsection Setting the Address of a Socket + +@pindex sys/socket.h +Use the @code{bind} function to assign an address to a socket. The +prototype for @code{bind} is in the header file @file{sys/socket.h}. +For examples of use, see @ref{File Namespace}, or see @ref{Inet Example}. + +@comment sys/socket.h +@comment BSD +@deftypefun int bind (int @var{socket}, struct sockaddr *@var{addr}, size_t @var{length}) +The @code{bind} function assigns an address to the socket +@var{socket}. The @var{addr} and @var{length} arguments specify the +address; the detailed format of the address depends on the namespace. +The first part of the address is always the format designator, which +specifies a namespace, and says that the address is in the format for +that namespace. + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item EADDRNOTAVAIL +The specified address is not available on this machine. + +@item EADDRINUSE +Some other socket is already using the specified address. + +@item EINVAL +The socket @var{socket} already has an address. + +@item EACCES +You do not have permission to access the requested address. (In the +Internet domain, only the super-user is allowed to specify a port number +in the range 0 through @code{IPPORT_RESERVED} minus one; see +@ref{Ports}.) +@end table + +Additional conditions may be possible depending on the particular namespace +of the socket. +@end deftypefun + +@node Reading Address +@subsection Reading the Address of a Socket + +@pindex sys/socket.h +Use the function @code{getsockname} to examine the address of an +Internet socket. The prototype for this function is in the header file +@file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypefun int getsockname (int @var{socket}, struct sockaddr *@var{addr}, size_t *@var{length-ptr}) +The @code{getsockname} function returns information about the +address of the socket @var{socket} in the locations specified by the +@var{addr} and @var{length-ptr} arguments. Note that the +@var{length-ptr} is a pointer; you should initialize it to be the +allocation size of @var{addr}, and on return it contains the actual +size of the address data. + +The format of the address data depends on the socket namespace. The +length of the information is usually fixed for a given namespace, so +normally you can know exactly how much space is needed and can provide +that much. The usual practice is to allocate a place for the value +using the proper data type for the socket's namespace, then cast its +address to @code{struct sockaddr *} to pass it to @code{getsockname}. + +The return value is @code{0} on success and @code{-1} on error. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item ENOBUFS +There are not enough internal buffers available for the operation. +@end table +@end deftypefun + +You can't read the address of a socket in the file namespace. This is +consistent with the rest of the system; in general, there's no way to +find a file's name from a descriptor for that file. + +@node File Namespace +@section The File Namespace +@cindex file namespace, for sockets + +This section describes the details of the file namespace, whose +symbolic name (required when you create a socket) is @code{PF_FILE}. + +@menu +* Concepts: File Namespace Concepts. What you need to understand. +* Details: File Namespace Details. Address format, symbolic names, etc. +* Example: File Socket Example. Example of creating a socket. +@end menu + +@node File Namespace Concepts +@subsection File Namespace Concepts + +In the file namespace, socket addresses are file names. You can specify +any file name you want as the address of the socket, but you must have +write permission on the directory containing it. In order to connect to +a socket, you must have read permission for it. It's common to put +these files in the @file{/tmp} directory. + +One peculiarity of the file namespace is that the name is only used when +opening the connection; once that is over with, the address is not +meaningful and may not exist. + +Another peculiarity is that you cannot connect to such a socket from +another machine--not even if the other machine shares the file system +which contains the name of the socket. You can see the socket in a +directory listing, but connecting to it never succeeds. Some programs +take advantage of this, such as by asking the client to send its own +process ID, and using the process IDs to distinguish between clients. +However, we recommend you not use this method in protocols you design, +as we might someday permit connections from other machines that mount +the same file systems. Instead, send each new client an identifying +number if you want it to have one. + +After you close a socket in the file namespace, you should delete the +file name from the file system. Use @code{unlink} or @code{remove} to +do this; see @ref{Deleting Files}. + +The file namespace supports just one protocol for any communication +style; it is protocol number @code{0}. + +@node File Namespace Details +@subsection Details of File Namespace + +@pindex sys/socket.h +To create a socket in the file namespace, use the constant +@code{PF_FILE} as the @var{namespace} argument to @code{socket} or +@code{socketpair}. This constant is defined in @file{sys/socket.h}. + +@comment sys/socket.h +@comment GNU +@deftypevr Macro int PF_FILE +This designates the file namespace, in which socket addresses are file +names, and its associated family of protocols. +@end deftypevr + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int PF_UNIX +This is a synonym for @code{PF_FILE}, for compatibility's sake. +@end deftypevr + +The structure for specifying socket names in the file namespace is +defined in the header file @file{sys/un.h}: +@pindex sys/un.h + +@comment sys/un.h +@comment BSD +@deftp {Data Type} {struct sockaddr_un} +This structure is used to specify file namespace socket addresses. It has +the following members: + +@table @code +@item short int sun_family +This identifies the address family or format of the socket address. +You should store the value @code{AF_FILE} to designate the file +namespace. @xref{Socket Addresses}. + +@item char sun_path[108] +This is the file name to use. + +@strong{Incomplete:} Why is 108 a magic number? RMS suggests making +this a zero-length array and tweaking the example following to use +@code{alloca} to allocate an appropriate amount of storage based on +the length of the filename. +@end table +@end deftp + +You should compute the @var{length} parameter for a socket address in +the file namespace as the sum of the size of the @code{sun_family} +component and the string length (@emph{not} the allocation size!) of +the file name string. + +@node File Socket Example +@subsection Example of File-Namespace Sockets + +Here is an example showing how to create and name a socket in the file +namespace. + +@smallexample +@include mkfsock.c.texi +@end smallexample + +@node Internet Namespace +@section The Internet Namespace +@cindex Internet namespace, for sockets + +This section describes the details the protocols and socket naming +conventions used in the Internet namespace. + +To create a socket in the Internet namespace, use the symbolic name +@code{PF_INET} of this namespace as the @var{namespace} argument to +@code{socket} or @code{socketpair}. This macro is defined in +@file{sys/socket.h}. +@pindex sys/socket.h + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int PF_INET +This designates the Internet namespace and associated family of +protocols. +@end deftypevr + +A socket address for the Internet namespace includes the following components: + +@itemize @bullet +@item +The address of the machine you want to connect to. Internet addresses +can be specified in several ways; these are discussed in @ref{Internet +Address Format}, @ref{Host Addresses}, and @ref{Host Names}. + +@item +A port number for that machine. @xref{Ports}. +@end itemize + +You must ensure that the address and port number are represented in a +canonical format called @dfn{network byte order}. @xref{Byte Order}, +for information about this. + +@menu +* Internet Address Format:: How socket addresses are specified in the + Internet namespace. +* Host Addresses:: All about host addresses of internet host. +* Protocols Database:: Referring to protocols by name. +* Ports:: Internet port numbers. +* Services Database:: Ports may have symbolic names. +* Byte Order:: Different hosts may use different byte + ordering conventions; you need to + canonicalize host address and port number. +* Inet Example:: Putting it all together. +@end menu + +@node Internet Address Format +@subsection Internet Socket Address Format + +In the Internet namespace, a socket address consists of a host address +and a port on that host. In addition, the protocol you choose serves +effectively as a part of the address because local port numbers are +meaningful only within a particular protocol. + +The data type for representing socket addresses in the Internet namespace +is defined in the header file @file{netinet/in.h}. +@pindex netinet/in.h + +@comment netinet/in.h +@comment BSD +@deftp {Data Type} {struct sockaddr_in} +This is the data type used to represent socket addresses in the +Internet namespace. It has the following members: + +@table @code +@item short int sin_family +This identifies the address family or format of the socket address. +You should store the value of @code{AF_INET} in this member. +@xref{Socket Addresses}. + +@item struct in_addr sin_addr +This is the Internet address of the host machine. @xref{Host +Addresses}, and @ref{Host Names}, for how to get a value to store +here. + +@item unsigned short int sin_port +This is the port number. @xref{Ports}. +@end table +@end deftp + +When you call @code{bind} or @code{getsockname}, you should specify +@code{sizeof (struct sockaddr_in)} as the @var{length} parameter if +you are using an Internet namespace socket address. + +@node Host Addresses +@subsection Host Addresses + +Each computer on the Internet has one or more @dfn{Internet addresses}, +numbers which identify that computer among all those on the Internet. +Users typically write numeric host addresses as sequences of four +numbers, separated by periods, as in @samp{128.52.46.32}. + +Each computer also has one or more @dfn{host names}, which are strings +of words separated by periods, as in @samp{churchy.gnu.ai.mit.edu}. + +Programs that let the user specify a host typically accept both numeric +addresses and host names. But the program needs a numeric address to +open a connection; to use a host name, you must convert it to the +numeric address it stands for. + +@menu +* Abstract Host Addresses:: What a host number consists of. +* Data type: Host Address Data Type. Data type for a host number. +* Functions: Host Address Functions. Functions to operate on them. +* Names: Host Names. Translating host names to host numbers. +@end menu + +@node Abstract Host Addresses +@subsubsection Internet Host Addresses +@cindex host address, Internet +@cindex Internet host address + +@ifinfo +Each computer on the Internet has one or more Internet addresses, +numbers which identify that computer among all those on the Internet. +@end ifinfo + +@cindex network number +@cindex local network address number +An Internet host address is a number containing four bytes of data. +These are divided into two parts, a @dfn{network number} and a +@dfn{local network address number} within that network. The network +number consists of the first one, two or three bytes; the rest of the +bytes are the local address. + +Network numbers are registered with the Network Information Center +(NIC), and are divided into three classes---A, B, and C. The local +network address numbers of individual machines are registered with the +administrator of the particular network. + +Class A networks have single-byte numbers in the range 0 to 127. There +are only a small number of Class A networks, but they can each support a +very large number of hosts. Medium-sized Class B networks have two-byte +network numbers, with the first byte in the range 128 to 191. Class C +networks are the smallest; they have three-byte network numbers, with +the first byte in the range 192-255. Thus, the first 1, 2, or 3 bytes +of an Internet address specifies a network. The remaining bytes of the +Internet address specify the address within that network. + +The Class A network 0 is reserved for broadcast to all networks. In +addition, the host number 0 within each network is reserved for broadcast +to all hosts in that network. + +The Class A network 127 is reserved for loopback; you can always use +the Internet address @samp{127.0.0.1} to refer to the host machine. + +Since a single machine can be a member of multiple networks, it can +have multiple Internet host addresses. However, there is never +supposed to be more than one machine with the same host address. + +@c !!! this section could document the IN_CLASS* macros in <netinet/in.h>. + +@cindex standard dot notation, for Internet addresses +@cindex dot notation, for Internet addresses +There are four forms of the @dfn{standard numbers-and-dots notation} +for Internet addresses: + +@table @code +@item @var{a}.@var{b}.@var{c}.@var{d} +This specifies all four bytes of the address individually. + +@item @var{a}.@var{b}.@var{c} +The last part of the address, @var{c}, is interpreted as a 2-byte quantity. +This is useful for specifying host addresses in a Class B network with +network address number @code{@var{a}.@var{b}}. + +@item @var{a}.@var{b} +The last part of the address, @var{c}, is interpreted as a 3-byte quantity. +This is useful for specifying host addresses in a Class A network with +network address number @var{a}. + +@item @var{a} +If only one part is given, this corresponds directly to the host address +number. +@end table + +Within each part of the address, the usual C conventions for specifying +the radix apply. In other words, a leading @samp{0x} or @samp{0X} implies +hexadecimal radix; a leading @samp{0} implies octal; and otherwise decimal +radix is assumed. + +@node Host Address Data Type +@subsubsection Host Address Data Type + +Internet host addresses are represented in some contexts as integers +(type @code{unsigned long int}). In other contexts, the integer is +packaged inside a structure of type @code{struct in_addr}. It would +be better if the usage were made consistent, but it is not hard to extract +the integer from the structure or put the integer into a structure. + +The following basic definitions for Internet addresses appear in the +header file @file{netinet/in.h}: +@pindex netinet/in.h + +@comment netinet/in.h +@comment BSD +@deftp {Data Type} {struct in_addr} +This data type is used in certain contexts to contain an Internet host +address. It has just one field, named @code{s_addr}, which records the +host address number as an @code{unsigned long int}. +@end deftp + +@comment netinet/in.h +@comment BSD +@deftypevr Macro {unsigned long int} INADDR_LOOPBACK +You can use this constant to stand for ``the address of this machine,'' +instead of finding its actual address. It is the Internet address +@samp{127.0.0.1}, which is usually called @samp{localhost}. This +special constant saves you the trouble of looking up the address of your +own machine. Also, the system usually implements @code{INADDR_LOOPBACK} +specially, avoiding any network traffic for the case of one machine +talking to itself. +@end deftypevr + +@comment netinet/in.h +@comment BSD +@deftypevr Macro {unsigned long int} INADDR_ANY +You can use this constant to stand for ``any incoming address,'' when +binding to an address. @xref{Setting Address}. This is the usual +address to give in the @code{sin_addr} member of @w{@code{struct +sockaddr_in}} when you want to accept Internet connections. +@end deftypevr + +@comment netinet/in.h +@comment BSD +@deftypevr Macro {unsigned long int} INADDR_BROADCAST +This constant is the address you use to send a broadcast message. +@c !!! broadcast needs further documented +@end deftypevr + +@comment netinet/in.h +@comment BSD +@deftypevr Macro {unsigned long int} INADDR_NONE +This constant is returned by some functions to indicate an error. +@end deftypevr + +@node Host Address Functions +@subsubsection Host Address Functions + +@pindex arpa/inet.h +These additional functions for manipulating Internet addresses are +declared in @file{arpa/inet.h}. They represent Internet addresses in +network byte order; they represent network numbers and +local-address-within-network numbers in host byte order. +@xref{Byte Order}, for an explanation of network and host byte order. + +@comment arpa/inet.h +@comment BSD +@deftypefun {int} inet_aton (const char *@var{name}, struct in_addr *@var{addr}) +This function converts the Internet host address @var{name} +from the standard numbers-and-dots notation into binary data and stores +it in the @code{struct in_addr} that @var{addr} points to. +@code{inet_aton} returns nonzero if the address is valid, zero if not. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun {unsigned long int} inet_addr (const char *@var{name}) +This function converts the Internet host address @var{name} from the +standard numbers-and-dots notation into binary data. If the input is +not valid, @code{inet_addr} returns @code{INADDR_NONE}. This is an +obsolete interface to @code{inet_aton}, described immediately above; it +is obsolete because @code{INADDR_NONE} is a valid address +(255.255.255.255), and @code{inet_aton} provides a cleaner way to +indicate error return. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun {unsigned long int} inet_network (const char *@var{name}) +This function extracts the network number from the address @var{name}, +given in the standard numbers-and-dots notation. +If the input is not valid, @code{inet_network} returns @code{-1}. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun {char *} inet_ntoa (struct in_addr @var{addr}) +This function converts the Internet host address @var{addr} to a +string in the standard numbers-and-dots notation. The return value is +a pointer into a statically-allocated buffer. Subsequent calls will +overwrite the same buffer, so you should copy the string if you need +to save it. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun {struct in_addr} inet_makeaddr (int @var{net}, int @var{local}) +This function makes an Internet host address by combining the network +number @var{net} with the local-address-within-network number +@var{local}. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun int inet_lnaof (struct in_addr @var{addr}) +This function returns the local-address-within-network part of the +Internet host address @var{addr}. +@end deftypefun + +@comment arpa/inet.h +@comment BSD +@deftypefun int inet_netof (struct in_addr @var{addr}) +This function returns the network number part of the Internet host +address @var{addr}. +@end deftypefun + +@node Host Names +@subsubsection Host Names +@cindex hosts database +@cindex converting host name to address +@cindex converting host address to name + +Besides the standard numbers-and-dots notation for Internet addresses, +you can also refer to a host by a symbolic name. The advantage of a +symbolic name is that it is usually easier to remember. For example, +the machine with Internet address @samp{128.52.46.32} is also known as +@samp{churchy.gnu.ai.mit.edu}; and other machines in the @samp{gnu.ai.mit.edu} +domain can refer to it simply as @samp{churchy}. + +@pindex /etc/hosts +@pindex netdb.h +Internally, the system uses a database to keep track of the mapping +between host names and host numbers. This database is usually either +the file @file{/etc/hosts} or an equivalent provided by a name server. +The functions and other symbols for accessing this database are declared +in @file{netdb.h}. They are BSD features, defined unconditionally if +you include @file{netdb.h}. + +@comment netdb.h +@comment BSD +@deftp {Data Type} {struct hostent} +This data type is used to represent an entry in the hosts database. It +has the following members: + +@table @code +@item char *h_name +This is the ``official'' name of the host. + +@item char **h_aliases +These are alternative names for the host, represented as a null-terminated +vector of strings. + +@item int h_addrtype +This is the host address type; in practice, its value is always +@code{AF_INET}. In principle other kinds of addresses could be +represented in the data base as well as Internet addresses; if this were +done, you might find a value in this field other than @code{AF_INET}. +@xref{Socket Addresses}. + +@item int h_length +This is the length, in bytes, of each address. + +@item char **h_addr_list +This is the vector of addresses for the host. (Recall that the host +might be connected to multiple networks and have different addresses on +each one.) The vector is terminated by a null pointer. + +@item char *h_addr +This is a synonym for @code{h_addr_list[0]}; in other words, it is the +first host address. +@end table +@end deftp + +As far as the host database is concerned, each address is just a block +of memory @code{h_length} bytes long. But in other contexts there is an +implicit assumption that you can convert this to a @code{struct in_addr} or +an @code{unsigned long int}. Host addresses in a @code{struct hostent} +structure are always given in network byte order; see @ref{Byte Order}. + +You can use @code{gethostbyname} or @code{gethostbyaddr} to search the +hosts database for information about a particular host. The information +is returned in a statically-allocated structure; you must copy the +information if you need to save it across calls. + +@comment netdb.h +@comment BSD +@deftypefun {struct hostent *} gethostbyname (const char *@var{name}) +The @code{gethostbyname} function returns information about the host +named @var{name}. If the lookup fails, it returns a null pointer. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct hostent *} gethostbyaddr (const char *@var{addr}, int @var{length}, int @var{format}) +The @code{gethostbyaddr} function returns information about the host +with Internet address @var{addr}. The @var{length} argument is the +size (in bytes) of the address at @var{addr}. @var{format} specifies +the address format; for an Internet address, specify a value of +@code{AF_INET}. + +If the lookup fails, @code{gethostbyaddr} returns a null pointer. +@end deftypefun + +@vindex h_errno +If the name lookup by @code{gethostbyname} or @code{gethostbyaddr} +fails, you can find out the reason by looking at the value of the +variable @code{h_errno}. (It would be cleaner design for these +functions to set @code{errno}, but use of @code{h_errno} is compatible +with other systems.) Before using @code{h_errno}, you must declare it +like this: + +@smallexample +extern int h_errno; +@end smallexample + +Here are the error codes that you may find in @code{h_errno}: + +@table @code +@comment netdb.h +@comment BSD +@item HOST_NOT_FOUND +@vindex HOST_NOT_FOUND +No such host is known in the data base. + +@comment netdb.h +@comment BSD +@item TRY_AGAIN +@vindex TRY_AGAIN +This condition happens when the name server could not be contacted. If +you try again later, you may succeed then. + +@comment netdb.h +@comment BSD +@item NO_RECOVERY +@vindex NO_RECOVERY +A non-recoverable error occurred. + +@comment netdb.h +@comment BSD +@item NO_ADDRESS +@vindex NO_ADDRESS +The host database contains an entry for the name, but it doesn't have an +associated Internet address. +@end table + +You can also scan the entire hosts database one entry at a time using +@code{sethostent}, @code{gethostent}, and @code{endhostent}. Be careful +in using these functions, because they are not reentrant. + +@comment netdb.h +@comment BSD +@deftypefun void sethostent (int @var{stayopen}) +This function opens the hosts database to begin scanning it. You can +then call @code{gethostent} to read the entries. + +@c There was a rumor that this flag has different meaning if using the DNS, +@c but it appears this description is accurate in that case also. +If the @var{stayopen} argument is nonzero, this sets a flag so that +subsequent calls to @code{gethostbyname} or @code{gethostbyaddr} will +not close the database (as they usually would). This makes for more +efficiency if you call those functions several times, by avoiding +reopening the database for each call. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct hostent *} gethostent () +This function returns the next entry in the hosts database. It +returns a null pointer if there are no more entries. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun void endhostent () +This function closes the hosts database. +@end deftypefun + +@node Ports +@subsection Internet Ports +@cindex port number + +A socket address in the Internet namespace consists of a machine's +Internet address plus a @dfn{port number} which distinguishes the +sockets on a given machine (for a given protocol). Port numbers range +from 0 to 65,535. + +Port numbers less than @code{IPPORT_RESERVED} are reserved for standard +servers, such as @code{finger} and @code{telnet}. There is a database +that keeps track of these, and you can use the @code{getservbyname} +function to map a service name onto a port number; see @ref{Services +Database}. + +If you write a server that is not one of the standard ones defined in +the database, you must choose a port number for it. Use a number +greater than @code{IPPORT_USERRESERVED}; such numbers are reserved for +servers and won't ever be generated automatically by the system. +Avoiding conflicts with servers being run by other users is up to you. + +When you use a socket without specifying its address, the system +generates a port number for it. This number is between +@code{IPPORT_RESERVED} and @code{IPPORT_USERRESERVED}. + +On the Internet, it is actually legitimate to have two different +sockets with the same port number, as long as they never both try to +communicate with the same socket address (host address plus port +number). You shouldn't duplicate a port number except in special +circumstances where a higher-level protocol requires it. Normally, +the system won't let you do it; @code{bind} normally insists on +distinct port numbers. To reuse a port number, you must set the +socket option @code{SO_REUSEADDR}. @xref{Socket-Level Options}. + +@pindex netinet/in.h +These macros are defined in the header file @file{netinet/in.h}. + +@comment netinet/in.h +@comment BSD +@deftypevr Macro int IPPORT_RESERVED +Port numbers less than @code{IPPORT_RESERVED} are reserved for +superuser use. +@end deftypevr + +@comment netinet/in.h +@comment BSD +@deftypevr Macro int IPPORT_USERRESERVED +Port numbers greater than or equal to @code{IPPORT_USERRESERVED} are +reserved for explicit use; they will never be allocated automatically. +@end deftypevr + +@node Services Database +@subsection The Services Database +@cindex services database +@cindex converting service name to port number +@cindex converting port number to service name + +@pindex /etc/services +The database that keeps track of ``well-known'' services is usually +either the file @file{/etc/services} or an equivalent from a name server. +You can use these utilities, declared in @file{netdb.h}, to access +the services database. +@pindex netdb.h + +@comment netdb.h +@comment BSD +@deftp {Data Type} {struct servent} +This data type holds information about entries from the services database. +It has the following members: + +@table @code +@item char *s_name +This is the ``official'' name of the service. + +@item char **s_aliases +These are alternate names for the service, represented as an array of +strings. A null pointer terminates the array. + +@item int s_port +This is the port number for the service. Port numbers are given in +network byte order; see @ref{Byte Order}. + +@item char *s_proto +This is the name of the protocol to use with this service. +@xref{Protocols Database}. +@end table +@end deftp + +To get information about a particular service, use the +@code{getservbyname} or @code{getservbyport} functions. The information +is returned in a statically-allocated structure; you must copy the +information if you need to save it across calls. + +@comment netdb.h +@comment BSD +@deftypefun {struct servent *} getservbyname (const char *@var{name}, const char *@var{proto}) +The @code{getservbyname} function returns information about the +service named @var{name} using protocol @var{proto}. If it can't find +such a service, it returns a null pointer. + +This function is useful for servers as well as for clients; servers +use it to determine which port they should listen on (@pxref{Listening}). +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct servent *} getservbyport (int @var{port}, const char *@var{proto}) +The @code{getservbyport} function returns information about the +service at port @var{port} using protocol @var{proto}. If it can't +find such a service, it returns a null pointer. +@end deftypefun + +You can also scan the services database using @code{setservent}, +@code{getservent}, and @code{endservent}. Be careful in using these +functions, because they are not reentrant. + +@comment netdb.h +@comment BSD +@deftypefun void setservent (int @var{stayopen}) +This function opens the services database to begin scanning it. + +If the @var{stayopen} argument is nonzero, this sets a flag so that +subsequent calls to @code{getservbyname} or @code{getservbyport} will +not close the database (as they usually would). This makes for more +efficiency if you call those functions several times, by avoiding +reopening the database for each call. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct servent *} getservent (void) +This function returns the next entry in the services database. If +there are no more entries, it returns a null pointer. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun void endservent (void) +This function closes the services database. +@end deftypefun + +@node Byte Order +@subsection Byte Order Conversion +@cindex byte order conversion, for socket +@cindex converting byte order + +@cindex big-endian +@cindex little-endian +Different kinds of computers use different conventions for the +ordering of bytes within a word. Some computers put the most +significant byte within a word first (this is called ``big-endian'' +order), and others put it last (``little-endian'' order). + +@cindex network byte order +So that machines with different byte order conventions can +communicate, the Internet protocols specify a canonical byte order +convention for data transmitted over the network. This is known +as the @dfn{network byte order}. + +When establishing an Internet socket connection, you must make sure that +the data in the @code{sin_port} and @code{sin_addr} members of the +@code{sockaddr_in} structure are represented in the network byte order. +If you are encoding integer data in the messages sent through the +socket, you should convert this to network byte order too. If you don't +do this, your program may fail when running on or talking to other kinds +of machines. + +If you use @code{getservbyname} and @code{gethostbyname} or +@code{inet_addr} to get the port number and host address, the values are +already in the network byte order, and you can copy them directly into +the @code{sockaddr_in} structure. + +Otherwise, you have to convert the values explicitly. Use +@code{htons} and @code{ntohs} to convert values for the @code{sin_port} +member. Use @code{htonl} and @code{ntohl} to convert values for the +@code{sin_addr} member. (Remember, @code{struct in_addr} is equivalent +to @code{unsigned long int}.) These functions are declared in +@file{netinet/in.h}. +@pindex netinet/in.h + +@comment netinet/in.h +@comment BSD +@deftypefun {unsigned short int} htons (unsigned short int @var{hostshort}) +This function converts the @code{short} integer @var{hostshort} from +host byte order to network byte order. +@end deftypefun + +@comment netinet/in.h +@comment BSD +@deftypefun {unsigned short int} ntohs (unsigned short int @var{netshort}) +This function converts the @code{short} integer @var{netshort} from +network byte order to host byte order. +@end deftypefun + +@comment netinet/in.h +@comment BSD +@deftypefun {unsigned long int} htonl (unsigned long int @var{hostlong}) +This function converts the @code{long} integer @var{hostlong} from +host byte order to network byte order. +@end deftypefun + +@comment netinet/in.h +@comment BSD +@deftypefun {unsigned long int} ntohl (unsigned long int @var{netlong}) +This function converts the @code{long} integer @var{netlong} from +network byte order to host byte order. +@end deftypefun + +@node Protocols Database +@subsection Protocols Database +@cindex protocols database + +The communications protocol used with a socket controls low-level +details of how data is exchanged. For example, the protocol implements +things like checksums to detect errors in transmissions, and routing +instructions for messages. Normal user programs have little reason to +mess with these details directly. + +@cindex TCP (Internet protocol) +The default communications protocol for the Internet namespace depends on +the communication style. For stream communication, the default is TCP +(``transmission control protocol''). For datagram communication, the +default is UDP (``user datagram protocol''). For reliable datagram +communication, the default is RDP (``reliable datagram protocol''). +You should nearly always use the default. + +@pindex /etc/protocols +Internet protocols are generally specified by a name instead of a +number. The network protocols that a host knows about are stored in a +database. This is usually either derived from the file +@file{/etc/protocols}, or it may be an equivalent provided by a name +server. You look up the protocol number associated with a named +protocol in the database using the @code{getprotobyname} function. + +Here are detailed descriptions of the utilities for accessing the +protocols database. These are declared in @file{netdb.h}. +@pindex netdb.h + +@comment netdb.h +@comment BSD +@deftp {Data Type} {struct protoent} +This data type is used to represent entries in the network protocols +database. It has the following members: + +@table @code +@item char *p_name +This is the official name of the protocol. + +@item char **p_aliases +These are alternate names for the protocol, specified as an array of +strings. The last element of the array is a null pointer. + +@item int p_proto +This is the protocol number (in host byte order); use this member as the +@var{protocol} argument to @code{socket}. +@end table +@end deftp + +You can use @code{getprotobyname} and @code{getprotobynumber} to search +the protocols database for a specific protocol. The information is +returned in a statically-allocated structure; you must copy the +information if you need to save it across calls. + +@comment netdb.h +@comment BSD +@deftypefun {struct protoent *} getprotobyname (const char *@var{name}) +The @code{getprotobyname} function returns information about the +network protocol named @var{name}. If there is no such protocol, it +returns a null pointer. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct protoent *} getprotobynumber (int @var{protocol}) +The @code{getprotobynumber} function returns information about the +network protocol with number @var{protocol}. If there is no such +protocol, it returns a null pointer. +@end deftypefun + +You can also scan the whole protocols database one protocol at a time by +using @code{setprotoent}, @code{getprotoent}, and @code{endprotoent}. +Be careful in using these functions, because they are not reentrant. + +@comment netdb.h +@comment BSD +@deftypefun void setprotoent (int @var{stayopen}) +This function opens the protocols database to begin scanning it. + +If the @var{stayopen} argument is nonzero, this sets a flag so that +subsequent calls to @code{getprotobyname} or @code{getprotobynumber} will +not close the database (as they usually would). This makes for more +efficiency if you call those functions several times, by avoiding +reopening the database for each call. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct protoent *} getprotoent (void) +This function returns the next entry in the protocols database. It +returns a null pointer if there are no more entries. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun void endprotoent (void) +This function closes the protocols database. +@end deftypefun + +@node Inet Example +@subsection Internet Socket Example + +Here is an example showing how to create and name a socket in the +Internet namespace. The newly created socket exists on the machine that +the program is running on. Rather than finding and using the machine's +Internet address, this example specifies @code{INADDR_ANY} as the host +address; the system replaces that with the machine's actual address. + +@smallexample +@include mkisock.c.texi +@end smallexample + +Here is another example, showing how you can fill in a @code{sockaddr_in} +structure, given a host name string and a port number: + +@smallexample +@include isockad.c.texi +@end smallexample + +@node Misc Namespaces +@section Other Namespaces + +@vindex PF_NS +@vindex PF_ISO +@vindex PF_CCITT +@vindex PF_IMPLINK +@vindex PF_ROUTE +Certain other namespaces and associated protocol families are supported +but not documented yet because they are not often used. @code{PF_NS} +refers to the Xerox Network Software protocols. @code{PF_ISO} stands +for Open Systems Interconnect. @code{PF_CCITT} refers to protocols from +CCITT. @file{socket.h} defines these symbols and others naming protocols +not actually implemented. + +@code{PF_IMPLINK} is used for communicating between hosts and Internet +Message Processors. For information on this, and on @code{PF_ROUTE}, an +occasionally-used local area routing protocol, see the GNU Hurd Manual +(to appear in the future). + +@node Open/Close Sockets +@section Opening and Closing Sockets + +This section describes the actual library functions for opening and +closing sockets. The same functions work for all namespaces and +connection styles. + +@menu +* Creating a Socket:: How to open a socket. +* Closing a Socket:: How to close a socket. +* Socket Pairs:: These are created like pipes. +@end menu + +@node Creating a Socket +@subsection Creating a Socket +@cindex creating a socket +@cindex socket, creating +@cindex opening a socket + +The primitive for creating a socket is the @code{socket} function, +declared in @file{sys/socket.h}. +@pindex sys/socket.h + +@comment sys/socket.h +@comment BSD +@deftypefun int socket (int @var{namespace}, int @var{style}, int @var{protocol}) +This function creates a socket and specifies communication style +@var{style}, which should be one of the socket styles listed in +@ref{Communication Styles}. The @var{namespace} argument specifies +the namespace; it must be @code{PF_FILE} (@pxref{File Namespace}) or +@code{PF_INET} (@pxref{Internet Namespace}). @var{protocol} +designates the specific protocol (@pxref{Socket Concepts}); zero is +usually right for @var{protocol}. + +The return value from @code{socket} is the file descriptor for the new +socket, or @code{-1} in case of error. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EPROTONOSUPPORT +The @var{protocol} or @var{style} is not supported by the +@var{namespace} specified. + +@item EMFILE +The process already has too many file descriptors open. + +@item ENFILE +The system already has too many file descriptors open. + +@item EACCESS +The process does not have privilege to create a socket of the specified +@var{style} or @var{protocol}. + +@item ENOBUFS +The system ran out of internal buffer space. +@end table + +The file descriptor returned by the @code{socket} function supports both +read and write operations. But, like pipes, sockets do not support file +positioning operations. +@end deftypefun + +For examples of how to call the @code{socket} function, +see @ref{File Namespace}, or @ref{Inet Example}. + + +@node Closing a Socket +@subsection Closing a Socket +@cindex socket, closing +@cindex closing a socket +@cindex shutting down a socket +@cindex socket shutdown + +When you are finished using a socket, you can simply close its +file descriptor with @code{close}; see @ref{Opening and Closing Files}. +If there is still data waiting to be transmitted over the connection, +normally @code{close} tries to complete this transmission. You +can control this behavior using the @code{SO_LINGER} socket option to +specify a timeout period; see @ref{Socket Options}. + +@pindex sys/socket.h +You can also shut down only reception or only transmission on a +connection by calling @code{shutdown}, which is declared in +@file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypefun int shutdown (int @var{socket}, int @var{how}) +The @code{shutdown} function shuts down the connection of socket +@var{socket}. The argument @var{how} specifies what action to +perform: + +@table @code +@item 0 +Stop receiving data for this socket. If further data arrives, +reject it. + +@item 1 +Stop trying to transmit data from this socket. Discard any data +waiting to be sent. Stop looking for acknowledgement of data already +sent; don't retransmit it if it is lost. + +@item 2 +Stop both reception and transmission. +@end table + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +@var{socket} is not a valid file descriptor. + +@item ENOTSOCK +@var{socket} is not a socket. + +@item ENOTCONN +@var{socket} is not connected. +@end table +@end deftypefun + +@node Socket Pairs +@subsection Socket Pairs +@cindex creating a socket pair +@cindex socket pair +@cindex opening a socket pair + +@pindex sys/socket.h +A @dfn{socket pair} consists of a pair of connected (but unnamed) +sockets. It is very similar to a pipe and is used in much the same +way. Socket pairs are created with the @code{socketpair} function, +declared in @file{sys/socket.h}. A socket pair is much like a pipe; the +main difference is that the socket pair is bidirectional, whereas the +pipe has one input-only end and one output-only end (@pxref{Pipes and +FIFOs}). + +@comment sys/socket.h +@comment BSD +@deftypefun int socketpair (int @var{namespace}, int @var{style}, int @var{protocol}, int @var{filedes}@t{[2]}) +This function creates a socket pair, returning the file descriptors in +@code{@var{filedes}[0]} and @code{@var{filedes}[1]}. The socket pair +is a full-duplex communications channel, so that both reading and writing +may be performed at either end. + +The @var{namespace}, @var{style}, and @var{protocol} arguments are +interpreted as for the @code{socket} function. @var{style} should be +one of the communication styles listed in @ref{Communication Styles}. +The @var{namespace} argument specifies the namespace, which must be +@code{AF_FILE} (@pxref{File Namespace}); @var{protocol} specifies the +communications protocol, but zero is the only meaningful value. + +If @var{style} specifies a connectionless communication style, then +the two sockets you get are not @emph{connected}, strictly speaking, +but each of them knows the other as the default destination address, +so they can send packets to each other. + +The @code{socketpair} function returns @code{0} on success and @code{-1} +on failure. The following @code{errno} error conditions are defined +for this function: + +@table @code +@item EMFILE +The process has too many file descriptors open. + +@item EAFNOSUPPORT +The specified namespace is not supported. + +@item EPROTONOSUPPORT +The specified protocol is not supported. + +@item EOPNOTSUPP +The specified protocol does not support the creation of socket pairs. +@end table +@end deftypefun + +@node Connections +@section Using Sockets with Connections + +@cindex connection +@cindex client +@cindex server +The most common communication styles involve making a connection to a +particular other socket, and then exchanging data with that socket +over and over. Making a connection is asymmetric; one side (the +@dfn{client}) acts to request a connection, while the other side (the +@dfn{server}) makes a socket and waits for the connection request. + +@iftex +@itemize @bullet +@item +@ref{Connecting}, describes what the client program must do to +initiate a connection with a server. + +@item +@ref{Listening}, and @ref{Accepting Connections}, describe what the +server program must do to wait for and act upon connection requests +from clients. + +@item +@ref{Transferring Data}, describes how data is transferred through the +connected socket. +@end itemize +@end iftex + +@menu +* Connecting:: What the client program must do. +* Listening:: How a server program waits for requests. +* Accepting Connections:: What the server does when it gets a request. +* Who is Connected:: Getting the address of the + other side of a connection. +* Transferring Data:: How to send and receive data. +* Byte Stream Example:: An example program: a client for communicating + over a byte stream socket in the Internet namespace. +* Server Example:: A corresponding server program. +* Out-of-Band Data:: This is an advanced feature. +@end menu + +@node Connecting +@subsection Making a Connection +@cindex connecting a socket +@cindex socket, connecting +@cindex socket, initiating a connection +@cindex socket, client actions + +In making a connection, the client makes a connection while the server +waits for and accepts the connection. Here we discuss what the client +program must do, using the @code{connect} function, which is declared in +@file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypefun int connect (int @var{socket}, struct sockaddr *@var{addr}, size_t @var{length}) +The @code{connect} function initiates a connection from the socket +with file descriptor @var{socket} to the socket whose address is +specified by the @var{addr} and @var{length} arguments. (This socket +is typically on another machine, and it must be already set up as a +server.) @xref{Socket Addresses}, for information about how these +arguments are interpreted. + +Normally, @code{connect} waits until the server responds to the request +before it returns. You can set nonblocking mode on the socket +@var{socket} to make @code{connect} return immediately without waiting +for the response. @xref{File Status Flags}, for information about +nonblocking mode. +@c !!! how do you tell when it has finished connecting? I suspect the +@c way you do it is select for writing. + +The normal return value from @code{connect} is @code{0}. If an error +occurs, @code{connect} returns @code{-1}. The following @code{errno} +error conditions are defined for this function: + +@table @code +@item EBADF +The socket @var{socket} is not a valid file descriptor. + +@item ENOTSOCK +The socket @var{socket} is not a socket. + +@item EADDRNOTAVAIL +The specified address is not available on the remote machine. + +@item EAFNOSUPPORT +The namespace of the @var{addr} is not supported by this socket. + +@item EISCONN +The socket @var{socket} is already connected. + +@item ETIMEDOUT +The attempt to establish the connection timed out. + +@item ECONNREFUSED +The server has actively refused to establish the connection. + +@item ENETUNREACH +The network of the given @var{addr} isn't reachable from this host. + +@item EADDRINUSE +The socket address of the given @var{addr} is already in use. + +@item EINPROGRESS +The socket @var{socket} is non-blocking and the connection could not be +established immediately. You can determine when the connection is +completely established with @code{select}; @pxref{Waiting for I/O}. +Another @code{connect} call on the same socket, before the connection is +completely established, will fail with @code{EALREADY}. + +@item EALREADY +The socket @var{socket} is non-blocking and already has a pending +connection in progress (see @code{EINPROGRESS} above). +@end table +@end deftypefun + +@node Listening +@subsection Listening for Connections +@cindex listening (sockets) +@cindex sockets, server actions +@cindex sockets, listening + +Now let us consider what the server process must do to accept +connections on a socket. First it must use the @code{listen} function +to enable connection requests on the socket, and then accept each +incoming connection with a call to @code{accept} (@pxref{Accepting +Connections}). Once connection requests are enabled on a server socket, +the @code{select} function reports when the socket has a connection +ready to be accepted (@pxref{Waiting for I/O}). + +The @code{listen} function is not allowed for sockets using +connectionless communication styles. + +You can write a network server that does not even start running until a +connection to it is requested. @xref{Inetd Servers}. + +In the Internet namespace, there are no special protection mechanisms +for controlling access to connect to a port; any process on any machine +can make a connection to your server. If you want to restrict access to +your server, make it examine the addresses associated with connection +requests or implement some other handshaking or identification +protocol. + +In the File namespace, the ordinary file protection bits control who has +access to connect to the socket. + +@comment sys/socket.h +@comment BSD +@deftypefun int listen (int @var{socket}, unsigned int @var{n}) +The @code{listen} function enables the socket @var{socket} to accept +connections, thus making it a server socket. + +The argument @var{n} specifies the length of the queue for pending +connections. When the queue fills, new clients attempting to connect +fail with @code{ECONNREFUSED} until the server calls @code{accept} to +accept a connection from the queue. + +The @code{listen} function returns @code{0} on success and @code{-1} +on failure. The following @code{errno} error conditions are defined +for this function: + +@table @code +@item EBADF +The argument @var{socket} is not a valid file descriptor. + +@item ENOTSOCK +The argument @var{socket} is not a socket. + +@item EOPNOTSUPP +The socket @var{socket} does not support this operation. +@end table +@end deftypefun + +@node Accepting Connections +@subsection Accepting Connections +@cindex sockets, accepting connections +@cindex accepting connections + +When a server receives a connection request, it can complete the +connection by accepting the request. Use the function @code{accept} +to do this. + +A socket that has been established as a server can accept connection +requests from multiple clients. The server's original socket +@emph{does not become part} of the connection; instead, @code{accept} +makes a new socket which participates in the connection. +@code{accept} returns the descriptor for this socket. The server's +original socket remains available for listening for further connection +requests. + +The number of pending connection requests on a server socket is finite. +If connection requests arrive from clients faster than the server can +act upon them, the queue can fill up and additional requests are refused +with a @code{ECONNREFUSED} error. You can specify the maximum length of +this queue as an argument to the @code{listen} function, although the +system may also impose its own internal limit on the length of this +queue. + +@comment sys/socket.h +@comment BSD +@deftypefun int accept (int @var{socket}, struct sockaddr *@var{addr}, size_t *@var{length-ptr}) +This function is used to accept a connection request on the server +socket @var{socket}. + +The @code{accept} function waits if there are no connections pending, +unless the socket @var{socket} has nonblocking mode set. (You can use +@code{select} to wait for a pending connection, with a nonblocking +socket.) @xref{File Status Flags}, for information about nonblocking +mode. + +The @var{addr} and @var{length-ptr} arguments are used to return +information about the name of the client socket that initiated the +connection. @xref{Socket Addresses}, for information about the format +of the information. + +Accepting a connection does not make @var{socket} part of the +connection. Instead, it creates a new socket which becomes +connected. The normal return value of @code{accept} is the file +descriptor for the new socket. + +After @code{accept}, the original socket @var{socket} remains open and +unconnected, and continues listening until you close it. You can +accept further connections with @var{socket} by calling @code{accept} +again. + +If an error occurs, @code{accept} returns @code{-1}. The following +@code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} argument is not a socket. + +@item EOPNOTSUPP +The descriptor @var{socket} does not support this operation. + +@item EWOULDBLOCK +@var{socket} has nonblocking mode set, and there are no pending +connections immediately available. +@end table +@end deftypefun + +The @code{accept} function is not allowed for sockets using +connectionless communication styles. + +@node Who is Connected +@subsection Who is Connected to Me? + +@comment sys/socket.h +@comment BSD +@deftypefun int getpeername (int @var{socket}, struct sockaddr *@var{addr}, size_t *@var{length-ptr}) +The @code{getpeername} function returns the address of the socket that +@var{socket} is connected to; it stores the address in the memory space +specified by @var{addr} and @var{length-ptr}. It stores the length of +the address in @code{*@var{length-ptr}}. + +@xref{Socket Addresses}, for information about the format of the +address. In some operating systems, @code{getpeername} works only for +sockets in the Internet domain. + +The return value is @code{0} on success and @code{-1} on error. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The argument @var{socket} is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item ENOTCONN +The socket @var{socket} is not connected. + +@item ENOBUFS +There are not enough internal buffers available. +@end table +@end deftypefun + + +@node Transferring Data +@subsection Transferring Data +@cindex reading from a socket +@cindex writing to a socket + +Once a socket has been connected to a peer, you can use the ordinary +@code{read} and @code{write} operations (@pxref{I/O Primitives}) to +transfer data. A socket is a two-way communications channel, so read +and write operations can be performed at either end. + +There are also some I/O modes that are specific to socket operations. +In order to specify these modes, you must use the @code{recv} and +@code{send} functions instead of the more generic @code{read} and +@code{write} functions. The @code{recv} and @code{send} functions take +an additional argument which you can use to specify various flags to +control the special I/O modes. For example, you can specify the +@code{MSG_OOB} flag to read or write out-of-band data, the +@code{MSG_PEEK} flag to peek at input, or the @code{MSG_DONTROUTE} flag +to control inclusion of routing information on output. + +@menu +* Sending Data:: Sending data with @code{send}. +* Receiving Data:: Reading data with @code{recv}. +* Socket Data Options:: Using @code{send} and @code{recv}. +@end menu + +@node Sending Data +@subsubsection Sending Data + +@pindex sys/socket.h +The @code{send} function is declared in the header file +@file{sys/socket.h}. If your @var{flags} argument is zero, you can just +as well use @code{write} instead of @code{send}; see @ref{I/O +Primitives}. If the socket was connected but the connection has broken, +you get a @code{SIGPIPE} signal for any use of @code{send} or +@code{write} (@pxref{Miscellaneous Signals}). + +@comment sys/socket.h +@comment BSD +@deftypefun int send (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}) +The @code{send} function is like @code{write}, but with the additional +flags @var{flags}. The possible values of @var{flags} are described +in @ref{Socket Data Options}. + +This function returns the number of bytes transmitted, or @code{-1} on +failure. If the socket is nonblocking, then @code{send} (like +@code{write}) can return after sending just part of the data. +@xref{File Status Flags}, for information about nonblocking mode. + +Note, however, that a successful return value merely indicates that +the message has been sent without error, not necessarily that it has +been received without error. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item EINTR +The operation was interrupted by a signal before any data was sent. +@xref{Interrupted Primitives}. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item EMSGSIZE +The socket type requires that the message be sent atomically, but the +message is too large for this to be possible. + +@item EWOULDBLOCK +Nonblocking mode has been set on the socket, and the write operation +would block. (Normally @code{send} blocks until the operation can be +completed.) + +@item ENOBUFS +There is not enough internal buffer space available. + +@item ENOTCONN +You never connected this socket. + +@item EPIPE +This socket was connected but the connection is now broken. In this +case, @code{send} generates a @code{SIGPIPE} signal first; if that +signal is ignored or blocked, or if its handler returns, then +@code{send} fails with @code{EPIPE}. +@end table +@end deftypefun + +@node Receiving Data +@subsubsection Receiving Data + +@pindex sys/socket.h +The @code{recv} function is declared in the header file +@file{sys/socket.h}. If your @var{flags} argument is zero, you can +just as well use @code{read} instead of @code{recv}; see @ref{I/O +Primitives}. + +@comment sys/socket.h +@comment BSD +@deftypefun int recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}) +The @code{recv} function is like @code{read}, but with the additional +flags @var{flags}. The possible values of @var{flags} are described +In @ref{Socket Data Options}. + +If nonblocking mode is set for @var{socket}, and no data is available to +be read, @code{recv} fails immediately rather than waiting. @xref{File +Status Flags}, for information about nonblocking mode. + +This function returns the number of bytes received, or @code{-1} on failure. +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item EWOULDBLOCK +Nonblocking mode has been set on the socket, and the read operation +would block. (Normally, @code{recv} blocks until there is input +available to be read.) + +@item EINTR +The operation was interrupted by a signal before any data was read. +@xref{Interrupted Primitives}. + +@item ENOTCONN +You never connected this socket. +@end table +@end deftypefun + +@node Socket Data Options +@subsubsection Socket Data Options + +@pindex sys/socket.h +The @var{flags} argument to @code{send} and @code{recv} is a bit +mask. You can bitwise-OR the values of the following macros together +to obtain a value for this argument. All are defined in the header +file @file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int MSG_OOB +Send or receive out-of-band data. @xref{Out-of-Band Data}. +@end deftypevr + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int MSG_PEEK +Look at the data but don't remove it from the input queue. This is +only meaningful with input functions such as @code{recv}, not with +@code{send}. +@end deftypevr + +@comment sys/socket.h +@comment BSD +@deftypevr Macro int MSG_DONTROUTE +Don't include routing information in the message. This is only +meaningful with output operations, and is usually only of interest for +diagnostic or routing programs. We don't try to explain it here. +@end deftypevr + +@node Byte Stream Example +@subsection Byte Stream Socket Example + +Here is an example client program that makes a connection for a byte +stream socket in the Internet namespace. It doesn't do anything +particularly interesting once it has connected to the server; it just +sends a text string to the server and exits. + +@smallexample +@include inetcli.c.texi +@end smallexample + +@node Server Example +@subsection Byte Stream Connection Server Example + +The server end is much more complicated. Since we want to allow +multiple clients to be connected to the server at the same time, it +would be incorrect to wait for input from a single client by simply +calling @code{read} or @code{recv}. Instead, the right thing to do is +to use @code{select} (@pxref{Waiting for I/O}) to wait for input on +all of the open sockets. This also allows the server to deal with +additional connection requests. + +This particular server doesn't do anything interesting once it has +gotten a message from a client. It does close the socket for that +client when it detects an end-of-file condition (resulting from the +client shutting down its end of the connection). + +This program uses @code{make_socket} and @code{init_sockaddr} to set +up the socket address; see @ref{Inet Example}. + +@smallexample +@include inetsrv.c.texi +@end smallexample + +@node Out-of-Band Data +@subsection Out-of-Band Data + +@cindex out-of-band data +@cindex high-priority data +Streams with connections permit @dfn{out-of-band} data that is +delivered with higher priority than ordinary data. Typically the +reason for sending out-of-band data is to send notice of an +exceptional condition. The way to send out-of-band data is using +@code{send}, specifying the flag @code{MSG_OOB} (@pxref{Sending +Data}). + +Out-of-band data is received with higher priority because the +receiving process need not read it in sequence; to read the next +available out-of-band data, use @code{recv} with the @code{MSG_OOB} +flag (@pxref{Receiving Data}). Ordinary read operations do not read +out-of-band data; they read only the ordinary data. + +@cindex urgent socket condition +When a socket finds that out-of-band data is on its way, it sends a +@code{SIGURG} signal to the owner process or process group of the +socket. You can specify the owner using the @code{F_SETOWN} command +to the @code{fcntl} function; see @ref{Interrupt Input}. You must +also establish a handler for this signal, as described in @ref{Signal +Handling}, in order to take appropriate action such as reading the +out-of-band data. + +Alternatively, you can test for pending out-of-band data, or wait +until there is out-of-band data, using the @code{select} function; it +can wait for an exceptional condition on the socket. @xref{Waiting +for I/O}, for more information about @code{select}. + +Notification of out-of-band data (whether with @code{SIGURG} or with +@code{select}) indicates that out-of-band data is on the way; the data +may not actually arrive until later. If you try to read the +out-of-band data before it arrives, @code{recv} fails with an +@code{EWOULDBLOCK} error. + +Sending out-of-band data automatically places a ``mark'' in the stream +of ordinary data, showing where in the sequence the out-of-band data +``would have been''. This is useful when the meaning of out-of-band +data is ``cancel everything sent so far''. Here is how you can test, +in the receiving process, whether any ordinary data was sent before +the mark: + +@smallexample +success = ioctl (socket, SIOCATMARK, &result); +@end smallexample + +Here's a function to discard any ordinary data preceding the +out-of-band mark: + +@smallexample +int +discard_until_mark (int socket) +@{ + while (1) + @{ + /* @r{This is not an arbitrary limit; any size will do.} */ + char buffer[1024]; + int result, success; + + /* @r{If we have reached the mark, return.} */ + success = ioctl (socket, SIOCATMARK, &result); + if (success < 0) + perror ("ioctl"); + if (result) + return; + + /* @r{Otherwise, read a bunch of ordinary data and discard it.} + @r{This is guaranteed not to read past the mark} + @r{if it starts before the mark.} */ + success = read (socket, buffer, sizeof buffer); + if (success < 0) + perror ("read"); + @} +@} +@end smallexample + +If you don't want to discard the ordinary data preceding the mark, you +may need to read some of it anyway, to make room in internal system +buffers for the out-of-band data. If you try to read out-of-band data +and get an @code{EWOULDBLOCK} error, try reading some ordinary data +(saving it so that you can use it when you want it) and see if that +makes room. Here is an example: + +@smallexample +struct buffer +@{ + char *buffer; + int size; + struct buffer *next; +@}; + +/* @r{Read the out-of-band data from SOCKET and return it} + @r{as a `struct buffer', which records the address of the data} + @r{and its size.} + + @r{It may be necessary to read some ordinary data} + @r{in order to make room for the out-of-band data.} + @r{If so, the ordinary data is saved as a chain of buffers} + @r{found in the `next' field of the value.} */ + +struct buffer * +read_oob (int socket) +@{ + struct buffer *tail = 0; + struct buffer *list = 0; + + while (1) + @{ + /* @r{This is an arbitrary limit.} + @r{Does anyone know how to do this without a limit?} */ + char *buffer = (char *) xmalloc (1024); + struct buffer *link; + int success; + int result; + + /* @r{Try again to read the out-of-band data.} */ + success = recv (socket, buffer, sizeof buffer, MSG_OOB); + if (success >= 0) + @{ + /* @r{We got it, so return it.} */ + struct buffer *link + = (struct buffer *) xmalloc (sizeof (struct buffer)); + link->buffer = buffer; + link->size = success; + link->next = list; + return link; + @} + + /* @r{If we fail, see if we are at the mark.} */ + success = ioctl (socket, SIOCATMARK, &result); + if (success < 0) + perror ("ioctl"); + if (result) + @{ + /* @r{At the mark; skipping past more ordinary data cannot help.} + @r{So just wait a while.} */ + sleep (1); + continue; + @} + + /* @r{Otherwise, read a bunch of ordinary data and save it.} + @r{This is guaranteed not to read past the mark} + @r{if it starts before the mark.} */ + success = read (socket, buffer, sizeof buffer); + if (success < 0) + perror ("read"); + + /* @r{Save this data in the buffer list.} */ + @{ + struct buffer *link + = (struct buffer *) xmalloc (sizeof (struct buffer)); + link->buffer = buffer; + link->size = success; + + /* @r{Add the new link to the end of the list.} */ + if (tail) + tail->next = link; + else + list = link; + tail = link; + @} + @} +@} +@end smallexample + +@node Datagrams +@section Datagram Socket Operations + +@cindex datagram socket +This section describes how to use communication styles that don't use +connections (styles @code{SOCK_DGRAM} and @code{SOCK_RDM}). Using +these styles, you group data into packets and each packet is an +independent communication. You specify the destination for each +packet individually. + +Datagram packets are like letters: you send each one independently, +with its own destination address, and they may arrive in the wrong +order or not at all. + +The @code{listen} and @code{accept} functions are not allowed for +sockets using connectionless communication styles. + +@menu +* Sending Datagrams:: Sending packets on a datagram socket. +* Receiving Datagrams:: Receiving packets on a datagram socket. +* Datagram Example:: An example program: packets sent over a + datagram socket in the file namespace. +* Example Receiver:: Another program, that receives those packets. +@end menu + +@node Sending Datagrams +@subsection Sending Datagrams +@cindex sending a datagram +@cindex transmitting datagrams +@cindex datagrams, transmitting + +@pindex sys/socket.h +The normal way of sending data on a datagram socket is by using the +@code{sendto} function, declared in @file{sys/socket.h}. + +You can call @code{connect} on a datagram socket, but this only +specifies a default destination for further data transmission on the +socket. When a socket has a default destination, then you can use +@code{send} (@pxref{Sending Data}) or even @code{write} (@pxref{I/O +Primitives}) to send a packet there. You can cancel the default +destination by calling @code{connect} using an address format of +@code{AF_UNSPEC} in the @var{addr} argument. @xref{Connecting}, for +more information about the @code{connect} function. + +@comment sys/socket.h +@comment BSD +@deftypefun int sendto (int @var{socket}, void *@var{buffer}. size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, size_t @var{length}) +The @code{sendto} function transmits the data in the @var{buffer} +through the socket @var{socket} to the destination address specified +by the @var{addr} and @var{length} arguments. The @var{size} argument +specifies the number of bytes to be transmitted. + +The @var{flags} are interpreted the same way as for @code{send}; see +@ref{Socket Data Options}. + +The return value and error conditions are also the same as for +@code{send}, but you cannot rely on the system to detect errors and +report them; the most common error is that the packet is lost or there +is no one at the specified address to receive it, and the operating +system on your machine usually does not know this. + +It is also possible for one call to @code{sendto} to report an error +due to a problem related to a previous call. +@end deftypefun + +@node Receiving Datagrams +@subsection Receiving Datagrams +@cindex receiving datagrams + +The @code{recvfrom} function reads a packet from a datagram socket and +also tells you where it was sent from. This function is declared in +@file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypefun int recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, size_t *@var{length-ptr}) +The @code{recvfrom} function reads one packet from the socket +@var{socket} into the buffer @var{buffer}. The @var{size} argument +specifies the maximum number of bytes to be read. + +If the packet is longer than @var{size} bytes, then you get the first +@var{size} bytes of the packet, and the rest of the packet is lost. +There's no way to read the rest of the packet. Thus, when you use a +packet protocol, you must always know how long a packet to expect. + +The @var{addr} and @var{length-ptr} arguments are used to return the +address where the packet came from. @xref{Socket Addresses}. For a +socket in the file domain, the address information won't be meaningful, +since you can't read the address of such a socket (@pxref{File +Namespace}). You can specify a null pointer as the @var{addr} argument +if you are not interested in this information. + +The @var{flags} are interpreted the same way as for @code{recv} +(@pxref{Socket Data Options}). The return value and error conditions +are also the same as for @code{recv}. +@end deftypefun + +You can use plain @code{recv} (@pxref{Receiving Data}) instead of +@code{recvfrom} if you know don't need to find out who sent the packet +(either because you know where it should come from or because you +treat all possible senders alike). Even @code{read} can be used if +you don't want to specify @var{flags} (@pxref{I/O Primitives}). + +@ignore +@c sendmsg and recvmsg are like readv and writev in that they +@c use a series of buffers. It's not clear this is worth +@c supporting or that we support them. +@c !!! they can do more; it is hairy + +@comment sys/socket.h +@comment BSD +@deftp {Data Type} {struct msghdr} +@end deftp + +@comment sys/socket.h +@comment BSD +@deftypefun int sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags}) +@end deftypefun + +@comment sys/socket.h +@comment BSD +@deftypefun int recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags}) +@end deftypefun +@end ignore + +@node Datagram Example +@subsection Datagram Socket Example + +Here is a set of example programs that send messages over a datagram +stream in the file namespace. Both the client and server programs use the +@code{make_named_socket} function that was presented in @ref{File +Namespace}, to create and name their sockets. + +First, here is the server program. It sits in a loop waiting for +messages to arrive, bouncing each message back to the sender. +Obviously, this isn't a particularly useful program, but it does show +the general ideas involved. + +@smallexample +@include filesrv.c.texi +@end smallexample + +@node Example Receiver +@subsection Example of Reading Datagrams + +Here is the client program corresponding to the server above. + +It sends a datagram to the server and then waits for a reply. Notice +that the socket for the client (as well as for the server) in this +example has to be given a name. This is so that the server can direct +a message back to the client. Since the socket has no associated +connection state, the only way the server can do this is by +referencing the name of the client. + +@smallexample +@include filecli.c.texi +@end smallexample + +Keep in mind that datagram socket communications are unreliable. In +this example, the client program waits indefinitely if the message +never reaches the server or if the server's response never comes +back. It's up to the user running the program to kill it and restart +it, if desired. A more automatic solution could be to use +@code{select} (@pxref{Waiting for I/O}) to establish a timeout period +for the reply, and in case of timeout either resend the message or +shut down the socket and exit. + +@node Inetd +@section The @code{inetd} Daemon + +We've explained above how to write a server program that does its own +listening. Such a server must already be running in order for anyone +to connect to it. + +Another way to provide service for an Internet port is to let the daemon +program @code{inetd} do the listening. @code{inetd} is a program that +runs all the time and waits (using @code{select}) for messages on a +specified set of ports. When it receives a message, it accepts the +connection (if the socket style calls for connections) and then forks a +child process to run the corresponding server program. You specify the +ports and their programs in the file @file{/etc/inetd.conf}. + +@menu +* Inetd Servers:: +* Configuring Inetd:: +@end menu + +@node Inetd Servers +@subsection @code{inetd} Servers + +Writing a server program to be run by @code{inetd} is very simple. Each time +someone requests a connection to the appropriate port, a new server +process starts. The connection already exists at this time; the +socket is available as the standard input descriptor and as the +standard output descriptor (descriptors 0 and 1) in the server +process. So the server program can begin reading and writing data +right away. Often the program needs only the ordinary I/O facilities; +in fact, a general-purpose filter program that knows nothing about +sockets can work as a byte stream server run by @code{inetd}. + +You can also use @code{inetd} for servers that use connectionless +communication styles. For these servers, @code{inetd} does not try to accept +a connection, since no connection is possible. It just starts the +server program, which can read the incoming datagram packet from +descriptor 0. The server program can handle one request and then +exit, or you can choose to write it to keep reading more requests +until no more arrive, and then exit. You must specify which of these +two techniques the server uses, when you configure @code{inetd}. + +@node Configuring Inetd +@subsection Configuring @code{inetd} + +The file @file{/etc/inetd.conf} tells @code{inetd} which ports to listen to +and what server programs to run for them. Normally each entry in the +file is one line, but you can split it onto multiple lines provided +all but the first line of the entry start with whitespace. Lines that +start with @samp{#} are comments. + +Here are two standard entries in @file{/etc/inetd.conf}: + +@smallexample +ftp stream tcp nowait root /libexec/ftpd ftpd +talk dgram udp wait root /libexec/talkd talkd +@end smallexample + +An entry has this format: + +@smallexample +@var{service} @var{style} @var{protocol} @var{wait} @var{username} @var{program} @var{arguments} +@end smallexample + +The @var{service} field says which service this program provides. It +should be the name of a service defined in @file{/etc/services}. +@code{inetd} uses @var{service} to decide which port to listen on for +this entry. + +The fields @var{style} and @var{protocol} specify the communication +style and the protocol to use for the listening socket. The style +should be the name of a communication style, converted to lower case +and with @samp{SOCK_} deleted---for example, @samp{stream} or +@samp{dgram}. @var{protocol} should be one of the protocols listed in +@file{/etc/protocols}. The typical protocol names are @samp{tcp} for +byte stream connections and @samp{udp} for unreliable datagrams. + +The @var{wait} field should be either @samp{wait} or @samp{nowait}. +Use @samp{wait} if @var{style} is a connectionless style and the +server, once started, handles multiple requests, as many as come in. +Use @samp{nowait} if @code{inetd} should start a new process for each message +or request that comes in. If @var{style} uses connections, then +@var{wait} @strong{must} be @samp{nowait}. + +@var{user} is the user name that the server should run as. @code{inetd} runs +as root, so it can set the user ID of its children arbitrarily. It's +best to avoid using @samp{root} for @var{user} if you can; but some +servers, such as Telnet and FTP, read a username and password +themselves. These servers need to be root initially so they can log +in as commanded by the data coming over the network. + +@var{program} together with @var{arguments} specifies the command to +run to start the server. @var{program} should be an absolute file +name specifying the executable file to run. @var{arguments} consists +of any number of whitespace-separated words, which become the +command-line arguments of @var{program}. The first word in +@var{arguments} is argument zero, which should by convention be the +program name itself (sans directories). + +If you edit @file{/etc/inetd.conf}, you can tell @code{inetd} to reread the +file and obey its new contents by sending the @code{inetd} process the +@code{SIGHUP} signal. You'll have to use @code{ps} to determine the +process ID of the @code{inetd} process, as it is not fixed. + +@c !!! could document /etc/inetd.sec + +@node Socket Options +@section Socket Options +@cindex socket options + +This section describes how to read or set various options that modify +the behavior of sockets and their underlying communications protocols. + +@cindex level, for socket options +@cindex socket option level +When you are manipulating a socket option, you must specify which +@dfn{level} the option pertains to. This describes whether the option +applies to the socket interface, or to a lower-level communications +protocol interface. + +@menu +* Socket Option Functions:: The basic functions for setting and getting + socket options. +* Socket-Level Options:: Details of the options at the socket level. +@end menu + +@node Socket Option Functions +@subsection Socket Option Functions + +@pindex sys/socket.h +Here are the functions for examining and modifying socket options. +They are declared in @file{sys/socket.h}. + +@comment sys/socket.h +@comment BSD +@deftypefun int getsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, size_t *@var{optlen-ptr}) +The @code{getsockopt} function gets information about the value of +option @var{optname} at level @var{level} for socket @var{socket}. + +The option value is stored in a buffer that @var{optval} points to. +Before the call, you should supply in @code{*@var{optlen-ptr}} the +size of this buffer; on return, it contains the number of bytes of +information actually stored in the buffer. + +Most options interpret the @var{optval} buffer as a single @code{int} +value. + +The actual return value of @code{getsockopt} is @code{0} on success +and @code{-1} on failure. The following @code{errno} error conditions +are defined: + +@table @code +@item EBADF +The @var{socket} argument is not a valid file descriptor. + +@item ENOTSOCK +The descriptor @var{socket} is not a socket. + +@item ENOPROTOOPT +The @var{optname} doesn't make sense for the given @var{level}. +@end table +@end deftypefun + +@comment sys/socket.h +@comment BSD +@deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, size_t @var{optlen}) +This function is used to set the socket option @var{optname} at level +@var{level} for socket @var{socket}. The value of the option is passed +in the buffer @var{optval}, which has size @var{optlen}. + +The return value and error codes for @code{setsockopt} are the same as +for @code{getsockopt}. +@end deftypefun + +@node Socket-Level Options +@subsection Socket-Level Options + +@comment sys/socket.h +@comment BSD +@deftypevr Constant int SOL_SOCKET +Use this constant as the @var{level} argument to @code{getsockopt} or +@code{setsockopt} to manipulate the socket-level options described in +this section. +@end deftypevr + +@pindex sys/socket.h +Here is a table of socket-level option names; all are defined in the +header file @file{sys/socket.h}. + +@table @code +@comment sys/socket.h +@comment BSD +@item SO_DEBUG +@c Extra blank line here makes the table look better. + +This option toggles recording of debugging information in the underlying +protocol modules. The value has type @code{int}; a nonzero value means +``yes''. +@c !!! should say how this is used +@c Ok, anyone who knows, please explain. + +@comment sys/socket.h +@comment BSD +@item SO_REUSEADDR +This option controls whether @code{bind} (@pxref{Setting Address}) +should permit reuse of local addresses for this socket. If you enable +this option, you can actually have two sockets with the same Internet +port number; but the system won't allow you to use the two +identically-named sockets in a way that would confuse the Internet. The +reason for this option is that some higher-level Internet protocols, +including FTP, require you to keep reusing the same socket number. + +The value has type @code{int}; a nonzero value means ``yes''. + +@comment sys/socket.h +@comment BSD +@item SO_KEEPALIVE +This option controls whether the underlying protocol should +periodically transmit messages on a connected socket. If the peer +fails to respond to these messages, the connection is considered +broken. The value has type @code{int}; a nonzero value means +``yes''. + +@comment sys/socket.h +@comment BSD +@item SO_DONTROUTE +This option controls whether outgoing messages bypass the normal +message routing facilities. If set, messages are sent directly to the +network interface instead. The value has type @code{int}; a nonzero +value means ``yes''. + +@comment sys/socket.h +@comment BSD +@item SO_LINGER +This option specifies what should happen when the socket of a type +that promises reliable delivery still has untransmitted messages when +it is closed; see @ref{Closing a Socket}. The value has type +@code{struct linger}. + +@comment sys/socket.h +@comment BSD +@deftp {Data Type} {struct linger} +This structure type has the following members: + +@table @code +@item int l_onoff +This field is interpreted as a boolean. If nonzero, @code{close} +blocks until the data is transmitted or the timeout period has expired. + +@item int l_linger +This specifies the timeout period, in seconds. +@end table +@end deftp + +@comment sys/socket.h +@comment BSD +@item SO_BROADCAST +This option controls whether datagrams may be broadcast from the socket. +The value has type @code{int}; a nonzero value means ``yes''. + +@comment sys/socket.h +@comment BSD +@item SO_OOBINLINE +If this option is set, out-of-band data received on the socket is +placed in the normal input queue. This permits it to be read using +@code{read} or @code{recv} without specifying the @code{MSG_OOB} +flag. @xref{Out-of-Band Data}. The value has type @code{int}; a +nonzero value means ``yes''. + +@comment sys/socket.h +@comment BSD +@item SO_SNDBUF +This option gets or sets the size of the output buffer. The value is a +@code{size_t}, which is the size in bytes. + +@comment sys/socket.h +@comment BSD +@item SO_RCVBUF +This option gets or sets the size of the input buffer. The value is a +@code{size_t}, which is the size in bytes. + +@comment sys/socket.h +@comment GNU +@item SO_STYLE +@comment sys/socket.h +@comment BSD +@itemx SO_TYPE +This option can be used with @code{getsockopt} only. It is used to +get the socket's communication style. @code{SO_TYPE} is the +historical name, and @code{SO_STYLE} is the preferred name in GNU. +The value has type @code{int} and its value designates a communication +style; see @ref{Communication Styles}. + +@comment sys/socket.h +@comment BSD +@item SO_ERROR +@c Extra blank line here makes the table look better. + +This option can be used with @code{getsockopt} only. It is used to reset +the error status of the socket. The value is an @code{int}, which represents +the previous error status. +@c !!! what is "socket error status"? this is never defined. +@end table + +@node Networks Database +@section Networks Database +@cindex networks database +@cindex converting network number to network name +@cindex converting network name to network number + +@pindex /etc/networks +@pindex netdb.h +Many systems come with a database that records a list of networks known +to the system developer. This is usually kept either in the file +@file{/etc/networks} or in an equivalent from a name server. This data +base is useful for routing programs such as @code{route}, but it is not +useful for programs that simply communicate over the network. We +provide functions to access this data base, which are declared in +@file{netdb.h}. + +@comment netdb.h +@comment BSD +@deftp {Data Type} {struct netent} +This data type is used to represent information about entries in the +networks database. It has the following members: + +@table @code +@item char *n_name +This is the ``official'' name of the network. + +@item char **n_aliases +These are alternative names for the network, represented as a vector +of strings. A null pointer terminates the array. + +@item int n_addrtype +This is the type of the network number; this is always equal to +@code{AF_INET} for Internet networks. + +@item unsigned long int n_net +This is the network number. Network numbers are returned in host +byte order; see @ref{Byte Order}. +@end table +@end deftp + +Use the @code{getnetbyname} or @code{getnetbyaddr} functions to search +the networks database for information about a specific network. The +information is returned in a statically-allocated structure; you must +copy the information if you need to save it. + +@comment netdb.h +@comment BSD +@deftypefun {struct netent *} getnetbyname (const char *@var{name}) +The @code{getnetbyname} function returns information about the network +named @var{name}. It returns a null pointer if there is no such +network. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct netent *} getnetbyaddr (long @var{net}, int @var{type}) +The @code{getnetbyaddr} function returns information about the network +of type @var{type} with number @var{net}. You should specify a value of +@code{AF_INET} for the @var{type} argument for Internet networks. + +@code{getnetbyaddr} returns a null pointer if there is no such +network. +@end deftypefun + +You can also scan the networks database using @code{setnetent}, +@code{getnetent}, and @code{endnetent}. Be careful in using these +functions, because they are not reentrant. + +@comment netdb.h +@comment BSD +@deftypefun void setnetent (int @var{stayopen}) +This function opens and rewinds the networks database. + +If the @var{stayopen} argument is nonzero, this sets a flag so that +subsequent calls to @code{getnetbyname} or @code{getnetbyaddr} will +not close the database (as they usually would). This makes for more +efficiency if you call those functions several times, by avoiding +reopening the database for each call. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun {struct netent *} getnetent (void) +This function returns the next entry in the networks database. It +returns a null pointer if there are no more entries. +@end deftypefun + +@comment netdb.h +@comment BSD +@deftypefun void endnetent (void) +This function closes the networks database. +@end deftypefun diff --git a/manual/startup.texi b/manual/startup.texi new file mode 100644 index 0000000000..c4f2b2f03f --- /dev/null +++ b/manual/startup.texi @@ -0,0 +1,908 @@ +@node Process Startup +@chapter Process Startup and Termination + +@cindex process +@dfn{Processes} are the primitive units for allocation of system +resources. Each process has its own address space and (usually) one +thread of control. A process executes a program; you can have multiple +processes executing the same program, but each process has its own copy +of the program within its own address space and executes it +independently of the other copies. + +This chapter explains what your program should do to handle the startup +of a process, to terminate its process, and to receive information +(arguments and the environment) from the parent process. + +@menu +* Program Arguments:: Parsing your program's command-line arguments. +* Environment Variables:: How to access parameters inherited from + a parent process. +* Program Termination:: How to cause a process to terminate and + return status information to its parent. +@end menu + +@node Program Arguments +@section Program Arguments +@cindex program arguments +@cindex command line arguments +@cindex arguments, to program + +@cindex program startup +@cindex startup of program +@cindex invocation of program +@cindex @code{main} function +@findex main +The system starts a C program by calling the function @code{main}. It +is up to you to write a function named @code{main}---otherwise, you +won't even be able to link your program without errors. + +In ANSI C you can define @code{main} either to take no arguments, or to +take two arguments that represent the command line arguments to the +program, like this: + +@smallexample +int main (int @var{argc}, char *@var{argv}[]) +@end smallexample + +@cindex argc (program argument count) +@cindex argv (program argument vector) +The command line arguments are the whitespace-separated tokens given in +the shell command used to invoke the program; thus, in @samp{cat foo +bar}, the arguments are @samp{foo} and @samp{bar}. The only way a +program can look at its command line arguments is via the arguments of +@code{main}. If @code{main} doesn't take arguments, then you cannot get +at the command line. + +The value of the @var{argc} argument is the number of command line +arguments. The @var{argv} argument is a vector of C strings; its +elements are the individual command line argument strings. The file +name of the program being run is also included in the vector as the +first element; the value of @var{argc} counts this element. A null +pointer always follows the last element: @code{@var{argv}[@var{argc}]} +is this null pointer. + +For the command @samp{cat foo bar}, @var{argc} is 3 and @var{argv} has +three elements, @code{"cat"}, @code{"foo"} and @code{"bar"}. + +If the syntax for the command line arguments to your program is simple +enough, you can simply pick the arguments off from @var{argv} by hand. +But unless your program takes a fixed number of arguments, or all of the +arguments are interpreted in the same way (as file names, for example), +you are usually better off using @code{getopt} to do the parsing. + +In Unix systems you can define @code{main} a third way, using three arguments: + +@smallexample +int main (int @var{argc}, char *@var{argv}[], char *@var{envp}) +@end smallexample + +The first two arguments are just the same. The third argument +@var{envp} gives the process's environment; it is the same as the value +of @code{environ}. @xref{Environment Variables}. POSIX.1 does not +allow this three-argument form, so to be portable it is best to write +@code{main} to take two arguments, and use the value of @code{environ}. + +@menu +* Argument Syntax:: By convention, options start with a hyphen. +* Parsing Options:: The @code{getopt} function. +* Example of Getopt:: An example of parsing options with @code{getopt}. +* Long Options:: GNU suggests utilities accept long-named options. + Here is how to do that. +* Long Option Example:: An example of using @code{getopt_long}. +@end menu + +@node Argument Syntax +@subsection Program Argument Syntax Conventions +@cindex program argument syntax +@cindex syntax, for program arguments +@cindex command argument syntax + +POSIX recommends these conventions for command line arguments. +@code{getopt} (@pxref{Parsing Options}) makes it easy to implement them. + +@itemize @bullet +@item +Arguments are options if they begin with a hyphen delimiter (@samp{-}). + +@item +Multiple options may follow a hyphen delimiter in a single token if +the options do not take arguments. Thus, @samp{-abc} is equivalent to +@samp{-a -b -c}. + +@item +Option names are single alphanumeric characters (as for @code{isalnum}; +see @ref{Classification of Characters}). + +@item +Certain options require an argument. For example, the @samp{-o} command +of the @code{ld} command requires an argument---an output file name. + +@item +An option and its argument may or may not appear as separate tokens. (In +other words, the whitespace separating them is optional.) Thus, +@w{@samp{-o foo}} and @samp{-ofoo} are equivalent. + +@item +Options typically precede other non-option arguments. + +The implementation of @code{getopt} in the GNU C library normally makes +it appear as if all the option arguments were specified before all the +non-option arguments for the purposes of parsing, even if the user of +your program intermixed option and non-option arguments. It does this +by reordering the elements of the @var{argv} array. This behavior is +nonstandard; if you want to suppress it, define the +@code{_POSIX_OPTION_ORDER} environment variable. @xref{Standard +Environment}. + +@item +The argument @samp{--} terminates all options; any following arguments +are treated as non-option arguments, even if they begin with a hyphen. + +@item +A token consisting of a single hyphen character is interpreted as an +ordinary non-option argument. By convention, it is used to specify +input from or output to the standard input and output streams. + +@item +Options may be supplied in any order, or appear multiple times. The +interpretation is left up to the particular application program. +@end itemize + +@cindex long-named options +GNU adds @dfn{long options} to these conventions. Long options consist +of @samp{--} followed by a name made of alphanumeric characters and +dashes. Option names are typically one to three words long, with +hyphens to separate words. Users can abbreviate the option names as +long as the abbreviations are unique. + +To specify an argument for a long option, write +@samp{--@var{name}=@var{value}}. This syntax enables a long option to +accept an argument that is itself optional. + +Eventually, the GNU system will provide completion for long option names +in the shell. + +@node Parsing Options +@subsection Parsing Program Options +@cindex program arguments, parsing +@cindex command arguments, parsing +@cindex parsing program arguments + +Here are the details about how to call the @code{getopt} function. To +use this facility, your program must include the header file +@file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.2 +@deftypevar int opterr +If the value of this variable is nonzero, then @code{getopt} prints an +error message to the standard error stream if it encounters an unknown +option character or an option with a missing required argument. This is +the default behavior. If you set this variable to zero, @code{getopt} +does not print any messages, but it still returns the character @code{?} +to indicate an error. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar int optopt +When @code{getopt} encounters an unknown option character or an option +with a missing required argument, it stores that option character in +this variable. You can use this for providing your own diagnostic +messages. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar int optind +This variable is set by @code{getopt} to the index of the next element +of the @var{argv} array to be processed. Once @code{getopt} has found +all of the option arguments, you can use this variable to determine +where the remaining non-option arguments begin. The initial value of +this variable is @code{1}. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypevar {char *} optarg +This variable is set by @code{getopt} to point at the value of the +option argument, for those options that accept arguments. +@end deftypevar + +@comment unistd.h +@comment POSIX.2 +@deftypefun int getopt (int @var{argc}, char **@var{argv}, const char *@var{options}) +The @code{getopt} function gets the next option argument from the +argument list specified by the @var{argv} and @var{argc} arguments. +Normally these values come directly from the arguments received by +@code{main}. + +The @var{options} argument is a string that specifies the option +characters that are valid for this program. An option character in this +string can be followed by a colon (@samp{:}) to indicate that it takes a +required argument. + +If the @var{options} argument string begins with a hyphen (@samp{-}), this +is treated specially. It permits arguments that are not options to be +returned as if they were associated with option character @samp{\0}. + +The @code{getopt} function returns the option character for the next +command line option. When no more option arguments are available, it +returns @code{-1}. There may still be more non-option arguments; you +must compare the external variable @code{optind} against the @var{argc} +parameter to check this. + +If the option has an argument, @code{getopt} returns the argument by +storing it in the varables @var{optarg}. You don't ordinarily need to +copy the @code{optarg} string, since it is a pointer into the original +@var{argv} array, not into a static area that might be overwritten. + +If @code{getopt} finds an option character in @var{argv} that was not +included in @var{options}, or a missing option argument, it returns +@samp{?} and sets the external variable @code{optopt} to the actual +option character. If the first character of @var{options} is a colon +(@samp{:}), then @code{getopt} returns @samp{:} instead of @samp{?} to +indicate a missing option argument. In addition, if the external +variable @code{opterr} is nonzero (which is the default), @code{getopt} +prints an error message. +@end deftypefun + +@node Example of Getopt +@subsection Example of Parsing Arguments with @code{getopt} + +Here is an example showing how @code{getopt} is typically used. The +key points to notice are: + +@itemize @bullet +@item +Normally, @code{getopt} is called in a loop. When @code{getopt} returns +@code{-1}, indicating no more options are present, the loop terminates. + +@item +A @code{switch} statement is used to dispatch on the return value from +@code{getopt}. In typical use, each case just sets a variable that +is used later in the program. + +@item +A second loop is used to process the remaining non-option arguments. +@end itemize + +@smallexample +@include testopt.c.texi +@end smallexample + +Here are some examples showing what this program prints with different +combinations of arguments: + +@smallexample +% testopt +aflag = 0, bflag = 0, cvalue = (null) + +% testopt -a -b +aflag = 1, bflag = 1, cvalue = (null) + +% testopt -ab +aflag = 1, bflag = 1, cvalue = (null) + +% testopt -c foo +aflag = 0, bflag = 0, cvalue = foo + +% testopt -cfoo +aflag = 0, bflag = 0, cvalue = foo + +% testopt arg1 +aflag = 0, bflag = 0, cvalue = (null) +Non-option argument arg1 + +% testopt -a arg1 +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument arg1 + +% testopt -c foo arg1 +aflag = 0, bflag = 0, cvalue = foo +Non-option argument arg1 + +% testopt -a -- -b +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument -b + +% testopt -a - +aflag = 1, bflag = 0, cvalue = (null) +Non-option argument - +@end smallexample + +@node Long Options +@subsection Parsing Long Options + +To accept GNU-style long options as well as single-character options, +use @code{getopt_long} instead of @code{getopt}. You should make every +program accept long options if it uses any options, for this takes +little extra work and helps beginners remember how to use the program. + +@comment getopt.h +@comment GNU +@deftp {Data Type} {struct option} +This structure describes a single long option name for the sake of +@code{getopt_long}. The argument @var{longopts} must be an array of +these structures, one for each long option. Terminate the array with an +element containing all zeros. + +The @code{struct option} structure has these fields: + +@table @code +@item const char *name +This field is the name of the option. It is a string. + +@item int has_arg +This field says whether the option takes an argument. It is an integer, +and there are three legitimate values: @w{@code{no_argument}}, +@code{required_argument} and @code{optional_argument}. + +@item int *flag +@itemx int val +These fields control how to report or act on the option when it occurs. + +If @code{flag} is a null pointer, then the @code{val} is a value which +identifies this option. Often these values are chosen to uniquely +identify particular long options. + +If @code{flag} is not a null pointer, it should be the address of an +@code{int} variable which is the flag for this option. The value in +@code{val} is the value to store in the flag to indicate that the option +was seen. +@end table +@end deftp + +@comment getopt.h +@comment GNU +@deftypefun int getopt_long (int @var{argc}, char **@var{argv}, const char *@var{shortopts}, struct option *@var{longopts}, int *@var{indexptr}) +Decode options from the vector @var{argv} (whose length is @var{argc}). +The argument @var{shortopts} describes the short options to accept, just as +it does in @code{getopt}. The argument @var{longopts} describes the long +options to accept (see above). + +When @code{getopt_long} encounters a short option, it does the same +thing that @code{getopt} would do: it returns the character code for the +option, and stores the options argument (if it has one) in @code{optarg}. + +When @code{getopt_long} encounters a long option, it takes actions based +on the @code{flag} and @code{val} fields of the definition of that +option. + +If @code{flag} is a null pointer, then @code{getopt_long} returns the +contents of @code{val} to indicate which option it found. You should +arrange distinct values in the @code{val} field for options with +different meanings, so you can decode these values after +@code{getopt_long} returns. If the long option is equivalent to a short +option, you can use the short option's character code in @code{val}. + +If @code{flag} is not a null pointer, that means this option should just +set a flag in the program. The flag is a variable of type @code{int} +that you define. Put the address of the flag in the @code{flag} field. +Put in the @code{val} field the value you would like this option to +store in the flag. In this case, @code{getopt_long} returns @code{0}. + +For any long option, @code{getopt_long} tells you the index in the array +@var{longopts} of the options definition, by storing it into +@code{*@var{indexptr}}. You can get the name of the option with +@code{@var{longopts}[*@var{indexptr}].name}. So you can distinguish among +long options either by the values in their @code{val} fields or by their +indices. You can also distinguish in this way among long options that +set flags. + +When a long option has an argument, @code{getopt_long} puts the argument +value in the variable @code{optarg} before returning. When the option +has no argument, the value in @code{optarg} is a null pointer. This is +how you can tell whether an optional argument was supplied. + +When @code{getopt_long} has no more options to handle, it returns +@code{-1}, and leaves in the variable @code{optind} the index in +@var{argv} of the next remaining argument. +@end deftypefun + +@node Long Option Example +@subsection Example of Parsing Long Options + +@smallexample +@include longopt.c.texi +@end smallexample + +@node Environment Variables +@section Environment Variables + +@cindex environment variable +When a program is executed, it receives information about the context in +which it was invoked in two ways. The first mechanism uses the +@var{argv} and @var{argc} arguments to its @code{main} function, and is +discussed in @ref{Program Arguments}. The second mechanism uses +@dfn{environment variables} and is discussed in this section. + +The @var{argv} mechanism is typically used to pass command-line +arguments specific to the particular program being invoked. The +environment, on the other hand, keeps track of information that is +shared by many programs, changes infrequently, and that is less +frequently used. + +The environment variables discussed in this section are the same +environment variables that you set using assignments and the +@code{export} command in the shell. Programs executed from the shell +inherit all of the environment variables from the shell. +@c !!! xref to right part of bash manual when it exists + +@cindex environment +Standard environment variables are used for information about the user's +home directory, terminal type, current locale, and so on; you can define +additional variables for other purposes. The set of all environment +variables that have values is collectively known as the +@dfn{environment}. + +Names of environment variables are case-sensitive and must not contain +the character @samp{=}. System-defined environment variables are +invariably uppercase. + +The values of environment variables can be anything that can be +represented as a string. A value must not contain an embedded null +character, since this is assumed to terminate the string. + + +@menu +* Environment Access:: How to get and set the values of + environment variables. +* Standard Environment:: These environment variables have + standard interpretations. +@end menu + +@node Environment Access +@subsection Environment Access +@cindex environment access +@cindex environment representation + +The value of an environment variable can be accessed with the +@code{getenv} function. This is declared in the header file +@file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun {char *} getenv (const char *@var{name}) +This function returns a string that is the value of the environment +variable @var{name}. You must not modify this string. In some non-Unix +systems not using the GNU library, it might be overwritten by subsequent +calls to @code{getenv} (but not by any other library function). If the +environment variable @var{name} is not defined, the value is a null +pointer. +@end deftypefun + + +@comment stdlib.h +@comment SVID +@deftypefun int putenv (const char *@var{string}) +The @code{putenv} function adds or removes definitions from the environment. +If the @var{string} is of the form @samp{@var{name}=@var{value}}, the +definition is added to the environment. Otherwise, the @var{string} is +interpreted as the name of an environment variable, and any definition +for this variable in the environment is removed. + +The GNU library provides this function for compatibility with SVID; it +may not be available in other systems. +@end deftypefun + +@c !!! BSD function setenv + +You can deal directly with the underlying representation of environment +objects to add more variables to the environment (for example, to +communicate with another program you are about to execute; see +@ref{Executing a File}). + +@comment unistd.h +@comment POSIX.1 +@deftypevar {char **} environ +The environment is represented as an array of strings. Each string is +of the format @samp{@var{name}=@var{value}}. The order in which +strings appear in the environment is not significant, but the same +@var{name} must not appear more than once. The last element of the +array is a null pointer. + +This variable is declared in the header file @file{unistd.h}. + +If you just want to get the value of an environment variable, use +@code{getenv}. +@end deftypevar + +Unix systems, and the GNU system, pass the initial value of +@code{environ} as the third argument to @code{main}. +@xref{Program Arguments}. + +@node Standard Environment +@subsection Standard Environment Variables +@cindex standard environment variables + +These environment variables have standard meanings. This doesn't mean +that they are always present in the environment; but if these variables +@emph{are} present, they have these meanings. You shouldn't try to use +these environment variable names for some other purpose. + +@comment Extra blank lines make it look better. +@table @code +@item HOME +@cindex HOME environment variable +@cindex home directory + +This is a string representing the user's @dfn{home directory}, or +initial default working directory. + +The user can set @code{HOME} to any value. +If you need to make sure to obtain the proper home directory +for a particular user, you should not use @code{HOME}; instead, +look up the user's name in the user database (@pxref{User Database}). + +For most purposes, it is better to use @code{HOME}, precisely because +this lets the user specify the value. + +@c !!! also USER +@item LOGNAME +@cindex LOGNAME environment variable + +This is the name that the user used to log in. Since the value in the +environment can be tweaked arbitrarily, this is not a reliable way to +identify the user who is running a process; a function like +@code{getlogin} (@pxref{Who Logged In}) is better for that purpose. + +For most purposes, it is better to use @code{LOGNAME}, precisely because +this lets the user specify the value. + +@item PATH +@cindex PATH environment variable + +A @dfn{path} is a sequence of directory names which is used for +searching for a file. The variable @code{PATH} holds a path used +for searching for programs to be run. + +The @code{execlp} and @code{execvp} functions (@pxref{Executing a File}) +use this environment variable, as do many shells and other utilities +which are implemented in terms of those functions. + +The syntax of a path is a sequence of directory names separated by +colons. An empty string instead of a directory name stands for the +current directory (@pxref{Working Directory}). + +A typical value for this environment variable might be a string like: + +@smallexample +:/bin:/etc:/usr/bin:/usr/new/X11:/usr/new:/usr/local/bin +@end smallexample + +This means that if the user tries to execute a program named @code{foo}, +the system will look for files named @file{foo}, @file{/bin/foo}, +@file{/etc/foo}, and so on. The first of these files that exists is +the one that is executed. + +@c !!! also TERMCAP +@item TERM +@cindex TERM environment variable + +This specifies the kind of terminal that is receiving program output. +Some programs can make use of this information to take advantage of +special escape sequences or terminal modes supported by particular kinds +of terminals. Many programs which use the termcap library +(@pxref{Finding a Terminal Description,Find,,termcap,The Termcap Library +Manual}) use the @code{TERM} environment variable, for example. + +@item TZ +@cindex TZ environment variable + +This specifies the time zone. @xref{TZ Variable}, for information about +the format of this string and how it is used. + +@item LANG +@cindex LANG environment variable + +This specifies the default locale to use for attribute categories where +neither @code{LC_ALL} nor the specific environment variable for that +category is set. @xref{Locales}, for more information about +locales. + +@ignore +@c I doubt this really exists +@item LC_ALL +@cindex LC_ALL environment variable + +This is similar to the @code{LANG} environment variable. However, its +value takes precedence over any values provided for the individual +attribute category environment variables, or for the @code{LANG} +environment variable. +@end ignore + +@item LC_COLLATE +@cindex LC_COLLATE environment variable + +This specifies what locale to use for string sorting. + +@item LC_CTYPE +@cindex LC_CTYPE environment variable + +This specifies what locale to use for character sets and character +classification. + +@item LC_MONETARY +@cindex LC_MONETARY environment variable + +This specifies what locale to use for formatting monetary values. + +@item LC_NUMERIC +@cindex LC_NUMERIC environment variable + +This specifies what locale to use for formatting numbers. + +@item LC_TIME +@cindex LC_TIME environment variable + +This specifies what locale to use for formatting date/time values. + +@item _POSIX_OPTION_ORDER +@cindex _POSIX_OPTION_ORDER environment variable. + +If this environment variable is defined, it suppresses the usual +reordering of command line arguments by @code{getopt}. @xref{Argument Syntax}. + +@c !!! GNU also has COREFILE, CORESERVER, EXECSERVERS +@end table + +@node Program Termination +@section Program Termination +@cindex program termination +@cindex process termination + +@cindex exit status value +The usual way for a program to terminate is simply for its @code{main} +function to return. The @dfn{exit status value} returned from the +@code{main} function is used to report information back to the process's +parent process or shell. + +A program can also terminate normally by calling the @code{exit} +function. + +In addition, programs can be terminated by signals; this is discussed in +more detail in @ref{Signal Handling}. The @code{abort} function causes +a signal that kills the program. + +@menu +* Normal Termination:: If a program calls @code{exit}, a + process terminates normally. +* Exit Status:: The @code{exit status} provides information + about why the process terminated. +* Cleanups on Exit:: A process can run its own cleanup + functions upon normal termination. +* Aborting a Program:: The @code{abort} function causes + abnormal program termination. +* Termination Internals:: What happens when a process terminates. +@end menu + +@node Normal Termination +@subsection Normal Termination + +A process terminates normally when the program calls @code{exit}. +Returning from @code{main} is equivalent to calling @code{exit}, and +the value that @code{main} returns is used as the argument to @code{exit}. + +@comment stdlib.h +@comment ANSI +@deftypefun void exit (int @var{status}) +The @code{exit} function terminates the process with status +@var{status}. This function does not return. +@end deftypefun + +Normal termination causes the following actions: + +@enumerate +@item +Functions that were registered with the @code{atexit} or @code{on_exit} +functions are called in the reverse order of their registration. This +mechanism allows your application to specify its own ``cleanup'' actions +to be performed at program termination. Typically, this is used to do +things like saving program state information in a file, or unlocking +locks in shared data bases. + +@item +All open streams are closed, writing out any buffered output data. See +@ref{Closing Streams}. In addition, temporary files opened +with the @code{tmpfile} function are removed; see @ref{Temporary Files}. + +@item +@code{_exit} is called, terminating the program. @xref{Termination Internals}. +@end enumerate + +@node Exit Status +@subsection Exit Status +@cindex exit status + +When a program exits, it can return to the parent process a small +amount of information about the cause of termination, using the +@dfn{exit status}. This is a value between 0 and 255 that the exiting +process passes as an argument to @code{exit}. + +Normally you should use the exit status to report very broad information +about success or failure. You can't provide a lot of detail about the +reasons for the failure, and most parent processes would not want much +detail anyway. + +There are conventions for what sorts of status values certain programs +should return. The most common convention is simply 0 for success and 1 +for failure. Programs that perform comparison use a different +convention: they use status 1 to indicate a mismatch, and status 2 to +indicate an inability to compare. Your program should follow an +existing convention if an existing convention makes sense for it. + +A general convention reserves status values 128 and up for special +purposes. In particular, the value 128 is used to indicate failure to +execute another program in a subprocess. This convention is not +universally obeyed, but it is a good idea to follow it in your programs. + +@strong{Warning:} Don't try to use the number of errors as the exit +status. This is actually not very useful; a parent process would +generally not care how many errors occurred. Worse than that, it does +not work, because the status value is truncated to eight bits. +Thus, if the program tried to report 256 errors, the parent would +receive a report of 0 errors---that is, success. + +For the same reason, it does not work to use the value of @code{errno} +as the exit status---these can exceed 255. + +@strong{Portability note:} Some non-POSIX systems use different +conventions for exit status values. For greater portability, you can +use the macros @code{EXIT_SUCCESS} and @code{EXIT_FAILURE} for the +conventional status value for success and failure, respectively. They +are declared in the file @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int EXIT_SUCCESS +This macro can be used with the @code{exit} function to indicate +successful program completion. + +On POSIX systems, the value of this macro is @code{0}. On other +systems, the value might be some other (possibly non-constant) integer +expression. +@end deftypevr + +@comment stdlib.h +@comment ANSI +@deftypevr Macro int EXIT_FAILURE +This macro can be used with the @code{exit} function to indicate +unsuccessful program completion in a general sense. + +On POSIX systems, the value of this macro is @code{1}. On other +systems, the value might be some other (possibly non-constant) integer +expression. Other nonzero status values also indicate future. Certain +programs use different nonzero status values to indicate particular +kinds of "non-success". For example, @code{diff} uses status value +@code{1} to mean that the files are different, and @code{2} or more to +mean that there was difficulty in opening the files. +@end deftypevr + +@node Cleanups on Exit +@subsection Cleanups on Exit + +Your program can arrange to run its own cleanup functions if normal +termination happens. If you are writing a library for use in various +application programs, then it is unreliable to insist that all +applications call the library's cleanup functions explicitly before +exiting. It is much more robust to make the cleanup invisible to the +application, by setting up a cleanup function in the library itself +using @code{atexit} or @code{on_exit}. + +@comment stdlib.h +@comment ANSI +@deftypefun int atexit (void (*@var{function}) (void)) +The @code{atexit} function registers the function @var{function} to be +called at normal program termination. The @var{function} is called with +no arguments. + +The return value from @code{atexit} is zero on success and nonzero if +the function cannot be registered. +@end deftypefun + +@comment stdlib.h +@comment SunOS +@deftypefun int on_exit (void (*@var{function})(int @var{status}, void *@var{arg}), void *@var{arg}) +This function is a somewhat more powerful variant of @code{atexit}. It +accepts two arguments, a function @var{function} and an arbitrary +pointer @var{arg}. At normal program termination, the @var{function} is +called with two arguments: the @var{status} value passed to @code{exit}, +and the @var{arg}. + +This function is included in the GNU C library only for compatibility +for SunOS, and may not be supported by other implementations. +@end deftypefun + +Here's a trivial program that illustrates the use of @code{exit} and +@code{atexit}: + +@smallexample +@include atexit.c.texi +@end smallexample + +@noindent +When this program is executed, it just prints the message and exits. + +@node Aborting a Program +@subsection Aborting a Program +@cindex aborting a program + +You can abort your program using the @code{abort} function. The prototype +for this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftypefun void abort (void) +The @code{abort} function causes abnormal program termination. This +does not execute cleanup functions registered with @code{atexit} or +@code{on_exit}. + +This function actually terminates the process by raising a +@code{SIGABRT} signal, and your program can include a handler to +intercept this signal; see @ref{Signal Handling}. +@end deftypefun + +@c Put in by rms. Don't remove. +@cartouche +@strong{Future Change Warning:} Proposed Federal censorship regulations +may prohibit us from giving you information about the possibility of +calling this function. We would be required to say that this is not an +acceptable way of terminating a program. +@end cartouche + +@node Termination Internals +@subsection Termination Internals + +The @code{_exit} function is the primitive used for process termination +by @code{exit}. It is declared in the header file @file{unistd.h}. +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun void _exit (int @var{status}) +The @code{_exit} function is the primitive for causing a process to +terminate with status @var{status}. Calling this function does not +execute cleanup functions registered with @code{atexit} or +@code{on_exit}. +@end deftypefun + +When a process terminates for any reason---either by an explicit +termination call, or termination as a result of a signal---the +following things happen: + +@itemize @bullet +@item +All open file descriptors in the process are closed. @xref{Low-Level I/O}. +Note that streams are not flushed automatically when the process +terminates; @xref{I/O on Streams}. + +@item +The low-order 8 bits of the return status code are saved to be reported +back to the parent process via @code{wait} or @code{waitpid}; see +@ref{Process Completion}. + +@item +Any child processes of the process being terminated are assigned a new +parent process. (On most systems, including GNU, this is the @code{init} +process, with process ID 1.) + +@item +A @code{SIGCHLD} signal is sent to the parent process. + +@item +If the process is a session leader that has a controlling terminal, then +a @code{SIGHUP} signal is sent to each process in the foreground job, +and the controlling terminal is disassociated from that session. +@xref{Job Control}. + +@item +If termination of a process causes a process group to become orphaned, +and any member of that process group is stopped, then a @code{SIGHUP} +signal and a @code{SIGCONT} signal are sent to each process in the +group. @xref{Job Control}. +@end itemize diff --git a/manual/stdio.texi b/manual/stdio.texi new file mode 100644 index 0000000000..411d94a242 --- /dev/null +++ b/manual/stdio.texi @@ -0,0 +1,3635 @@ +@node I/O on Streams, Low-Level I/O, I/O Overview, Top +@chapter Input/Output on Streams + +This chapter describes the functions for creating streams and performing +input and output operations on them. As discussed in @ref{I/O +Overview}, a stream is a fairly abstract, high-level concept +representing a communications channel to a file, device, or process. + +@menu +* Streams:: About the data type representing a stream. +* Standard Streams:: Streams to the standard input and output + devices are created for you. +* Opening Streams:: How to create a stream to talk to a file. +* Closing Streams:: Close a stream when you are finished with it. +* Simple Output:: Unformatted output by characters and lines. +* Character Input:: Unformatted input by characters and words. +* Line Input:: Reading a line or a record from a stream. +* Unreading:: Peeking ahead/pushing back input just read. +* Block Input/Output:: Input and output operations on blocks of data. +* Formatted Output:: @code{printf} and related functions. +* Customizing Printf:: You can define new conversion specifiers for + @code{printf} and friends. +* Formatted Input:: @code{scanf} and related functions. +* EOF and Errors:: How you can tell if an I/O error happens. +* Binary Streams:: Some systems distinguish between text files + and binary files. +* File Positioning:: About random-access streams. +* Portable Positioning:: Random access on peculiar ANSI C systems. +* Stream Buffering:: How to control buffering of streams. +* Other Kinds of Streams:: Streams that do not necessarily correspond + to an open file. +@end menu + +@node Streams +@section Streams + +For historical reasons, the type of the C data structure that represents +a stream is called @code{FILE} rather than ``stream''. Since most of +the library functions deal with objects of type @code{FILE *}, sometimes +the term @dfn{file pointer} is also used to mean ``stream''. This leads +to unfortunate confusion over terminology in many books on C. This +manual, however, is careful to use the terms ``file'' and ``stream'' +only in the technical sense. +@cindex file pointer + +@pindex stdio.h +The @code{FILE} type is declared in the header file @file{stdio.h}. + +@comment stdio.h +@comment ANSI +@deftp {Data Type} FILE +This is the data type used to represent stream objects. A @code{FILE} +object holds all of the internal state information about the connection +to the associated file, including such things as the file position +indicator and buffering information. Each stream also has error and +end-of-file status indicators that can be tested with the @code{ferror} +and @code{feof} functions; see @ref{EOF and Errors}. +@end deftp + +@code{FILE} objects are allocated and managed internally by the +input/output library functions. Don't try to create your own objects of +type @code{FILE}; let the library do it. Your programs should +deal only with pointers to these objects (that is, @code{FILE *} values) +rather than the objects themselves. +@c !!! should say that FILE's have "No user-servicable parts inside." + +@node Standard Streams +@section Standard Streams +@cindex standard streams +@cindex streams, standard + +When the @code{main} function of your program is invoked, it already has +three predefined streams open and available for use. These represent +the ``standard'' input and output channels that have been established +for the process. + +These streams are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypevar {FILE *} stdin +The @dfn{standard input} stream, which is the normal source of input for the +program. +@end deftypevar +@cindex standard input stream + +@comment stdio.h +@comment ANSI +@deftypevar {FILE *} stdout +The @dfn{standard output} stream, which is used for normal output from +the program. +@end deftypevar +@cindex standard output stream + +@comment stdio.h +@comment ANSI +@deftypevar {FILE *} stderr +The @dfn{standard error} stream, which is used for error messages and +diagnostics issued by the program. +@end deftypevar +@cindex standard error stream + +In the GNU system, you can specify what files or processes correspond to +these streams using the pipe and redirection facilities provided by the +shell. (The primitives shells use to implement these facilities are +described in @ref{File System Interface}.) Most other operating systems +provide similar mechanisms, but the details of how to use them can vary. + +In the GNU C library, @code{stdin}, @code{stdout}, and @code{stderr} are +normal variables which you can set just like any others. For example, to redirect +the standard output to a file, you could do: + +@smallexample +fclose (stdout); +stdout = fopen ("standard-output-file", "w"); +@end smallexample + +Note however, that in other systems @code{stdin}, @code{stdout}, and +@code{stderr} are macros that you cannot assign to in the normal way. +But you can use @code{freopen} to get the effect of closing one and +reopening it. @xref{Opening Streams}. + +@node Opening Streams +@section Opening Streams + +@cindex opening a stream +Opening a file with the @code{fopen} function creates a new stream and +establishes a connection between the stream and a file. This may +involve creating a new file. + +@pindex stdio.h +Everything described in this section is declared in the header file +@file{stdio.h}. + +@comment stdio.h +@comment ANSI +@deftypefun {FILE *} fopen (const char *@var{filename}, const char *@var{opentype}) +The @code{fopen} function opens a stream for I/O to the file +@var{filename}, and returns a pointer to the stream. + +The @var{opentype} argument is a string that controls how the file is +opened and specifies attributes of the resulting stream. It must begin +with one of the following sequences of characters: + +@table @samp +@item r +Open an existing file for reading only. + +@item w +Open the file for writing only. If the file already exists, it is +truncated to zero length. Otherwise a new file is created. + +@item a +Open a file for append access; that is, writing at the end of file only. +If the file already exists, its initial contents are unchanged and +output to the stream is appended to the end of the file. +Otherwise, a new, empty file is created. + +@item r+ +Open an existing file for both reading and writing. The initial contents +of the file are unchanged and the initial file position is at the +beginning of the file. + +@item w+ +Open a file for both reading and writing. If the file already exists, it +is truncated to zero length. Otherwise, a new file is created. + +@item a+ +Open or create file for both reading and appending. If the file exists, +its initial contents are unchanged. Otherwise, a new file is created. +The initial file position for reading is at the beginning of the file, +but output is always appended to the end of the file. +@end table + +As you can see, @samp{+} requests a stream that can do both input and +output. The ANSI standard says that when using such a stream, you must +call @code{fflush} (@pxref{Stream Buffering}) or a file positioning +function such as @code{fseek} (@pxref{File Positioning}) when switching +from reading to writing or vice versa. Otherwise, internal buffers +might not be emptied properly. The GNU C library does not have this +limitation; you can do arbitrary reading and writing operations on a +stream in whatever order. + +Additional characters may appear after these to specify flags for the +call. Always put the mode (@samp{r}, @samp{w+}, etc.) first; that is +the only part you are guaranteed will be understood by all systems. + +The GNU C library defines one additional character for use in +@var{opentype}: the character @samp{x} insists on creating a new +file---if a file @var{filename} already exists, @code{fopen} fails +rather than opening it. If you use @samp{x} you can are guaranteed that +you will not clobber an existing file. This is equivalent to the +@code{O_EXCL} option to the @code{open} function (@pxref{Opening and +Closing Files}). + +The character @samp{b} in @var{opentype} has a standard meaning; it +requests a binary stream rather than a text stream. But this makes no +difference in POSIX systems (including the GNU system). If both +@samp{+} and @samp{b} are specified, they can appear in either order. +@xref{Binary Streams}. + +Any other characters in @var{opentype} are simply ignored. They may be +meaningful in other systems. + +If the open fails, @code{fopen} returns a null pointer. +@end deftypefun + +You can have multiple streams (or file descriptors) pointing to the same +file open at the same time. If you do only input, this works +straightforwardly, but you must be careful if any output streams are +included. @xref{Stream/Descriptor Precautions}. This is equally true +whether the streams are in one program (not usual) or in several +programs (which can easily happen). It may be advantageous to use the +file locking facilities to avoid simultaneous access. @xref{File +Locks}. + +@comment stdio.h +@comment ANSI +@deftypevr Macro int FOPEN_MAX +The value of this macro is an integer constant expression that +represents the minimum number of streams that the implementation +guarantees can be open simultaneously. You might be able to open more +than this many streams, but that is not guaranteed. The value of this +constant is at least eight, which includes the three standard streams +@code{stdin}, @code{stdout}, and @code{stderr}. In POSIX.1 systems this +value is determined by the @code{OPEN_MAX} parameter; @pxref{General +Limits}. In BSD and GNU, it is controlled by the @code{RLIMIT_NOFILE} +resource limit; @pxref{Limits on Resources}. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypefun {FILE *} freopen (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream}) +This function is like a combination of @code{fclose} and @code{fopen}. +It first closes the stream referred to by @var{stream}, ignoring any +errors that are detected in the process. (Because errors are ignored, +you should not use @code{freopen} on an output stream if you have +actually done any output using the stream.) Then the file named by +@var{filename} is opened with mode @var{opentype} as for @code{fopen}, +and associated with the same stream object @var{stream}. + +If the operation fails, a null pointer is returned; otherwise, +@code{freopen} returns @var{stream}. + +@code{freopen} has traditionally been used to connect a standard stream +such as @code{stdin} with a file of your own choice. This is useful in +programs in which use of a standard stream for certain purposes is +hard-coded. In the GNU C library, you can simply close the standard +streams and open new ones with @code{fopen}. But other systems lack +this ability, so using @code{freopen} is more portable. +@end deftypefun + + +@node Closing Streams +@section Closing Streams + +@cindex closing a stream +When a stream is closed with @code{fclose}, the connection between the +stream and the file is cancelled. After you have closed a stream, you +cannot perform any additional operations on it. + +@comment stdio.h +@comment ANSI +@deftypefun int fclose (FILE *@var{stream}) +This function causes @var{stream} to be closed and the connection to +the corresponding file to be broken. Any buffered output is written +and any buffered input is discarded. The @code{fclose} function returns +a value of @code{0} if the file was closed successfully, and @code{EOF} +if an error was detected. + +It is important to check for errors when you call @code{fclose} to close +an output stream, because real, everyday errors can be detected at this +time. For example, when @code{fclose} writes the remaining buffered +output, it might get an error because the disk is full. Even if you +know the buffer is empty, errors can still occur when closing a file if +you are using NFS. + +The function @code{fclose} is declared in @file{stdio.h}. +@end deftypefun + +If the @code{main} function to your program returns, or if you call the +@code{exit} function (@pxref{Normal Termination}), all open streams are +automatically closed properly. If your program terminates in any other +manner, such as by calling the @code{abort} function (@pxref{Aborting a +Program}) or from a fatal signal (@pxref{Signal Handling}), open streams +might not be closed properly. Buffered output might not be flushed and +files may be incomplete. For more information on buffering of streams, +see @ref{Stream Buffering}. + +@node Simple Output +@section Simple Output by Characters or Lines + +@cindex writing to a stream, by characters +This section describes functions for performing character- and +line-oriented output. + +These functions are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int fputc (int @var{c}, FILE *@var{stream}) +The @code{fputc} function converts the character @var{c} to type +@code{unsigned char}, and writes it to the stream @var{stream}. +@code{EOF} is returned if a write error occurs; otherwise the +character @var{c} is returned. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int putc (int @var{c}, FILE *@var{stream}) +This is just like @code{fputc}, except that most systems implement it as +a macro, making it faster. One consequence is that it may evaluate the +@var{stream} argument more than once, which is an exception to the +general rule for macros. @code{putc} is usually the best function to +use for writing a single character. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int putchar (int @var{c}) +The @code{putchar} function is equivalent to @code{putc} with +@code{stdout} as the value of the @var{stream} argument. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int fputs (const char *@var{s}, FILE *@var{stream}) +The function @code{fputs} writes the string @var{s} to the stream +@var{stream}. The terminating null character is not written. +This function does @emph{not} add a newline character, either. +It outputs only the characters in the string. + +This function returns @code{EOF} if a write error occurs, and otherwise +a non-negative value. + +For example: + +@smallexample +fputs ("Are ", stdout); +fputs ("you ", stdout); +fputs ("hungry?\n", stdout); +@end smallexample + +@noindent +outputs the text @samp{Are you hungry?} followed by a newline. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int puts (const char *@var{s}) +The @code{puts} function writes the string @var{s} to the stream +@code{stdout} followed by a newline. The terminating null character of +the string is not written. (Note that @code{fputs} does @emph{not} +write a newline as this function does.) + +@code{puts} is the most convenient function for printing simple +messages. For example: + +@smallexample +puts ("This is a message."); +@end smallexample +@end deftypefun + +@comment stdio.h +@comment SVID +@deftypefun int putw (int @var{w}, FILE *@var{stream}) +This function writes the word @var{w} (that is, an @code{int}) to +@var{stream}. It is provided for compatibility with SVID, but we +recommend you use @code{fwrite} instead (@pxref{Block Input/Output}). +@end deftypefun + +@node Character Input +@section Character Input + +@cindex reading from a stream, by characters +This section describes functions for performing character-oriented input. +These functions are declared in the header file @file{stdio.h}. +@pindex stdio.h + +These functions return an @code{int} value that is either a character of +input, or the special value @code{EOF} (usually -1). It is important to +store the result of these functions in a variable of type @code{int} +instead of @code{char}, even when you plan to use it only as a +character. Storing @code{EOF} in a @code{char} variable truncates its +value to the size of a character, so that it is no longer +distinguishable from the valid character @samp{(char) -1}. So always +use an @code{int} for the result of @code{getc} and friends, and check +for @code{EOF} after the call; once you've verified that the result is +not @code{EOF}, you can be sure that it will fit in a @samp{char} +variable without loss of information. + +@comment stdio.h +@comment ANSI +@deftypefun int fgetc (FILE *@var{stream}) +This function reads the next character as an @code{unsigned char} from +the stream @var{stream} and returns its value, converted to an +@code{int}. If an end-of-file condition or read error occurs, +@code{EOF} is returned instead. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int getc (FILE *@var{stream}) +This is just like @code{fgetc}, except that it is permissible (and +typical) for it to be implemented as a macro that evaluates the +@var{stream} argument more than once. @code{getc} is often highly +optimized, so it is usually the best function to use to read a single +character. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int getchar (void) +The @code{getchar} function is equivalent to @code{getc} with @code{stdin} +as the value of the @var{stream} argument. +@end deftypefun + +Here is an example of a function that does input using @code{fgetc}. It +would work just as well using @code{getc} instead, or using +@code{getchar ()} instead of @w{@code{fgetc (stdin)}}. + +@smallexample +int +y_or_n_p (const char *question) +@{ + fputs (question, stdout); + while (1) + @{ + int c, answer; + /* @r{Write a space to separate answer from question.} */ + fputc (' ', stdout); + /* @r{Read the first character of the line.} + @r{This should be the answer character, but might not be.} */ + c = tolower (fgetc (stdin)); + answer = c; + /* @r{Discard rest of input line.} */ + while (c != '\n' && c != EOF) + c = fgetc (stdin); + /* @r{Obey the answer if it was valid.} */ + if (answer == 'y') + return 1; + if (answer == 'n') + return 0; + /* @r{Answer was invalid: ask for valid answer.} */ + fputs ("Please answer y or n:", stdout); + @} +@} +@end smallexample + +@comment stdio.h +@comment SVID +@deftypefun int getw (FILE *@var{stream}) +This function reads a word (that is, an @code{int}) from @var{stream}. +It's provided for compatibility with SVID. We recommend you use +@code{fread} instead (@pxref{Block Input/Output}). Unlike @code{getc}, +any @code{int} value could be a valid result. @code{getw} returns +@code{EOF} when it encounters end-of-file or an error, but there is no +way to distinguish this from an input word with value -1. +@end deftypefun + +@node Line Input +@section Line-Oriented Input + +Since many programs interpret input on the basis of lines, it's +convenient to have functions to read a line of text from a stream. + +Standard C has functions to do this, but they aren't very safe: null +characters and even (for @code{gets}) long lines can confuse them. So +the GNU library provides the nonstandard @code{getline} function that +makes it easy to read lines reliably. + +Another GNU extension, @code{getdelim}, generalizes @code{getline}. It +reads a delimited record, defined as everything through the next +occurrence of a specified delimiter character. + +All these functions are declared in @file{stdio.h}. + +@comment stdio.h +@comment GNU +@deftypefun ssize_t getline (char **@var{lineptr}, size_t *@var{n}, FILE *@var{stream}) +This function reads an entire line from @var{stream}, storing the text +(including the newline and a terminating null character) in a buffer +and storing the buffer address in @code{*@var{lineptr}}. + +Before calling @code{getline}, you should place in @code{*@var{lineptr}} +the address of a buffer @code{*@var{n}} bytes long, allocated with +@code{malloc}. If this buffer is long enough to hold the line, +@code{getline} stores the line in this buffer. Otherwise, +@code{getline} makes the buffer bigger using @code{realloc}, storing the +new buffer address back in @code{*@var{lineptr}} and the increased size +back in @code{*@var{n}}. +@xref{Unconstrained Allocation}. + +If you set @code{*@var{lineptr}} to a null pointer, and @code{*@var{n}} +to zero, before the call, then @code{getline} allocates the initial +buffer for you by calling @code{malloc}. + +In either case, when @code{getline} returns, @code{*@var{lineptr}} is +a @code{char *} which points to the text of the line. + +When @code{getline} is successful, it returns the number of characters +read (including the newline, but not including the terminating null). +This value enables you to distinguish null characters that are part of +the line from the null character inserted as a terminator. + +This function is a GNU extension, but it is the recommended way to read +lines from a stream. The alternative standard functions are unreliable. + +If an error occurs or end of file is reached, @code{getline} returns +@code{-1}. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun ssize_t getdelim (char **@var{lineptr}, size_t *@var{n}, int @var{delimiter}, FILE *@var{stream}) +This function is like @code{getline} except that the character which +tells it to stop reading is not necessarily newline. The argument +@var{delimiter} specifies the delimiter character; @code{getdelim} keeps +reading until it sees that character (or end of file). + +The text is stored in @var{lineptr}, including the delimiter character +and a terminating null. Like @code{getline}, @code{getdelim} makes +@var{lineptr} bigger if it isn't big enough. + +@code{getline} is in fact implemented in terms of @code{getdelim}, just +like this: + +@smallexample +ssize_t +getline (char **lineptr, size_t *n, FILE *stream) +@{ + return getdelim (lineptr, n, '\n', stream); +@} +@end smallexample +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun {char *} fgets (char *@var{s}, int @var{count}, FILE *@var{stream}) +The @code{fgets} function reads characters from the stream @var{stream} +up to and including a newline character and stores them in the string +@var{s}, adding a null character to mark the end of the string. You +must supply @var{count} characters worth of space in @var{s}, but the +number of characters read is at most @var{count} @minus{} 1. The extra +character space is used to hold the null character at the end of the +string. + +If the system is already at end of file when you call @code{fgets}, then +the contents of the array @var{s} are unchanged and a null pointer is +returned. A null pointer is also returned if a read error occurs. +Otherwise, the return value is the pointer @var{s}. + +@strong{Warning:} If the input data has a null character, you can't tell. +So don't use @code{fgets} unless you know the data cannot contain a null. +Don't use it to read files edited by the user because, if the user inserts +a null character, you should either handle it properly or print a clear +error message. We recommend using @code{getline} instead of @code{fgets}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefn {Deprecated function} {char *} gets (char *@var{s}) +The function @code{gets} reads characters from the stream @code{stdin} +up to the next newline character, and stores them in the string @var{s}. +The newline character is discarded (note that this differs from the +behavior of @code{fgets}, which copies the newline character into the +string). If @code{gets} encounters a read error or end-of-file, it +returns a null pointer; otherwise it returns @var{s}. + +@strong{Warning:} The @code{gets} function is @strong{very dangerous} +because it provides no protection against overflowing the string +@var{s}. The GNU library includes it for compatibility only. You +should @strong{always} use @code{fgets} or @code{getline} instead. To +remind you of this, the linker (if using GNU @code{ld}) will issue a +warning whenever you use @code{gets}. +@end deftypefn + +@node Unreading +@section Unreading +@cindex peeking at input +@cindex unreading characters +@cindex pushing input back + +In parser programs it is often useful to examine the next character in +the input stream without removing it from the stream. This is called +``peeking ahead'' at the input because your program gets a glimpse of +the input it will read next. + +Using stream I/O, you can peek ahead at input by first reading it and +then @dfn{unreading} it (also called @dfn{pushing it back} on the stream). +Unreading a character makes it available to be input again from the stream, +by the next call to @code{fgetc} or other input function on that stream. + +@menu +* Unreading Idea:: An explanation of unreading with pictures. +* How Unread:: How to call @code{ungetc} to do unreading. +@end menu + +@node Unreading Idea +@subsection What Unreading Means + +Here is a pictorial explanation of unreading. Suppose you have a +stream reading a file that contains just six characters, the letters +@samp{foobar}. Suppose you have read three characters so far. The +situation looks like this: + +@smallexample +f o o b a r + ^ +@end smallexample + +@noindent +so the next input character will be @samp{b}. + +@c @group Invalid outside @example +If instead of reading @samp{b} you unread the letter @samp{o}, you get a +situation like this: + +@smallexample +f o o b a r + | + o-- + ^ +@end smallexample + +@noindent +so that the next input characters will be @samp{o} and @samp{b}. +@c @end group + +@c @group +If you unread @samp{9} instead of @samp{o}, you get this situation: + +@smallexample +f o o b a r + | + 9-- + ^ +@end smallexample + +@noindent +so that the next input characters will be @samp{9} and @samp{b}. +@c @end group + +@node How Unread +@subsection Using @code{ungetc} To Do Unreading + +The function to unread a character is called @code{ungetc}, because it +reverses the action of @code{getc}. + +@comment stdio.h +@comment ANSI +@deftypefun int ungetc (int @var{c}, FILE *@var{stream}) +The @code{ungetc} function pushes back the character @var{c} onto the +input stream @var{stream}. So the next input from @var{stream} will +read @var{c} before anything else. + +If @var{c} is @code{EOF}, @code{ungetc} does nothing and just returns +@code{EOF}. This lets you call @code{ungetc} with the return value of +@code{getc} without needing to check for an error from @code{getc}. + +The character that you push back doesn't have to be the same as the last +character that was actually read from the stream. In fact, it isn't +necessary to actually read any characters from the stream before +unreading them with @code{ungetc}! But that is a strange way to write +a program; usually @code{ungetc} is used only to unread a character +that was just read from the same stream. + +The GNU C library only supports one character of pushback---in other +words, it does not work to call @code{ungetc} twice without doing input +in between. Other systems might let you push back multiple characters; +then reading from the stream retrieves the characters in the reverse +order that they were pushed. + +Pushing back characters doesn't alter the file; only the internal +buffering for the stream is affected. If a file positioning function +(such as @code{fseek} or @code{rewind}; @pxref{File Positioning}) is +called, any pending pushed-back characters are discarded. + +Unreading a character on a stream that is at end of file clears the +end-of-file indicator for the stream, because it makes the character of +input available. After you read that character, trying to read again +will encounter end of file. +@end deftypefun + +Here is an example showing the use of @code{getc} and @code{ungetc} to +skip over whitespace characters. When this function reaches a +non-whitespace character, it unreads that character to be seen again on +the next read operation on the stream. + +@smallexample +#include <stdio.h> +#include <ctype.h> + +void +skip_whitespace (FILE *stream) +@{ + int c; + do + /* @r{No need to check for @code{EOF} because it is not} + @r{@code{isspace}, and @code{ungetc} ignores @code{EOF}.} */ + c = getc (stream); + while (isspace (c)); + ungetc (c, stream); +@} +@end smallexample + +@node Block Input/Output +@section Block Input/Output + +This section describes how to do input and output operations on blocks +of data. You can use these functions to read and write binary data, as +well as to read and write text in fixed-size blocks instead of by +characters or lines. +@cindex binary I/O to a stream +@cindex block I/O to a stream +@cindex reading from a stream, by blocks +@cindex writing to a stream, by blocks + +Binary files are typically used to read and write blocks of data in the +same format as is used to represent the data in a running program. In +other words, arbitrary blocks of memory---not just character or string +objects---can be written to a binary file, and meaningfully read in +again by the same program. + +Storing data in binary form is often considerably more efficient than +using the formatted I/O functions. Also, for floating-point numbers, +the binary form avoids possible loss of precision in the conversion +process. On the other hand, binary files can't be examined or modified +easily using many standard file utilities (such as text editors), and +are not portable between different implementations of the language, or +different kinds of computers. + +These functions are declared in @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun size_t fread (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) +This function reads up to @var{count} objects of size @var{size} into +the array @var{data}, from the stream @var{stream}. It returns the +number of objects actually read, which might be less than @var{count} if +a read error occurs or the end of the file is reached. This function +returns a value of zero (and doesn't read anything) if either @var{size} +or @var{count} is zero. + +If @code{fread} encounters end of file in the middle of an object, it +returns the number of complete objects read, and discards the partial +object. Therefore, the stream remains at the actual end of the file. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun size_t fwrite (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) +This function writes up to @var{count} objects of size @var{size} from +the array @var{data}, to the stream @var{stream}. The return value is +normally @var{count}, if the call succeeds. Any other value indicates +some sort of error, such as running out of space. +@end deftypefun + +@node Formatted Output +@section Formatted Output + +@cindex format string, for @code{printf} +@cindex template, for @code{printf} +@cindex formatted output to a stream +@cindex writing to a stream, formatted +The functions described in this section (@code{printf} and related +functions) provide a convenient way to perform formatted output. You +call @code{printf} with a @dfn{format string} or @dfn{template string} +that specifies how to format the values of the remaining arguments. + +Unless your program is a filter that specifically performs line- or +character-oriented processing, using @code{printf} or one of the other +related functions described in this section is usually the easiest and +most concise way to perform output. These functions are especially +useful for printing error messages, tables of data, and the like. + +@menu +* Formatted Output Basics:: Some examples to get you started. +* Output Conversion Syntax:: General syntax of conversion + specifications. +* Table of Output Conversions:: Summary of output conversions and + what they do. +* Integer Conversions:: Details about formatting of integers. +* Floating-Point Conversions:: Details about formatting of + floating-point numbers. +* Other Output Conversions:: Details about formatting of strings, + characters, pointers, and the like. +* Formatted Output Functions:: Descriptions of the actual functions. +* Dynamic Output:: Functions that allocate memory for the output. +* Variable Arguments Output:: @code{vprintf} and friends. +* Parsing a Template String:: What kinds of args does a given template + call for? +* Example of Parsing:: Sample program using @code{parse_printf_format}. +@end menu + +@node Formatted Output Basics +@subsection Formatted Output Basics + +The @code{printf} function can be used to print any number of arguments. +The template string argument you supply in a call provides +information not only about the number of additional arguments, but also +about their types and what style should be used for printing them. + +Ordinary characters in the template string are simply written to the +output stream as-is, while @dfn{conversion specifications} introduced by +a @samp{%} character in the template cause subsequent arguments to be +formatted and written to the output stream. For example, +@cindex conversion specifications (@code{printf}) + +@smallexample +int pct = 37; +char filename[] = "foo.txt"; +printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n", + filename, pct); +@end smallexample + +@noindent +produces output like + +@smallexample +Processing of `foo.txt' is 37% finished. +Please be patient. +@end smallexample + +This example shows the use of the @samp{%d} conversion to specify that +an @code{int} argument should be printed in decimal notation, the +@samp{%s} conversion to specify printing of a string argument, and +the @samp{%%} conversion to print a literal @samp{%} character. + +There are also conversions for printing an integer argument as an +unsigned value in octal, decimal, or hexadecimal radix (@samp{%o}, +@samp{%u}, or @samp{%x}, respectively); or as a character value +(@samp{%c}). + +Floating-point numbers can be printed in normal, fixed-point notation +using the @samp{%f} conversion or in exponential notation using the +@samp{%e} conversion. The @samp{%g} conversion uses either @samp{%e} +or @samp{%f} format, depending on what is more appropriate for the +magnitude of the particular number. + +You can control formatting more precisely by writing @dfn{modifiers} +between the @samp{%} and the character that indicates which conversion +to apply. These slightly alter the ordinary behavior of the conversion. +For example, most conversion specifications permit you to specify a +minimum field width and a flag indicating whether you want the result +left- or right-justified within the field. + +The specific flags and modifiers that are permitted and their +interpretation vary depending on the particular conversion. They're all +described in more detail in the following sections. Don't worry if this +all seems excessively complicated at first; you can almost always get +reasonable free-format output without using any of the modifiers at all. +The modifiers are mostly used to make the output look ``prettier'' in +tables. + +@node Output Conversion Syntax +@subsection Output Conversion Syntax + +This section provides details about the precise syntax of conversion +specifications that can appear in a @code{printf} template +string. + +Characters in the template string that are not part of a +conversion specification are printed as-is to the output stream. +Multibyte character sequences (@pxref{Extended Characters}) are permitted in +a template string. + +The conversion specifications in a @code{printf} template string have +the general form: + +@example +% @var{flags} @var{width} @r{[} . @var{precision} @r{]} @var{type} @var{conversion} +@end example + +For example, in the conversion specifier @samp{%-10.8ld}, the @samp{-} +is a flag, @samp{10} specifies the field width, the precision is +@samp{8}, the letter @samp{l} is a type modifier, and @samp{d} specifies +the conversion style. (This particular type specifier says to +print a @code{long int} argument in decimal notation, with a minimum of +8 digits left-justified in a field at least 10 characters wide.) + +In more detail, output conversion specifications consist of an +initial @samp{%} character followed in sequence by: + +@itemize @bullet +@item +Zero or more @dfn{flag characters} that modify the normal behavior of +the conversion specification. +@cindex flag character (@code{printf}) + +@item +An optional decimal integer specifying the @dfn{minimum field width}. +If the normal conversion produces fewer characters than this, the field +is padded with spaces to the specified width. This is a @emph{minimum} +value; if the normal conversion produces more characters than this, the +field is @emph{not} truncated. Normally, the output is right-justified +within the field. +@cindex minimum field width (@code{printf}) + +You can also specify a field width of @samp{*}. This means that the +next argument in the argument list (before the actual value to be +printed) is used as the field width. The value must be an @code{int}. +If the value is negative, this means to set the @samp{-} flag (see +below) and to use the absolute value as the field width. + +@item +An optional @dfn{precision} to specify the number of digits to be +written for the numeric conversions. If the precision is specified, it +consists of a period (@samp{.}) followed optionally by a decimal integer +(which defaults to zero if omitted). +@cindex precision (@code{printf}) + +You can also specify a precision of @samp{*}. This means that the next +argument in the argument list (before the actual value to be printed) is +used as the precision. The value must be an @code{int}, and is ignored +if it is negative. If you specify @samp{*} for both the field width and +precision, the field width argument precedes the precision argument. +Other C library versions may not recognize this syntax. + +@item +An optional @dfn{type modifier character}, which is used to specify the +data type of the corresponding argument if it differs from the default +type. (For example, the integer conversions assume a type of @code{int}, +but you can specify @samp{h}, @samp{l}, or @samp{L} for other integer +types.) +@cindex type modifier character (@code{printf}) + +@item +A character that specifies the conversion to be applied. +@end itemize + +The exact options that are permitted and how they are interpreted vary +between the different conversion specifiers. See the descriptions of the +individual conversions for information about the particular options that +they use. + +With the @samp{-Wformat} option, the GNU C compiler checks calls to +@code{printf} and related functions. It examines the format string and +verifies that the correct number and types of arguments are supplied. +There is also a GNU C syntax to tell the compiler that a function you +write uses a @code{printf}-style format string. +@xref{Function Attributes, , Declaring Attributes of Functions, +gcc.info, Using GNU CC}, for more information. + +@node Table of Output Conversions +@subsection Table of Output Conversions +@cindex output conversions, for @code{printf} + +Here is a table summarizing what all the different conversions do: + +@table @asis +@item @samp{%d}, @samp{%i} +Print an integer as a signed decimal number. @xref{Integer +Conversions}, for details. @samp{%d} and @samp{%i} are synonymous for +output, but are different when used with @code{scanf} for input +(@pxref{Table of Input Conversions}). + +@item @samp{%o} +Print an integer as an unsigned octal number. @xref{Integer +Conversions}, for details. + +@item @samp{%u} +Print an integer as an unsigned decimal number. @xref{Integer +Conversions}, for details. + +@item @samp{%x}, @samp{%X} +Print an integer as an unsigned hexadecimal number. @samp{%x} uses +lower-case letters and @samp{%X} uses upper-case. @xref{Integer +Conversions}, for details. + +@item @samp{%f} +Print a floating-point number in normal (fixed-point) notation. +@xref{Floating-Point Conversions}, for details. + +@item @samp{%e}, @samp{%E} +Print a floating-point number in exponential notation. @samp{%e} uses +lower-case letters and @samp{%E} uses upper-case. @xref{Floating-Point +Conversions}, for details. + +@item @samp{%g}, @samp{%G} +Print a floating-point number in either normal or exponential notation, +whichever is more appropriate for its magnitude. @samp{%g} uses +lower-case letters and @samp{%G} uses upper-case. @xref{Floating-Point +Conversions}, for details. + +@item @samp{%c} +Print a single character. @xref{Other Output Conversions}. + +@item @samp{%s} +Print a string. @xref{Other Output Conversions}. + +@item @samp{%p} +Print the value of a pointer. @xref{Other Output Conversions}. + +@item @samp{%n} +Get the number of characters printed so far. @xref{Other Output Conversions}. +Note that this conversion specification never produces any output. + +@item @samp{%m} +Print the string corresponding to the value of @code{errno}. +(This is a GNU extension.) +@xref{Other Output Conversions}. + +@item @samp{%%} +Print a literal @samp{%} character. @xref{Other Output Conversions}. +@end table + +If the syntax of a conversion specification is invalid, unpredictable +things will happen, so don't do this. If there aren't enough function +arguments provided to supply values for all the conversion +specifications in the template string, or if the arguments are not of +the correct types, the results are unpredictable. If you supply more +arguments than conversion specifications, the extra argument values are +simply ignored; this is sometimes useful. + +@node Integer Conversions +@subsection Integer Conversions + +This section describes the options for the @samp{%d}, @samp{%i}, +@samp{%o}, @samp{%u}, @samp{%x}, and @samp{%X} conversion +specifications. These conversions print integers in various formats. + +The @samp{%d} and @samp{%i} conversion specifications both print an +@code{int} argument as a signed decimal number; while @samp{%o}, +@samp{%u}, and @samp{%x} print the argument as an unsigned octal, +decimal, or hexadecimal number (respectively). The @samp{%X} conversion +specification is just like @samp{%x} except that it uses the characters +@samp{ABCDEF} as digits instead of @samp{abcdef}. + +The following flags are meaningful: + +@table @asis +@item @samp{-} +Left-justify the result in the field (instead of the normal +right-justification). + +@item @samp{+} +For the signed @samp{%d} and @samp{%i} conversions, print a +plus sign if the value is positive. + +@item @samp{ } +For the signed @samp{%d} and @samp{%i} conversions, if the result +doesn't start with a plus or minus sign, prefix it with a space +character instead. Since the @samp{+} flag ensures that the result +includes a sign, this flag is ignored if you supply both of them. + +@item @samp{#} +For the @samp{%o} conversion, this forces the leading digit to be +@samp{0}, as if by increasing the precision. For @samp{%x} or +@samp{%X}, this prefixes a leading @samp{0x} or @samp{0X} (respectively) +to the result. This doesn't do anything useful for the @samp{%d}, +@samp{%i}, or @samp{%u} conversions. Using this flag produces output +which can be parsed by the @code{strtoul} function (@pxref{Parsing of +Integers}) and @code{scanf} with the @samp{%i} conversion +(@pxref{Numeric Input Conversions}). + +@item @samp{'} +Separate the digits into groups as specified by the locale specified for +the @code{LC_NUMERIC} category; @pxref{General Numeric}. This flag is a +GNU extension. + +@item @samp{0} +Pad the field with zeros instead of spaces. The zeros are placed after +any indication of sign or base. This flag is ignored if the @samp{-} +flag is also specified, or if a precision is specified. +@end table + +If a precision is supplied, it specifies the minimum number of digits to +appear; leading zeros are produced if necessary. If you don't specify a +precision, the number is printed with as many digits as it needs. If +you convert a value of zero with an explicit precision of zero, then no +characters at all are produced. + +Without a type modifier, the corresponding argument is treated as an +@code{int} (for the signed conversions @samp{%i} and @samp{%d}) or +@code{unsigned int} (for the unsigned conversions @samp{%o}, @samp{%u}, +@samp{%x}, and @samp{%X}). Recall that since @code{printf} and friends +are variadic, any @code{char} and @code{short} arguments are +automatically converted to @code{int} by the default argument +promotions. For arguments of other integer types, you can use these +modifiers: + +@table @samp +@item h +Specifies that the argument is a @code{short int} or @code{unsigned +short int}, as appropriate. A @code{short} argument is converted to an +@code{int} or @code{unsigned int} by the default argument promotions +anyway, but the @samp{h} modifier says to convert it back to a +@code{short} again. + +@item l +Specifies that the argument is a @code{long int} or @code{unsigned long +int}, as appropriate. Two @samp{l} characters is like the @samp{L} +modifier, below. + +@item L +@itemx ll +@itemx q +Specifies that the argument is a @code{long long int}. (This type is +an extension supported by the GNU C compiler. On systems that don't +support extra-long integers, this is the same as @code{long int}.) + +The @samp{q} modifier is another name for the same thing, which comes +from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad'' +@code{int}. + +@item Z +Specifies that the argument is a @code{size_t}. This is a GNU extension. +@end table + +Here is an example. Using the template string: + +@smallexample +"|%5d|%-5d|%+5d|%+-5d|% 5d|%05d|%5.0d|%5.2d|%d|\n" +@end smallexample + +@noindent +to print numbers using the different options for the @samp{%d} +conversion gives results like: + +@smallexample +| 0|0 | +0|+0 | 0|00000| | 00|0| +| 1|1 | +1|+1 | 1|00001| 1| 01|1| +| -1|-1 | -1|-1 | -1|-0001| -1| -01|-1| +|100000|100000|+100000| 100000|100000|100000|100000|100000| +@end smallexample + +In particular, notice what happens in the last case where the number +is too large to fit in the minimum field width specified. + +Here are some more examples showing how unsigned integers print under +various format options, using the template string: + +@smallexample +"|%5u|%5o|%5x|%5X|%#5o|%#5x|%#5X|%#10.8x|\n" +@end smallexample + +@smallexample +| 0| 0| 0| 0| 0| 0x0| 0X0|0x00000000| +| 1| 1| 1| 1| 01| 0x1| 0X1|0x00000001| +|100000|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0| +@end smallexample + + +@node Floating-Point Conversions +@subsection Floating-Point Conversions + +This section discusses the conversion specifications for floating-point +numbers: the @samp{%f}, @samp{%e}, @samp{%E}, @samp{%g}, and @samp{%G} +conversions. + +The @samp{%f} conversion prints its argument in fixed-point notation, +producing output of the form +@w{[@code{-}]@var{ddd}@code{.}@var{ddd}}, +where the number of digits following the decimal point is controlled +by the precision you specify. + +The @samp{%e} conversion prints its argument in exponential notation, +producing output of the form +@w{[@code{-}]@var{d}@code{.}@var{ddd}@code{e}[@code{+}|@code{-}]@var{dd}}. +Again, the number of digits following the decimal point is controlled by +the precision. The exponent always contains at least two digits. The +@samp{%E} conversion is similar but the exponent is marked with the letter +@samp{E} instead of @samp{e}. + +The @samp{%g} and @samp{%G} conversions print the argument in the style +of @samp{%e} or @samp{%E} (respectively) if the exponent would be less +than -4 or greater than or equal to the precision; otherwise they use the +@samp{%f} style. Trailing zeros are removed from the fractional portion +of the result and a decimal-point character appears only if it is +followed by a digit. + +The following flags can be used to modify the behavior: + +@comment We use @asis instead of @samp so we can have ` ' as an item. +@table @asis +@item @samp{-} +Left-justify the result in the field. Normally the result is +right-justified. + +@item @samp{+} +Always include a plus or minus sign in the result. + +@item @samp{ } +If the result doesn't start with a plus or minus sign, prefix it with a +space instead. Since the @samp{+} flag ensures that the result includes +a sign, this flag is ignored if you supply both of them. + +@item @samp{#} +Specifies that the result should always include a decimal point, even +if no digits follow it. For the @samp{%g} and @samp{%G} conversions, +this also forces trailing zeros after the decimal point to be left +in place where they would otherwise be removed. + +@item @samp{'} +Separate the digits of the integer part of the result into groups as +specified by the locale specified for the @code{LC_NUMERIC} category; +@pxref{General Numeric}. This flag is a GNU extension. + +@item @samp{0} +Pad the field with zeros instead of spaces; the zeros are placed +after any sign. This flag is ignored if the @samp{-} flag is also +specified. +@end table + +The precision specifies how many digits follow the decimal-point +character for the @samp{%f}, @samp{%e}, and @samp{%E} conversions. For +these conversions, the default precision is @code{6}. If the precision +is explicitly @code{0}, this suppresses the decimal point character +entirely. For the @samp{%g} and @samp{%G} conversions, the precision +specifies how many significant digits to print. Significant digits are +the first digit before the decimal point, and all the digits after it. +If the precision @code{0} or not specified for @samp{%g} or @samp{%G}, +it is treated like a value of @code{1}. If the value being printed +cannot be expressed accurately in the specified number of digits, the +value is rounded to the nearest number that fits. + +Without a type modifier, the floating-point conversions use an argument +of type @code{double}. (By the default argument promotions, any +@code{float} arguments are automatically converted to @code{double}.) +The following type modifier is supported: + +@table @samp +@item L +An uppercase @samp{L} specifies that the argument is a @code{long +double}. +@end table + +Here are some examples showing how numbers print using the various +floating-point conversions. All of the numbers were printed using +this template string: + +@smallexample +"|%12.4f|%12.4e|%12.4g|\n" +@end smallexample + +Here is the output: + +@smallexample +| 0.0000| 0.0000e+00| 0| +| 1.0000| 1.0000e+00| 1| +| -1.0000| -1.0000e+00| -1| +| 100.0000| 1.0000e+02| 100| +| 1000.0000| 1.0000e+03| 1000| +| 10000.0000| 1.0000e+04| 1e+04| +| 12345.0000| 1.2345e+04| 1.234e+04| +| 100000.0000| 1.0000e+05| 1e+05| +| 123456.0000| 1.2346e+05| 1.234e+05| +@end smallexample + +Notice how the @samp{%g} conversion drops trailing zeros. + +@node Other Output Conversions +@subsection Other Output Conversions + +This section describes miscellaneous conversions for @code{printf}. + +The @samp{%c} conversion prints a single character. The @code{int} +argument is first converted to an @code{unsigned char}. The @samp{-} +flag can be used to specify left-justification in the field, but no +other flags are defined, and no precision or type modifier can be given. +For example: + +@smallexample +printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o'); +@end smallexample + +@noindent +prints @samp{hello}. + +The @samp{%s} conversion prints a string. The corresponding argument +must be of type @code{char *} (or @code{const char *}). A precision can +be specified to indicate the maximum number of characters to write; +otherwise characters in the string up to but not including the +terminating null character are written to the output stream. The +@samp{-} flag can be used to specify left-justification in the field, +but no other flags or type modifiers are defined for this conversion. +For example: + +@smallexample +printf ("%3s%-6s", "no", "where"); +@end smallexample + +@noindent +prints @samp{ nowhere }. + +If you accidentally pass a null pointer as the argument for a @samp{%s} +conversion, the GNU library prints it as @samp{(null)}. We think this +is more useful than crashing. But it's not good practice to pass a null +argument intentionally. + +The @samp{%m} conversion prints the string corresponding to the error +code in @code{errno}. @xref{Error Messages}. Thus: + +@smallexample +fprintf (stderr, "can't open `%s': %m\n", filename); +@end smallexample + +@noindent +is equivalent to: + +@smallexample +fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno)); +@end smallexample + +@noindent +The @samp{%m} conversion is a GNU C library extension. + +The @samp{%p} conversion prints a pointer value. The corresponding +argument must be of type @code{void *}. In practice, you can use any +type of pointer. + +In the GNU system, non-null pointers are printed as unsigned integers, +as if a @samp{%#x} conversion were used. Null pointers print as +@samp{(nil)}. (Pointers might print differently in other systems.) + +For example: + +@smallexample +printf ("%p", "testing"); +@end smallexample + +@noindent +prints @samp{0x} followed by a hexadecimal number---the address of the +string constant @code{"testing"}. It does not print the word +@samp{testing}. + +You can supply the @samp{-} flag with the @samp{%p} conversion to +specify left-justification, but no other flags, precision, or type +modifiers are defined. + +The @samp{%n} conversion is unlike any of the other output conversions. +It uses an argument which must be a pointer to an @code{int}, but +instead of printing anything it stores the number of characters printed +so far by this call at that location. The @samp{h} and @samp{l} type +modifiers are permitted to specify that the argument is of type +@code{short int *} or @code{long int *} instead of @code{int *}, but no +flags, field width, or precision are permitted. + +For example, + +@smallexample +int nchar; +printf ("%d %s%n\n", 3, "bears", &nchar); +@end smallexample + +@noindent +prints: + +@smallexample +3 bears +@end smallexample + +@noindent +and sets @code{nchar} to @code{7}, because @samp{3 bears} is seven +characters. + + +The @samp{%%} conversion prints a literal @samp{%} character. This +conversion doesn't use an argument, and no flags, field width, +precision, or type modifiers are permitted. + + +@node Formatted Output Functions +@subsection Formatted Output Functions + +This section describes how to call @code{printf} and related functions. +Prototypes for these functions are in the header file @file{stdio.h}. +Because these functions take a variable number of arguments, you +@emph{must} declare prototypes for them before using them. Of course, +the easiest way to make sure you have all the right prototypes is to +just include @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int printf (const char *@var{template}, @dots{}) +The @code{printf} function prints the optional arguments under the +control of the template string @var{template} to the stream +@code{stdout}. It returns the number of characters printed, or a +negative value if there was an output error. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int fprintf (FILE *@var{stream}, const char *@var{template}, @dots{}) +This function is just like @code{printf}, except that the output is +written to the stream @var{stream} instead of @code{stdout}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{}) +This is like @code{printf}, except that the output is stored in the character +array @var{s} instead of written to a stream. A null character is written +to mark the end of the string. + +The @code{sprintf} function returns the number of characters stored in +the array @var{s}, not including the terminating null character. + +The behavior of this function is undefined if copying takes place +between objects that overlap---for example, if @var{s} is also given +as an argument to be printed under control of the @samp{%s} conversion. +@xref{Copying and Concatenation}. + +@strong{Warning:} The @code{sprintf} function can be @strong{dangerous} +because it can potentially output more characters than can fit in the +allocation size of the string @var{s}. Remember that the field width +given in a conversion specification is only a @emph{minimum} value. + +To avoid this problem, you can use @code{snprintf} or @code{asprintf}, +described below. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int snprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, @dots{}) +The @code{snprintf} function is similar to @code{sprintf}, except that +the @var{size} argument specifies the maximum number of characters to +produce. The trailing null character is counted towards this limit, so +you should allocate at least @var{size} characters for the string @var{s}. + +The return value is the number of characters stored, not including the +terminating null. If this value equals @code{@var{size} - 1}, then +there was not enough space in @var{s} for all the output. You should +try again with a bigger output string. Here is an example of doing +this: + +@smallexample +@group +/* @r{Construct a message describing the value of a variable} + @r{whose name is @var{name} and whose value is @var{value}.} */ +char * +make_message (char *name, char *value) +@{ + /* @r{Guess we need no more than 100 chars of space.} */ + int size = 100; + char *buffer = (char *) xmalloc (size); +@end group +@group + while (1) + @{ + /* @r{Try to print in the allocated space.} */ + int nchars = snprintf (buffer, size, + "value of %s is %s", + name, value); + /* @r{If that worked, return the string.} */ + if (nchars < size) + return buffer; + /* @r{Else try again with twice as much space.} */ + size *= 2; + buffer = (char *) xrealloc (size, buffer); + @} +@} +@end group +@end smallexample + +In practice, it is often easier just to use @code{asprintf}, below. +@end deftypefun + +@node Dynamic Output +@subsection Dynamically Allocating Formatted Output + +The functions in this section do formatted output and place the results +in dynamically allocated memory. + +@comment stdio.h +@comment GNU +@deftypefun int asprintf (char **@var{ptr}, const char *@var{template}, @dots{}) +This function is similar to @code{sprintf}, except that it dynamically +allocates a string (as with @code{malloc}; @pxref{Unconstrained +Allocation}) to hold the output, instead of putting the output in a +buffer you allocate in advance. The @var{ptr} argument should be the +address of a @code{char *} object, and @code{asprintf} stores a pointer +to the newly allocated string at that location. + +Here is how to use @code{asprintf} to get the same result as the +@code{snprintf} example, but more easily: + +@smallexample +/* @r{Construct a message describing the value of a variable} + @r{whose name is @var{name} and whose value is @var{value}.} */ +char * +make_message (char *name, char *value) +@{ + char *result; + asprintf (&result, "value of %s is %s", name, value); + return result; +@} +@end smallexample +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int obstack_printf (struct obstack *@var{obstack}, const char *@var{template}, @dots{}) +This function is similar to @code{asprintf}, except that it uses the +obstack @var{obstack} to allocate the space. @xref{Obstacks}. + +The characters are written onto the end of the current object. +To get at them, you must finish the object with @code{obstack_finish} +(@pxref{Growing Objects}).@refill +@end deftypefun + +@node Variable Arguments Output +@subsection Variable Arguments Output Functions + +The functions @code{vprintf} and friends are provided so that you can +define your own variadic @code{printf}-like functions that make use of +the same internals as the built-in formatted output functions. + +The most natural way to define such functions would be to use a language +construct to say, ``Call @code{printf} and pass this template plus all +of my arguments after the first five.'' But there is no way to do this +in C, and it would be hard to provide a way, since at the C language +level there is no way to tell how many arguments your function received. + +Since that method is impossible, we provide alternative functions, the +@code{vprintf} series, which lets you pass a @code{va_list} to describe +``all of my arguments after the first five.'' + +When it is sufficient to define a macro rather than a real function, +the GNU C compiler provides a way to do this much more easily with macros. +For example: + +@smallexample +#define myprintf(a, b, c, d, e, rest...) printf (mytemplate , ## rest...) +@end smallexample + +@noindent +@xref{Macro Varargs, , Macros with Variable Numbers of Arguments, +gcc.info, Using GNU CC}, for details. But this is limited to macros, +and does not apply to real functions at all. + +Before calling @code{vprintf} or the other functions listed in this +section, you @emph{must} call @code{va_start} (@pxref{Variadic +Functions}) to initialize a pointer to the variable arguments. Then you +can call @code{va_arg} to fetch the arguments that you want to handle +yourself. This advances the pointer past those arguments. + +Once your @code{va_list} pointer is pointing at the argument of your +choice, you are ready to call @code{vprintf}. That argument and all +subsequent arguments that were passed to your function are used by +@code{vprintf} along with the template that you specified separately. + +In some other systems, the @code{va_list} pointer may become invalid +after the call to @code{vprintf}, so you must not use @code{va_arg} +after you call @code{vprintf}. Instead, you should call @code{va_end} +to retire the pointer from service. However, you can safely call +@code{va_start} on another pointer variable and begin fetching the +arguments again through that pointer. Calling @code{vprintf} does not +destroy the argument list of your function, merely the particular +pointer that you passed to it. + +GNU C does not have such restrictions. You can safely continue to fetch +arguments from a @code{va_list} pointer after passing it to +@code{vprintf}, and @code{va_end} is a no-op. (Note, however, that +subsequent @code{va_arg} calls will fetch the same arguments which +@code{vprintf} previously used.) + +Prototypes for these functions are declared in @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int vprintf (const char *@var{template}, va_list @var{ap}) +This function is similar to @code{printf} except that, instead of taking +a variable number of arguments directly, it takes an argument list +pointer @var{ap}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap}) +This is the equivalent of @code{fprintf} with the variable argument list +specified directly as for @code{vprintf}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int vsprintf (char *@var{s}, const char *@var{template}, va_list @var{ap}) +This is the equivalent of @code{sprintf} with the variable argument list +specified directly as for @code{vprintf}. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int vsnprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, va_list @var{ap}) +This is the equivalent of @code{snprintf} with the variable argument list +specified directly as for @code{vprintf}. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int vasprintf (char **@var{ptr}, const char *@var{template}, va_list @var{ap}) +The @code{vasprintf} function is the equivalent of @code{asprintf} with the +variable argument list specified directly as for @code{vprintf}. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int obstack_vprintf (struct obstack *@var{obstack}, const char *@var{template}, va_list @var{ap}) +The @code{obstack_vprintf} function is the equivalent of +@code{obstack_printf} with the variable argument list specified directly +as for @code{vprintf}.@refill +@end deftypefun + +Here's an example showing how you might use @code{vfprintf}. This is a +function that prints error messages to the stream @code{stderr}, along +with a prefix indicating the name of the program +(@pxref{Error Messages}, for a description of +@code{program_invocation_short_name}). + +@smallexample +@group +#include <stdio.h> +#include <stdarg.h> + +void +eprintf (const char *template, ...) +@{ + va_list ap; + extern char *program_invocation_short_name; + + fprintf (stderr, "%s: ", program_invocation_short_name); + va_start (ap, count); + vfprintf (stderr, template, ap); + va_end (ap); +@} +@end group +@end smallexample + +@noindent +You could call @code{eprintf} like this: + +@smallexample +eprintf ("file `%s' does not exist\n", filename); +@end smallexample + +In GNU C, there is a special construct you can use to let the compiler +know that a function uses a @code{printf}-style format string. Then it +can check the number and types of arguments in each call to the +function, and warn you when they do not match the format string. +For example, take this declaration of @code{eprintf}: + +@smallexample +void eprintf (const char *template, ...) + __attribute__ ((format (printf, 1, 2))); +@end smallexample + +@noindent +This tells the compiler that @code{eprintf} uses a format string like +@code{printf} (as opposed to @code{scanf}; @pxref{Formatted Input}); +the format string appears as the first argument; +and the arguments to satisfy the format begin with the second. +@xref{Function Attributes, , Declaring Attributes of Functions, +gcc.info, Using GNU CC}, for more information. + +@node Parsing a Template String +@subsection Parsing a Template String +@cindex parsing a template string + +You can use the function @code{parse_printf_format} to obtain +information about the number and types of arguments that are expected by +a given template string. This function permits interpreters that +provide interfaces to @code{printf} to avoid passing along invalid +arguments from the user's program, which could cause a crash. + +All the symbols described in this section are declared in the header +file @file{printf.h}. + +@comment printf.h +@comment GNU +@deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes}) +This function returns information about the number and types of +arguments expected by the @code{printf} template string @var{template}. +The information is stored in the array @var{argtypes}; each element of +this array describes one argument. This information is encoded using +the various @samp{PA_} macros, listed below. + +The @var{n} argument specifies the number of elements in the array +@var{argtypes}. This is the most elements that +@code{parse_printf_format} will try to write. + +@code{parse_printf_format} returns the total number of arguments required +by @var{template}. If this number is greater than @var{n}, then the +information returned describes only the first @var{n} arguments. If you +want information about more than that many arguments, allocate a bigger +array and call @code{parse_printf_format} again. +@end deftypefun + +The argument types are encoded as a combination of a basic type and +modifier flag bits. + +@comment printf.h +@comment GNU +@deftypevr Macro int PA_FLAG_MASK +This macro is a bitmask for the type modifier flag bits. You can write +the expression @code{(argtypes[i] & PA_FLAG_MASK)} to extract just the +flag bits for an argument, or @code{(argtypes[i] & ~PA_FLAG_MASK)} to +extract just the basic type code. +@end deftypevr + +Here are symbolic constants that represent the basic types; they stand +for integer values. + +@table @code +@comment printf.h +@comment GNU +@item PA_INT +@vindex PA_INT +This specifies that the base type is @code{int}. + +@comment printf.h +@comment GNU +@item PA_CHAR +@vindex PA_CHAR +This specifies that the base type is @code{int}, cast to @code{char}. + +@comment printf.h +@comment GNU +@item PA_STRING +@vindex PA_STRING +This specifies that the base type is @code{char *}, a null-terminated string. + +@comment printf.h +@comment GNU +@item PA_POINTER +@vindex PA_POINTER +This specifies that the base type is @code{void *}, an arbitrary pointer. + +@comment printf.h +@comment GNU +@item PA_FLOAT +@vindex PA_FLOAT +This specifies that the base type is @code{float}. + +@comment printf.h +@comment GNU +@item PA_DOUBLE +@vindex PA_DOUBLE +This specifies that the base type is @code{double}. + +@comment printf.h +@comment GNU +@item PA_LAST +@vindex PA_LAST +You can define additional base types for your own programs as offsets +from @code{PA_LAST}. For example, if you have data types @samp{foo} +and @samp{bar} with their own specialized @code{printf} conversions, +you could define encodings for these types as: + +@smallexample +#define PA_FOO PA_LAST +#define PA_BAR (PA_LAST + 1) +@end smallexample +@end table + +Here are the flag bits that modify a basic type. They are combined with +the code for the basic type using inclusive-or. + +@table @code +@comment printf.h +@comment GNU +@item PA_FLAG_PTR +@vindex PA_FLAG_PTR +If this bit is set, it indicates that the encoded type is a pointer to +the base type, rather than an immediate value. +For example, @samp{PA_INT|PA_FLAG_PTR} represents the type @samp{int *}. + +@comment printf.h +@comment GNU +@item PA_FLAG_SHORT +@vindex PA_FLAG_SHORT +If this bit is set, it indicates that the base type is modified with +@code{short}. (This corresponds to the @samp{h} type modifier.) + +@comment printf.h +@comment GNU +@item PA_FLAG_LONG +@vindex PA_FLAG_LONG +If this bit is set, it indicates that the base type is modified with +@code{long}. (This corresponds to the @samp{l} type modifier.) + +@comment printf.h +@comment GNU +@item PA_FLAG_LONG_LONG +@vindex PA_FLAG_LONG_LONG +If this bit is set, it indicates that the base type is modified with +@code{long long}. (This corresponds to the @samp{L} type modifier.) + +@comment printf.h +@comment GNU +@item PA_FLAG_LONG_DOUBLE +@vindex PA_FLAG_LONG_DOUBLE +This is a synonym for @code{PA_FLAG_LONG_LONG}, used by convention with +a base type of @code{PA_DOUBLE} to indicate a type of @code{long double}. +@end table + +@ifinfo +For an example of using these facilitles, see @ref{Example of Parsing}. +@end ifinfo + +@node Example of Parsing +@subsection Example of Parsing a Template String + +Here is an example of decoding argument types for a format string. We +assume this is part of an interpreter which contains arguments of type +@code{NUMBER}, @code{CHAR}, @code{STRING} and @code{STRUCTURE} (and +perhaps others which are not valid here). + +@smallexample +/* @r{Test whether the @var{nargs} specified objects} + @r{in the vector @var{args} are valid} + @r{for the format string @var{format}:} + @r{if so, return 1.} + @r{If not, return 0 after printing an error message.} */ + +int +validate_args (char *format, int nargs, OBJECT *args) +@{ + int *argtypes; + int nwanted; + + /* @r{Get the information about the arguments.} + @r{Each conversion specification must be at least two characters} + @r{long, so there cannot be more specifications than half the} + @r{length of the string.} */ + + argtypes = (int *) alloca (strlen (format) / 2 * sizeof (int)); + nwanted = parse_printf_format (string, nelts, argtypes); + + /* @r{Check the number of arguments.} */ + if (nwanted > nargs) + @{ + error ("too few arguments (at least %d required)", nwanted); + return 0; + @} + + /* @r{Check the C type wanted for each argument} + @r{and see if the object given is suitable.} */ + for (i = 0; i < nwanted; i++) + @{ + int wanted; + + if (argtypes[i] & PA_FLAG_PTR) + wanted = STRUCTURE; + else + switch (argtypes[i] & ~PA_FLAG_MASK) + @{ + case PA_INT: + case PA_FLOAT: + case PA_DOUBLE: + wanted = NUMBER; + break; + case PA_CHAR: + wanted = CHAR; + break; + case PA_STRING: + wanted = STRING; + break; + case PA_POINTER: + wanted = STRUCTURE; + break; + @} + if (TYPE (args[i]) != wanted) + @{ + error ("type mismatch for arg number %d", i); + return 0; + @} + @} + return 1; +@} +@end smallexample + +@node Customizing Printf +@section Customizing @code{printf} +@cindex customizing @code{printf} +@cindex defining new @code{printf} conversions +@cindex extending @code{printf} + +The GNU C library lets you define your own custom conversion specifiers +for @code{printf} template strings, to teach @code{printf} clever ways +to print the important data structures of your program. + +The way you do this is by registering the conversion with the function +@code{register_printf_function}; see @ref{Registering New Conversions}. +One of the arguments you pass to this function is a pointer to a handler +function that produces the actual output; see @ref{Defining the Output +Handler}, for information on how to write this function. + +You can also install a function that just returns information about the +number and type of arguments expected by the conversion specifier. +@xref{Parsing a Template String}, for information about this. + +The facilities of this section are declared in the header file +@file{printf.h}. + +@menu +* Registering New Conversions:: Using @code{register_printf_function} + to register a new output conversion. +* Conversion Specifier Options:: The handler must be able to get + the options specified in the + template when it is called. +* Defining the Output Handler:: Defining the handler and arginfo + functions that are passed as arguments + to @code{register_printf_function}. +* Printf Extension Example:: How to define a @code{printf} + handler function. +@end menu + +@strong{Portability Note:} The ability to extend the syntax of +@code{printf} template strings is a GNU extension. ANSI standard C has +nothing similar. + +@node Registering New Conversions +@subsection Registering New Conversions + +The function to register a new output conversion is +@code{register_printf_function}, declared in @file{printf.h}. +@pindex printf.h + +@comment printf.h +@comment GNU +@deftypefun int register_printf_function (int @var{spec}, printf_function @var{handler-function}, printf_arginfo_function @var{arginfo-function}) +This function defines the conversion specifier character @var{spec}. +Thus, if @var{spec} is @code{'z'}, it defines the conversion @samp{%z}. +You can redefine the built-in conversions like @samp{%s}, but flag +characters like @samp{#} and type modifiers like @samp{l} can never be +used as conversions; calling @code{register_printf_function} for those +characters has no effect. + +The @var{handler-function} is the function called by @code{printf} and +friends when this conversion appears in a template string. +@xref{Defining the Output Handler}, for information about how to define +a function to pass as this argument. If you specify a null pointer, any +existing handler function for @var{spec} is removed. + +The @var{arginfo-function} is the function called by +@code{parse_printf_format} when this conversion appears in a +template string. @xref{Parsing a Template String}, for information +about this. + +Normally, you install both functions for a conversion at the same time, +but if you are never going to call @code{parse_printf_format}, you do +not need to define an arginfo function. + +The return value is @code{0} on success, and @code{-1} on failure +(which occurs if @var{spec} is out of range). + +You can redefine the standard output conversions, but this is probably +not a good idea because of the potential for confusion. Library routines +written by other people could break if you do this. +@end deftypefun + +@node Conversion Specifier Options +@subsection Conversion Specifier Options + +If you define a meaning for @samp{%q}, what if the template contains +@samp{%+23q} or @samp{%-#q}? To implement a sensible meaning for these, +the handler when called needs to be able to get the options specified in +the template. + +Both the @var{handler-function} and @var{arginfo-function} arguments +to @code{register_printf_function} accept an argument that points to a +@code{struct printf_info}, which contains information about the options +appearing in an instance of the conversion specifier. This data type +is declared in the header file @file{printf.h}. +@pindex printf.h + +@comment printf.h +@comment GNU +@deftp {Type} {struct printf_info} +This structure is used to pass information about the options appearing +in an instance of a conversion specifier in a @code{printf} template +string to the handler and arginfo functions for that specifier. It +contains the following members: + +@table @code +@item int prec +This is the precision specified. The value is @code{-1} if no precision +was specified. If the precision was given as @samp{*}, the +@code{printf_info} structure passed to the handler function contains the +actual value retrieved from the argument list. But the structure passed +to the arginfo function contains a value of @code{INT_MIN}, since the +actual value is not known. + +@item int width +This is the minimum field width specified. The value is @code{0} if no +width was specified. If the field width was given as @samp{*}, the +@code{printf_info} structure passed to the handler function contains the +actual value retrieved from the argument list. But the structure passed +to the arginfo function contains a value of @code{INT_MIN}, since the +actual value is not known. + +@item char spec +This is the conversion specifier character specified. It's stored in +the structure so that you can register the same handler function for +multiple characters, but still have a way to tell them apart when the +handler function is called. + +@item unsigned int is_long_double +This is a boolean that is true if the @samp{L}, @samp{ll}, or @samp{q} +type modifier was specified. For integer conversions, this indicates +@code{long long int}, as opposed to @code{long double} for floating +point conversions. + +@item unsigned int is_short +This is a boolean that is true if the @samp{h} type modifier was specified. + +@item unsigned int is_long +This is a boolean that is true if the @samp{l} type modifier was specified. + +@item unsigned int alt +This is a boolean that is true if the @samp{#} flag was specified. + +@item unsigned int space +This is a boolean that is true if the @samp{ } flag was specified. + +@item unsigned int left +This is a boolean that is true if the @samp{-} flag was specified. + +@item unsigned int showsign +This is a boolean that is true if the @samp{+} flag was specified. + +@item unsigned int group +This is a boolean that is true if the @samp{'} flag was specified. + +@item char pad +This is the character to use for padding the output to the minimum field +width. The value is @code{'0'} if the @samp{0} flag was specified, and +@code{' '} otherwise. +@end table +@end deftp + + +@node Defining the Output Handler +@subsection Defining the Output Handler + +Now let's look at how to define the handler and arginfo functions +which are passed as arguments to @code{register_printf_function}. + +You should define your handler functions with a prototype like: + +@smallexample +int @var{function} (FILE *stream, const struct printf_info *info, + va_list *ap_pointer) +@end smallexample + +The @code{stream} argument passed to the handler function is the stream to +which it should write output. + +The @code{info} argument is a pointer to a structure that contains +information about the various options that were included with the +conversion in the template string. You should not modify this structure +inside your handler function. @xref{Conversion Specifier Options}, for +a description of this data structure. + +The @code{ap_pointer} argument is used to pass the tail of the variable +argument list containing the values to be printed to your handler. +Unlike most other functions that can be passed an explicit variable +argument list, this is a @emph{pointer} to a @code{va_list}, rather than +the @code{va_list} itself. Thus, you should fetch arguments by +means of @code{va_arg (@var{type}, *ap_pointer)}. + +(Passing a pointer here allows the function that calls your handler +function to update its own @code{va_list} variable to account for the +arguments that your handler processes. @xref{Variadic Functions}.) + +Your handler function should return a value just like @code{printf} +does: it should return the number of characters it has written, or a +negative value to indicate an error. + +@comment printf.h +@comment GNU +@deftp {Data Type} printf_function +This is the data type that a handler function should have. +@end deftp + +If you are going to use @w{@code{parse_printf_format}} in your +application, you should also define a function to pass as the +@var{arginfo-function} argument for each new conversion you install with +@code{register_printf_function}. + +You should define these functions with a prototype like: + +@smallexample +int @var{function} (const struct printf_info *info, + size_t n, int *argtypes) +@end smallexample + +The return value from the function should be the number of arguments the +conversion expects. The function should also fill in no more than +@var{n} elements of the @var{argtypes} array with information about the +types of each of these arguments. This information is encoded using the +various @samp{PA_} macros. (You will notice that this is the same +calling convention @code{parse_printf_format} itself uses.) + +@comment printf.h +@comment GNU +@deftp {Data Type} printf_arginfo_function +This type is used to describe functions that return information about +the number and type of arguments used by a conversion specifier. +@end deftp + +@node Printf Extension Example +@subsection @code{printf} Extension Example + +Here is an example showing how to define a @code{printf} handler function. +This program defines a data structure called a @code{Widget} and +defines the @samp{%W} conversion to print information about @w{@code{Widget *}} +arguments, including the pointer value and the name stored in the data +structure. The @samp{%W} conversion supports the minimum field width and +left-justification options, but ignores everything else. + +@smallexample +@include rprintf.c.texi +@end smallexample + +The output produced by this program looks like: + +@smallexample +|<Widget 0xffeffb7c: mywidget>| +| <Widget 0xffeffb7c: mywidget>| +|<Widget 0xffeffb7c: mywidget> | +@end smallexample + +@node Formatted Input +@section Formatted Input + +@cindex formatted input from a stream +@cindex reading from a stream, formatted +@cindex format string, for @code{scanf} +@cindex template, for @code{scanf} +The functions described in this section (@code{scanf} and related +functions) provide facilities for formatted input analogous to the +formatted output facilities. These functions provide a mechanism for +reading arbitrary values under the control of a @dfn{format string} or +@dfn{template string}. + +@menu +* Formatted Input Basics:: Some basics to get you started. +* Input Conversion Syntax:: Syntax of conversion specifications. +* Table of Input Conversions:: Summary of input conversions and what they do. +* Numeric Input Conversions:: Details of conversions for reading numbers. +* String Input Conversions:: Details of conversions for reading strings. +* Dynamic String Input:: String conversions that @code{malloc} the buffer. +* Other Input Conversions:: Details of miscellaneous other conversions. +* Formatted Input Functions:: Descriptions of the actual functions. +* Variable Arguments Input:: @code{vscanf} and friends. +@end menu + +@node Formatted Input Basics +@subsection Formatted Input Basics + +Calls to @code{scanf} are superficially similar to calls to +@code{printf} in that arbitrary arguments are read under the control of +a template string. While the syntax of the conversion specifications in +the template is very similar to that for @code{printf}, the +interpretation of the template is oriented more towards free-format +input and simple pattern matching, rather than fixed-field formatting. +For example, most @code{scanf} conversions skip over any amount of +``white space'' (including spaces, tabs, and newlines) in the input +file, and there is no concept of precision for the numeric input +conversions as there is for the corresponding output conversions. +Ordinarily, non-whitespace characters in the template are expected to +match characters in the input stream exactly, but a matching failure is +distinct from an input error on the stream. +@cindex conversion specifications (@code{scanf}) + +Another area of difference between @code{scanf} and @code{printf} is +that you must remember to supply pointers rather than immediate values +as the optional arguments to @code{scanf}; the values that are read are +stored in the objects that the pointers point to. Even experienced +programmers tend to forget this occasionally, so if your program is +getting strange errors that seem to be related to @code{scanf}, you +might want to double-check this. + +When a @dfn{matching failure} occurs, @code{scanf} returns immediately, +leaving the first non-matching character as the next character to be +read from the stream. The normal return value from @code{scanf} is the +number of values that were assigned, so you can use this to determine if +a matching error happened before all the expected values were read. +@cindex matching failure, in @code{scanf} + +The @code{scanf} function is typically used for things like reading in +the contents of tables. For example, here is a function that uses +@code{scanf} to initialize an array of @code{double}: + +@smallexample +void +readarray (double *array, int n) +@{ + int i; + for (i=0; i<n; i++) + if (scanf (" %lf", &(array[i])) != 1) + invalid_input_error (); +@} +@end smallexample + +The formatted input functions are not used as frequently as the +formatted output functions. Partly, this is because it takes some care +to use them properly. Another reason is that it is difficult to recover +from a matching error. + +If you are trying to read input that doesn't match a single, fixed +pattern, you may be better off using a tool such as Flex to generate a +lexical scanner, or Bison to generate a parser, rather than using +@code{scanf}. For more information about these tools, see @ref{, , , +flex.info, Flex: The Lexical Scanner Generator}, and @ref{, , , +bison.info, The Bison Reference Manual}. + +@node Input Conversion Syntax +@subsection Input Conversion Syntax + +A @code{scanf} template string is a string that contains ordinary +multibyte characters interspersed with conversion specifications that +start with @samp{%}. + +Any whitespace character (as defined by the @code{isspace} function; +@pxref{Classification of Characters}) in the template causes any number +of whitespace characters in the input stream to be read and discarded. +The whitespace characters that are matched need not be exactly the same +whitespace characters that appear in the template string. For example, +write @samp{ , } in the template to recognize a comma with optional +whitespace before and after. + +Other characters in the template string that are not part of conversion +specifications must match characters in the input stream exactly; if +this is not the case, a matching failure occurs. + +The conversion specifications in a @code{scanf} template string +have the general form: + +@smallexample +% @var{flags} @var{width} @var{type} @var{conversion} +@end smallexample + +In more detail, an input conversion specification consists of an initial +@samp{%} character followed in sequence by: + +@itemize @bullet +@item +An optional @dfn{flag character} @samp{*}, which says to ignore the text +read for this specification. When @code{scanf} finds a conversion +specification that uses this flag, it reads input as directed by the +rest of the conversion specification, but it discards this input, does +not use a pointer argument, and does not increment the count of +successful assignments. +@cindex flag character (@code{scanf}) + +@item +An optional flag character @samp{a} (valid with string conversions only) +which requests allocation of a buffer long enough to store the string in. +(This is a GNU extension.) +@xref{Dynamic String Input}. + +@item +An optional decimal integer that specifies the @dfn{maximum field +width}. Reading of characters from the input stream stops either when +this maximum is reached or when a non-matching character is found, +whichever happens first. Most conversions discard initial whitespace +characters (those that don't are explicitly documented), and these +discarded characters don't count towards the maximum field width. +String input conversions store a null character to mark the end of the +input; the maximum field width does not include this terminator. +@cindex maximum field width (@code{scanf}) + +@item +An optional @dfn{type modifier character}. For example, you can +specify a type modifier of @samp{l} with integer conversions such as +@samp{%d} to specify that the argument is a pointer to a @code{long int} +rather than a pointer to an @code{int}. +@cindex type modifier character (@code{scanf}) + +@item +A character that specifies the conversion to be applied. +@end itemize + +The exact options that are permitted and how they are interpreted vary +between the different conversion specifiers. See the descriptions of the +individual conversions for information about the particular options that +they allow. + +With the @samp{-Wformat} option, the GNU C compiler checks calls to +@code{scanf} and related functions. It examines the format string and +verifies that the correct number and types of arguments are supplied. +There is also a GNU C syntax to tell the compiler that a function you +write uses a @code{scanf}-style format string. +@xref{Function Attributes, , Declaring Attributes of Functions, +gcc.info, Using GNU CC}, for more information. + +@node Table of Input Conversions +@subsection Table of Input Conversions +@cindex input conversions, for @code{scanf} + +Here is a table that summarizes the various conversion specifications: + +@table @asis +@item @samp{%d} +Matches an optionally signed integer written in decimal. @xref{Numeric +Input Conversions}. + +@item @samp{%i} +Matches an optionally signed integer in any of the formats that the C +language defines for specifying an integer constant. @xref{Numeric +Input Conversions}. + +@item @samp{%o} +Matches an unsigned integer written in octal radix. +@xref{Numeric Input Conversions}. + +@item @samp{%u} +Matches an unsigned integer written in decimal radix. +@xref{Numeric Input Conversions}. + +@item @samp{%x}, @samp{%X} +Matches an unsigned integer written in hexadecimal radix. +@xref{Numeric Input Conversions}. + +@item @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, @samp{%G} +Matches an optionally signed floating-point number. @xref{Numeric Input +Conversions}. + +@item @samp{%s} +Matches a string containing only non-whitespace characters. +@xref{String Input Conversions}. + +@item @samp{%[} +Matches a string of characters that belong to a specified set. +@xref{String Input Conversions}. + +@item @samp{%c} +Matches a string of one or more characters; the number of characters +read is controlled by the maximum field width given for the conversion. +@xref{String Input Conversions}. + +@item @samp{%p} +Matches a pointer value in the same implementation-defined format used +by the @samp{%p} output conversion for @code{printf}. @xref{Other Input +Conversions}. + +@item @samp{%n} +This conversion doesn't read any characters; it records the number of +characters read so far by this call. @xref{Other Input Conversions}. + +@item @samp{%%} +This matches a literal @samp{%} character in the input stream. No +corresponding argument is used. @xref{Other Input Conversions}. +@end table + +If the syntax of a conversion specification is invalid, the behavior is +undefined. If there aren't enough function arguments provided to supply +addresses for all the conversion specifications in the template strings +that perform assignments, or if the arguments are not of the correct +types, the behavior is also undefined. On the other hand, extra +arguments are simply ignored. + +@node Numeric Input Conversions +@subsection Numeric Input Conversions + +This section describes the @code{scanf} conversions for reading numeric +values. + +The @samp{%d} conversion matches an optionally signed integer in decimal +radix. The syntax that is recognized is the same as that for the +@code{strtol} function (@pxref{Parsing of Integers}) with the value +@code{10} for the @var{base} argument. + +The @samp{%i} conversion matches an optionally signed integer in any of +the formats that the C language defines for specifying an integer +constant. The syntax that is recognized is the same as that for the +@code{strtol} function (@pxref{Parsing of Integers}) with the value +@code{0} for the @var{base} argument. (You can print integers in this +syntax with @code{printf} by using the @samp{#} flag character with the +@samp{%x}, @samp{%o}, or @samp{%d} conversion. @xref{Integer Conversions}.) + +For example, any of the strings @samp{10}, @samp{0xa}, or @samp{012} +could be read in as integers under the @samp{%i} conversion. Each of +these specifies a number with decimal value @code{10}. + +The @samp{%o}, @samp{%u}, and @samp{%x} conversions match unsigned +integers in octal, decimal, and hexadecimal radices, respectively. The +syntax that is recognized is the same as that for the @code{strtoul} +function (@pxref{Parsing of Integers}) with the appropriate value +(@code{8}, @code{10}, or @code{16}) for the @var{base} argument. + +The @samp{%X} conversion is identical to the @samp{%x} conversion. They +both permit either uppercase or lowercase letters to be used as digits. + +The default type of the corresponding argument for the @code{%d} and +@code{%i} conversions is @code{int *}, and @code{unsigned int *} for the +other integer conversions. You can use the following type modifiers to +specify other sizes of integer: + +@table @samp +@item h +Specifies that the argument is a @code{short int *} or @code{unsigned +short int *}. + +@item l +Specifies that the argument is a @code{long int *} or @code{unsigned +long int *}. Two @samp{l} characters is like the @samp{L} modifier, below. + +@need 100 +@item ll +@itemx L +@itemx q +Specifies that the argument is a @code{long long int *} or @code{unsigned long long int *}. (The @code{long long} type is an extension supported by the +GNU C compiler. For systems that don't provide extra-long integers, this +is the same as @code{long int}.) + +The @samp{q} modifier is another name for the same thing, which comes +from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad'' +@code{int}. +@end table + +All of the @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, and @samp{%G} +input conversions are interchangeable. They all match an optionally +signed floating point number, in the same syntax as for the +@code{strtod} function (@pxref{Parsing of Floats}). + +For the floating-point input conversions, the default argument type is +@code{float *}. (This is different from the corresponding output +conversions, where the default type is @code{double}; remember that +@code{float} arguments to @code{printf} are converted to @code{double} +by the default argument promotions, but @code{float *} arguments are +not promoted to @code{double *}.) You can specify other sizes of float +using these type modifiers: + +@table @samp +@item l +Specifies that the argument is of type @code{double *}. + +@item L +Specifies that the argument is of type @code{long double *}. +@end table + +@node String Input Conversions +@subsection String Input Conversions + +This section describes the @code{scanf} input conversions for reading +string and character values: @samp{%s}, @samp{%[}, and @samp{%c}. + +You have two options for how to receive the input from these +conversions: + +@itemize @bullet +@item +Provide a buffer to store it in. This is the default. You +should provide an argument of type @code{char *}. + +@strong{Warning:} To make a robust program, you must make sure that the +input (plus its terminating null) cannot possibly exceed the size of the +buffer you provide. In general, the only way to do this is to specify a +maximum field width one less than the buffer size. @strong{If you +provide the buffer, always specify a maximum field width to prevent +overflow.} + +@item +Ask @code{scanf} to allocate a big enough buffer, by specifying the +@samp{a} flag character. This is a GNU extension. You should provide +an argument of type @code{char **} for the buffer address to be stored +in. @xref{Dynamic String Input}. +@end itemize + +The @samp{%c} conversion is the simplest: it matches a fixed number of +characters, always. The maximum field with says how many characters to +read; if you don't specify the maximum, the default is 1. This +conversion doesn't append a null character to the end of the text it +reads. It also does not skip over initial whitespace characters. It +reads precisely the next @var{n} characters, and fails if it cannot get +that many. Since there is always a maximum field width with @samp{%c} +(whether specified, or 1 by default), you can always prevent overflow by +making the buffer long enough. + +The @samp{%s} conversion matches a string of non-whitespace characters. +It skips and discards initial whitespace, but stops when it encounters +more whitespace after having read something. It stores a null character +at the end of the text that it reads. + +For example, reading the input: + +@smallexample + hello, world +@end smallexample + +@noindent +with the conversion @samp{%10c} produces @code{" hello, wo"}, but +reading the same input with the conversion @samp{%10s} produces +@code{"hello,"}. + +@strong{Warning:} If you do not specify a field width for @samp{%s}, +then the number of characters read is limited only by where the next +whitespace character appears. This almost certainly means that invalid +input can make your program crash---which is a bug. + +To read in characters that belong to an arbitrary set of your choice, +use the @samp{%[} conversion. You specify the set between the @samp{[} +character and a following @samp{]} character, using the same syntax used +in regular expressions. As special cases: + +@itemize @bullet +@item +A literal @samp{]} character can be specified as the first character +of the set. + +@item +An embedded @samp{-} character (that is, one that is not the first or +last character of the set) is used to specify a range of characters. + +@item +If a caret character @samp{^} immediately follows the initial @samp{[}, +then the set of allowed input characters is the everything @emph{except} +the characters listed. +@end itemize + +The @samp{%[} conversion does not skip over initial whitespace +characters. + +Here are some examples of @samp{%[} conversions and what they mean: + +@table @samp +@item %25[1234567890] +Matches a string of up to 25 digits. + +@item %25[][] +Matches a string of up to 25 square brackets. + +@item %25[^ \f\n\r\t\v] +Matches a string up to 25 characters long that doesn't contain any of +the standard whitespace characters. This is slightly different from +@samp{%s}, because if the input begins with a whitespace character, +@samp{%[} reports a matching failure while @samp{%s} simply discards the +initial whitespace. + +@item %25[a-z] +Matches up to 25 lowercase characters. +@end table + +One more reminder: the @samp{%s} and @samp{%[} conversions are +@strong{dangerous} if you don't specify a maximum width or use the +@samp{a} flag, because input too long would overflow whatever buffer you +have provided for it. No matter how long your buffer is, a user could +supply input that is longer. A well-written program reports invalid +input with a comprehensible error message, not with a crash. + +@node Dynamic String Input +@subsection Dynamically Allocating String Conversions + +A GNU extension to formatted input lets you safely read a string with no +maximum size. Using this feature, you don't supply a buffer; instead, +@code{scanf} allocates a buffer big enough to hold the data and gives +you its address. To use this feature, write @samp{a} as a flag +character, as in @samp{%as} or @samp{%a[0-9a-z]}. + +The pointer argument you supply for where to store the input should have +type @code{char **}. The @code{scanf} function allocates a buffer and +stores its address in the word that the argument points to. You should +free the buffer with @code{free} when you no longer need it. + +Here is an example of using the @samp{a} flag with the @samp{%[@dots{}]} +conversion specification to read a ``variable assignment'' of the form +@samp{@var{variable} = @var{value}}. + +@smallexample +@{ + char *variable, *value; + + if (2 > scanf ("%a[a-zA-Z0-9] = %a[^\n]\n", + &variable, &value)) + @{ + invalid_input_error (); + return 0; + @} + + @dots{} +@} +@end smallexample + +@node Other Input Conversions +@subsection Other Input Conversions + +This section describes the miscellaneous input conversions. + +The @samp{%p} conversion is used to read a pointer value. It recognizes +the same syntax as is used by the @samp{%p} output conversion for +@code{printf} (@pxref{Other Output Conversions}); that is, a hexadecimal +number just as the @samp{%x} conversion accepts. The corresponding +argument should be of type @code{void **}; that is, the address of a +place to store a pointer. + +The resulting pointer value is not guaranteed to be valid if it was not +originally written during the same program execution that reads it in. + +The @samp{%n} conversion produces the number of characters read so far +by this call. The corresponding argument should be of type @code{int *}. +This conversion works in the same way as the @samp{%n} conversion for +@code{printf}; see @ref{Other Output Conversions}, for an example. + +The @samp{%n} conversion is the only mechanism for determining the +success of literal matches or conversions with suppressed assignments. +If the @samp{%n} follows the locus of a matching failure, then no value +is stored for it since @code{scanf} returns before processing the +@samp{%n}. If you store @code{-1} in that argument slot before calling +@code{scanf}, the presence of @code{-1} after @code{scanf} indicates an +error occurred before the @samp{%n} was reached. + +Finally, the @samp{%%} conversion matches a literal @samp{%} character +in the input stream, without using an argument. This conversion does +not permit any flags, field width, or type modifier to be specified. + +@node Formatted Input Functions +@subsection Formatted Input Functions + +Here are the descriptions of the functions for performing formatted +input. +Prototypes for these functions are in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int scanf (const char *@var{template}, @dots{}) +The @code{scanf} function reads formatted input from the stream +@code{stdin} under the control of the template string @var{template}. +The optional arguments are pointers to the places which receive the +resulting values. + +The return value is normally the number of successful assignments. If +an end-of-file condition is detected before any matches are performed +(including matches against whitespace and literal characters in the +template), then @code{EOF} is returned. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int fscanf (FILE *@var{stream}, const char *@var{template}, @dots{}) +This function is just like @code{scanf}, except that the input is read +from the stream @var{stream} instead of @code{stdin}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{}) +This is like @code{scanf}, except that the characters are taken from the +null-terminated string @var{s} instead of from a stream. Reaching the +end of the string is treated as an end-of-file condition. + +The behavior of this function is undefined if copying takes place +between objects that overlap---for example, if @var{s} is also given +as an argument to receive a string read under control of the @samp{%s} +conversion. +@end deftypefun + +@node Variable Arguments Input +@subsection Variable Arguments Input Functions + +The functions @code{vscanf} and friends are provided so that you can +define your own variadic @code{scanf}-like functions that make use of +the same internals as the built-in formatted output functions. +These functions are analogous to the @code{vprintf} series of output +functions. @xref{Variable Arguments Output}, for important +information on how to use them. + +@strong{Portability Note:} The functions listed in this section are GNU +extensions. + +@comment stdio.h +@comment GNU +@deftypefun int vscanf (const char *@var{template}, va_list @var{ap}) +This function is similar to @code{scanf} except that, instead of taking +a variable number of arguments directly, it takes an argument list +pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}). +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int vfscanf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap}) +This is the equivalent of @code{fscanf} with the variable argument list +specified directly as for @code{vscanf}. +@end deftypefun + +@comment stdio.h +@comment GNU +@deftypefun int vsscanf (const char *@var{s}, const char *@var{template}, va_list @var{ap}) +This is the equivalent of @code{sscanf} with the variable argument list +specified directly as for @code{vscanf}. +@end deftypefun + +In GNU C, there is a special construct you can use to let the compiler +know that a function uses a @code{scanf}-style format string. Then it +can check the number and types of arguments in each call to the +function, and warn you when they do not match the format string. +@xref{Function Attributes, , Declaring Attributes of Functions, +gcc.info, Using GNU CC}, for details. + +@node EOF and Errors +@section End-Of-File and Errors + +@cindex end of file, on a stream +Many of the functions described in this chapter return the value of the +macro @code{EOF} to indicate unsuccessful completion of the operation. +Since @code{EOF} is used to report both end of file and random errors, +it's often better to use the @code{feof} function to check explicitly +for end of file and @code{ferror} to check for errors. These functions +check indicators that are part of the internal state of the stream +object, indicators set if the appropriate condition was detected by a +previous I/O operation on that stream. + +These symbols are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypevr Macro int EOF +This macro is an integer value that is returned by a number of functions +to indicate an end-of-file condition, or some other error situation. +With the GNU library, @code{EOF} is @code{-1}. In other libraries, its +value may be some other negative number. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypefun void clearerr (FILE *@var{stream}) +This function clears the end-of-file and error indicators for the +stream @var{stream}. + +The file positioning functions (@pxref{File Positioning}) also clear the +end-of-file indicator for the stream. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int feof (FILE *@var{stream}) +The @code{feof} function returns nonzero if and only if the end-of-file +indicator for the stream @var{stream} is set. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int ferror (FILE *@var{stream}) +The @code{ferror} function returns nonzero if and only if the error +indicator for the stream @var{stream} is set, indicating that an error +has occurred on a previous operation on the stream. +@end deftypefun + +In addition to setting the error indicator associated with the stream, +the functions that operate on streams also set @code{errno} in the same +way as the corresponding low-level functions that operate on file +descriptors. For example, all of the functions that perform output to a +stream---such as @code{fputc}, @code{printf}, and @code{fflush}---are +implemented in terms of @code{write}, and all of the @code{errno} error +conditions defined for @code{write} are meaningful for these functions. +For more information about the descriptor-level I/O functions, see +@ref{Low-Level I/O}. + +@node Binary Streams +@section Text and Binary Streams + +The GNU system and other POSIX-compatible operating systems organize all +files as uniform sequences of characters. However, some other systems +make a distinction between files containing text and files containing +binary data, and the input and output facilities of ANSI C provide for +this distinction. This section tells you how to write programs portable +to such systems. + +@cindex text stream +@cindex binary stream +When you open a stream, you can specify either a @dfn{text stream} or a +@dfn{binary stream}. You indicate that you want a binary stream by +specifying the @samp{b} modifier in the @var{opentype} argument to +@code{fopen}; see @ref{Opening Streams}. Without this +option, @code{fopen} opens the file as a text stream. + +Text and binary streams differ in several ways: + +@itemize @bullet +@item +The data read from a text stream is divided into @dfn{lines} which are +terminated by newline (@code{'\n'}) characters, while a binary stream is +simply a long series of characters. A text stream might on some systems +fail to handle lines more than 254 characters long (including the +terminating newline character). +@cindex lines (in a text file) + +@item +On some systems, text files can contain only printing characters, +horizontal tab characters, and newlines, and so text streams may not +support other characters. However, binary streams can handle any +character value. + +@item +Space characters that are written immediately preceding a newline +character in a text stream may disappear when the file is read in again. + +@item +More generally, there need not be a one-to-one mapping between +characters that are read from or written to a text stream, and the +characters in the actual file. +@end itemize + +Since a binary stream is always more capable and more predictable than a +text stream, you might wonder what purpose text streams serve. Why not +simply always use binary streams? The answer is that on these operating +systems, text and binary streams use different file formats, and the +only way to read or write ``an ordinary file of text'' that can work +with other text-oriented programs is through a text stream. + +In the GNU library, and on all POSIX systems, there is no difference +between text streams and binary streams. When you open a stream, you +get the same kind of stream regardless of whether you ask for binary. +This stream can handle any file content, and has none of the +restrictions that text streams sometimes have. + +@node File Positioning +@section File Positioning +@cindex file positioning on a stream +@cindex positioning a stream +@cindex seeking on a stream + +The @dfn{file position} of a stream describes where in the file the +stream is currently reading or writing. I/O on the stream advances the +file position through the file. In the GNU system, the file position is +represented as an integer, which counts the number of bytes from the +beginning of the file. @xref{File Position}. + +During I/O to an ordinary disk file, you can change the file position +whenever you wish, so as to read or write any portion of the file. Some +other kinds of files may also permit this. Files which support changing +the file position are sometimes referred to as @dfn{random-access} +files. + +You can use the functions in this section to examine or modify the file +position indicator associated with a stream. The symbols listed below +are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun {long int} ftell (FILE *@var{stream}) +This function returns the current file position of the stream +@var{stream}. + +This function can fail if the stream doesn't support file positioning, +or if the file position can't be represented in a @code{long int}, and +possibly for other reasons as well. If a failure occurs, a value of +@code{-1} is returned. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence}) +The @code{fseek} function is used to change the file position of the +stream @var{stream}. The value of @var{whence} must be one of the +constants @code{SEEK_SET}, @code{SEEK_CUR}, or @code{SEEK_END}, to +indicate whether the @var{offset} is relative to the beginning of the +file, the current file position, or the end of the file, respectively. + +This function returns a value of zero if the operation was successful, +and a nonzero value to indicate failure. A successful call also clears +the end-of-file indicator of @var{stream} and discards any characters +that were ``pushed back'' by the use of @code{ungetc}. + +@code{fseek} either flushes any buffered output before setting the file +position or else remembers it so it will be written later in its proper +place in the file. +@end deftypefun + +@strong{Portability Note:} In non-POSIX systems, @code{ftell} and +@code{fseek} might work reliably only on binary streams. @xref{Binary +Streams}. + +The following symbolic constants are defined for use as the @var{whence} +argument to @code{fseek}. They are also used with the @code{lseek} +function (@pxref{I/O Primitives}) and to specify offsets for file locks +(@pxref{Control Operations}). + +@comment stdio.h +@comment ANSI +@deftypevr Macro int SEEK_SET +This is an integer constant which, when used as the @var{whence} +argument to the @code{fseek} function, specifies that the offset +provided is relative to the beginning of the file. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int SEEK_CUR +This is an integer constant which, when used as the @var{whence} +argument to the @code{fseek} function, specifies that the offset +provided is relative to the current file position. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int SEEK_END +This is an integer constant which, when used as the @var{whence} +argument to the @code{fseek} function, specifies that the offset +provided is relative to the end of the file. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypefun void rewind (FILE *@var{stream}) +The @code{rewind} function positions the stream @var{stream} at the +begining of the file. It is equivalent to calling @code{fseek} on the +@var{stream} with an @var{offset} argument of @code{0L} and a +@var{whence} argument of @code{SEEK_SET}, except that the return +value is discarded and the error indicator for the stream is reset. +@end deftypefun + +These three aliases for the @samp{SEEK_@dots{}} constants exist for the +sake of compatibility with older BSD systems. They are defined in two +different header files: @file{fcntl.h} and @file{sys/file.h}. + +@table @code +@comment sys/file.h +@comment BSD +@item L_SET +@vindex L_SET +An alias for @code{SEEK_SET}. + +@comment sys/file.h +@comment BSD +@item L_INCR +@vindex L_INCR +An alias for @code{SEEK_CUR}. + +@comment sys/file.h +@comment BSD +@item L_XTND +@vindex L_XTND +An alias for @code{SEEK_END}. +@end table + +@node Portable Positioning +@section Portable File-Position Functions + +On the GNU system, the file position is truly a character count. You +can specify any character count value as an argument to @code{fseek} and +get reliable results for any random access file. However, some ANSI C +systems do not represent file positions in this way. + +On some systems where text streams truly differ from binary streams, it +is impossible to represent the file position of a text stream as a count +of characters from the beginning of the file. For example, the file +position on some systems must encode both a record offset within the +file, and a character offset within the record. + +As a consequence, if you want your programs to be portable to these +systems, you must observe certain rules: + +@itemize @bullet +@item +The value returned from @code{ftell} on a text stream has no predictable +relationship to the number of characters you have read so far. The only +thing you can rely on is that you can use it subsequently as the +@var{offset} argument to @code{fseek} to move back to the same file +position. + +@item +In a call to @code{fseek} on a text stream, either the @var{offset} must +either be zero; or @var{whence} must be @code{SEEK_SET} and the +@var{offset} must be the result of an earlier call to @code{ftell} on +the same stream. + +@item +The value of the file position indicator of a text stream is undefined +while there are characters that have been pushed back with @code{ungetc} +that haven't been read or discarded. @xref{Unreading}. +@end itemize + +But even if you observe these rules, you may still have trouble for long +files, because @code{ftell} and @code{fseek} use a @code{long int} value +to represent the file position. This type may not have room to encode +all the file positions in a large file. + +So if you do want to support systems with peculiar encodings for the +file positions, it is better to use the functions @code{fgetpos} and +@code{fsetpos} instead. These functions represent the file position +using the data type @code{fpos_t}, whose internal representation varies +from system to system. + +These symbols are declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftp {Data Type} fpos_t +This is the type of an object that can encode information about the +file position of a stream, for use by the functions @code{fgetpos} and +@code{fsetpos}. + +In the GNU system, @code{fpos_t} is equivalent to @code{off_t} or +@code{long int}. In other systems, it might have a different internal +representation. +@end deftp + +@comment stdio.h +@comment ANSI +@deftypefun int fgetpos (FILE *@var{stream}, fpos_t *@var{position}) +This function stores the value of the file position indicator for the +stream @var{stream} in the @code{fpos_t} object pointed to by +@var{position}. If successful, @code{fgetpos} returns zero; otherwise +it returns a nonzero value and stores an implementation-defined positive +value in @code{errno}. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypefun int fsetpos (FILE *@var{stream}, const fpos_t @var{position}) +This function sets the file position indicator for the stream @var{stream} +to the position @var{position}, which must have been set by a previous +call to @code{fgetpos} on the same stream. If successful, @code{fsetpos} +clears the end-of-file indicator on the stream, discards any characters +that were ``pushed back'' by the use of @code{ungetc}, and returns a value +of zero. Otherwise, @code{fsetpos} returns a nonzero value and stores +an implementation-defined positive value in @code{errno}. +@end deftypefun + +@node Stream Buffering +@section Stream Buffering + +@cindex buffering of streams +Characters that are written to a stream are normally accumulated and +transmitted asynchronously to the file in a block, instead of appearing +as soon as they are output by the application program. Similarly, +streams often retrieve input from the host environment in blocks rather +than on a character-by-character basis. This is called @dfn{buffering}. + +If you are writing programs that do interactive input and output using +streams, you need to understand how buffering works when you design the +user interface to your program. Otherwise, you might find that output +(such as progress or prompt messages) doesn't appear when you intended +it to, or other unexpected behavior. + +This section deals only with controlling when characters are transmitted +between the stream and the file or device, and @emph{not} with how +things like echoing, flow control, and the like are handled on specific +classes of devices. For information on common control operations on +terminal devices, see @ref{Low-Level Terminal Interface}. + +You can bypass the stream buffering facilities altogether by using the +low-level input and output functions that operate on file descriptors +instead. @xref{Low-Level I/O}. + +@menu +* Buffering Concepts:: Terminology is defined here. +* Flushing Buffers:: How to ensure that output buffers are flushed. +* Controlling Buffering:: How to specify what kind of buffering to use. +@end menu + +@node Buffering Concepts +@subsection Buffering Concepts + +There are three different kinds of buffering strategies: + +@itemize @bullet +@item +Characters written to or read from an @dfn{unbuffered} stream are +transmitted individually to or from the file as soon as possible. +@cindex unbuffered stream + +@item +Characters written to a @dfn{line buffered} stream are transmitted to +the file in blocks when a newline character is encountered. +@cindex line buffered stream + +@item +Characters written to or read from a @dfn{fully buffered} stream are +transmitted to or from the file in blocks of arbitrary size. +@cindex fully buffered stream +@end itemize + +Newly opened streams are normally fully buffered, with one exception: a +stream connected to an interactive device such as a terminal is +initially line buffered. @xref{Controlling Buffering}, for information +on how to select a different kind of buffering. Usually the automatic +selection gives you the most convenient kind of buffering for the file +or device you open. + +The use of line buffering for interactive devices implies that output +messages ending in a newline will appear immediately---which is usually +what you want. Output that doesn't end in a newline might or might not +show up immediately, so if you want them to appear immediately, you +should flush buffered output explicitly with @code{fflush}, as described +in @ref{Flushing Buffers}. + +@node Flushing Buffers +@subsection Flushing Buffers + +@cindex flushing a stream +@dfn{Flushing} output on a buffered stream means transmitting all +accumulated characters to the file. There are many circumstances when +buffered output on a stream is flushed automatically: + +@itemize @bullet +@item +When you try to do output and the output buffer is full. + +@item +When the stream is closed. @xref{Closing Streams}. + +@item +When the program terminates by calling @code{exit}. +@xref{Normal Termination}. + +@item +When a newline is written, if the stream is line buffered. + +@item +Whenever an input operation on @emph{any} stream actually reads data +from its file. +@end itemize + +If you want to flush the buffered output at another time, call +@code{fflush}, which is declared in the header file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int fflush (FILE *@var{stream}) +This function causes any buffered output on @var{stream} to be delivered +to the file. If @var{stream} is a null pointer, then +@code{fflush} causes buffered output on @emph{all} open output streams +to be flushed. + +This function returns @code{EOF} if a write error occurs, or zero +otherwise. +@end deftypefun + +@strong{Compatibility Note:} Some brain-damaged operating systems have +been known to be so thoroughly fixated on line-oriented input and output +that flushing a line buffered stream causes a newline to be written! +Fortunately, this ``feature'' seems to be becoming less common. You do +not need to worry about this in the GNU system. + + +@node Controlling Buffering +@subsection Controlling Which Kind of Buffering + +After opening a stream (but before any other operations have been +performed on it), you can explicitly specify what kind of buffering you +want it to have using the @code{setvbuf} function. +@cindex buffering, controlling + +The facilities listed in this section are declared in the header +file @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment ANSI +@deftypefun int setvbuf (FILE *@var{stream}, char *@var{buf}, int @var{mode}, size_t @var{size}) +This function is used to specify that the stream @var{stream} should +have the buffering mode @var{mode}, which can be either @code{_IOFBF} +(for full buffering), @code{_IOLBF} (for line buffering), or +@code{_IONBF} (for unbuffered input/output). + +If you specify a null pointer as the @var{buf} argument, then @code{setvbuf} +allocates a buffer itself using @code{malloc}. This buffer will be freed +when you close the stream. + +Otherwise, @var{buf} should be a character array that can hold at least +@var{size} characters. You should not free the space for this array as +long as the stream remains open and this array remains its buffer. You +should usually either allocate it statically, or @code{malloc} +(@pxref{Unconstrained Allocation}) the buffer. Using an automatic array +is not a good idea unless you close the file before exiting the block +that declares the array. + +While the array remains a stream buffer, the stream I/O functions will +use the buffer for their internal purposes. You shouldn't try to access +the values in the array directly while the stream is using it for +buffering. + +The @code{setvbuf} function returns zero on success, or a nonzero value +if the value of @var{mode} is not valid or if the request could not +be honored. +@end deftypefun + +@comment stdio.h +@comment ANSI +@deftypevr Macro int _IOFBF +The value of this macro is an integer constant expression that can be +used as the @var{mode} argument to the @code{setvbuf} function to +specify that the stream should be fully buffered. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int _IOLBF +The value of this macro is an integer constant expression that can be +used as the @var{mode} argument to the @code{setvbuf} function to +specify that the stream should be line buffered. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int _IONBF +The value of this macro is an integer constant expression that can be +used as the @var{mode} argument to the @code{setvbuf} function to +specify that the stream should be unbuffered. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypevr Macro int BUFSIZ +The value of this macro is an integer constant expression that is good +to use for the @var{size} argument to @code{setvbuf}. This value is +guaranteed to be at least @code{256}. + +The value of @code{BUFSIZ} is chosen on each system so as to make stream +I/O efficient. So it is a good idea to use @code{BUFSIZ} as the size +for the buffer when you call @code{setvbuf}. + +Actually, you can get an even better value to use for the buffer size +by means of the @code{fstat} system call: it is found in the +@code{st_blksize} field of the file attributes. @xref{Attribute Meanings}. + +Sometimes people also use @code{BUFSIZ} as the allocation size of +buffers used for related purposes, such as strings used to receive a +line of input with @code{fgets} (@pxref{Character Input}). There is no +particular reason to use @code{BUFSIZ} for this instead of any other +integer, except that it might lead to doing I/O in chunks of an +efficient size. +@end deftypevr + +@comment stdio.h +@comment ANSI +@deftypefun void setbuf (FILE *@var{stream}, char *@var{buf}) +If @var{buf} is a null pointer, the effect of this function is +equivalent to calling @code{setvbuf} with a @var{mode} argument of +@code{_IONBF}. Otherwise, it is equivalent to calling @code{setvbuf} +with @var{buf}, and a @var{mode} of @code{_IOFBF} and a @var{size} +argument of @code{BUFSIZ}. + +The @code{setbuf} function is provided for compatibility with old code; +use @code{setvbuf} in all new programs. +@end deftypefun + +@comment stdio.h +@comment BSD +@deftypefun void setbuffer (FILE *@var{stream}, char *@var{buf}, size_t @var{size}) +If @var{buf} is a null pointer, this function makes @var{stream} unbuffered. +Otherwise, it makes @var{stream} fully buffered using @var{buf} as the +buffer. The @var{size} argument specifies the length of @var{buf}. + +This function is provided for compatibility with old BSD code. Use +@code{setvbuf} instead. +@end deftypefun + +@comment stdio.h +@comment BSD +@deftypefun void setlinebuf (FILE *@var{stream}) +This function makes @var{stream} be line buffered, and allocates the +buffer for you. + +This function is provided for compatibility with old BSD code. Use +@code{setvbuf} instead. +@end deftypefun + +@node Other Kinds of Streams +@section Other Kinds of Streams + +The GNU library provides ways for you to define additional kinds of +streams that do not necessarily correspond to an open file. + +One such type of stream takes input from or writes output to a string. +These kinds of streams are used internally to implement the +@code{sprintf} and @code{sscanf} functions. You can also create such a +stream explicitly, using the functions described in @ref{String Streams}. + +More generally, you can define streams that do input/output to arbitrary +objects using functions supplied by your program. This protocol is +discussed in @ref{Custom Streams}. + +@strong{Portability Note:} The facilities described in this section are +specific to GNU. Other systems or C implementations might or might not +provide equivalent functionality. + +@menu +* String Streams:: Streams that get data from or put data in + a string or memory buffer. +* Obstack Streams:: Streams that store data in an obstack. +* Custom Streams:: Defining your own streams with an arbitrary + input data source and/or output data sink. +@end menu + +@node String Streams +@subsection String Streams + +@cindex stream, for I/O to a string +@cindex string stream +The @code{fmemopen} and @code{open_memstream} functions allow you to do +I/O to a string or memory buffer. These facilities are declared in +@file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment GNU +@deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype}) +This function opens a stream that allows the access specified by the +@var{opentype} argument, that reads from or writes to the buffer specified +by the argument @var{buf}. This array must be at least @var{size} bytes long. + +If you specify a null pointer as the @var{buf} argument, @code{fmemopen} +dynamically allocates (as with @code{malloc}; @pxref{Unconstrained +Allocation}) an array @var{size} bytes long. This is really only useful +if you are going to write things to the buffer and then read them back +in again, because you have no way of actually getting a pointer to the +buffer (for this, try @code{open_memstream}, below). The buffer is +freed when the stream is open. + +The argument @var{opentype} is the same as in @code{fopen} +(@xref{Opening Streams}). If the @var{opentype} specifies +append mode, then the initial file position is set to the first null +character in the buffer. Otherwise the initial file position is at the +beginning of the buffer. + +When a stream open for writing is flushed or closed, a null character +(zero byte) is written at the end of the buffer if it fits. You +should add an extra byte to the @var{size} argument to account for this. +Attempts to write more than @var{size} bytes to the buffer result +in an error. + +For a stream open for reading, null characters (zero bytes) in the +buffer do not count as ``end of file''. Read operations indicate end of +file only when the file position advances past @var{size} bytes. So, if +you want to read characters from a null-terminated string, you should +supply the length of the string as the @var{size} argument. +@end deftypefun + +Here is an example of using @code{fmemopen} to create a stream for +reading from a string: + +@smallexample +@include memopen.c.texi +@end smallexample + +This program produces the following output: + +@smallexample +Got f +Got o +Got o +Got b +Got a +Got r +@end smallexample + +@comment stdio.h +@comment GNU +@deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc}) +This function opens a stream for writing to a buffer. The buffer is +allocated dynamically (as with @code{malloc}; @pxref{Unconstrained +Allocation}) and grown as necessary. + +When the stream is closed with @code{fclose} or flushed with +@code{fflush}, the locations @var{ptr} and @var{sizeloc} are updated to +contain the pointer to the buffer and its size. The values thus stored +remain valid only as long as no further output on the stream takes +place. If you do more output, you must flush the stream again to store +new values before you use them again. + +A null character is written at the end of the buffer. This null character +is @emph{not} included in the size value stored at @var{sizeloc}. + +You can move the stream's file position with @code{fseek} (@pxref{File +Positioning}). Moving the file position past the end of the data +already written fills the intervening space with zeroes. +@end deftypefun + +Here is an example of using @code{open_memstream}: + +@smallexample +@include memstrm.c.texi +@end smallexample + +This program produces the following output: + +@smallexample +buf = `hello', size = 5 +buf = `hello, world', size = 12 +@end smallexample + +@c @group Invalid outside @example. +@node Obstack Streams +@subsection Obstack Streams + +You can open an output stream that puts it data in an obstack. +@xref{Obstacks}. + +@comment stdio.h +@comment GNU +@deftypefun {FILE *} open_obstack_stream (struct obstack *@var{obstack}) +This function opens a stream for writing data into the obstack @var{obstack}. +This starts an object in the obstack and makes it grow as data is +written (@pxref{Growing Objects}). +@c @end group Doubly invalid because not nested right. + +Calling @code{fflush} on this stream updates the current size of the +object to match the amount of data that has been written. After a call +to @code{fflush}, you can examine the object temporarily. + +You can move the file position of an obstack stream with @code{fseek} +(@pxref{File Positioning}). Moving the file position past the end of +the data written fills the intervening space with zeros. + +To make the object permanent, update the obstack with @code{fflush}, and +then use @code{obstack_finish} to finalize the object and get its address. +The following write to the stream starts a new object in the obstack, +and later writes add to that object until you do another @code{fflush} +and @code{obstack_finish}. + +But how do you find out how long the object is? You can get the length +in bytes by calling @code{obstack_object_size} (@pxref{Status of an +Obstack}), or you can null-terminate the object like this: + +@smallexample +obstack_1grow (@var{obstack}, 0); +@end smallexample + +Whichever one you do, you must do it @emph{before} calling +@code{obstack_finish}. (You can do both if you wish.) +@end deftypefun + +Here is a sample function that uses @code{open_obstack_stream}: + +@smallexample +char * +make_message_string (const char *a, int b) +@{ + FILE *stream = open_obstack_stream (&message_obstack); + output_task (stream); + fprintf (stream, ": "); + fprintf (stream, a, b); + fprintf (stream, "\n"); + fclose (stream); + obstack_1grow (&message_obstack, 0); + return obstack_finish (&message_obstack); +@} +@end smallexample + +@node Custom Streams +@subsection Programming Your Own Custom Streams +@cindex custom streams +@cindex programming your own streams + +This section describes how you can make a stream that gets input from an +arbitrary data source or writes output to an arbitrary data sink +programmed by you. We call these @dfn{custom streams}. + +@c !!! this does not talk at all about the higher-level hooks + +@menu +* Streams and Cookies:: The @dfn{cookie} records where to fetch or + store data that is read or written. +* Hook Functions:: How you should define the four @dfn{hook + functions} that a custom stream needs. +@end menu + +@node Streams and Cookies +@subsubsection Custom Streams and Cookies +@cindex cookie, for custom stream + +Inside every custom stream is a special object called the @dfn{cookie}. +This is an object supplied by you which records where to fetch or store +the data read or written. It is up to you to define a data type to use +for the cookie. The stream functions in the library never refer +directly to its contents, and they don't even know what the type is; +they record its address with type @code{void *}. + +To implement a custom stream, you must specify @emph{how} to fetch or +store the data in the specified place. You do this by defining +@dfn{hook functions} to read, write, change ``file position'', and close +the stream. All four of these functions will be passed the stream's +cookie so they can tell where to fetch or store the data. The library +functions don't know what's inside the cookie, but your functions will +know. + +When you create a custom stream, you must specify the cookie pointer, +and also the four hook functions stored in a structure of type +@code{cookie_io_functions_t}. + +These facilities are declared in @file{stdio.h}. +@pindex stdio.h + +@comment stdio.h +@comment GNU +@deftp {Data Type} {cookie_io_functions_t} +This is a structure type that holds the functions that define the +communications protocol between the stream and its cookie. It has +the following members: + +@table @code +@item cookie_read_function_t *read +This is the function that reads data from the cookie. If the value is a +null pointer instead of a function, then read operations on ths stream +always return @code{EOF}. + +@item cookie_write_function_t *write +This is the function that writes data to the cookie. If the value is a +null pointer instead of a function, then data written to the stream is +discarded. + +@item cookie_seek_function_t *seek +This is the function that performs the equivalent of file positioning on +the cookie. If the value is a null pointer instead of a function, calls +to @code{fseek} on this stream can only seek to locations within the +buffer; any attempt to seek outside the buffer will return an +@code{ESPIPE} error. + +@item cookie_close_function_t *close +This function performs any appropriate cleanup on the cookie when +closing the stream. If the value is a null pointer instead of a +function, nothing special is done to close the cookie when the stream is +closed. +@end table +@end deftp + +@comment stdio.h +@comment GNU +@deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, cookie_io_functions_t @var{io-functions}) +This function actually creates the stream for communicating with the +@var{cookie} using the functions in the @var{io-functions} argument. +The @var{opentype} argument is interpreted as for @code{fopen}; +see @ref{Opening Streams}. (But note that the ``truncate on +open'' option is ignored.) The new stream is fully buffered. + +The @code{fopencookie} function returns the newly created stream, or a null +pointer in case of an error. +@end deftypefun + +@node Hook Functions +@subsubsection Custom Stream Hook Functions +@cindex hook functions (of custom streams) + +Here are more details on how you should define the four hook functions +that a custom stream needs. + +You should define the function to read data from the cookie as: + +@smallexample +ssize_t @var{reader} (void *@var{cookie}, void *@var{buffer}, size_t @var{size}) +@end smallexample + +This is very similar to the @code{read} function; see @ref{I/O +Primitives}. Your function should transfer up to @var{size} bytes into +the @var{buffer}, and return the number of bytes read, or zero to +indicate end-of-file. You can return a value of @code{-1} to indicate +an error. + +You should define the function to write data to the cookie as: + +@smallexample +ssize_t @var{writer} (void *@var{cookie}, const void *@var{buffer}, size_t @var{size}) +@end smallexample + +This is very similar to the @code{write} function; see @ref{I/O +Primitives}. Your function should transfer up to @var{size} bytes from +the buffer, and return the number of bytes written. You can return a +value of @code{-1} to indicate an error. + +You should define the function to perform seek operations on the cookie +as: + +@smallexample +int @var{seeker} (void *@var{cookie}, fpos_t *@var{position}, int @var{whence}) +@end smallexample + +For this function, the @var{position} and @var{whence} arguments are +interpreted as for @code{fgetpos}; see @ref{Portable Positioning}. In +the GNU library, @code{fpos_t} is equivalent to @code{off_t} or +@code{long int}, and simply represents the number of bytes from the +beginning of the file. + +After doing the seek operation, your function should store the resulting +file position relative to the beginning of the file in @var{position}. +Your function should return a value of @code{0} on success and @code{-1} +to indicate an error. + +You should define the function to do cleanup operations on the cookie +appropriate for closing the stream as: + +@smallexample +int @var{cleaner} (void *@var{cookie}) +@end smallexample + +Your function should return @code{-1} to indicate an error, and @code{0} +otherwise. + +@comment stdio.h +@comment GNU +@deftp {Data Type} cookie_read_function +This is the data type that the read function for a custom stream should have. +If you declare the function as shown above, this is the type it will have. +@end deftp + +@comment stdio.h +@comment GNU +@deftp {Data Type} cookie_write_function +The data type of the write function for a custom stream. +@end deftp + +@comment stdio.h +@comment GNU +@deftp {Data Type} cookie_seek_function +The data type of the seek function for a custom stream. +@end deftp + +@comment stdio.h +@comment GNU +@deftp {Data Type} cookie_close_function +The data type of the close function for a custom stream. +@end deftp + +@ignore +Roland says: + +@quotation +There is another set of functions one can give a stream, the +input-room and output-room functions. These functions must +understand stdio internals. To describe how to use these +functions, you also need to document lots of how stdio works +internally (which isn't relevant for other uses of stdio). +Perhaps I can write an interface spec from which you can write +good documentation. But it's pretty complex and deals with lots +of nitty-gritty details. I think it might be better to let this +wait until the rest of the manual is more done and polished. +@end quotation +@end ignore + +@c ??? This section could use an example. diff --git a/manual/string.texi b/manual/string.texi new file mode 100644 index 0000000000..c638912229 --- /dev/null +++ b/manual/string.texi @@ -0,0 +1,947 @@ +@node String and Array Utilities, Extended Characters, Character Handling, Top +@chapter String and Array Utilities + +Operations on strings (or arrays of characters) are an important part of +many programs. The GNU C library provides an extensive set of string +utility functions, including functions for copying, concatenating, +comparing, and searching strings. Many of these functions can also +operate on arbitrary regions of storage; for example, the @code{memcpy} +function can be used to copy the contents of any kind of array. + +It's fairly common for beginning C programmers to ``reinvent the wheel'' +by duplicating this functionality in their own code, but it pays to +become familiar with the library functions and to make use of them, +since this offers benefits in maintenance, efficiency, and portability. + +For instance, you could easily compare one string to another in two +lines of C code, but if you use the built-in @code{strcmp} function, +you're less likely to make a mistake. And, since these library +functions are typically highly optimized, your program may run faster +too. + +@menu +* Representation of Strings:: Introduction to basic concepts. +* String/Array Conventions:: Whether to use a string function or an + arbitrary array function. +* String Length:: Determining the length of a string. +* Copying and Concatenation:: Functions to copy the contents of strings + and arrays. +* String/Array Comparison:: Functions for byte-wise and character-wise + comparison. +* Collation Functions:: Functions for collating strings. +* Search Functions:: Searching for a specific element or substring. +* Finding Tokens in a String:: Splitting a string into tokens by looking + for delimiters. +@end menu + +@node Representation of Strings, String/Array Conventions, , String and Array Utilities +@section Representation of Strings +@cindex string, representation of + +This section is a quick summary of string concepts for beginning C +programmers. It describes how character strings are represented in C +and some common pitfalls. If you are already familiar with this +material, you can skip this section. + +@cindex string +@cindex null character +A @dfn{string} is an array of @code{char} objects. But string-valued +variables are usually declared to be pointers of type @code{char *}. +Such variables do not include space for the text of a string; that has +to be stored somewhere else---in an array variable, a string constant, +or dynamically allocated memory (@pxref{Memory Allocation}). It's up to +you to store the address of the chosen memory space into the pointer +variable. Alternatively you can store a @dfn{null pointer} in the +pointer variable. The null pointer does not point anywhere, so +attempting to reference the string it points to gets an error. + +By convention, a @dfn{null character}, @code{'\0'}, marks the end of a +string. For example, in testing to see whether the @code{char *} +variable @var{p} points to a null character marking the end of a string, +you can write @code{!*@var{p}} or @code{*@var{p} == '\0'}. + +A null character is quite different conceptually from a null pointer, +although both are represented by the integer @code{0}. + +@cindex string literal +@dfn{String literals} appear in C program source as strings of +characters between double-quote characters (@samp{"}). In ANSI C, +string literals can also be formed by @dfn{string concatenation}: +@code{"a" "b"} is the same as @code{"ab"}. Modification of string +literals is not allowed by the GNU C compiler, because literals +are placed in read-only storage. + +Character arrays that are declared @code{const} cannot be modified +either. It's generally good style to declare non-modifiable string +pointers to be of type @code{const char *}, since this often allows the +C compiler to detect accidental modifications as well as providing some +amount of documentation about what your program intends to do with the +string. + +The amount of memory allocated for the character array may extend past +the null character that normally marks the end of the string. In this +document, the term @dfn{allocation size} is always used to refer to the +total amount of memory allocated for the string, while the term +@dfn{length} refers to the number of characters up to (but not +including) the terminating null character. +@cindex length of string +@cindex allocation size of string +@cindex size of string +@cindex string length +@cindex string allocation + +A notorious source of program bugs is trying to put more characters in a +string than fit in its allocated size. When writing code that extends +strings or moves characters into a pre-allocated array, you should be +very careful to keep track of the length of the text and make explicit +checks for overflowing the array. Many of the library functions +@emph{do not} do this for you! Remember also that you need to allocate +an extra byte to hold the null character that marks the end of the +string. + +@node String/Array Conventions, String Length, Representation of Strings, String and Array Utilities +@section String and Array Conventions + +This chapter describes both functions that work on arbitrary arrays or +blocks of memory, and functions that are specific to null-terminated +arrays of characters. + +Functions that operate on arbitrary blocks of memory have names +beginning with @samp{mem} (such as @code{memcpy}) and invariably take an +argument which specifies the size (in bytes) of the block of memory to +operate on. The array arguments and return values for these functions +have type @code{void *}, and as a matter of style, the elements of these +arrays are referred to as ``bytes''. You can pass any kind of pointer +to these functions, and the @code{sizeof} operator is useful in +computing the value for the size argument. + +In contrast, functions that operate specifically on strings have names +beginning with @samp{str} (such as @code{strcpy}) and look for a null +character to terminate the string instead of requiring an explicit size +argument to be passed. (Some of these functions accept a specified +maximum length, but they also check for premature termination with a +null character.) The array arguments and return values for these +functions have type @code{char *}, and the array elements are referred +to as ``characters''. + +In many cases, there are both @samp{mem} and @samp{str} versions of a +function. The one that is more appropriate to use depends on the exact +situation. When your program is manipulating arbitrary arrays or blocks of +storage, then you should always use the @samp{mem} functions. On the +other hand, when you are manipulating null-terminated strings it is +usually more convenient to use the @samp{str} functions, unless you +already know the length of the string in advance. + +@node String Length, Copying and Concatenation, String/Array Conventions, String and Array Utilities +@section String Length + +You can get the length of a string using the @code{strlen} function. +This function is declared in the header file @file{string.h}. +@pindex string.h + +@comment string.h +@comment ANSI +@deftypefun size_t strlen (const char *@var{s}) +The @code{strlen} function returns the length of the null-terminated +string @var{s}. (In other words, it returns the offset of the terminating +null character within the array.) + +For example, +@smallexample +strlen ("hello, world") + @result{} 12 +@end smallexample + +When applied to a character array, the @code{strlen} function returns +the length of the string stored there, not its allocation size. You can +get the allocation size of the character array that holds a string using +the @code{sizeof} operator: + +@smallexample +char string[32] = "hello, world"; +sizeof (string) + @result{} 32 +strlen (string) + @result{} 12 +@end smallexample +@end deftypefun + +@node Copying and Concatenation, String/Array Comparison, String Length, String and Array Utilities +@section Copying and Concatenation + +You can use the functions described in this section to copy the contents +of strings and arrays, or to append the contents of one string to +another. These functions are declared in the header file +@file{string.h}. +@pindex string.h +@cindex copying strings and arrays +@cindex string copy functions +@cindex array copy functions +@cindex concatenating strings +@cindex string concatenation functions + +A helpful way to remember the ordering of the arguments to the functions +in this section is that it corresponds to an assignment expression, with +the destination array specified to the left of the source array. All +of these functions return the address of the destination array. + +Most of these functions do not work properly if the source and +destination arrays overlap. For example, if the beginning of the +destination array overlaps the end of the source array, the original +contents of that part of the source array may get overwritten before it +is copied. Even worse, in the case of the string functions, the null +character marking the end of the string may be lost, and the copy +function might get stuck in a loop trashing all the memory allocated to +your program. + +All functions that have problems copying between overlapping arrays are +explicitly identified in this manual. In addition to functions in this +section, there are a few others like @code{sprintf} (@pxref{Formatted +Output Functions}) and @code{scanf} (@pxref{Formatted Input +Functions}). + +@comment string.h +@comment ANSI +@deftypefun {void *} memcpy (void *@var{to}, const void *@var{from}, size_t @var{size}) +The @code{memcpy} function copies @var{size} bytes from the object +beginning at @var{from} into the object beginning at @var{to}. The +behavior of this function is undefined if the two arrays @var{to} and +@var{from} overlap; use @code{memmove} instead if overlapping is possible. + +The value returned by @code{memcpy} is the value of @var{to}. + +Here is an example of how you might use @code{memcpy} to copy the +contents of an array: + +@smallexample +struct foo *oldarray, *newarray; +int arraysize; +@dots{} +memcpy (new, old, arraysize * sizeof (struct foo)); +@end smallexample +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {void *} memmove (void *@var{to}, const void *@var{from}, size_t @var{size}) +@code{memmove} copies the @var{size} bytes at @var{from} into the +@var{size} bytes at @var{to}, even if those two blocks of space +overlap. In the case of overlap, @code{memmove} is careful to copy the +original values of the bytes in the block at @var{from}, including those +bytes which also belong to the block at @var{to}. +@end deftypefun + +@comment string.h +@comment SVID +@deftypefun {void *} memccpy (void *@var{to}, const void *@var{from}, int @var{c}, size_t @var{size}) +This function copies no more than @var{size} bytes from @var{from} to +@var{to}, stopping if a byte matching @var{c} is found. The return +value is a pointer into @var{to} one byte past where @var{c} was copied, +or a null pointer if no byte matching @var{c} appeared in the first +@var{size} bytes of @var{from}. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {void *} memset (void *@var{block}, int @var{c}, size_t @var{size}) +This function copies the value of @var{c} (converted to an +@code{unsigned char}) into each of the first @var{size} bytes of the +object beginning at @var{block}. It returns the value of @var{block}. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strcpy (char *@var{to}, const char *@var{from}) +This copies characters from the string @var{from} (up to and including +the terminating null character) into the string @var{to}. Like +@code{memcpy}, this function has undefined results if the strings +overlap. The return value is the value of @var{to}. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strncpy (char *@var{to}, const char *@var{from}, size_t @var{size}) +This function is similar to @code{strcpy} but always copies exactly +@var{size} characters into @var{to}. + +If the length of @var{from} is more than @var{size}, then @code{strncpy} +copies just the first @var{size} characters. Note that in this case +there is no null terminator written into @var{to}. + +If the length of @var{from} is less than @var{size}, then @code{strncpy} +copies all of @var{from}, followed by enough null characters to add up +to @var{size} characters in all. This behavior is rarely useful, but it +is specified by the ANSI C standard. + +The behavior of @code{strncpy} is undefined if the strings overlap. + +Using @code{strncpy} as opposed to @code{strcpy} is a way to avoid bugs +relating to writing past the end of the allocated space for @var{to}. +However, it can also make your program much slower in one common case: +copying a string which is probably small into a potentially large buffer. +In this case, @var{size} may be large, and when it is, @code{strncpy} will +waste a considerable amount of time copying null characters. +@end deftypefun + +@comment string.h +@comment SVID +@deftypefun {char *} strdup (const char *@var{s}) +This function copies the null-terminated string @var{s} into a newly +allocated string. The string is allocated using @code{malloc}; see +@ref{Unconstrained Allocation}. If @code{malloc} cannot allocate space +for the new string, @code{strdup} returns a null pointer. Otherwise it +returns a pointer to the new string. +@end deftypefun + +@comment string.h +@comment Unknown origin +@deftypefun {char *} stpcpy (char *@var{to}, const char *@var{from}) +This function is like @code{strcpy}, except that it returns a pointer to +the end of the string @var{to} (that is, the address of the terminating +null character) rather than the beginning. + +For example, this program uses @code{stpcpy} to concatenate @samp{foo} +and @samp{bar} to produce @samp{foobar}, which it then prints. + +@smallexample +@include stpcpy.c.texi +@end smallexample + +This function is not part of the ANSI or POSIX standards, and is not +customary on Unix systems, but we did not invent it either. Perhaps it +comes from MS-DOG. + +Its behavior is undefined if the strings overlap. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strcat (char *@var{to}, const char *@var{from}) +The @code{strcat} function is similar to @code{strcpy}, except that the +characters from @var{from} are concatenated or appended to the end of +@var{to}, instead of overwriting it. That is, the first character from +@var{from} overwrites the null character marking the end of @var{to}. + +An equivalent definition for @code{strcat} would be: + +@smallexample +char * +strcat (char *to, const char *from) +@{ + strcpy (to + strlen (to), from); + return to; +@} +@end smallexample + +This function has undefined results if the strings overlap. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strncat (char *@var{to}, const char *@var{from}, size_t @var{size}) +This function is like @code{strcat} except that not more than @var{size} +characters from @var{from} are appended to the end of @var{to}. A +single null character is also always appended to @var{to}, so the total +allocated size of @var{to} must be at least @code{@var{size} + 1} bytes +longer than its initial length. + +The @code{strncat} function could be implemented like this: + +@smallexample +@group +char * +strncat (char *to, const char *from, size_t size) +@{ + strncpy (to + strlen (to), from, size); + return to; +@} +@end group +@end smallexample + +The behavior of @code{strncat} is undefined if the strings overlap. +@end deftypefun + +Here is an example showing the use of @code{strncpy} and @code{strncat}. +Notice how, in the call to @code{strncat}, the @var{size} parameter +is computed to avoid overflowing the character array @code{buffer}. + +@smallexample +@include strncat.c.texi +@end smallexample + +@noindent +The output produced by this program looks like: + +@smallexample +hello +hello, wo +@end smallexample + +@comment string.h +@comment BSD +@deftypefun {void *} bcopy (void *@var{from}, const void *@var{to}, size_t @var{size}) +This is a partially obsolete alternative for @code{memmove}, derived from +BSD. Note that it is not quite equivalent to @code{memmove}, because the +arguments are not in the same order. +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun {void *} bzero (void *@var{block}, size_t @var{size}) +This is a partially obsolete alternative for @code{memset}, derived from +BSD. Note that it is not as general as @code{memset}, because the only +value it can store is zero. +@end deftypefun + +@node String/Array Comparison, Collation Functions, Copying and Concatenation, String and Array Utilities +@section String/Array Comparison +@cindex comparing strings and arrays +@cindex string comparison functions +@cindex array comparison functions +@cindex predicates on strings +@cindex predicates on arrays + +You can use the functions in this section to perform comparisons on the +contents of strings and arrays. As well as checking for equality, these +functions can also be used as the ordering functions for sorting +operations. @xref{Searching and Sorting}, for an example of this. + +Unlike most comparison operations in C, the string comparison functions +return a nonzero value if the strings are @emph{not} equivalent rather +than if they are. The sign of the value indicates the relative ordering +of the first characters in the strings that are not equivalent: a +negative value indicates that the first string is ``less'' than the +second, while a positive value indicates that the first string is +``greater''. + +The most common use of these functions is to check only for equality. +This is canonically done with an expression like @w{@samp{! strcmp (s1, s2)}}. + +All of these functions are declared in the header file @file{string.h}. +@pindex string.h + +@comment string.h +@comment ANSI +@deftypefun int memcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size}) +The function @code{memcmp} compares the @var{size} bytes of memory +beginning at @var{a1} against the @var{size} bytes of memory beginning +at @var{a2}. The value returned has the same sign as the difference +between the first differing pair of bytes (interpreted as @code{unsigned +char} objects, then promoted to @code{int}). + +If the contents of the two blocks are equal, @code{memcmp} returns +@code{0}. +@end deftypefun + +On arbitrary arrays, the @code{memcmp} function is mostly useful for +testing equality. It usually isn't meaningful to do byte-wise ordering +comparisons on arrays of things other than bytes. For example, a +byte-wise comparison on the bytes that make up floating-point numbers +isn't likely to tell you anything about the relationship between the +values of the floating-point numbers. + +You should also be careful about using @code{memcmp} to compare objects +that can contain ``holes'', such as the padding inserted into structure +objects to enforce alignment requirements, extra space at the end of +unions, and extra characters at the ends of strings whose length is less +than their allocated size. The contents of these ``holes'' are +indeterminate and may cause strange behavior when performing byte-wise +comparisons. For more predictable results, perform an explicit +component-wise comparison. + +For example, given a structure type definition like: + +@smallexample +struct foo + @{ + unsigned char tag; + union + @{ + double f; + long i; + char *p; + @} value; + @}; +@end smallexample + +@noindent +you are better off writing a specialized comparison function to compare +@code{struct foo} objects instead of comparing them with @code{memcmp}. + +@comment string.h +@comment ANSI +@deftypefun int strcmp (const char *@var{s1}, const char *@var{s2}) +The @code{strcmp} function compares the string @var{s1} against +@var{s2}, returning a value that has the same sign as the difference +between the first differing pair of characters (interpreted as +@code{unsigned char} objects, then promoted to @code{int}). + +If the two strings are equal, @code{strcmp} returns @code{0}. + +A consequence of the ordering used by @code{strcmp} is that if @var{s1} +is an initial substring of @var{s2}, then @var{s1} is considered to be +``less than'' @var{s2}. +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun int strcasecmp (const char *@var{s1}, const char *@var{s2}) +This function is like @code{strcmp}, except that differences in case +are ignored. + +@code{strcasecmp} is derived from BSD. +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun int strncasecmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n}) +This function is like @code{strncmp}, except that differences in case +are ignored. + +@code{strncasecmp} is a GNU extension. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun int strncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{size}) +This function is the similar to @code{strcmp}, except that no more than +@var{size} characters are compared. In other words, if the two strings are +the same in their first @var{size} characters, the return value is zero. +@end deftypefun + +Here are some examples showing the use of @code{strcmp} and @code{strncmp}. +These examples assume the use of the ASCII character set. (If some +other character set---say, EBCDIC---is used instead, then the glyphs +are associated with different numeric codes, and the return values +and ordering may differ.) + +@smallexample +strcmp ("hello", "hello") + @result{} 0 /* @r{These two strings are the same.} */ +strcmp ("hello", "Hello") + @result{} 32 /* @r{Comparisons are case-sensitive.} */ +strcmp ("hello", "world") + @result{} -15 /* @r{The character @code{'h'} comes before @code{'w'}.} */ +strcmp ("hello", "hello, world") + @result{} -44 /* @r{Comparing a null character against a comma.} */ +strncmp ("hello", "hello, world"", 5) + @result{} 0 /* @r{The initial 5 characters are the same.} */ +strncmp ("hello, world", "hello, stupid world!!!", 5) + @result{} 0 /* @r{The initial 5 characters are the same.} */ +@end smallexample + +@comment string.h +@comment BSD +@deftypefun int bcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size}) +This is an obsolete alias for @code{memcmp}, derived from BSD. +@end deftypefun + +@node Collation Functions, Search Functions, String/Array Comparison, String and Array Utilities +@section Collation Functions + +@cindex collating strings +@cindex string collation functions + +In some locales, the conventions for lexicographic ordering differ from +the strict numeric ordering of character codes. For example, in Spanish +most glyphs with diacritical marks such as accents are not considered +distinct letters for the purposes of collation. On the other hand, the +two-character sequence @samp{ll} is treated as a single letter that is +collated immediately after @samp{l}. + +You can use the functions @code{strcoll} and @code{strxfrm} (declared in +the header file @file{string.h}) to compare strings using a collation +ordering appropriate for the current locale. The locale used by these +functions in particular can be specified by setting the locale for the +@code{LC_COLLATE} category; see @ref{Locales}. +@pindex string.h + +In the standard C locale, the collation sequence for @code{strcoll} is +the same as that for @code{strcmp}. + +Effectively, the way these functions work is by applying a mapping to +transform the characters in a string to a byte sequence that represents +the string's position in the collating sequence of the current locale. +Comparing two such byte sequences in a simple fashion is equivalent to +comparing the strings with the locale's collating sequence. + +The function @code{strcoll} performs this translation implicitly, in +order to do one comparison. By contrast, @code{strxfrm} performs the +mapping explicitly. If you are making multiple comparisons using the +same string or set of strings, it is likely to be more efficient to use +@code{strxfrm} to transform all the strings just once, and subsequently +compare the transformed strings with @code{strcmp}. + +@comment string.h +@comment ANSI +@deftypefun int strcoll (const char *@var{s1}, const char *@var{s2}) +The @code{strcoll} function is similar to @code{strcmp} but uses the +collating sequence of the current locale for collation (the +@code{LC_COLLATE} locale). +@end deftypefun + +Here is an example of sorting an array of strings, using @code{strcoll} +to compare them. The actual sort algorithm is not written here; it +comes from @code{qsort} (@pxref{Array Sort Function}). The job of the +code shown here is to say how to compare the strings while sorting them. +(Later on in this section, we will show a way to do this more +efficiently using @code{strxfrm}.) + +@smallexample +/* @r{This is the comparison function used with @code{qsort}.} */ + +int +compare_elements (char **p1, char **p2) +@{ + return strcoll (*p1, *p2); +@} + +/* @r{This is the entry point---the function to sort} + @r{strings using the locale's collating sequence.} */ + +void +sort_strings (char **array, int nstrings) +@{ + /* @r{Sort @code{temp_array} by comparing the strings.} */ + qsort (array, sizeof (char *), + nstrings, compare_elements); +@} +@end smallexample + +@cindex converting string to collation order +@comment string.h +@comment ANSI +@deftypefun size_t strxfrm (char *@var{to}, const char *@var{from}, size_t @var{size}) +The function @code{strxfrm} transforms @var{string} using the collation +transformation determined by the locale currently selected for +collation, and stores the transformed string in the array @var{to}. Up +to @var{size} characters (including a terminating null character) are +stored. + +The behavior is undefined if the strings @var{to} and @var{from} +overlap; see @ref{Copying and Concatenation}. + +The return value is the length of the entire transformed string. This +value is not affected by the value of @var{size}, but if it is greater +than @var{size}, it means that the transformed string did not entirely +fit in the array @var{to}. In this case, only as much of the string as +actually fits was stored. To get the whole transformed string, call +@code{strxfrm} again with a bigger output array. + +The transformed string may be longer than the original string, and it +may also be shorter. + +If @var{size} is zero, no characters are stored in @var{to}. In this +case, @code{strxfrm} simply returns the number of characters that would +be the length of the transformed string. This is useful for determining +what size string to allocate. It does not matter what @var{to} is if +@var{size} is zero; @var{to} may even be a null pointer. +@end deftypefun + +Here is an example of how you can use @code{strxfrm} when +you plan to do many comparisons. It does the same thing as the previous +example, but much faster, because it has to transform each string only +once, no matter how many times it is compared with other strings. Even +the time needed to allocate and free storage is much less than the time +we save, when there are many strings. + +@smallexample +struct sorter @{ char *input; char *transformed; @}; + +/* @r{This is the comparison function used with @code{qsort}} + @r{to sort an array of @code{struct sorter}.} */ + +int +compare_elements (struct sorter *p1, struct sorter *p2) +@{ + return strcmp (p1->transformed, p2->transformed); +@} + +/* @r{This is the entry point---the function to sort} + @r{strings using the locale's collating sequence.} */ + +void +sort_strings_fast (char **array, int nstrings) +@{ + struct sorter temp_array[nstrings]; + int i; + + /* @r{Set up @code{temp_array}. Each element contains} + @r{one input string and its transformed string.} */ + for (i = 0; i < nstrings; i++) + @{ + size_t length = strlen (array[i]) * 2; + + temp_array[i].input = array[i]; + + /* @r{Transform @code{array[i]}.} + @r{First try a buffer probably big enough.} */ + while (1) + @{ + char *transformed = (char *) xmalloc (length); + if (strxfrm (transformed, array[i], length) < length) + @{ + temp_array[i].transformed = transformed; + break; + @} + /* @r{Try again with a bigger buffer.} */ + free (transformed); + length *= 2; + @} + @} + + /* @r{Sort @code{temp_array} by comparing transformed strings.} */ + qsort (temp_array, sizeof (struct sorter), + nstrings, compare_elements); + + /* @r{Put the elements back in the permanent array} + @r{in their sorted order.} */ + for (i = 0; i < nstrings; i++) + array[i] = temp_array[i].input; + + /* @r{Free the strings we allocated.} */ + for (i = 0; i < nstrings; i++) + free (temp_array[i].transformed); +@} +@end smallexample + +@strong{Compatibility Note:} The string collation functions are a new +feature of ANSI C. Older C dialects have no equivalent feature. + +@node Search Functions, Finding Tokens in a String, Collation Functions, String and Array Utilities +@section Search Functions + +This section describes library functions which perform various kinds +of searching operations on strings and arrays. These functions are +declared in the header file @file{string.h}. +@pindex string.h +@cindex search functions (for strings) +@cindex string search functions + +@comment string.h +@comment ANSI +@deftypefun {void *} memchr (const void *@var{block}, int @var{c}, size_t @var{size}) +This function finds the first occurrence of the byte @var{c} (converted +to an @code{unsigned char}) in the initial @var{size} bytes of the +object beginning at @var{block}. The return value is a pointer to the +located byte, or a null pointer if no match was found. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strchr (const char *@var{string}, int @var{c}) +The @code{strchr} function finds the first occurrence of the character +@var{c} (converted to a @code{char}) in the null-terminated string +beginning at @var{string}. The return value is a pointer to the located +character, or a null pointer if no match was found. + +For example, +@smallexample +strchr ("hello, world", 'l') + @result{} "llo, world" +strchr ("hello, world", '?') + @result{} NULL +@end smallexample + +The terminating null character is considered to be part of the string, +so you can use this function get a pointer to the end of a string by +specifying a null character as the value of the @var{c} argument. +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun {char *} index (const char *@var{string}, int @var{c}) +@code{index} is another name for @code{strchr}; they are exactly the same. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strrchr (const char *@var{string}, int @var{c}) +The function @code{strrchr} is like @code{strchr}, except that it searches +backwards from the end of the string @var{string} (instead of forwards +from the front). + +For example, +@smallexample +strrchr ("hello, world", 'l') + @result{} "ld" +@end smallexample +@end deftypefun + +@comment string.h +@comment BSD +@deftypefun {char *} rindex (const char *@var{string}, int @var{c}) +@code{rindex} is another name for @code{strrchr}; they are exactly the same. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strstr (const char *@var{haystack}, const char *@var{needle}) +This is like @code{strchr}, except that it searches @var{haystack} for a +substring @var{needle} rather than just a single character. It +returns a pointer into the string @var{haystack} that is the first +character of the substring, or a null pointer if no match was found. If +@var{needle} is an empty string, the function returns @var{haystack}. + +For example, +@smallexample +strstr ("hello, world", "l") + @result{} "llo, world" +strstr ("hello, world", "wo") + @result{} "world" +@end smallexample +@end deftypefun + + +@comment string.h +@comment GNU +@deftypefun {void *} memmem (const void *@var{needle}, size_t @var{needle-len},@*const void *@var{haystack}, size_t @var{haystack-len}) +This is like @code{strstr}, but @var{needle} and @var{haystack} are byte +arrays rather than null-terminated strings. @var{needle-len} is the +length of @var{needle} and @var{haystack-len} is the length of +@var{haystack}.@refill + +This function is a GNU extension. +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun size_t strspn (const char *@var{string}, const char *@var{skipset}) +The @code{strspn} (``string span'') function returns the length of the +initial substring of @var{string} that consists entirely of characters that +are members of the set specified by the string @var{skipset}. The order +of the characters in @var{skipset} is not important. + +For example, +@smallexample +strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz") + @result{} 5 +@end smallexample +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun size_t strcspn (const char *@var{string}, const char *@var{stopset}) +The @code{strcspn} (``string complement span'') function returns the length +of the initial substring of @var{string} that consists entirely of characters +that are @emph{not} members of the set specified by the string @var{stopset}. +(In other words, it returns the offset of the first character in @var{string} +that is a member of the set @var{stopset}.) + +For example, +@smallexample +strcspn ("hello, world", " \t\n,.;!?") + @result{} 5 +@end smallexample +@end deftypefun + +@comment string.h +@comment ANSI +@deftypefun {char *} strpbrk (const char *@var{string}, const char *@var{stopset}) +The @code{strpbrk} (``string pointer break'') function is related to +@code{strcspn}, except that it returns a pointer to the first character +in @var{string} that is a member of the set @var{stopset} instead of the +length of the initial substring. It returns a null pointer if no such +character from @var{stopset} is found. + +@c @group Invalid outside the example. +For example, + +@smallexample +strpbrk ("hello, world", " \t\n,.;!?") + @result{} ", world" +@end smallexample +@c @end group +@end deftypefun + +@node Finding Tokens in a String, , Search Functions, String and Array Utilities +@section Finding Tokens in a String + +@c !!! Document strsep, which is a better thing to use than strtok. + +@cindex tokenizing strings +@cindex breaking a string into tokens +@cindex parsing tokens from a string +It's fairly common for programs to have a need to do some simple kinds +of lexical analysis and parsing, such as splitting a command string up +into tokens. You can do this with the @code{strtok} function, declared +in the header file @file{string.h}. +@pindex string.h + +@comment string.h +@comment ANSI +@deftypefun {char *} strtok (char *@var{newstring}, const char *@var{delimiters}) +A string can be split into tokens by making a series of calls to the +function @code{strtok}. + +The string to be split up is passed as the @var{newstring} argument on +the first call only. The @code{strtok} function uses this to set up +some internal state information. Subsequent calls to get additional +tokens from the same string are indicated by passing a null pointer as +the @var{newstring} argument. Calling @code{strtok} with another +non-null @var{newstring} argument reinitializes the state information. +It is guaranteed that no other library function ever calls @code{strtok} +behind your back (which would mess up this internal state information). + +The @var{delimiters} argument is a string that specifies a set of delimiters +that may surround the token being extracted. All the initial characters +that are members of this set are discarded. The first character that is +@emph{not} a member of this set of delimiters marks the beginning of the +next token. The end of the token is found by looking for the next +character that is a member of the delimiter set. This character in the +original string @var{newstring} is overwritten by a null character, and the +pointer to the beginning of the token in @var{newstring} is returned. + +On the next call to @code{strtok}, the searching begins at the next +character beyond the one that marked the end of the previous token. +Note that the set of delimiters @var{delimiters} do not have to be the +same on every call in a series of calls to @code{strtok}. + +If the end of the string @var{newstring} is reached, or if the remainder of +string consists only of delimiter characters, @code{strtok} returns +a null pointer. +@end deftypefun + +@strong{Warning:} Since @code{strtok} alters the string it is parsing, +you always copy the string to a temporary buffer before parsing it with +@code{strtok}. If you allow @code{strtok} to modify a string that came +from another part of your program, you are asking for trouble; that +string may be part of a data structure that could be used for other +purposes during the parsing, when alteration by @code{strtok} makes the +data structure temporarily inaccurate. + +The string that you are operating on might even be a constant. Then +when @code{strtok} tries to modify it, your program will get a fatal +signal for writing in read-only memory. @xref{Program Error Signals}. + +This is a special case of a general principle: if a part of a program +does not have as its purpose the modification of a certain data +structure, then it is error-prone to modify the data structure +temporarily. + +The function @code{strtok} is not reentrant. @xref{Nonreentrancy}, for +a discussion of where and why reentrancy is important. + +Here is a simple example showing the use of @code{strtok}. + +@comment Yes, this example has been tested. +@smallexample +#include <string.h> +#include <stddef.h> + +@dots{} + +char string[] = "words separated by spaces -- and, punctuation!"; +const char delimiters[] = " .,;:!-"; +char *token; + +@dots{} + +token = strtok (string, delimiters); /* token => "words" */ +token = strtok (NULL, delimiters); /* token => "separated" */ +token = strtok (NULL, delimiters); /* token => "by" */ +token = strtok (NULL, delimiters); /* token => "spaces" */ +token = strtok (NULL, delimiters); /* token => "and" */ +token = strtok (NULL, delimiters); /* token => "punctuation" */ +token = strtok (NULL, delimiters); /* token => NULL */ +@end smallexample diff --git a/manual/summary.awk b/manual/summary.awk new file mode 100644 index 0000000000..2eade0c20d --- /dev/null +++ b/manual/summary.awk @@ -0,0 +1,110 @@ +# awk script to create summary.texinfo from the library texinfo files. + +# Copyright (C) 1992, 1993 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# This script recognizes sequences that look like: +# @comment HEADER.h +# @comment STANDARD +# @def... ITEM | @item ITEM | @vindex ITEM + +BEGIN { header = 0; +nameword["@defun"]=1 +nameword["@defmac"]=1 +nameword["@defspec"]=1 +nameword["@defvar"]=1 +nameword["@defopt"]=1 +nameword["@deffn"]=2 +nameword["@defvr"]=2 +nameword["@deftp"]=2 +nameword["@deftypefun"]=2 +nameword["@deftypevar"]=2 +nameword["@deftypefn"]=3 +nameword["@deftypevr"]=3 +firstword["@defun"]=1 +firstword["@defmac"]=1 +firstword["@defspec"]=1 +firstword["@defvar"]=1 +firstword["@defopt"]=1 +firstword["@deffn"]=2 +firstword["@defvr"]=2 +firstword["@deftp"]=2 +firstword["@deftypefun"]=1 +firstword["@deftypevar"]=1 +firstword["@deftypefn"]=2 +firstword["@deftypevr"]=2 +nameword["@item"]=1 +firstword["@item"]=1 +nameword["@itemx"]=1 +firstword["@itemx"]=1 +nameword["@vindex"]=1 +firstword["@vindex"]=1 + +print "@c DO NOT EDIT THIS FILE!" +print "@c This file is generated by summary.awk from the Texinfo sources." +} + +$1 == "@node" { node=$2; + for (i = 3; i <= NF; ++i) + { node=node " " $i; if ( $i ~ /,/ ) break; } + } + +$1 == "@comment" && $2 ~ /\.h$/ { header="@file{" $2 "}"; + for (i = 3; i <= NF; ++i) + header=header ", @file{" $i "}" + } + +$1 == "@comment" && $2 == "(none)" { header = -1; } + +$1 == "@comment" && header != 0 { std=$2; + for (i=3;i<=NF;++i) std=std " " $i } + +header != 0 && $1 ~ /@def|@item|@vindex/ \ + { defn=""; name=""; curly=0; n=1; + for (i = 2; i <= NF; ++i) { + if ($i ~ /^{/ && $i !~ /}/) { + curly=1 + word=substr ($i, 2, length ($i)) + } + else { + if (curly) { + if ($i ~ /}$/) { + curly=0 + word=word " " substr ($i, 1, length ($i) - 1) + } else + word=word " " $i + } + # Handle a single word in braces. + else if ($i ~ /^{.*}$/) + word=substr ($i, 2, length ($i) - 2) + else + word=$i + if (!curly) { + if (n >= firstword[$1]) + defn=defn " " word + if (n == nameword[$1]) + name=word + ++n + } + } + } + printf "@comment %s%c", name, 012 # FF + printf "@item%s%c%c", defn, 012, 012 + if (header != -1) printf "%s ", header; + printf "(%s): @ref{%s}.%c\n", std, node, 012; + header = 0 } diff --git a/manual/sysinfo.texi b/manual/sysinfo.texi new file mode 100644 index 0000000000..a30536db6e --- /dev/null +++ b/manual/sysinfo.texi @@ -0,0 +1,180 @@ +@node System Information, System Configuration, Users and Groups, Top +@chapter System Information + +This chapter describes functions that return information about the +particular machine that is in use---the type of hardware, the type of +software, and the individual machine's name. + +@menu +* Host Identification:: Determining the name of the machine. +* Hardware/Software Type ID:: Determining the hardware type of the + machine and what operating system it is + running. +@end menu + + +@node Host Identification +@section Host Identification + +This section explains how to identify the particular machine that your +program is running on. The identification of a machine consists of its +Internet host name and Internet address; see @ref{Internet Namespace}. +The host name should always be a fully qualified domain name, like +@w{@samp{crispy-wheats-n-chicken.ai.mit.edu}}, not a simple name like +just @w{@samp{crispy-wheats-n-chicken}}. + +@pindex hostname +@pindex hostid +@pindex unistd.h +Prototypes for these functions appear in @file{unistd.h}. The shell +commands @code{hostname} and @code{hostid} work by calling them. + +@comment unistd.h +@comment BSD +@deftypefun int gethostname (char *@var{name}, size_t @var{size}) +This function returns the name of the host machine in the array +@var{name}. The @var{size} argument specifies the size of this array, +in bytes. + +The return value is @code{0} on success and @code{-1} on failure. In +the GNU C library, @code{gethostname} fails if @var{size} is not large +enough; then you can try again with a larger array. The following +@code{errno} error condition is defined for this function: + +@table @code +@item ENAMETOOLONG +The @var{size} argument is less than the size of the host name plus one. +@end table + +@pindex sys/param.h +On some systems, there is a symbol for the maximum possible host name +length: @code{MAXHOSTNAMELEN}. It is defined in @file{sys/param.h}. +But you can't count on this to exist, so it is cleaner to handle +failure and try again. + +@code{gethostname} stores the beginning of the host name in @var{name} +even if the host name won't entirely fit. For some purposes, a +truncated host name is good enough. If it is, you can ignore the +error code. +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int sethostname (const char *@var{name}, size_t @var{length}) +The @code{sethostname} function sets the name of the host machine to +@var{name}, a string with length @var{length}. Only privileged +processes are allowed to do this. Usually it happens just once, at +system boot time. + +The return value is @code{0} on success and @code{-1} on failure. +The following @code{errno} error condition is defined for this function: + +@table @code +@item EPERM +This process cannot set the host name because it is not privileged. +@end table +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun {long int} gethostid (void) +This function returns the ``host ID'' of the machine the program is +running on. By convention, this is usually the primary Internet address +of that machine, converted to a @w{@code{long int}}. However, some +systems it is a meaningless but unique number which is hard-coded for +each machine. +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int sethostid (long int @var{id}) +The @code{sethostid} function sets the ``host ID'' of the host machine +to @var{id}. Only privileged processes are allowed to do this. Usually +it happens just once, at system boot time. + +The return value is @code{0} on success and @code{-1} on failure. +The following @code{errno} error condition is defined for this function: + +@table @code +@item EPERM +This process cannot set the host name because it is not privileged. + +@item ENOSYS +The operating system does not support setting the host ID. On some +systems, the host ID is a meaningless but unique number hard-coded for +each machine. +@end table +@end deftypefun + +@node Hardware/Software Type ID +@section Hardware/Software Type Identification + +You can use the @code{uname} function to find out some information about +the type of computer your program is running on. This function and the +associated data type are declared in the header file +@file{sys/utsname.h}. +@pindex sys/utsname.h + +@comment sys/utsname.h +@comment POSIX.1 +@deftp {Data Type} {struct utsname} +The @code{utsname} structure is used to hold information returned +by the @code{uname} function. It has the following members: + +@table @code +@item char sysname[] +This is the name of the operating system in use. + +@item char nodename[] +This is the network name of this particular computer. In the GNU +library, the value is the same as that returned by @code{gethostname}; +see @ref{Host Identification}. + +@item char release[] +This is the current release level of the operating system implementation. + +@item char version[] +This is the current version level within the release of the operating +system. + +@item char machine[] +This is a description of the type of hardware that is in use. + +Some systems provide a mechanism to interrogate the kernel directly for +this information. On systems without such a mechanism, the GNU C +library fills in this field based on the configuration name that was +specified when building and installing the library. + +GNU uses a three-part name to describe a system configuration; the three +parts are @var{cpu}, @var{manufacturer} and @var{system-type}, and they +are separated with dashes. Any possible combination of three names is +potentially meaningful, but most such combinations are meaningless in +practice and even the meaningful ones are not necessarily supported by +any particular GNU program. + +Since the value in @code{machine} is supposed to describe just the +hardware, it consists of the first two parts of the configuration name: +@samp{@var{cpu}-@var{manufacturer}}. For example, it might be one of these: + +@quotation +@code{"sparc-sun"}, +@code{"i386-@var{anything}"}, +@code{"m68k-hp"}, +@code{"m68k-sony"}, +@code{"m68k-sun"}, +@code{"mips-dec"} +@end quotation +@end table +@end deftp + +@comment sys/utsname.h +@comment POSIX.1 +@deftypefun int uname (struct utsname *@var{info}) +The @code{uname} function fills in the structure pointed to by +@var{info} with information about the operating system and host machine. +A non-negative value indicates that the data was successfully stored. + +@code{-1} as the value indicates an error. The only error possible is +@code{EFAULT}, which we normally don't mention as it is always a +possibility. +@end deftypefun diff --git a/manual/terminal.texi b/manual/terminal.texi new file mode 100644 index 0000000000..a9593ccfc5 --- /dev/null +++ b/manual/terminal.texi @@ -0,0 +1,1787 @@ +@node Low-Level Terminal Interface +@chapter Low-Level Terminal Interface + +This chapter describes functions that are specific to terminal devices. +You can use these functions to do things like turn off input echoing; +set serial line characteristics such as line speed and flow control; and +change which characters are used for end-of-file, command-line editing, +sending signals, and similar control functions. + +Most of the functions in this chapter operate on file descriptors. +@xref{Low-Level I/O}, for more information about what a file +descriptor is and how to open a file descriptor for a terminal device. + +@menu +* Is It a Terminal:: How to determine if a file is a terminal + device, and what its name is. +* I/O Queues:: About flow control and typeahead. +* Canonical or Not:: Two basic styles of input processing. +* Terminal Modes:: How to examine and modify flags controlling + details of terminal I/O: echoing, + signals, editing. +* Line Control:: Sending break sequences, clearing + terminal buffers @dots{} +* Noncanon Example:: How to read single characters without echo. +@end menu + +@node Is It a Terminal +@section Identifying Terminals +@cindex terminal identification +@cindex identifying terminals + +The functions described in this chapter only work on files that +correspond to terminal devices. You can find out whether a file +descriptor is associated with a terminal by using the @code{isatty} +function. + +@pindex unistd.h +Prototypes for both @code{isatty} and @code{ttyname} are declared in +the header file @file{unistd.h}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun int isatty (int @var{filedes}) +This function returns @code{1} if @var{filedes} is a file descriptor +associated with an open terminal device, and @code{0} otherwise. +@end deftypefun + +If a file descriptor is associated with a terminal, you can get its +associated file name using the @code{ttyname} function. See also the +@code{ctermid} function, described in @ref{Identifying the Terminal}. + +@comment unistd.h +@comment POSIX.1 +@deftypefun {char *} ttyname (int @var{filedes}) +If the file descriptor @var{filedes} is associated with a terminal +device, the @code{ttyname} function returns a pointer to a +statically-allocated, null-terminated string containing the file name of +the terminal file. The value is a null pointer if the file descriptor +isn't associated with a terminal, or the file name cannot be determined. +@end deftypefun + +@node I/O Queues +@section I/O Queues + +Many of the remaining functions in this section refer to the input and +output queues of a terminal device. These queues implement a form of +buffering @emph{within the kernel} independent of the buffering +implemented by I/O streams (@pxref{I/O on Streams}). + +@cindex terminal input queue +@cindex typeahead buffer +The @dfn{terminal input queue} is also sometimes referred to as its +@dfn{typeahead buffer}. It holds the characters that have been received +from the terminal but not yet read by any process. + +The size of the terminal's input queue is described by the +@code{MAX_INPUT} and @w{@code{_POSIX_MAX_INPUT}} parameters; see @ref{Limits +for Files}. You are guaranteed a queue size of at least +@code{MAX_INPUT}, but the queue might be larger, and might even +dynamically change size. If input flow control is enabled by setting +the @code{IXOFF} input mode bit (@pxref{Input Modes}), the terminal +driver transmits STOP and START characters to the terminal when +necessary to prevent the queue from overflowing. Otherwise, input may +be lost if it comes in too fast from the terminal. In canonical mode, +all input stays in the queue until a newline character is received, so +the terminal input queue can fill up when you type a very long line. +@xref{Canonical or Not}. + +@cindex terminal output queue +The @dfn{terminal output queue} is like the input queue, but for output; +it contains characters that have been written by processes, but not yet +transmitted to the terminal. If output flow control is enabled by +setting the @code{IXON} input mode bit (@pxref{Input Modes}), the +terminal driver obeys STOP and STOP characters sent by the terminal to +stop and restart transmission of output. + +@dfn{Clearing} the terminal input queue means discarding any characters +that have been received but not yet read. Similarly, clearing the +terminal output queue means discarding any characters that have been +written but not yet transmitted. + +@node Canonical or Not +@section Two Styles of Input: Canonical or Not + +POSIX systems support two basic modes of input: canonical and +noncanonical. + +@cindex canonical input processing +In @dfn{canonical input processing} mode, terminal input is processed in +lines terminated by newline (@code{'\n'}), EOF, or EOL characters. No +input can be read until an entire line has been typed by the user, and +the @code{read} function (@pxref{I/O Primitives}) returns at most a +single line of input, no matter how many bytes are requested. + +In canonical input mode, the operating system provides input editing +facilities: some characters are interpreted specially to perform editing +operations within the current line of text, such as ERASE and KILL. +@xref{Editing Characters}. + +The constants @code{_POSIX_MAX_CANON} and @code{MAX_CANON} parameterize +the maximum number of bytes which may appear in a single line of +canonical input. @xref{Limits for Files}. You are guaranteed a maximum +line length of at least @code{MAX_CANON} bytes, but the maximum might be +larger, and might even dynamically change size. + +@cindex noncanonical input processing +In @dfn{noncanonical input processing} mode, characters are not grouped +into lines, and ERASE and KILL processing is not performed. The +granularity with which bytes are read in noncanonical input mode is +controlled by the MIN and TIME settings. @xref{Noncanonical Input}. + +Most programs use canonical input mode, because this gives the user a +way to edit input line by line. The usual reason to use noncanonical +mode is when the program accepts single-character commands or provides +its own editing facilities. + +The choice of canonical or noncanonical input is controlled by the +@code{ICANON} flag in the @code{c_lflag} member of @code{struct termios}. +@xref{Local Modes}. + +@node Terminal Modes +@section Terminal Modes + +@pindex termios.h +This section describes the various terminal attributes that control how +input and output are done. The functions, data structures, and symbolic +constants are all declared in the header file @file{termios.h}. +@c !!! should mention terminal attributes are distinct from file attributes + +@menu +* Mode Data Types:: The data type @code{struct termios} and + related types. +* Mode Functions:: Functions to read and set the terminal + attributes. +* Setting Modes:: The right way to set terminal attributes + reliably. +* Input Modes:: Flags controlling low-level input handling. +* Output Modes:: Flags controlling low-level output handling. +* Control Modes:: Flags controlling serial port behavior. +* Local Modes:: Flags controlling high-level input handling. +* Line Speed:: How to read and set the terminal line speed. +* Special Characters:: Characters that have special effects, + and how to change them. +* Noncanonical Input:: Controlling how long to wait for input. +@end menu + +@node Mode Data Types +@subsection Terminal Mode Data Types +@cindex terminal mode data types + +The entire collection of attributes of a terminal is stored in a +structure of type @code{struct termios}. This structure is used +with the functions @code{tcgetattr} and @code{tcsetattr} to read +and set the attributes. + +@comment termios.h +@comment POSIX.1 +@deftp {Data Type} {struct termios} +Structure that records all the I/O attributes of a terminal. The +structure includes at least the following members: + +@table @code +@item tcflag_t c_iflag +A bit mask specifying flags for input modes; see @ref{Input Modes}. + +@item tcflag_t c_oflag +A bit mask specifying flags for output modes; see @ref{Output Modes}. + +@item tcflag_t c_cflag +A bit mask specifying flags for control modes; see @ref{Control Modes}. + +@item tcflag_t c_lflag +A bit mask specifying flags for local modes; see @ref{Local Modes}. + +@item cc_t c_cc[NCCS] +An array specifying which characters are associated with various +control functions; see @ref{Special Characters}. +@end table + +The @code{struct termios} structure also contains members which +encode input and output transmission speeds, but the representation is +not specified. @xref{Line Speed}, for how to examine and store the +speed values. +@end deftp + +The following sections describe the details of the members of the +@code{struct termios} structure. + +@comment termios.h +@comment POSIX.1 +@deftp {Data Type} tcflag_t +This is an unsigned integer type used to represent the various +bit masks for terminal flags. +@end deftp + +@comment termios.h +@comment POSIX.1 +@deftp {Data Type} cc_t +This is an unsigned integer type used to represent characters associated +with various terminal control functions. +@end deftp + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int NCCS +The value of this macro is the number of elements in the @code{c_cc} +array. +@end deftypevr + +@node Mode Functions +@subsection Terminal Mode Functions +@cindex terminal mode functions + +@comment termios.h +@comment POSIX.1 +@deftypefun int tcgetattr (int @var{filedes}, struct termios *@var{termios-p}) +This function is used to examine the attributes of the terminal +device with file descriptor @var{filedes}. The attributes are returned +in the structure that @var{termios-p} points to. + +If successful, @code{tcgetattr} returns @code{0}. A return value of @code{-1} +indicates an error. The following @code{errno} error conditions are +defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item ENOTTY +The @var{filedes} is not associated with a terminal. +@end table +@end deftypefun + +@comment termios.h +@comment POSIX.1 +@deftypefun int tcsetattr (int @var{filedes}, int @var{when}, const struct termios *@var{termios-p}) +This function sets the attributes of the terminal device with file +descriptor @var{filedes}. The new attributes are taken from the +structure that @var{termios-p} points to. + +The @var{when} argument specifies how to deal with input and output +already queued. It can be one of the following values: + +@table @code +@comment termios.h +@comment POSIX.1 +@item TCSANOW +@vindex TCSANOW +Make the change immediately. + +@comment termios.h +@comment POSIX.1 +@item TCSADRAIN +@vindex TCSADRAIN +Make the change after waiting until all queued output has been written. +You should usually use this option when changing parameters that affect +output. + +@comment termios.h +@comment POSIX.1 +@item TCSAFLUSH +@vindex TCSAFLUSH +This is like @code{TCSADRAIN}, but also discards any queued input. + +@comment termios.h +@comment BSD +@item TCSASOFT +@vindex TCSASOFT +This is a flag bit that you can add to any of the above alternatives. +Its meaning is to inhibit alteration of the state of the terminal +hardware. It is a BSD extension; it is only supported on BSD systems +and the GNU system. + +Using @code{TCSASOFT} is exactly the same as setting the @code{CIGNORE} +bit in the @code{c_cflag} member of the structure @var{termios-p} points +to. @xref{Control Modes}, for a description of @code{CIGNORE}. +@end table + +If this function is called from a background process on its controlling +terminal, normally all processes in the process group are sent a +@code{SIGTTOU} signal, in the same way as if the process were trying to +write to the terminal. The exception is if the calling process itself +is ignoring or blocking @code{SIGTTOU} signals, in which case the +operation is performed and no signal is sent. @xref{Job Control}. + +If successful, @code{tcsetattr} returns @code{0}. A return value of +@code{-1} indicates an error. The following @code{errno} error +conditions are defined for this function: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item ENOTTY +The @var{filedes} is not associated with a terminal. + +@item EINVAL +Either the value of the @code{when} argument is not valid, or there is +something wrong with the data in the @var{termios-p} argument. +@end table +@end deftypefun + +Although @code{tcgetattr} and @code{tcsetattr} specify the terminal +device with a file descriptor, the attributes are those of the terminal +device itself and not of the file descriptor. This means that the +effects of changing terminal attributes are persistent; if another +process opens the terminal file later on, it will see the changed +attributes even though it doesn't have anything to do with the open file +descriptor you originally specified in changing the attributes. + +Similarly, if a single process has multiple or duplicated file +descriptors for the same terminal device, changing the terminal +attributes affects input and output to all of these file +descriptors. This means, for example, that you can't open one file +descriptor or stream to read from a terminal in the normal +line-buffered, echoed mode; and simultaneously have another file +descriptor for the same terminal that you use to read from it in +single-character, non-echoed mode. Instead, you have to explicitly +switch the terminal back and forth between the two modes. + +@node Setting Modes +@subsection Setting Terminal Modes Properly + +When you set terminal modes, you should call @code{tcgetattr} first to +get the current modes of the particular terminal device, modify only +those modes that you are really interested in, and store the result with +@code{tcsetattr}. + +It's a bad idea to simply initialize a @code{struct termios} structure +to a chosen set of attributes and pass it directly to @code{tcsetattr}. +Your program may be run years from now, on systems that support members +not documented in this manual. The way to avoid setting these members +to unreasonable values is to avoid changing them. + +What's more, different terminal devices may require different mode +settings in order to function properly. So you should avoid blindly +copying attributes from one terminal device to another. + +When a member contains a collection of independent flags, as the +@code{c_iflag}, @code{c_oflag} and @code{c_cflag} members do, even +setting the entire member is a bad idea, because particular operating +systems have their own flags. Instead, you should start with the +current value of the member and alter only the flags whose values matter +in your program, leaving any other flags unchanged. + +Here is an example of how to set one flag (@code{ISTRIP}) in the +@code{struct termios} structure while properly preserving all the other +data in the structure: + +@smallexample +@group +int +set_istrip (int desc, int value) +@{ + struct termios settings; + int result; +@end group + +@group + result = tcgetattr (desc, &settings); + if (result < 0) + @{ + perror ("error in tcgetattr"); + return 0; + @} +@end group +@group + settings.c_iflag &= ~ISTRIP; + if (value) + settings.c_iflag |= ISTRIP; +@end group +@group + result = tcsetattr (desc, TCSANOW, &settings); + if (result < 0) + @{ + perror ("error in tcgetattr"); + return; + @} + return 1; +@} +@end group +@end smallexample + +@node Input Modes +@subsection Input Modes + +This section describes the terminal attribute flags that control +fairly low-level aspects of input processing: handling of parity errors, +break signals, flow control, and @key{RET} and @key{LFD} characters. + +All of these flags are bits in the @code{c_iflag} member of the +@code{struct termios} structure. The member is an integer, and you +change flags using the operators @code{&}, @code{|} and @code{^}. Don't +try to specify the entire value for @code{c_iflag}---instead, change +only specific flags and leave the rest untouched (@pxref{Setting +Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t INPCK +@cindex parity checking +If this bit is set, input parity checking is enabled. If it is not set, +no checking at all is done for parity errors on input; the +characters are simply passed through to the application. + +Parity checking on input processing is independent of whether parity +detection and generation on the underlying terminal hardware is enabled; +see @ref{Control Modes}. For example, you could clear the @code{INPCK} +input mode flag and set the @code{PARENB} control mode flag to ignore +parity errors on input, but still generate parity on output. + +If this bit is set, what happens when a parity error is detected depends +on whether the @code{IGNPAR} or @code{PARMRK} bits are set. If neither +of these bits are set, a byte with a parity error is passed to the +application as a @code{'\0'} character. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IGNPAR +If this bit is set, any byte with a framing or parity error is ignored. +This is only useful if @code{INPCK} is also set. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t PARMRK +If this bit is set, input bytes with parity or framing errors are marked +when passed to the program. This bit is meaningful only when +@code{INPCK} is set and @code{IGNPAR} is not set. + +The way erroneous bytes are marked is with two preceding bytes, +@code{377} and @code{0}. Thus, the program actually reads three bytes +for one erroneous byte received from the terminal. + +If a valid byte has the value @code{0377}, and @code{ISTRIP} (see below) +is not set, the program might confuse it with the prefix that marks a +parity error. So a valid byte @code{0377} is passed to the program as +two bytes, @code{0377} @code{0377}, in this case. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ISTRIP +If this bit is set, valid input bytes are stripped to seven bits; +otherwise, all eight bits are available for programs to read. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IGNBRK +If this bit is set, break conditions are ignored. + +@cindex break condition, detecting +A @dfn{break condition} is defined in the context of asynchronous +serial data transmission as a series of zero-value bits longer than a +single byte. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t BRKINT +If this bit is set and @code{IGNBRK} is not set, a break condition +clears the terminal input and output queues and raises a @code{SIGINT} +signal for the foreground process group associated with the terminal. + +If neither @code{BRKINT} nor @code{IGNBRK} are set, a break condition is +passed to the application as a single @code{'\0'} character if +@code{PARMRK} is not set, or otherwise as a three-character sequence +@code{'\377'}, @code{'\0'}, @code{'\0'}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IGNCR +If this bit is set, carriage return characters (@code{'\r'}) are +discarded on input. Discarding carriage return may be useful on +terminals that send both carriage return and linefeed when you type the +@key{RET} key. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ICRNL +If this bit is set and @code{IGNCR} is not set, carriage return characters +(@code{'\r'}) received as input are passed to the application as newline +characters (@code{'\n'}). +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t INLCR +If this bit is set, newline characters (@code{'\n'}) received as input +are passed to the application as carriage return characters (@code{'\r'}). +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IXOFF +If this bit is set, start/stop control on input is enabled. In other +words, the computer sends STOP and START characters as necessary to +prevent input from coming in faster than programs are reading it. The +idea is that the actual terminal hardware that is generating the input +data responds to a STOP character by suspending transmission, and to a +START character by resuming transmission. @xref{Start/Stop Characters}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IXON +If this bit is set, start/stop control on output is enabled. In other +words, if the computer receives a STOP character, it suspends output +until a START character is received. In this case, the STOP and START +characters are never passed to the application program. If this bit is +not set, then START and STOP can be read as ordinary characters. +@xref{Start/Stop Characters}. +@c !!! mention this interferes with using C-s and C-q for programs like emacs +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t IXANY +If this bit is set, any input character restarts output when output has +been suspended with the STOP character. Otherwise, only the START +character restarts output. + +This is a BSD extension; it exists only on BSD systems and the GNU system. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t IMAXBEL +If this bit is set, then filling up the terminal input buffer sends a +BEL character (code @code{007}) to the terminal to ring the bell. + +This is a BSD extension. +@end deftypevr + +@node Output Modes +@subsection Output Modes + +This section describes the terminal flags and fields that control how +output characters are translated and padded for display. All of these +are contained in the @code{c_oflag} member of the @w{@code{struct termios}} +structure. + +The @code{c_oflag} member itself is an integer, and you change the flags +and fields using the operators @code{&}, @code{|}, and @code{^}. Don't +try to specify the entire value for @code{c_oflag}---instead, change +only specific flags and leave the rest untouched (@pxref{Setting +Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t OPOST +If this bit is set, output data is processed in some unspecified way so +that it is displayed appropriately on the terminal device. This +typically includes mapping newline characters (@code{'\n'}) onto +carriage return and linefeed pairs. + +If this bit isn't set, the characters are transmitted as-is. +@end deftypevr + +The following three bits are BSD features, and they exist only BSD +systems and the GNU system. They are effective only if @code{OPOST} is +set. + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ONLCR +If this bit is set, convert the newline character on output into a pair +of characters, carriage return followed by linefeed. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t OXTABS +If this bit is set, convert tab characters on output into the appropriate +number of spaces to emulate a tab stop every eight columns. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ONOEOT +If this bit is set, discard @kbd{C-d} characters (code @code{004}) on +output. These characters cause many dial-up terminals to disconnect. +@end deftypevr + +@node Control Modes +@subsection Control Modes + +This section describes the terminal flags and fields that control +parameters usually associated with asynchronous serial data +transmission. These flags may not make sense for other kinds of +terminal ports (such as a network connection pseudo-terminal). All of +these are contained in the @code{c_cflag} member of the @code{struct +termios} structure. + +The @code{c_cflag} member itself is an integer, and you change the flags +and fields using the operators @code{&}, @code{|}, and @code{^}. Don't +try to specify the entire value for @code{c_cflag}---instead, change +only specific flags and leave the rest untouched (@pxref{Setting +Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CLOCAL +If this bit is set, it indicates that the terminal is connected +``locally'' and that the modem status lines (such as carrier detect) +should be ignored. +@cindex modem status lines +@cindex carrier detect + +On many systems if this bit is not set and you call @code{open} without +the @code{O_NONBLOCK} flag set, @code{open} blocks until a modem +connection is established. + +If this bit is not set and a modem disconnect is detected, a +@code{SIGHUP} signal is sent to the controlling process group for the +terminal (if it has one). Normally, this causes the process to exit; +see @ref{Signal Handling}. Reading from the terminal after a disconnect +causes an end-of-file condition, and writing causes an @code{EIO} error +to be returned. The terminal device must be closed and reopened to +clear the condition. +@cindex modem disconnect +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t HUPCL +If this bit is set, a modem disconnect is generated when all processes +that have the terminal device open have either closed the file or exited. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CREAD +If this bit is set, input can be read from the terminal. Otherwise, +input is discarded when it arrives. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CSTOPB +If this bit is set, two stop bits are used. Otherwise, only one stop bit +is used. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t PARENB +If this bit is set, generation and detection of a parity bit are enabled. +@xref{Input Modes}, for information on how input parity errors are handled. + +If this bit is not set, no parity bit is added to output characters, and +input characters are not checked for correct parity. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t PARODD +This bit is only useful if @code{PARENB} is set. If @code{PARODD} is set, +odd parity is used, otherwise even parity is used. +@end deftypevr + +The control mode flags also includes a field for the number of bits per +character. You can use the @code{CSIZE} macro as a mask to extract the +value, like this: @code{settings.c_cflag & CSIZE}. + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CSIZE +This is a mask for the number of bits per character. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CS5 +This specifies five bits per byte. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CS6 +This specifies six bits per byte. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CS7 +This specifies seven bits per byte. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t CS8 +This specifies eight bits per byte. +@end deftypevr + +The following four bits are BSD extensions; this exist only on BSD +systems and the GNU system. + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t CCTS_OFLOW +If this bit is set, enable flow control of output based on the CTS wire +(RS232 protocol). +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t CRTS_IFLOW +If this bit is set, enable flow control of input based on the RTS wire +(RS232 protocol). +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t MDMBUF +If this bit is set, enable carrier-based flow control of output. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t CIGNORE +If this bit is set, it says to ignore the control modes and line speed +values entirely. This is only meaningful in a call to @code{tcsetattr}. + +The @code{c_cflag} member and the line speed values returned by +@code{cfgetispeed} and @code{cfgetospeed} will be unaffected by the +call. @code{CIGNORE} is useful if you want to set all the software +modes in the other members, but leave the hardware details in +@code{c_cflag} unchanged. (This is how the @code{TCSASOFT} flag to +@code{tcsettattr} works.) + +This bit is never set in the structure filled in by @code{tcgetattr}. +@end deftypevr + +@node Local Modes +@subsection Local Modes + +This section describes the flags for the @code{c_lflag} member of the +@code{struct termios} structure. These flags generally control +higher-level aspects of input processing than the input modes flags +described in @ref{Input Modes}, such as echoing, signals, and the choice +of canonical or noncanonical input. + +The @code{c_lflag} member itself is an integer, and you change the flags +and fields using the operators @code{&}, @code{|}, and @code{^}. Don't +try to specify the entire value for @code{c_lflag}---instead, change +only specific flags and leave the rest untouched (@pxref{Setting +Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ICANON +This bit, if set, enables canonical input processing mode. Otherwise, +input is processed in noncanonical mode. @xref{Canonical or Not}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ECHO +If this bit is set, echoing of input characters back to the terminal +is enabled. +@cindex echo of terminal input +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ECHOE +If this bit is set, echoing indicates erasure of input with the ERASE +character by erasing the last character in the current line from the +screen. Otherwise, the character erased is re-echoed to show what has +happened (suitable for a printing terminal). + +This bit only controls the display behavior; the @code{ICANON} bit by +itself controls actual recognition of the ERASE character and erasure of +input, without which @code{ECHOE} is simply irrelevant. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ECHOPRT +This bit is like @code{ECHOE}, enables display of the ERASE character in +a way that is geared to a hardcopy terminal. When you type the ERASE +character, a @samp{\} character is printed followed by the first +character erased. Typing the ERASE character again just prints the next +character erased. Then, the next time you type a normal character, a +@samp{/} character is printed before the character echoes. + +This is a BSD extension, and exists only in BSD systems and the +GNU system. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ECHOK +This bit enables special display of the KILL character by moving to a +new line after echoing the KILL character normally. The behavior of +@code{ECHOKE} (below) is nicer to look at. + +If this bit is not set, the KILL character echoes just as it would if it +were not the KILL character. Then it is up to the user to remember that +the KILL character has erased the preceding input; there is no +indication of this on the screen. + +This bit only controls the display behavior; the @code{ICANON} bit by +itself controls actual recognition of the KILL character and erasure of +input, without which @code{ECHOK} is simply irrelevant. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ECHOKE +This bit is similar to @code{ECHOK}. It enables special display of the +KILL character by erasing on the screen the entire line that has been +killed. This is a BSD extension, and exists only in BSD systems and the +GNU system. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ECHONL +If this bit is set and the @code{ICANON} bit is also set, then the +newline (@code{'\n'}) character is echoed even if the @code{ECHO} bit +is not set. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ECHOCTL +If this bit is set and the @code{ECHO} bit is also set, echo control +characters with @samp{^} followed by the corresponding text character. +Thus, control-A echoes as @samp{^A}. This is usually the preferred mode +for interactive input, because echoing a control character back to the +terminal could have some undesired effect on the terminal. + +This is a BSD extension, and exists only in BSD systems and the +GNU system. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t ISIG +This bit controls whether the INTR, QUIT, and SUSP characters are +recognized. The functions associated with these characters are performed +if and only if this bit is set. Being in canonical or noncanonical +input mode has no affect on the interpretation of these characters. + +You should use caution when disabling recognition of these characters. +Programs that cannot be interrupted interactively are very +user-unfriendly. If you clear this bit, your program should provide +some alternate interface that allows the user to interactively send the +signals associated with these characters, or to escape from the program. +@cindex interactive signals, from terminal + +@xref{Signal Characters}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t IEXTEN +POSIX.1 gives @code{IEXTEN} implementation-defined meaning, +so you cannot rely on this interpretation on all systems. + +On BSD systems and the GNU system, it enables the LNEXT and DISCARD characters. +@xref{Other Special}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t NOFLSH +Normally, the INTR, QUIT, and SUSP characters cause input and output +queues for the terminal to be cleared. If this bit is set, the queues +are not cleared. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro tcflag_t TOSTOP +If this bit is set and the system supports job control, then +@code{SIGTTOU} signals are generated by background processes that +attempt to write to the terminal. @xref{Access to the Terminal}. +@end deftypevr + +The following bits are BSD extensions; they exist only in BSD systems +and the GNU system. + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t ALTWERASE +This bit determines how far the WERASE character should erase. The +WERASE character erases back to the beginning of a word; the question +is, where do words begin? + +If this bit is clear, then the beginning of a word is a nonwhitespace +character following a whitespace character. If the bit is set, then the +beginning of a word is an alphanumeric character or underscore following +a character which is none of those. + +@xref{Editing Characters}, for more information about the WERASE character. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t FLUSHO +This is the bit that toggles when the user types the DISCARD character. +While this bit is set, all output is discarded. @xref{Other Special}. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t NOKERNINFO +Setting this bit disables handling of the STATUS character. +@xref{Other Special}. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro tcflag_t PENDIN +If this bit is set, it indicates that there is a line of input that +needs to be reprinted. Typing the REPRINT character sets this bit; the +bit remains set until reprinting is finished. @xref{Editing Characters}. +@end deftypevr + +@c EXTPROC is too obscure to document now. --roland + +@node Line Speed +@subsection Line Speed +@cindex line speed +@cindex baud rate +@cindex terminal line speed +@cindex terminal line speed + +The terminal line speed tells the computer how fast to read and write +data on the terminal. + +If the terminal is connected to a real serial line, the terminal speed +you specify actually controls the line---if it doesn't match the +terminal's own idea of the speed, communication does not work. Real +serial ports accept only certain standard speeds. Also, particular +hardware may not support even all the standard speeds. Specifying a +speed of zero hangs up a dialup connection and turns off modem control +signals. + +If the terminal is not a real serial line (for example, if it is a +network connection), then the line speed won't really affect data +transmission speed, but some programs will use it to determine the +amount of padding needed. It's best to specify a line speed value that +matches the actual speed of the actual terminal, but you can safely +experiment with different values to vary the amount of padding. + +There are actually two line speeds for each terminal, one for input and +one for output. You can set them independently, but most often +terminals use the same speed for both directions. + +The speed values are stored in the @code{struct termios} structure, but +don't try to access them in the @code{struct termios} structure +directly. Instead, you should use the following functions to read and +store them: + +@comment termios.h +@comment POSIX.1 +@deftypefun speed_t cfgetospeed (const struct termios *@var{termios-p}) +This function returns the output line speed stored in the structure +@code{*@var{termios-p}}. +@end deftypefun + +@comment termios.h +@comment POSIX.1 +@deftypefun speed_t cfgetispeed (const struct termios *@var{termios-p}) +This function returns the input line speed stored in the structure +@code{*@var{termios-p}}. +@end deftypefun + +@comment termios.h +@comment POSIX.1 +@deftypefun int cfsetospeed (struct termios *@var{termios-p}, speed_t @var{speed}) +This function stores @var{speed} in @code{*@var{termios-p}} as the output +speed. The normal return value is @code{0}; a value of @code{-1} +indicates an error. If @var{speed} is not a speed, @code{cfsetospeed} +returns @code{-1}. +@end deftypefun + +@comment termios.h +@comment POSIX.1 +@deftypefun int cfsetispeed (struct termios *@var{termios-p}, speed_t @var{speed}) +This function stores @var{speed} in @code{*@var{termios-p}} as the input +speed. The normal return value is @code{0}; a value of @code{-1} +indicates an error. If @var{speed} is not a speed, @code{cfsetospeed} +returns @code{-1}. +@end deftypefun + +@comment termios.h +@comment BSD +@deftypefun int cfsetspeed (struct termios *@var{termios-p}, speed_t @var{speed}) +This function stores @var{speed} in @code{*@var{termios-p}} as both the +input and output speeds. The normal return value is @code{0}; a value +of @code{-1} indicates an error. If @var{speed} is not a speed, +@code{cfsetspeed} returns @code{-1}. This function is an extension in +4.4 BSD. +@end deftypefun + +@comment termios.h +@comment POSIX.1 +@deftp {Data Type} speed_t +The @code{speed_t} type is an unsigned integer data type used to +represent line speeds. +@end deftp + +The functions @code{cfsetospeed} and @code{cfsetispeed} report errors +only for speed values that the system simply cannot handle. If you +specify a speed value that is basically acceptable, then those functions +will succeed. But they do not check that a particular hardware device +can actually support the specified speeds---in fact, they don't know +which device you plan to set the speed for. If you use @code{tcsetattr} +to set the speed of a particular device to a value that it cannot +handle, @code{tcsetattr} returns @code{-1}. + +@strong{Portability note:} In the GNU library, the functions above +accept speeds measured in bits per second as input, and return speed +values measured in bits per second. Other libraries require speeds to +be indicated by special codes. For POSIX.1 portability, you must use +one of the following symbols to represent the speed; their precise +numeric values are system-dependent, but each name has a fixed meaning: +@code{B110} stands for 110 bps, @code{B300} for 300 bps, and so on. +There is no portable way to represent any speed but these, but these are +the only speeds that typical serial lines can support. + +@comment termios.h +@comment POSIX.1 +@vindex B0 +@comment termios.h +@comment POSIX.1 +@vindex B50 +@comment termios.h +@comment POSIX.1 +@vindex B75 +@comment termios.h +@comment POSIX.1 +@vindex B110 +@comment termios.h +@comment POSIX.1 +@vindex B134 +@comment termios.h +@comment POSIX.1 +@vindex B150 +@comment termios.h +@comment POSIX.1 +@vindex B200 +@comment termios.h +@comment POSIX.1 +@vindex B300 +@comment termios.h +@comment POSIX.1 +@vindex B600 +@comment termios.h +@comment POSIX.1 +@vindex B1200 +@comment termios.h +@comment POSIX.1 +@vindex B1800 +@comment termios.h +@comment POSIX.1 +@vindex B2400 +@comment termios.h +@comment POSIX.1 +@vindex B4800 +@comment termios.h +@comment POSIX.1 +@vindex B9600 +@comment termios.h +@comment POSIX.1 +@vindex B19200 +@comment termios.h +@comment POSIX.1 +@vindex B38400 +@smallexample +B0 B50 B75 B110 B134 B150 B200 +B300 B600 B1200 B1800 B2400 B4800 +B9600 B19200 B38400 +@end smallexample + +@vindex EXTA +@vindex EXTB +BSD defines two additional speed symbols as aliases: @code{EXTA} is an +alias for @code{B19200} and @code{EXTB} is an alias for @code{B38400}. +These aliases are obsolete. + +@node Special Characters +@subsection Special Characters + +In canonical input, the terminal driver recognizes a number of special +characters which perform various control functions. These include the +ERASE character (usually @key{DEL}) for editing input, and other editing +characters. The INTR character (normally @kbd{C-c}) for sending a +@code{SIGINT} signal, and other signal-raising characters, may be +available in either canonical or noncanonical input mode. All these +characters are described in this section. + +The particular characters used are specified in the @code{c_cc} member +of the @code{struct termios} structure. This member is an array; each +element specifies the character for a particular role. Each element has +a symbolic constant that stands for the index of that element---for +example, @code{INTR} is the index of the element that specifies the INTR +character, so storing @code{'='} in @code{@var{termios}.c_cc[INTR]} +specifies @samp{=} as the INTR character. + +@vindex _POSIX_VDISABLE +On some systems, you can disable a particular special character function +by specifying the value @code{_POSIX_VDISABLE} for that role. This +value is unequal to any possible character code. @xref{Options for +Files}, for more information about how to tell whether the operating +system you are using supports @code{_POSIX_VDISABLE}. + +@menu +* Editing Characters:: Special characters that terminate lines and + delete text, and other editing functions. +* Signal Characters:: Special characters that send or raise signals + to or for certain classes of processes. +* Start/Stop Characters:: Special characters that suspend or resume + suspended output. +* Other Special:: Other special characters for BSD systems: + they can discard output, and print status. +@end menu + +@node Editing Characters +@subsubsection Characters for Input Editing + +These special characters are active only in canonical input mode. +@xref{Canonical or Not}. + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VEOF +@cindex EOF character +This is the subscript for the EOF character in the special control +character array. @code{@var{termios}.c_cc[VEOF]} holds the character +itself. + +The EOF character is recognized only in canonical input mode. It acts +as a line terminator in the same way as a newline character, but if the +EOF character is typed at the beginning of a line it causes @code{read} +to return a byte count of zero, indicating end-of-file. The EOF +character itself is discarded. + +Usually, the EOF character is @kbd{C-d}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VEOL +@cindex EOL character +This is the subscript for the EOL character in the special control +character array. @code{@var{termios}.c_cc[VEOL]} holds the character +itself. + +The EOL character is recognized only in canonical input mode. It acts +as a line terminator, just like a newline character. The EOL character +is not discarded; it is read as the last character in the input line. + +@c !!! example: this is set to ESC by 4.3 csh with "set filec" so it can +@c complete partial lines without using cbreak or raw mode. + +You don't need to use the EOL character to make @key{RET} end a line. +Just set the ICRNL flag. In fact, this is the default state of +affairs. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro int VEOL2 +@cindex EOL2 character +This is the subscript for the EOL2 character in the special control +character array. @code{@var{termios}.c_cc[VEOL2]} holds the character +itself. + +The EOL2 character works just like the EOL character (see above), but it +can be a different character. Thus, you can specify two characters to +terminate an input line, by setting EOL to one of them and EOL2 to the +other. + +The EOL2 character is a BSD extension; it exists only on BSD systems +and the GNU system. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VERASE +@cindex ERASE character +This is the subscript for the ERASE character in the special control +character array. @code{@var{termios}.c_cc[VERASE]} holds the +character itself. + +The ERASE character is recognized only in canonical input mode. When +the user types the erase character, the previous character typed is +discarded. (If the terminal generates multibyte character sequences, +this may cause more than one byte of input to be discarded.) This +cannot be used to erase past the beginning of the current line of text. +The ERASE character itself is discarded. +@c !!! mention ECHOE here + +Usually, the ERASE character is @key{DEL}. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro int VWERASE +@cindex WERASE character +This is the subscript for the WERASE character in the special control +character array. @code{@var{termios}.c_cc[VWERASE]} holds the character +itself. + +The WERASE character is recognized only in canonical mode. It erases an +entire word of prior input, and any whitespace after it; whitespace +characters before the word are not erased. + +The definition of a ``word'' depends on the setting of the +@code{ALTWERASE} mode; @pxref{Local Modes}. + +If the @code{ALTWERASE} mode is not set, a word is defined as a sequence +of any characters except space or tab. + +If the @code{ALTWERASE} mode is set, a word is defined as a sequence of +characters containing only letters, numbers, and underscores, optionally +followed by one character that is not a letter, number, or underscore. + +The WERASE character is usually @kbd{C-w}. + +This is a BSD extension. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VKILL +@cindex KILL character +This is the subscript for the KILL character in the special control +character array. @code{@var{termios}.c_cc[VKILL]} holds the character +itself. + +The KILL character is recognized only in canonical input mode. When the +user types the kill character, the entire contents of the current line +of input are discarded. The kill character itself is discarded too. + +The KILL character is usually @kbd{C-u}. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro int VREPRINT +@cindex REPRINT character +This is the subscript for the REPRINT character in the special control +character array. @code{@var{termios}.c_cc[VREPRINT]} holds the character +itself. + +The REPRINT character is recognized only in canonical mode. It reprints +the current input line. If some asynchronous output has come while you +are typing, this lets you see the line you are typing clearly again. + +The REPRINT character is usually @kbd{C-r}. + +This is a BSD extension. +@end deftypevr + +@node Signal Characters +@subsubsection Characters that Cause Signals + +These special characters may be active in either canonical or noncanonical +input mode, but only when the @code{ISIG} flag is set (@pxref{Local +Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VINTR +@cindex INTR character +@cindex interrupt character +This is the subscript for the INTR character in the special control +character array. @code{@var{termios}.c_cc[VINTR]} holds the character +itself. + +The INTR (interrupt) character raises a @code{SIGINT} signal for all +processes in the foreground job associated with the terminal. The INTR +character itself is then discarded. @xref{Signal Handling}, for more +information about signals. + +Typically, the INTR character is @kbd{C-c}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VQUIT +@cindex QUIT character +This is the subscript for the QUIT character in the special control +character array. @code{@var{termios}.c_cc[VQUIT]} holds the character +itself. + +The QUIT character raises a @code{SIGQUIT} signal for all processes in +the foreground job associated with the terminal. The QUIT character +itself is then discarded. @xref{Signal Handling}, for more information +about signals. + +Typically, the QUIT character is @kbd{C-\}. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VSUSP +@cindex SUSP character +@cindex suspend character +This is the subscript for the SUSP character in the special control +character array. @code{@var{termios}.c_cc[VSUSP]} holds the character +itself. + +The SUSP (suspend) character is recognized only if the implementation +supports job control (@pxref{Job Control}). It causes a @code{SIGTSTP} +signal to be sent to all processes in the foreground job associated with +the terminal. The SUSP character itself is then discarded. +@xref{Signal Handling}, for more information about signals. + +Typically, the SUSP character is @kbd{C-z}. +@end deftypevr + +Few applications disable the normal interpretation of the SUSP +character. If your program does this, it should provide some other +mechanism for the user to stop the job. When the user invokes this +mechanism, the program should send a @code{SIGTSTP} signal to the +process group of the process, not just to the process itself. +@xref{Signaling Another Process}. + +@comment termios.h +@comment BSD +@deftypevr Macro int VDSUSP +@cindex DSUSP character +@cindex delayed suspend character +This is the subscript for the DSUSP character in the special control +character array. @code{@var{termios}.c_cc[VDSUSP]} holds the character +itself. + +The DSUSP (suspend) character is recognized only if the implementation +supports job control (@pxref{Job Control}). It sends a @code{SIGTSTP} +signal, like the SUSP character, but not right away---only when the +program tries to read it as input. Not all systems with job control +support DSUSP; only BSD-compatible systems (including the GNU system). + +@xref{Signal Handling}, for more information about signals. + +Typically, the DSUSP character is @kbd{C-y}. +@end deftypevr + +@node Start/Stop Characters +@subsubsection Special Characters for Flow Control + +These special characters may be active in either canonical or noncanonical +input mode, but their use is controlled by the flags @code{IXON} and +@code{IXOFF} (@pxref{Input Modes}). + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VSTART +@cindex START character +This is the subscript for the START character in the special control +character array. @code{@var{termios}.c_cc[VSTART]} holds the +character itself. + +The START character is used to support the @code{IXON} and @code{IXOFF} +input modes. If @code{IXON} is set, receiving a START character resumes +suspended output; the START character itself is discarded. If +@code{IXANY} is set, receiving any character at all resumes suspended +output; the resuming character is not discarded unless it is the START +character. @code{IXOFF} is set, the system may also transmit START +characters to the terminal. + +The usual value for the START character is @kbd{C-q}. You may not be +able to change this value---the hardware may insist on using @kbd{C-q} +regardless of what you specify. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VSTOP +@cindex STOP character +This is the subscript for the STOP character in the special control +character array. @code{@var{termios}.c_cc[VSTOP]} holds the character +itself. + +The STOP character is used to support the @code{IXON} and @code{IXOFF} +input modes. If @code{IXON} is set, receiving a STOP character causes +output to be suspended; the STOP character itself is discarded. If +@code{IXOFF} is set, the system may also transmit STOP characters to the +terminal, to prevent the input queue from overflowing. + +The usual value for the STOP character is @kbd{C-s}. You may not be +able to change this value---the hardware may insist on using @kbd{C-s} +regardless of what you specify. +@end deftypevr + +@node Other Special +@subsubsection Other Special Characters + +These special characters exist only in BSD systems and the GNU system. + +@comment termios.h +@comment BSD +@deftypevr Macro int VLNEXT +@cindex LNEXT character +This is the subscript for the LNEXT character in the special control +character array. @code{@var{termios}.c_cc[VLNEXT]} holds the character +itself. + +The LNEXT character is recognized only when @code{IEXTEN} is set, but in +both canonical and noncanonical mode. It disables any special +significance of the next character the user types. Even if the +character would normally perform some editting function or generate a +signal, it is read as a plain character. This is the analogue of the +@kbd{C-q} command in Emacs. ``LNEXT'' stands for ``literal next.'' + +The LNEXT character is usually @kbd{C-v}. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro int VDISCARD +@cindex DISCARD character +This is the subscript for the DISCARD character in the special control +character array. @code{@var{termios}.c_cc[VDISCARD]} holds the character +itself. + +The DISCARD character is recognized only when @code{IEXTEN} is set, but +in both canonical and noncanonical mode. Its effect is to toggle the +discard-output flag. When this flag is set, all program output is +discarded. Setting the flag also discards all output currently in the +output buffer. Typing any other character resets the flag. +@end deftypevr + +@comment termios.h +@comment BSD +@deftypevr Macro int VSTATUS +@cindex STATUS character +This is the subscript for the STATUS character in the special control +character array. @code{@var{termios}.c_cc[VSTATUS]} holds the character +itself. + +The STATUS character's effect is to print out a status message about how +the current process is running. + +The STATUS character is recognized only in canonical mode, and only if +@code{NOKERNINFO} is not set. +@end deftypevr + +@node Noncanonical Input +@subsection Noncanonical Input + +In noncanonical input mode, the special editing characters such as +ERASE and KILL are ignored. The system facilities for the user to edit +input are disabled in noncanonical mode, so that all input characters +(unless they are special for signal or flow-control purposes) are passed +to the application program exactly as typed. It is up to the +application program to give the user ways to edit the input, if +appropriate. + +Noncanonical mode offers special parameters called MIN and TIME for +controlling whether and how long to wait for input to be available. You +can even use them to avoid ever waiting---to return immediately with +whatever input is available, or with no input. + +The MIN and TIME are stored in elements of the @code{c_cc} array, which +is a member of the @w{@code{struct termios}} structure. Each element of +this array has a particular role, and each element has a symbolic +constant that stands for the index of that element. @code{VMIN} and +@code{VMAX} are the names for the indices in the array of the MIN and +TIME slots. + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VMIN +@cindex MIN termios slot +This is the subscript for the MIN slot in the @code{c_cc} array. Thus, +@code{@var{termios}.c_cc[VMIN]} is the value itself. + +The MIN slot is only meaningful in noncanonical input mode; it +specifies the minimum number of bytes that must be available in the +input queue in order for @code{read} to return. +@end deftypevr + +@comment termios.h +@comment POSIX.1 +@deftypevr Macro int VTIME +@cindex TIME termios slot +This is the subscript for the TIME slot in the @code{c_cc} array. Thus, +@code{@var{termios}.c_cc[VTIME]} is the value itself. + +The TIME slot is only meaningful in noncanonical input mode; it +specifies how long to wait for input before returning, in units of 0.1 +seconds. +@end deftypevr + +The MIN and TIME values interact to determine the criterion for when +@code{read} should return; their precise meanings depend on which of +them are nonzero. There are four possible cases: + +@itemize @bullet +@item +Both TIME and MIN are nonzero. + +In this case, TIME specifies how long to wait after each input character +to see if more input arrives. After the first character received, +@code{read} keeps waiting until either MIN bytes have arrived in all, or +TIME elapses with no further input. + +@code{read} always blocks until the first character arrives, even if +TIME elapses first. @code{read} can return more than MIN characters if +more than MIN happen to be in the queue. + +@item +Both MIN and TIME are zero. + +In this case, @code{read} always returns immediately with as many +characters as are available in the queue, up to the number requested. +If no input is immediately available, @code{read} returns a value of +zero. + +@item +MIN is zero but TIME has a nonzero value. + +In this case, @code{read} waits for time TIME for input to become +available; the availability of a single byte is enough to satisfy the +read request and cause @code{read} to return. When it returns, it +returns as many characters as are available, up to the number requested. +If no input is available before the timer expires, @code{read} returns a +value of zero. + +@item +TIME is zero but MIN has a nonzero value. + +In this case, @code{read} waits until at least MIN bytes are available +in the queue. At that time, @code{read} returns as many characters as +are available, up to the number requested. @code{read} can return more +than MIN characters if more than MIN happen to be in the queue. +@end itemize + +What happens if MIN is 50 and you ask to read just 10 bytes? +Normally, @code{read} waits until there are 50 bytes in the buffer (or, +more generally, the wait condition described above is satisfied), and +then reads 10 of them, leaving the other 40 buffered in the operating +system for a subsequent call to @code{read}. + +@strong{Portability note:} On some systems, the MIN and TIME slots are +actually the same as the EOF and EOL slots. This causes no serious +problem because the MIN and TIME slots are used only in noncanonical +input and the EOF and EOL slots are used only in canonical input, but it +isn't very clean. The GNU library allocates separate slots for these +uses. + +@comment termios.h +@comment BSD +@deftypefun int cfmakeraw (struct termios *@var{termios-p}) +This function provides an easy way to set up @code{*@var{termios-p}} for +what has traditionally been called ``raw mode'' in BSD. This uses +noncanonical input, and turns off most processing to give an unmodified +channel to the terminal. + +It does exactly this: +@smallexample + @var{termios-p}->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + @var{termios-p}->c_oflag &= ~OPOST; + @var{termios-p}->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + @var{termios-p}->c_cflag &= ~(CSIZE|PARENB); + @var{termios-p}->c_cflag |= CS8; +@end smallexample +@end deftypefun + +@node Line Control +@section Line Control Functions +@cindex terminal line control functions + +These functions perform miscellaneous control actions on terminal +devices. As regards terminal access, they are treated like doing +output: if any of these functions is used by a background process on its +controlling terminal, normally all processes in the process group are +sent a @code{SIGTTOU} signal. The exception is if the calling process +itself is ignoring or blocking @code{SIGTTOU} signals, in which case the +operation is performed and no signal is sent. @xref{Job Control}. + +@cindex break condition, generating +@comment termios.h +@comment POSIX.1 +@deftypefun int tcsendbreak (int @var{filedes}, int @var{duration}) +This function generates a break condition by transmitting a stream of +zero bits on the terminal associated with the file descriptor +@var{filedes}. The duration of the break is controlled by the +@var{duration} argument. If zero, the duration is between 0.25 and 0.5 +seconds. The meaning of a nonzero value depends on the operating system. + +This function does nothing if the terminal is not an asynchronous serial +data port. + +The return value is normally zero. In the event of an error, a value +of @code{-1} is returned. The following @code{errno} error conditions +are defined for this function: + +@table @code +@item EBADF +The @var{filedes} is not a valid file descriptor. + +@item ENOTTY +The @var{filedes} is not associated with a terminal device. +@end table +@end deftypefun + + +@cindex flushing terminal output queue +@cindex terminal output queue, flushing +@comment termios.h +@comment POSIX.1 +@deftypefun int tcdrain (int @var{filedes}) +The @code{tcdrain} function waits until all queued +output to the terminal @var{filedes} has been transmitted. + +The return value is normally zero. In the event of an error, a value +of @code{-1} is returned. The following @code{errno} error conditions +are defined for this function: + +@table @code +@item EBADF +The @var{filedes} is not a valid file descriptor. + +@item ENOTTY +The @var{filedes} is not associated with a terminal device. + +@item EINTR +The operation was interrupted by delivery of a signal. +@xref{Interrupted Primitives}. +@end table +@end deftypefun + + +@cindex clearing terminal input queue +@cindex terminal input queue, clearing +@comment termios.h +@comment POSIX.1 +@deftypefun int tcflush (int @var{filedes}, int @var{queue}) +The @code{tcflush} function is used to clear the input and/or output +queues associated with the terminal file @var{filedes}. The @var{queue} +argument specifies which queue(s) to clear, and can be one of the +following values: + +@c Extra blank lines here make it look better. +@table @code +@vindex TCIFLUSH +@item TCIFLUSH + +Clear any input data received, but not yet read. + +@vindex TCOFLUSH +@item TCOFLUSH + +Clear any output data written, but not yet transmitted. + +@vindex TCIOFLUSH +@item TCIOFLUSH + +Clear both queued input and output. +@end table + +The return value is normally zero. In the event of an error, a value +of @code{-1} is returned. The following @code{errno} error conditions +are defined for this function: + +@table @code +@item EBADF +The @var{filedes} is not a valid file descriptor. + +@item ENOTTY +The @var{filedes} is not associated with a terminal device. + +@item EINVAL +A bad value was supplied as the @var{queue} argument. +@end table + +It is unfortunate that this function is named @code{tcflush}, because +the term ``flush'' is normally used for quite another operation---waiting +until all output is transmitted---and using it for discarding input or +output would be confusing. Unfortunately, the name @code{tcflush} comes +from POSIX and we cannot change it. +@end deftypefun + +@cindex flow control, terminal +@cindex terminal flow control +@comment termios.h +@comment POSIX.1 +@deftypefun int tcflow (int @var{filedes}, int @var{action}) +The @code{tcflow} function is used to perform operations relating to +XON/XOFF flow control on the terminal file specified by @var{filedes}. + +The @var{action} argument specifies what operation to perform, and can +be one of the following values: + +@table @code +@vindex TCOOFF +@item TCOOFF +Suspend transmission of output. + +@vindex TCOON +@item TCOON +Restart transmission of output. + +@vindex TCIOFF +@item TCIOFF +Transmit a STOP character. + +@vindex TCION +@item TCION +Transmit a START character. +@end table + +For more information about the STOP and START characters, see @ref{Special +Characters}. + +The return value is normally zero. In the event of an error, a value +of @code{-1} is returned. The following @code{errno} error conditions +are defined for this function: + +@table @code +@vindex EBADF +@item EBADF +The @var{filedes} is not a valid file descriptor. + +@vindex ENOTTY +@item ENOTTY +The @var{filedes} is not associated with a terminal device. + +@vindex EINVAL +@item EINVAL +A bad value was supplied as the @var{action} argument. +@end table +@end deftypefun + +@node Noncanon Example +@section Noncanonical Mode Example + +Here is an example program that shows how you can set up a terminal +device to read single characters in noncanonical input mode, without +echo. + +@smallexample +@include termios.c.texi +@end smallexample + +This program is careful to restore the original terminal modes before +exiting or terminating with a signal. It uses the @code{atexit} +function (@pxref{Cleanups on Exit}) to make sure this is done +by @code{exit}. + +@ignore +@c !!!! the example doesn't handle any signals! +The signals handled in the example are the ones that typically occur due +to actions of the user. It might be desirable to handle other signals +such as SIGSEGV that can result from bugs in the program. +@end ignore + +The shell is supposed to take care of resetting the terminal modes when +a process is stopped or continued; see @ref{Job Control}. But some +existing shells do not actually do this, so you may wish to establish +handlers for job control signals that reset terminal modes. The above +example does so. diff --git a/manual/time.texi b/manual/time.texi new file mode 100644 index 0000000000..767c318a42 --- /dev/null +++ b/manual/time.texi @@ -0,0 +1,1574 @@ +@node Date and Time, Non-Local Exits, Arithmetic, Top +@chapter Date and Time + +This chapter describes functions for manipulating dates and times, +including functions for determining what the current time is and +conversion between different time representations. + +The time functions fall into three main categories: + +@itemize @bullet +@item +Functions for measuring elapsed CPU time are discussed in @ref{Processor +Time}. + +@item +Functions for measuring absolute clock or calendar time are discussed in +@ref{Calendar Time}. + +@item +Functions for setting alarms and timers are discussed in @ref{Setting +an Alarm}. +@end itemize + +@menu +* Processor Time:: Measures processor time used by a program. +* Calendar Time:: Manipulation of ``real'' dates and times. +* Setting an Alarm:: Sending a signal after a specified time. +* Sleeping:: Waiting for a period of time. +* Resource Usage:: Measuring various resources used. +* Limits on Resources:: Specifying limits on resource usage. +* Priority:: Reading or setting process run priority. +@end menu + +@node Processor Time +@section Processor Time + +If you're trying to optimize your program or measure its efficiency, it's +very useful to be able to know how much @dfn{processor time} or @dfn{CPU +time} it has used at any given point. Processor time is different from +actual wall clock time because it doesn't include any time spent waiting +for I/O or when some other process is running. Processor time is +represented by the data type @code{clock_t}, and is given as a number of +@dfn{clock ticks} relative to an arbitrary base time marking the beginning +of a single program invocation. +@cindex CPU time +@cindex processor time +@cindex clock ticks +@cindex ticks, clock +@cindex time, elapsed CPU + +@menu +* Basic CPU Time:: The @code{clock} function. +* Detailed CPU Time:: The @code{times} function. +@end menu + +@node Basic CPU Time +@subsection Basic CPU Time Inquiry + +To get the elapsed CPU time used by a process, you can use the +@code{clock} function. This facility is declared in the header file +@file{time.h}. +@pindex time.h + +In typical usage, you call the @code{clock} function at the beginning and +end of the interval you want to time, subtract the values, and then divide +by @code{CLOCKS_PER_SEC} (the number of clock ticks per second), like this: + +@smallexample +@group +#include <time.h> + +clock_t start, end; +double elapsed; + +start = clock(); +@dots{} /* @r{Do the work.} */ +end = clock(); +elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; +@end group +@end smallexample + +Different computers and operating systems vary wildly in how they keep +track of processor time. It's common for the internal processor clock +to have a resolution somewhere between hundredths and millionths of a +second. + +In the GNU system, @code{clock_t} is equivalent to @code{long int} and +@code{CLOCKS_PER_SEC} is an integer value. But in other systems, both +@code{clock_t} and the type of the macro @code{CLOCKS_PER_SEC} can be +either integer or floating-point types. Casting processor time values +to @code{double}, as in the example above, makes sure that operations +such as arithmetic and printing work properly and consistently no matter +what the underlying representation is. + +@comment time.h +@comment ANSI +@deftypevr Macro int CLOCKS_PER_SEC +The value of this macro is the number of clock ticks per second measured +by the @code{clock} function. +@end deftypevr + +@comment time.h +@comment POSIX.1 +@deftypevr Macro int CLK_TCK +This is an obsolete name for @code{CLOCKS_PER_SEC}. +@end deftypevr + +@comment time.h +@comment ANSI +@deftp {Data Type} clock_t +This is the type of the value returned by the @code{clock} function. +Values of type @code{clock_t} are in units of clock ticks. +@end deftp + +@comment time.h +@comment ANSI +@deftypefun clock_t clock (void) +This function returns the elapsed processor time. The base time is +arbitrary but doesn't change within a single process. If the processor +time is not available or cannot be represented, @code{clock} returns the +value @code{(clock_t)(-1)}. +@end deftypefun + + +@node Detailed CPU Time +@subsection Detailed Elapsed CPU Time Inquiry + +The @code{times} function returns more detailed information about +elapsed processor time in a @w{@code{struct tms}} object. You should +include the header file @file{sys/times.h} to use this facility. +@pindex sys/times.h + +@comment sys/times.h +@comment POSIX.1 +@deftp {Data Type} {struct tms} +The @code{tms} structure is used to return information about process +times. It contains at least the following members: + +@table @code +@item clock_t tms_utime +This is the CPU time used in executing the instructions of the calling +process. + +@item clock_t tms_stime +This is the CPU time used by the system on behalf of the calling process. + +@item clock_t tms_cutime +This is the sum of the @code{tms_utime} values and the @code{tms_cutime} +values of all terminated child processes of the calling process, whose +status has been reported to the parent process by @code{wait} or +@code{waitpid}; see @ref{Process Completion}. In other words, it +represents the total CPU time used in executing the instructions of all +the terminated child processes of the calling process, excluding child +processes which have not yet been reported by @code{wait} or +@code{waitpid}. + +@item clock_t tms_cstime +This is similar to @code{tms_cutime}, but represents the total CPU time +used by the system on behalf of all the terminated child processes of the +calling process. +@end table + +All of the times are given in clock ticks. These are absolute values; in a +newly created process, they are all zero. @xref{Creating a Process}. +@end deftp + +@comment sys/times.h +@comment POSIX.1 +@deftypefun clock_t times (struct tms *@var{buffer}) +The @code{times} function stores the processor time information for +the calling process in @var{buffer}. + +The return value is the same as the value of @code{clock()}: the elapsed +real time relative to an arbitrary base. The base is a constant within a +particular process, and typically represents the time since system +start-up. A value of @code{(clock_t)(-1)} is returned to indicate failure. +@end deftypefun + +@strong{Portability Note:} The @code{clock} function described in +@ref{Basic CPU Time}, is specified by the ANSI C standard. The +@code{times} function is a feature of POSIX.1. In the GNU system, the +value returned by the @code{clock} function is equivalent to the sum of +the @code{tms_utime} and @code{tms_stime} fields returned by +@code{times}. + +@node Calendar Time +@section Calendar Time + +This section describes facilities for keeping track of dates and times +according to the Gregorian calendar. +@cindex Gregorian calendar +@cindex time, calendar +@cindex date and time + +There are three representations for date and time information: + +@itemize @bullet +@item +@dfn{Calendar time} (the @code{time_t} data type) is a compact +representation, typically giving the number of seconds elapsed since +some implementation-specific base time. +@cindex calendar time + +@item +There is also a @dfn{high-resolution time} representation (the @code{struct +timeval} data type) that includes fractions of a second. Use this time +representation instead of ordinary calendar time when you need greater +precision. +@cindex high-resolution time + +@item +@dfn{Local time} or @dfn{broken-down time} (the @code{struct +tm} data type) represents the date and time as a set of components +specifying the year, month, and so on, for a specific time zone. +This time representation is usually used in conjunction with formatting +date and time values. +@cindex local time +@cindex broken-down time +@end itemize + +@menu +* Simple Calendar Time:: Facilities for manipulating calendar time. +* High-Resolution Calendar:: A time representation with greater precision. +* Broken-down Time:: Facilities for manipulating local time. +* Formatting Date and Time:: Converting times to strings. +* TZ Variable:: How users specify the time zone. +* Time Zone Functions:: Functions to examine or specify the time zone. +* Time Functions Example:: An example program showing use of some of + the time functions. +@end menu + +@node Simple Calendar Time +@subsection Simple Calendar Time + +This section describes the @code{time_t} data type for representing +calendar time, and the functions which operate on calendar time objects. +These facilities are declared in the header file @file{time.h}. +@pindex time.h + +@cindex epoch +@comment time.h +@comment ANSI +@deftp {Data Type} time_t +This is the data type used to represent calendar time. In the GNU C +library and other POSIX-compliant implementations, @code{time_t} is +equivalent to @code{long int}. When interpreted as an absolute time +value, it represents the number of seconds elapsed since 00:00:00 on +January 1, 1970, Coordinated Universal Time. (This date is sometimes +referred to as the @dfn{epoch}.) + +In other systems, @code{time_t} might be either an integer or +floating-point type. +@end deftp + +@comment time.h +@comment ANSI +@deftypefun double difftime (time_t @var{time1}, time_t @var{time0}) +The @code{difftime} function returns the number of seconds elapsed +between time @var{time1} and time @var{time0}, as a value of type +@code{double}. + +In the GNU system, you can simply subtract @code{time_t} values. But on +other systems, the @code{time_t} data type might use some other encoding +where subtraction doesn't work directly. +@end deftypefun + +@comment time.h +@comment ANSI +@deftypefun time_t time (time_t *@var{result}) +The @code{time} function returns the current time as a value of type +@code{time_t}. If the argument @var{result} is not a null pointer, the +time value is also stored in @code{*@var{result}}. If the calendar +time is not available, the value @w{@code{(time_t)(-1)}} is returned. +@end deftypefun + + +@node High-Resolution Calendar +@subsection High-Resolution Calendar + +The @code{time_t} data type used to represent calendar times has a +resolution of only one second. Some applications need more precision. + +So, the GNU C library also contains functions which are capable of +representing calendar times to a higher resolution than one second. The +functions and the associated data types described in this section are +declared in @file{sys/time.h}. +@pindex sys/time.h + +@comment sys/time.h +@comment BSD +@deftp {Data Type} {struct timeval} +The @code{struct timeval} structure represents a calendar time. It +has the following members: + +@table @code +@item long int tv_sec +This represents the number of seconds since the epoch. It is equivalent +to a normal @code{time_t} value. + +@item long int tv_usec +This is the fractional second value, represented as the number of +microseconds. + +Some times struct timeval values are used for time intervals. Then the +@code{tv_sec} member is the number of seconds in the interval, and +@code{tv_usec} is the number of additional microseconds. +@end table +@end deftp + +@comment sys/time.h +@comment BSD +@deftp {Data Type} {struct timezone} +The @code{struct timezone} structure is used to hold minimal information +about the local time zone. It has the following members: + +@table @code +@item int tz_minuteswest +This is the number of minutes west of GMT. + +@item int tz_dsttime +If nonzero, daylight savings time applies during some part of the year. +@end table + +The @code{struct timezone} type is obsolete and should never be used. +Instead, use the facilities described in @ref{Time Zone Functions}. +@end deftp + +It is often necessary to subtract two values of type @w{@code{struct +timeval}}. Here is the best way to do this. It works even on some +peculiar operating systems where the @code{tv_sec} member has an +unsigned type. + +@smallexample +/* @r{Subtract the `struct timeval' values X and Y,} + @r{storing the result in RESULT.} + @r{Return 1 if the difference is negative, otherwise 0.} */ + +int +timeval_subtract (result, x, y) + struct timeval *result, *x, *y; +@{ + /* @r{Perform the carry for the later subtraction by updating @var{y}.} */ + if (x->tv_usec < y->tv_usec) @{ + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + @} + if (x->tv_usec - y->tv_usec > 1000000) @{ + int nsec = (y->tv_usec - x->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + @} + + /* @r{Compute the time remaining to wait.} + @r{@code{tv_usec} is certainly positive.} */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* @r{Return 1 if result is negative.} */ + return x->tv_sec < y->tv_sec; +@} +@end smallexample + +@comment sys/time.h +@comment BSD +@deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp}) +The @code{gettimeofday} function returns the current date and time in the +@code{struct timeval} structure indicated by @var{tp}. Information about the +time zone is returned in the structure pointed at @var{tzp}. If the @var{tzp} +argument is a null pointer, time zone information is ignored. + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error condition is defined for this function: + +@table @code +@item ENOSYS +The operating system does not support getting time zone information, and +@var{tzp} is not a null pointer. The GNU operating system does not +support using @w{@code{struct timezone}} to represent time zone +information; that is an obsolete feature of 4.3 BSD. +Instead, use the facilities described in @ref{Time Zone Functions}. +@end table +@end deftypefun + +@comment sys/time.h +@comment BSD +@deftypefun int settimeofday (const struct timeval *@var{tp}, const struct timezone *@var{tzp}) +The @code{settimeofday} function sets the current date and time +according to the arguments. As for @code{gettimeofday}, time zone +information is ignored if @var{tzp} is a null pointer. + +You must be a privileged user in order to use @code{settimeofday}. + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EPERM +This process cannot set the time because it is not privileged. + +@item ENOSYS +The operating system does not support setting time zone information, and +@var{tzp} is not a null pointer. +@end table +@end deftypefun + +@comment sys/time.h +@comment BSD +@deftypefun int adjtime (const struct timeval *@var{delta}, struct timeval *@var{olddelta}) +This function speeds up or slows down the system clock in order to make +gradual adjustments in the current time. This ensures that the time +reported by the system clock is always monotonically increasing, which +might not happen if you simply set the current time. + +The @var{delta} argument specifies a relative adjustment to be made to +the current time. If negative, the system clock is slowed down for a +while until it has lost this much time. If positive, the system clock +is speeded up for a while. + +If the @var{olddelta} argument is not a null pointer, the @code{adjtime} +function returns information about any previous time adjustment that +has not yet completed. + +This function is typically used to synchronize the clocks of computers +in a local network. You must be a privileged user to use it. +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error condition is defined for this function: + +@table @code +@item EPERM +You do not have privilege to set the time. +@end table +@end deftypefun + +@strong{Portability Note:} The @code{gettimeofday}, @code{settimeofday}, +and @code{adjtime} functions are derived from BSD. + + +@node Broken-down Time +@subsection Broken-down Time +@cindex broken-down time +@cindex calendar time and broken-down time + +Calendar time is represented as a number of seconds. This is convenient +for calculation, but has no resemblance to the way people normally +represent dates and times. By contrast, @dfn{broken-down time} is a binary +representation separated into year, month, day, and so on. Broken down +time values are not useful for calculations, but they are useful for +printing human readable time. + +A broken-down time value is always relative to a choice of local time +zone, and it also indicates which time zone was used. + +The symbols in this section are declared in the header file @file{time.h}. + +@comment time.h +@comment ANSI +@deftp {Data Type} {struct tm} +This is the data type used to represent a broken-down time. The structure +contains at least the following members, which can appear in any order: + +@table @code +@item int tm_sec +This is the number of seconds after the minute, normally in the range +@code{0} to @code{59}. (The actual upper limit is @code{61}, to allow +for ``leap seconds''.) +@cindex leap second + +@item int tm_min +This is the number of minutes after the hour, in the range @code{0} to +@code{59}. + +@item int tm_hour +This is the number of hours past midnight, in the range @code{0} to +@code{23}. + +@item int tm_mday +This is the day of the month, in the range @code{1} to @code{31}. + +@item int tm_mon +This is the number of months since January, in the range @code{0} to +@code{11}. + +@item int tm_year +This is the number of years since @code{1900}. + +@item int tm_wday +This is the number of days since Sunday, in the range @code{0} to @code{6}. + +@item int tm_yday +This is the number of days since January 1, in the range @code{0} to +@code{365}. + +@item int tm_isdst +@cindex Daylight Saving Time +@cindex summer time +This is a flag that indicates whether Daylight Saving Time is (or was, or +will be) in effect at the time described. The value is positive if +Daylight Saving Time is in effect, zero if it is not, and negative if the +information is not available. + +@item long int tm_gmtoff +This field describes the time zone that was used to compute this +broken-down time value; it is the amount you must add to the local time +in that zone to get GMT, in units of seconds. The value is like that of +the variable @code{timezone} (@pxref{Time Zone Functions}). You can +also think of this as the ``number of seconds west'' of GMT. The +@code{tm_gmtoff} field is a GNU library extension. + +@item const char *tm_zone +This field is the three-letter name for the time zone that was used to +compute this broken-down time value. It is a GNU library extension. +@end table +@end deftp + +@comment time.h +@comment ANSI +@deftypefun {struct tm *} localtime (const time_t *@var{time}) +The @code{localtime} function converts the calendar time pointed to by +@var{time} to broken-down time representation, expressed relative to the +user's specified time zone. + +The return value is a pointer to a static broken-down time structure, which +might be overwritten by subsequent calls to any of the date and time +functions. (But no other library function overwrites the contents of this +object.) + +Calling @code{localtime} has one other effect: it sets the variable +@code{tzname} with information about the current time zone. @xref{Time +Zone Functions}. +@end deftypefun + +@comment time.h +@comment ANSI +@deftypefun {struct tm *} gmtime (const time_t *@var{time}) +This function is similar to @code{localtime}, except that the broken-down +time is expressed as Coordinated Universal Time (UTC)---that is, as +Greenwich Mean Time (GMT) rather than relative to the local time zone. + +Recall that calendar times are @emph{always} expressed in coordinated +universal time. +@end deftypefun + +@comment time.h +@comment ANSI +@deftypefun time_t mktime (struct tm *@var{brokentime}) +The @code{mktime} function is used to convert a broken-down time structure +to a calendar time representation. It also ``normalizes'' the contents of +the broken-down time structure, by filling in the day of week and day of +year based on the other date and time components. + +The @code{mktime} function ignores the specified contents of the +@code{tm_wday} and @code{tm_yday} members of the broken-down time +structure. It uses the values of the other components to compute the +calendar time; it's permissible for these components to have +unnormalized values outside of their normal ranges. The last thing that +@code{mktime} does is adjust the components of the @var{brokentime} +structure (including the @code{tm_wday} and @code{tm_yday}). + +If the specified broken-down time cannot be represented as a calendar time, +@code{mktime} returns a value of @code{(time_t)(-1)} and does not modify +the contents of @var{brokentime}. + +Calling @code{mktime} also sets the variable @code{tzname} with +information about the current time zone. @xref{Time Zone Functions}. +@end deftypefun + +@node Formatting Date and Time +@subsection Formatting Date and Time + +The functions described in this section format time values as strings. +These functions are declared in the header file @file{time.h}. +@pindex time.h + +@comment time.h +@comment ANSI +@deftypefun {char *} asctime (const struct tm *@var{brokentime}) +The @code{asctime} function converts the broken-down time value that +@var{brokentime} points to into a string in a standard format: + +@smallexample +"Tue May 21 13:46:22 1991\n" +@end smallexample + +The abbreviations for the days of week are: @samp{Sun}, @samp{Mon}, +@samp{Tue}, @samp{Wed}, @samp{Thu}, @samp{Fri}, and @samp{Sat}. + +The abbreviations for the months are: @samp{Jan}, @samp{Feb}, +@samp{Mar}, @samp{Apr}, @samp{May}, @samp{Jun}, @samp{Jul}, @samp{Aug}, +@samp{Sep}, @samp{Oct}, @samp{Nov}, and @samp{Dec}. + +The return value points to a statically allocated string, which might be +overwritten by subsequent calls to any of the date and time functions. +(But no other library function overwrites the contents of this +string.) +@end deftypefun + +@comment time.h +@comment ANSI +@deftypefun {char *} ctime (const time_t *@var{time}) +The @code{ctime} function is similar to @code{asctime}, except that the +time value is specified as a @code{time_t} calendar time value rather +than in broken-down local time format. It is equivalent to + +@smallexample +asctime (localtime (@var{time})) +@end smallexample + +@code{ctime} sets the variable @code{tzname}, because @code{localtime} +does so. @xref{Time Zone Functions}. +@end deftypefun + +@comment time.h +@comment ANSI +@deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime}) +This function is similar to the @code{sprintf} function (@pxref{Formatted +Input}), but the conversion specifications that can appear in the format +template @var{template} are specialized for printing components of the date +and time @var{brokentime} according to the locale currently specified for +time conversion (@pxref{Locales}). + +Ordinary characters appearing in the @var{template} are copied to the +output string @var{s}; this can include multibyte character sequences. +Conversion specifiers are introduced by a @samp{%} character, and are +replaced in the output string as follows: + +@table @code +@item %a +The abbreviated weekday name according to the current locale. + +@item %A +The full weekday name according to the current locale. + +@item %b +The abbreviated month name according to the current locale. + +@item %B +The full month name according to the current locale. + +@item %c +The preferred date and time representation for the current locale. + +@item %d +The day of the month as a decimal number (range @code{01} to @code{31}). + +@item %H +The hour as a decimal number, using a 24-hour clock (range @code{00} to +@code{23}). + +@item %I +The hour as a decimal number, using a 12-hour clock (range @code{01} to +@code{12}). + +@item %j +The day of the year as a decimal number (range @code{001} to @code{366}). + +@item %m +The month as a decimal number (range @code{01} to @code{12}). + +@item %M +The minute as a decimal number. + +@item %p +Either @samp{am} or @samp{pm}, according to the given time value; or the +corresponding strings for the current locale. + +@item %S +The second as a decimal number. + +@item %U +The week number of the current year as a decimal number, starting with +the first Sunday as the first day of the first week. + +@item %W +The week number of the current year as a decimal number, starting with +the first Monday as the first day of the first week. + +@item %w +The day of the week as a decimal number, Sunday being @code{0}. + +@item %x +The preferred date representation for the current locale, but without the +time. + +@item %X +The preferred time representation for the current locale, but with no date. + +@item %y +The year as a decimal number, but without a century (range @code{00} to +@code{99}). + +@item %Y +The year as a decimal number, including the century. + +@item %Z +The time zone or name or abbreviation (empty if the time zone can't be +determined). + +@item %% +A literal @samp{%} character. +@end table + +The @var{size} parameter can be used to specify the maximum number of +characters to be stored in the array @var{s}, including the terminating +null character. If the formatted time requires more than @var{size} +characters, the excess characters are discarded. The return value from +@code{strftime} is the number of characters placed in the array @var{s}, +not including the terminating null character. If the value equals +@var{size}, it means that the array @var{s} was too small; you should +repeat the call, providing a bigger array. + +If @var{s} is a null pointer, @code{strftime} does not actually write +anything, but instead returns the number of characters it would have written. + +For an example of @code{strftime}, see @ref{Time Functions Example}. +@end deftypefun + +@node TZ Variable +@subsection Specifying the Time Zone with @code{TZ} + +In POSIX systems, a user can specify the time zone by means of the +@code{TZ} environment variable. For information about how to set +environment variables, see @ref{Environment Variables}. The functions +for accessing the time zone are declared in @file{time.h}. +@pindex time.h +@cindex time zone + +You should not normally need to set @code{TZ}. If the system is +configured properly, the default timezone will be correct. You might +set @code{TZ} if you are using a computer over the network from a +different timezone, and would like times reported to you in the timezone +that local for you, rather than what is local for the computer. + +In POSIX.1 systems the value of the @code{TZ} variable can be of one of +three formats. With the GNU C library, the most common format is the +last one, which can specify a selection from a large database of time +zone information for many regions of the world. The first two formats +are used to describe the time zone information directly, which is both +more cumbersome and less precise. But the POSIX.1 standard only +specifies the details of the first two formats, so it is good to be +familiar with them in case you come across a POSIX.1 system that doesn't +support a time zone information database. + +The first format is used when there is no Daylight Saving Time (or +summer time) in the local time zone: + +@smallexample +@r{@var{std} @var{offset}} +@end smallexample + +The @var{std} string specifies the name of the time zone. It must be +three or more characters long and must not contain a leading colon or +embedded digits, commas, or plus or minus signs. There is no space +character separating the time zone name from the @var{offset}, so these +restrictions are necessary to parse the specification correctly. + +The @var{offset} specifies the time value one must add to the local time +to get a Coordinated Universal Time value. It has syntax like +[@code{+}|@code{-}]@var{hh}[@code{:}@var{mm}[@code{:}@var{ss}]]. This +is positive if the local time zone is west of the Prime Meridian and +negative if it is east. The hour must be between @code{0} and +@code{24}, and the minute and seconds between @code{0} and @code{59}. + +For example, here is how we would specify Eastern Standard Time, but +without any daylight savings time alternative: + +@smallexample +EST+5 +@end smallexample + +The second format is used when there is Daylight Saving Time: + +@smallexample +@r{@var{std} @var{offset} @var{dst} [@var{offset}]@code{,}@var{start}[@code{/}@var{time}]@code{,}@var{end}[@code{/}@var{time}]} +@end smallexample + +The initial @var{std} and @var{offset} specify the standard time zone, as +described above. The @var{dst} string and @var{offset} specify the name +and offset for the corresponding daylight savings time time zone; if the +@var{offset} is omitted, it defaults to one hour ahead of standard time. + +The remainder of the specification describes when daylight savings time is +in effect. The @var{start} field is when daylight savings time goes into +effect and the @var{end} field is when the change is made back to standard +time. The following formats are recognized for these fields: + +@table @code +@item J@var{n} +This specifies the Julian day, with @var{n} between @code{1} and @code{365}. +February 29 is never counted, even in leap years. + +@item @var{n} +This specifies the Julian day, with @var{n} between @code{0} and @code{365}. +February 29 is counted in leap years. + +@item M@var{m}.@var{w}.@var{d} +This specifies day @var{d} of week @var{w} of month @var{m}. The day +@var{d} must be between @code{0} (Sunday) and @code{6}. The week +@var{w} must be between @code{1} and @code{5}; week @code{1} is the +first week in which day @var{d} occurs, and week @code{5} specifies the +@emph{last} @var{d} day in the month. The month @var{m} should be +between @code{1} and @code{12}. +@end table + +The @var{time} fields specify when, in the local time currently in +effect, the change to the other time occurs. If omitted, the default is +@code{02:00:00}. + +For example, here is how one would specify the Eastern time zone in the +United States, including the appropriate daylight saving time and its dates +of applicability. The normal offset from GMT is 5 hours; since this is +west of the prime meridian, the sign is positive. Summer time begins on +the first Sunday in April at 2:00am, and ends on the last Sunday in October +at 2:00am. + +@smallexample +EST+5EDT,M4.1.0/M10.5.0 +@end smallexample + +The schedule of daylight savings time in any particular jurisdiction has +changed over the years. To be strictly correct, the conversion of dates +and times in the past should be based on the schedule that was in effect +then. However, this format has no facilities to let you specify how the +schedule has changed from year to year. The most you can do is specify +one particular schedule---usually the present day schedule---and this is +used to convert any date, no matter when. For precise time zone +specifications, it is best to use the time zone information database +(see below). + +The third format looks like this: + +@smallexample +:@var{characters} +@end smallexample + +Each operating system interprets this format differently; in the GNU C +library, @var{characters} is the name of a file which describes the time +zone. + +@pindex /etc/localtime +@pindex localtime +If the @code{TZ} environment variable does not have a value, the +operation chooses a time zone by default. In the GNU C library, the +default time zone is like the specification @samp{TZ=:/etc/localtime} +(or @samp{TZ=:/usr/local/etc/localtime}, depending on how GNU C library +was configured; @pxref{Installation}). Other C libraries use their own +rule for choosing the default time zone, so there is little we can say +about them. + +@cindex time zone database +@pindex /share/lib/zoneinfo +@pindex zoneinfo +If @var{characters} begins with a slash, it is an absolute file name; +otherwise the library looks for the file +@w{@file{/share/lib/zoneinfo/@var{characters}}}. The @file{zoneinfo} +directory contains data files describing local time zones in many +different parts of the world. The names represent major cities, with +subdirectories for geographical areas; for example, +@file{America/New_York}, @file{Europe/London}, @file{Asia/Hong_Kong}. +These data files are installed by the system administrator, who also +sets @file{/etc/localtime} to point to the data file for the local time +zone. The GNU C library comes with a large database of time zone +information for most regions of the world, which is maintained by a +community of volunteers and put in the public domain. + +@node Time Zone Functions +@subsection Functions and Variables for Time Zones + +@comment time.h +@comment POSIX.1 +@deftypevar char * tzname [2] +The array @code{tzname} contains two strings, which are the standard +three-letter names of the pair of time zones (standard and daylight +savings) that the user has selected. @code{tzname[0]} is the name of +the standard time zone (for example, @code{"EST"}), and @code{tzname[1]} +is the name for the time zone when daylight savings time is in use (for +example, @code{"EDT"}). These correspond to the @var{std} and @var{dst} +strings (respectively) from the @code{TZ} environment variable. + +The @code{tzname} array is initialized from the @code{TZ} environment +variable whenever @code{tzset}, @code{ctime}, @code{strftime}, +@code{mktime}, or @code{localtime} is called. +@end deftypevar + +@comment time.h +@comment POSIX.1 +@deftypefun void tzset (void) +The @code{tzset} function initializes the @code{tzname} variable from +the value of the @code{TZ} environment variable. It is not usually +necessary for your program to call this function, because it is called +automatically when you use the other time conversion functions that +depend on the time zone. +@end deftypefun + +The following variables are defined for compatibility with System V +Unix. These variables are set by calling @code{localtime}. + +@comment time.h +@comment SVID +@deftypevar {long int} timezone +This contains the difference between GMT and local standard time, in +seconds. For example, in the U.S. Eastern time zone, the value is +@code{5*60*60}. +@end deftypevar + +@comment time.h +@comment SVID +@deftypevar int daylight +This variable has a nonzero value if the standard U.S. daylight savings +time rules apply. +@end deftypevar + +@node Time Functions Example +@subsection Time Functions Example + +Here is an example program showing the use of some of the local time and +calendar time functions. + +@smallexample +@include strftim.c.texi +@end smallexample + +It produces output like this: + +@smallexample +Wed Jul 31 13:02:36 1991 +Today is Wednesday, July 31. +The time is 01:02 PM. +@end smallexample + + +@node Setting an Alarm +@section Setting an Alarm + +The @code{alarm} and @code{setitimer} functions provide a mechanism for a +process to interrupt itself at some future time. They do this by setting a +timer; when the timer expires, the process receives a signal. + +@cindex setting an alarm +@cindex interval timer, setting +@cindex alarms, setting +@cindex timers, setting +Each process has three independent interval timers available: + +@itemize @bullet +@item +A real-time timer that counts clock time. This timer sends a +@code{SIGALRM} signal to the process when it expires. +@cindex real-time timer +@cindex timer, real-time + +@item +A virtual timer that counts CPU time used by the process. This timer +sends a @code{SIGVTALRM} signal to the process when it expires. +@cindex virtual timer +@cindex timer, virtual + +@item +A profiling timer that counts both CPU time used by the process, and CPU +time spent in system calls on behalf of the process. This timer sends a +@code{SIGPROF} signal to the process when it expires. +@cindex profiling timer +@cindex timer, profiling + +This timer is useful for profiling in interpreters. The interval timer +mechanism does not have the fine granularity necessary for profiling +native code. +@c @xref{profil} !!! +@end itemize + +You can only have one timer of each kind set at any given time. If you +set a timer that has not yet expired, that timer is simply reset to the +new value. + +You should establish a handler for the appropriate alarm signal using +@code{signal} or @code{sigaction} before issuing a call to @code{setitimer} +or @code{alarm}. Otherwise, an unusual chain of events could cause the +timer to expire before your program establishes the handler, and in that +case it would be terminated, since that is the default action for the alarm +signals. @xref{Signal Handling}. + +The @code{setitimer} function is the primary means for setting an alarm. +This facility is declared in the header file @file{sys/time.h}. The +@code{alarm} function, declared in @file{unistd.h}, provides a somewhat +simpler interface for setting the real-time timer. +@pindex unistd.h +@pindex sys/time.h + +@comment sys/time.h +@comment BSD +@deftp {Data Type} {struct itimerval} +This structure is used to specify when a timer should expire. It contains +the following members: +@table @code +@item struct timeval it_interval +This is the interval between successive timer interrupts. If zero, the +alarm will only be sent once. + +@item struct timeval it_value +This is the interval to the first timer interrupt. If zero, the alarm is +disabled. +@end table + +The @code{struct timeval} data type is described in @ref{High-Resolution +Calendar}. +@end deftp + +@comment sys/time.h +@comment BSD +@deftypefun int setitimer (int @var{which}, struct itimerval *@var{new}, struct itimerval *@var{old}) +The @code{setitimer} function sets the timer specified by @var{which} +according to @var{new}. The @var{which} argument can have a value of +@code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, or @code{ITIMER_PROF}. + +If @var{old} is not a null pointer, @code{setitimer} returns information +about any previous unexpired timer of the same kind in the structure it +points to. + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error conditions are defined for this function: + +@table @code +@item EINVAL +The timer interval was too large. +@end table +@end deftypefun + +@comment sys/time.h +@comment BSD +@deftypefun int getitimer (int @var{which}, struct itimerval *@var{old}) +The @code{getitimer} function stores information about the timer specified +by @var{which} in the structure pointed at by @var{old}. + +The return value and error conditions are the same as for @code{setitimer}. +@end deftypefun + +@comment sys/time.h +@comment BSD +@table @code +@item ITIMER_REAL +@findex ITIMER_REAL +This constant can be used as the @var{which} argument to the +@code{setitimer} and @code{getitimer} functions to specify the real-time +timer. + +@comment sys/time.h +@comment BSD +@item ITIMER_VIRTUAL +@findex ITIMER_VIRTUAL +This constant can be used as the @var{which} argument to the +@code{setitimer} and @code{getitimer} functions to specify the virtual +timer. + +@comment sys/time.h +@comment BSD +@item ITIMER_PROF +@findex ITIMER_PROF +This constant can be used as the @var{which} argument to the +@code{setitimer} and @code{getitimer} functions to specify the profiling +timer. +@end table + +@comment unistd.h +@comment POSIX.1 +@deftypefun {unsigned int} alarm (unsigned int @var{seconds}) +The @code{alarm} function sets the real-time timer to expire in +@var{seconds} seconds. If you want to cancel any existing alarm, you +can do this by calling @code{alarm} with a @var{seconds} argument of +zero. + +The return value indicates how many seconds remain before the previous +alarm would have been sent. If there is no previous alarm, @code{alarm} +returns zero. +@end deftypefun + +The @code{alarm} function could be defined in terms of @code{setitimer} +like this: + +@smallexample +unsigned int +alarm (unsigned int seconds) +@{ + struct itimerval old, new; + new.it_interval.tv_usec = 0; + new.it_interval.tv_sec = 0; + new.it_value.tv_usec = 0; + new.it_value.tv_sec = (long int) seconds; + if (setitimer (ITIMER_REAL, &new, &old) < 0) + return 0; + else + return old.it_value.tv_sec; +@} +@end smallexample + +There is an example showing the use of the @code{alarm} function in +@ref{Handler Returns}. + +If you simply want your process to wait for a given number of seconds, +you should use the @code{sleep} function. @xref{Sleeping}. + +You shouldn't count on the signal arriving precisely when the timer +expires. In a multiprocessing environment there is typically some +amount of delay involved. + +@strong{Portability Note:} The @code{setitimer} and @code{getitimer} +functions are derived from BSD Unix, while the @code{alarm} function is +specified by the POSIX.1 standard. @code{setitimer} is more powerful than +@code{alarm}, but @code{alarm} is more widely used. + +@node Sleeping +@section Sleeping + +The function @code{sleep} gives a simple way to make the program wait +for short periods of time. If your program doesn't use signals (except +to terminate), then you can expect @code{sleep} to wait reliably for +the specified amount of time. Otherwise, @code{sleep} can return sooner +if a signal arrives; if you want to wait for a given period regardless +of signals, use @code{select} (@pxref{Waiting for I/O}) and don't +specify any descriptors to wait for. +@c !!! select can get EINTR; using SA_RESTART makes sleep win too. + +@comment unistd.h +@comment POSIX.1 +@deftypefun {unsigned int} sleep (unsigned int @var{seconds}) +The @code{sleep} function waits for @var{seconds} or until a signal +is delivered, whichever happens first. + +If @code{sleep} function returns because the requested time has +elapsed, it returns a value of zero. If it returns because of delivery +of a signal, its return value is the remaining time in the sleep period. + +The @code{sleep} function is declared in @file{unistd.h}. +@end deftypefun + +Resist the temptation to implement a sleep for a fixed amount of time by +using the return value of @code{sleep}, when nonzero, to call +@code{sleep} again. This will work with a certain amount of accuracy as +long as signals arrive infrequently. But each signal can cause the +eventual wakeup time to be off by an additional second or so. Suppose a +few signals happen to arrive in rapid succession by bad luck---there is +no limit on how much this could shorten or lengthen the wait. + +Instead, compute the time at which the program should stop waiting, and +keep trying to wait until that time. This won't be off by more than a +second. With just a little more work, you can use @code{select} and +make the waiting period quite accurate. (Of course, heavy system load +can cause unavoidable additional delays---unless the machine is +dedicated to one application, there is no way you can avoid this.) + +On some systems, @code{sleep} can do strange things if your program uses +@code{SIGALRM} explicitly. Even if @code{SIGALRM} signals are being +ignored or blocked when @code{sleep} is called, @code{sleep} might +return prematurely on delivery of a @code{SIGALRM} signal. If you have +established a handler for @code{SIGALRM} signals and a @code{SIGALRM} +signal is delivered while the process is sleeping, the action taken +might be just to cause @code{sleep} to return instead of invoking your +handler. And, if @code{sleep} is interrupted by delivery of a signal +whose handler requests an alarm or alters the handling of @code{SIGALRM}, +this handler and @code{sleep} will interfere. + +On the GNU system, it is safe to use @code{sleep} and @code{SIGALRM} in +the same program, because @code{sleep} does not work by means of +@code{SIGALRM}. + +@node Resource Usage +@section Resource Usage + +@pindex sys/resource.h +The function @code{getrusage} and the data type @code{struct rusage} +are used for examining the usage figures of a process. They are declared +in @file{sys/resource.h}. + +@comment sys/resource.h +@comment BSD +@deftypefun int getrusage (int @var{processes}, struct rusage *@var{rusage}) +This function reports the usage totals for processes specified by +@var{processes}, storing the information in @code{*@var{rusage}}. + +In most systems, @var{processes} has only two valid values: + +@table @code +@comment sys/resource.h +@comment BSD +@item RUSAGE_SELF +Just the current process. + +@comment sys/resource.h +@comment BSD +@item RUSAGE_CHILDREN +All child processes (direct and indirect) that have terminated already. +@end table + +In the GNU system, you can also inquire about a particular child process +by specifying its process ID. + +The return value of @code{getrusage} is zero for success, and @code{-1} +for failure. + +@table @code +@item EINVAL +The argument @var{processes} is not valid. +@end table +@end deftypefun + +One way of getting usage figures for a particular child process is with +the function @code{wait4}, which returns totals for a child when it +terminates. @xref{BSD Wait Functions}. + +@comment sys/resource.h +@comment BSD +@deftp {Data Type} {struct rusage} +This data type records a collection usage amounts for various sorts of +resources. It has the following members, and possibly others: + +@table @code +@item struct timeval ru_utime +Time spent executing user instructions. + +@item struct timeval ru_stime +Time spent in operating system code on behalf of @var{processes}. + +@item long int ru_maxrss +The maximum resident set size used, in kilobytes. That is, the maximum +number of kilobytes that @var{processes} used in real memory simultaneously. + +@item long int ru_ixrss +An integral value expressed in kilobytes times ticks of execution, which +indicates the amount of memory used by text that was shared with other +processes. + +@item long int ru_idrss +An integral value expressed the same way, which is the amount of +unshared memory used in data. + +@item long int ru_isrss +An integral value expressed the same way, which is the amount of +unshared memory used in stack space. + +@item long int ru_minflt +The number of page faults which were serviced without requiring any I/O. + +@item long int ru_majflt +The number of page faults which were serviced by doing I/O. + +@item long int ru_nswap +The number of times @var{processes} was swapped entirely out of main memory. + +@item long int ru_inblock +The number of times the file system had to read from the disk on behalf +of @var{processes}. + +@item long int ru_oublock +The number of times the file system had to write to the disk on behalf +of @var{processes}. + +@item long int ru_msgsnd +Number of IPC messages sent. + +@item long ru_msgrcv +Number of IPC messages received. + +@item long int ru_nsignals +Number of signals received. + +@item long int ru_nvcsw +The number of times @var{processes} voluntarily invoked a context switch +(usually to wait for some service). + +@item long int ru_nivcsw +The number of times an involuntary context switch took place (because +the time slice expired, or another process of higher priority became +runnable). +@end table +@end deftp + +An additional historical function for examining usage figures, +@code{vtimes}, is supported but not documented here. It is declared in +@file{sys/vtimes.h}. + +@node Limits on Resources +@section Limiting Resource Usage +@cindex resource limits +@cindex limits on resource usage +@cindex usage limits + +You can specify limits for the resource usage of a process. When the +process tries to exceed a limit, it may get a signal, or the system call +by which it tried to do so may fail, depending on the limit. Each +process initially inherits its limit values from its parent, but it can +subsequently change them. + +@pindex sys/resource.h +The symbols in this section are defined in @file{sys/resource.h}. + +@comment sys/resource.h +@comment BSD +@deftypefun int getrlimit (int @var{resource}, struct rlimit *@var{rlp}) +Read the current value and the maximum value of resource @var{resource} +and store them in @code{*@var{rlp}}. + +The return value is @code{0} on success and @code{-1} on failure. The +only possible @code{errno} error condition is @code{EFAULT}. +@end deftypefun + +@comment sys/resource.h +@comment BSD +@deftypefun int setrlimit (int @var{resource}, struct rlimit *@var{rlp}) +Store the current value and the maximum value of resource @var{resource} +in @code{*@var{rlp}}. + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error condition is possible: + +@table @code +@item EPERM +You tried to change the maximum permissible limit value, +but you don't have privileges to do so. +@end table +@end deftypefun + +@comment sys/resource.h +@comment BSD +@deftp {Data Type} {struct rlimit} +This structure is used with @code{getrlimit} to receive limit values, +and with @code{setrlimit} to specify limit values. It has two fields: + +@table @code +@item rlim_cur +The current value of the limit in question. +This is also called the ``soft limit''. +@cindex soft limit + +@item rlim_max +The maximum permissible value of the limit in question. You cannot set +the current value of the limit to a larger number than this maximum. +Only the super user can change the maximum permissible value. +This is also called the ``hard limit''. +@cindex hard limit +@end table + +In @code{getrlimit}, the structure is an output; it receives the current +values. In @code{setrlimit}, it specifies the new values. +@end deftp + +Here is a list of resources that you can specify a limit for. +Those that are sizes are measured in bytes. + +@table @code +@comment sys/resource.h +@comment BSD +@item RLIMIT_CPU +@vindex RLIMIT_CPU +The maximum amount of cpu time the process can use. If it runs for +longer than this, it gets a signal: @code{SIGXCPU}. The value is +measured in seconds. @xref{Operation Error Signals}. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_FSIZE +@vindex RLIMIT_FSIZE +The maximum size of file the process can create. Trying to write a +larger file causes a signal: @code{SIGXFSZ}. @xref{Operation Error +Signals}. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_DATA +@vindex RLIMIT_DATA +The maximum size of data memory for the process. If the process tries +to allocate data memory beyond this amount, the allocation function +fails. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_STACK +@vindex RLIMIT_STACK +The maximum stack size for the process. If the process tries to extend +its stack past this size, it gets a @code{SIGSEGV} signal. +@xref{Program Error Signals}. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_CORE +@vindex RLIMIT_CORE +The maximum size core file that this process can create. If the process +terminates and would dump a core file larger than this maximum size, +then no core file is created. So setting this limit to zero prevents +core files from ever being created. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_RSS +@vindex RLIMIT_RSS +The maximum amount of physical memory that this process should get. +This parameter is a guide for the system's scheduler and memory +allocator; the system may give the process more memory when there is a +surplus. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_MEMLOCK +The maximum amount of memory that can be locked into physical memory (so +it will never be paged out). + +@comment sys/resource.h +@comment BSD +@item RLIMIT_NPROC +The maximum number of processes that can be created with the same user ID. +If you have reached the limit for your user ID, @code{fork} will fail +with @code{EAGAIN}. @xref{Creating a Process}. + +@comment sys/resource.h +@comment BSD +@item RLIMIT_NOFILE +@vindex RLIMIT_NOFILE +@itemx RLIMIT_OFILE +@vindex RLIMIT_OFILE +The maximum number of files that the process can open. If it tries to +open more files than this, it gets error code @code{EMFILE}. +@xref{Error Codes}. Not all systems support this limit; GNU does, and +4.4 BSD does. + +@comment sys/resource.h +@comment BSD +@item RLIM_NLIMITS +@vindex RLIM_NLIMITS +The number of different resource limits. Any valid @var{resource} +operand must be less than @code{RLIM_NLIMITS}. +@end table + +@comment sys/resource.h +@comment BSD +@defvr Constant int RLIM_INFINITY +This constant stands for a value of ``infinity'' when supplied as +the limit value in @code{setrlimit}. +@end defvr + +@c ??? Someone want to finish these? +Two historical functions for setting resource limits, @code{ulimit} and +@code{vlimit}, are not documented here. The latter is declared in +@file{sys/vlimit.h} and comes from BSD. + +@node Priority +@section Process Priority +@cindex process priority +@cindex priority of a process + +@pindex sys/resource.h +When several processes try to run, their respective priorities determine +what share of the CPU each process gets. This section describes how you +can read and set the priority of a process. All these functions and +macros are declared in @file{sys/resource.h}. + +The range of valid priority values depends on the operating system, but +typically it runs from @code{-20} to @code{20}. A lower priority value +means the process runs more often. These constants describe the range of +priority values: + +@table @code +@comment sys/resource.h +@comment BSD +@item PRIO_MIN +@vindex PRIO_MIN +The smallest valid priority value. + +@comment sys/resource.h +@comment BSD +@item PRIO_MAX +@vindex PRIO_MAX +The smallest valid priority value. +@end table + +@comment sys/resource.h +@comment BSD +@deftypefun int getpriority (int @var{class}, int @var{id}) +Read the priority of a class of processes; @var{class} and @var{id} +specify which ones (see below). If the processes specified do not all +have the same priority, this returns the smallest value that any of them +has. + +The return value is the priority value on success, and @code{-1} on +failure. The following @code{errno} error condition are possible for +this function: + +@table @code +@item ESRCH +The combination of @var{class} and @var{id} does not match any existing +process. + +@item EINVAL +The value of @var{class} is not valid. +@end table + +When the return value is @code{-1}, it could indicate failure, or it +could be the priority value. The only way to make certain is to set +@code{errno = 0} before calling @code{getpriority}, then use @code{errno +!= 0} afterward as the criterion for failure. +@end deftypefun + +@comment sys/resource.h +@comment BSD +@deftypefun int setpriority (int @var{class}, int @var{id}, int @var{priority}) +Set the priority of a class of processes to @var{priority}; @var{class} +and @var{id} specify which ones (see below). + +The return value is @code{0} on success and @code{-1} on failure. The +following @code{errno} error condition are defined for this function: + +@table @code +@item ESRCH +The combination of @var{class} and @var{id} does not match any existing +process. + +@item EINVAL +The value of @var{class} is not valid. + +@item EPERM +You tried to set the priority of some other user's process, and you +don't have privileges for that. + +@item EACCES +You tried to lower the priority of a process, and you don't have +privileges for that. +@end table +@end deftypefun + +The arguments @var{class} and @var{id} together specify a set of +processes you are interested in. These are the possible values for +@var{class}: + +@table @code +@comment sys/resource.h +@comment BSD +@item PRIO_PROCESS +@vindex PRIO_PROCESS +Read or set the priority of one process. The argument @var{id} is a +process ID. + +@comment sys/resource.h +@comment BSD +@item PRIO_PGRP +@vindex PRIO_PGRP +Read or set the priority of one process group. The argument @var{id} is +a process group ID. + +@comment sys/resource.h +@comment BSD +@item PRIO_USER +@vindex PRIO_USER +Read or set the priority of one user's processes. The argument @var{id} +is a user ID. +@end table + +If the argument @var{id} is 0, it stands for the current process, +current process group, or the current user, according to @var{class}. + +@c ??? I don't know where we should say this comes from. +@comment Unix +@comment dunno.h +@deftypefun int nice (int @var{increment}) +Increment the priority of the current process by @var{increment}. +The return value is the same as for @code{setpriority}. + +Here is an equivalent definition for @code{nice}: + +@smallexample +int +nice (int increment) +@{ + int old = getpriority (PRIO_PROCESS, 0); + return setpriority (PRIO_PROCESS, 0, old + increment); +@} +@end smallexample +@end deftypefun diff --git a/manual/users.texi b/manual/users.texi new file mode 100644 index 0000000000..c35e8b6a5b --- /dev/null +++ b/manual/users.texi @@ -0,0 +1,1012 @@ +@node Users and Groups, System Information, Job Control, Top +@chapter Users and Groups + +Every user who can log in on the system is identified by a unique number +called the @dfn{user ID}. Each process has an effective user ID which +says which user's access permissions it has. + +Users are classified into @dfn{groups} for access control purposes. Each +process has one or more @dfn{group ID values} which say which groups the +process can use for access to files. + +The effective user and group IDs of a process collectively form its +@dfn{persona}. This determines which files the process can access. +Normally, a process inherits its persona from the parent process, but +under special circumstances a process can change its persona and thus +change its access permissions. + +Each file in the system also has a user ID and a group ID. Access +control works by comparing the user and group IDs of the file with those +of the running process. + +The system keeps a database of all the registered users, and another +database of all the defined groups. There are library functions you +can use to examine these databases. + +@menu +* User and Group IDs:: Each user has a unique numeric ID; + likewise for groups. +* Process Persona:: The user IDs and group IDs of a process. +* Why Change Persona:: Why a program might need to change + its user and/or group IDs. +* How Change Persona:: Changing the user and group IDs. +* Reading Persona:: How to examine the user and group IDs. + +* Setting User ID:: Functions for setting the user ID. +* Setting Groups:: Functions for setting the group IDs. + +* Enable/Disable Setuid:: Turning setuid access on and off. +* Setuid Program Example:: The pertinent parts of one sample program. +* Tips for Setuid:: How to avoid granting unlimited access. + +* Who Logged In:: Getting the name of the user who logged in, + or of the real user ID of the current process. + +* User Database:: Functions and data structures for + accessing the user database. +* Group Database:: Functions and data structures for + accessing the group database. +* Database Example:: Example program showing use of database + inquiry functions. +@end menu + +@node User and Group IDs +@section User and Group IDs + +@cindex login name +@cindex user name +@cindex user ID +Each user account on a computer system is identified by a @dfn{user +name} (or @dfn{login name}) and @dfn{user ID}. Normally, each user name +has a unique user ID, but it is possible for several login names to have +the same user ID. The user names and corresponding user IDs are stored +in a data base which you can access as described in @ref{User Database}. + +@cindex group name +@cindex group ID +Users are classified in @dfn{groups}. Each user name also belongs to +one or more groups, and has one @dfn{default group}. Users who are +members of the same group can share resources (such as files) that are +not accessible to users who are not a member of that group. Each group +has a @dfn{group name} and @dfn{group ID}. @xref{Group Database}, +for how to find information about a group ID or group name. + +@node Process Persona +@section The Persona of a Process +@cindex persona +@cindex effective user ID +@cindex effective group ID + +@c !!! bogus; not single ID. set of effective group IDs (and, in GNU, +@c set of effective UIDs) determines privilege. lying here and then +@c telling the truth below is confusing. +At any time, each process has a single user ID and a group ID which +determine the privileges of the process. These are collectively called +the @dfn{persona} of the process, because they determine ``who it is'' +for purposes of access control. These IDs are also called the +@dfn{effective user ID} and @dfn{effective group ID} of the process. + +Your login shell starts out with a persona which consists of your user +ID and your default group ID. +@c !!! also supplementary group IDs. +In normal circumstances, all your other processes inherit these values. + +@cindex real user ID +@cindex real group ID +A process also has a @dfn{real user ID} which identifies the user who +created the process, and a @dfn{real group ID} which identifies that +user's default group. These values do not play a role in access +control, so we do not consider them part of the persona. But they are +also important. + +Both the real and effective user ID can be changed during the lifetime +of a process. @xref{Why Change Persona}. + +@cindex supplementary group IDs +In addition, a user can belong to multiple groups, so the persona +includes @dfn{supplementary group IDs} that also contribute to access +permission. + +For details on how a process's effective user IDs and group IDs affect +its permission to access files, see @ref{Access Permission}. + +The user ID of a process also controls permissions for sending signals +using the @code{kill} function. @xref{Signaling Another Process}. + +@node Why Change Persona +@section Why Change the Persona of a Process? + +The most obvious situation where it is necessary for a process to change +its user and/or group IDs is the @code{login} program. When +@code{login} starts running, its user ID is @code{root}. Its job is to +start a shell whose user and group IDs are those of the user who is +logging in. (To accomplish this fully, @code{login} must set the real +user and group IDs as well as its persona. But this is a special case.) + +The more common case of changing persona is when an ordinary user +program needs access to a resource that wouldn't ordinarily be +accessible to the user actually running it. + +For example, you may have a file that is controlled by your program but +that shouldn't be read or modified directly by other users, either +because it implements some kind of locking protocol, or because you want +to preserve the integrity or privacy of the information it contains. +This kind of restricted access can be implemented by having the program +change its effective user or group ID to match that of the resource. + +Thus, imagine a game program that saves scores in a file. The game +program itself needs to be able to update this file no matter who is +running it, but if users can write the file without going through the +game, they can give themselves any scores they like. Some people +consider this undesirable, or even reprehensible. It can be prevented +by creating a new user ID and login name (say, @code{games}) to own the +scores file, and make the file writable only by this user. Then, when +the game program wants to update this file, it can change its effective +user ID to be that for @code{games}. In effect, the program must +adopt the persona of @code{games} so it can write the scores file. + +@node How Change Persona +@section How an Application Can Change Persona +@cindex @code{setuid} programs + +The ability to change the persona of a process can be a source of +unintentional privacy violations, or even intentional abuse. Because of +the potential for problems, changing persona is restricted to special +circumstances. + +You can't arbitrarily set your user ID or group ID to anything you want; +only privileged processes can do that. Instead, the normal way for a +program to change its persona is that it has been set up in advance to +change to a particular user or group. This is the function of the setuid +and setgid bits of a file's access mode. @xref{Permission Bits}. + +When the setuid bit of an executable file is set, executing that file +automatically changes the effective user ID to the user that owns the +file. Likewise, executing a file whose setgid bit is set changes the +effective group ID to the group of the file. @xref{Executing a File}. +Creating a file that changes to a particular user or group ID thus +requires full access to that user or group ID. + +@xref{File Attributes}, for a more general discussion of file modes and +accessibility. + +A process can always change its effective user (or group) ID back to its +real ID. Programs do this so as to turn off their special privileges +when they are not needed, which makes for more robustness. + +@c !!! talk about _POSIX_SAVED_IDS + +@node Reading Persona +@section Reading the Persona of a Process + +Here are detailed descriptions of the functions for reading the user and +group IDs of a process, both real and effective. To use these +facilities, you must include the header files @file{sys/types.h} and +@file{unistd.h}. +@pindex unistd.h +@pindex sys/types.h + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} uid_t +This is an integer data type used to represent user IDs. In the GNU +library, this is an alias for @code{unsigned int}. +@end deftp + +@comment sys/types.h +@comment POSIX.1 +@deftp {Data Type} gid_t +This is an integer data type used to represent group IDs. In the GNU +library, this is an alias for @code{unsigned int}. +@end deftp + +@comment unistd.h +@comment POSIX.1 +@deftypefun uid_t getuid (void) +The @code{getuid} function returns the real user ID of the process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun gid_t getgid (void) +The @code{getgid} function returns the real group ID of the process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun uid_t geteuid (void) +The @code{geteuid} function returns the effective user ID of the process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun gid_t getegid (void) +The @code{getegid} function returns the effective group ID of the process. +@end deftypefun + +@comment unistd.h +@comment POSIX.1 +@deftypefun int getgroups (int @var{count}, gid_t *@var{groups}) +The @code{getgroups} function is used to inquire about the supplementary +group IDs of the process. Up to @var{count} of these group IDs are +stored in the array @var{groups}; the return value from the function is +the number of group IDs actually stored. If @var{count} is smaller than +the total number of supplementary group IDs, then @code{getgroups} +returns a value of @code{-1} and @code{errno} is set to @code{EINVAL}. + +If @var{count} is zero, then @code{getgroups} just returns the total +number of supplementary group IDs. On systems that do not support +supplementary groups, this will always be zero. + +Here's how to use @code{getgroups} to read all the supplementary group +IDs: + +@smallexample +@group +gid_t * +read_all_groups (void) +@{ + int ngroups = getgroups (NULL, 0); + gid_t *groups + = (gid_t *) xmalloc (ngroups * sizeof (gid_t)); + int val = getgroups (ngroups, groups); + if (val < 0) + @{ + free (groups); + return NULL; + @} + return groups; +@} +@end group +@end smallexample +@end deftypefun + +@node Setting User ID +@section Setting the User ID + +This section describes the functions for altering the user ID (real +and/or effective) of a process. To use these facilities, you must +include the header files @file{sys/types.h} and @file{unistd.h}. +@pindex unistd.h +@pindex sys/types.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun int setuid (uid_t @var{newuid}) +This function sets both the real and effective user ID of the process +to @var{newuid}, provided that the process has appropriate privileges. +@c !!! also sets saved-id + +If the process is not privileged, then @var{newuid} must either be equal +to the real user ID or the saved user ID (if the system supports the +@code{_POSIX_SAVED_IDS} feature). In this case, @code{setuid} sets only +the effective user ID and not the real user ID. +@c !!! xref to discussion of _POSIX_SAVED_IDS + +The @code{setuid} function returns a value of @code{0} to indicate +successful completion, and a value of @code{-1} to indicate an error. +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EINVAL +The value of the @var{newuid} argument is invalid. + +@item EPERM +The process does not have the appropriate privileges; you do not +have permission to change to the specified ID. +@end table +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid}) +This function sets the real user ID of the process to @var{ruid} and the +effective user ID to @var{euid}. If @var{ruid} is @code{-1}, it means +not to change the real user ID; likewise if @var{euid} is @code{-1}, it +means not to change the effective user ID. + +The @code{setreuid} function exists for compatibility with 4.3 BSD Unix, +which does not support saved IDs. You can use this function to swap the +effective and real user IDs of the process. (Privileged processes are +not limited to this particular usage.) If saved IDs are supported, you +should use that feature instead of this function. @xref{Enable/Disable +Setuid}. + +The return value is @code{0} on success and @code{-1} on failure. +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EPERM +The process does not have the appropriate privileges; you do not +have permission to change to the specified ID. +@end table +@end deftypefun + +@node Setting Groups +@section Setting the Group IDs + +This section describes the functions for altering the group IDs (real +and effective) of a process. To use these facilities, you must include +the header files @file{sys/types.h} and @file{unistd.h}. +@pindex unistd.h +@pindex sys/types.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun int setgid (gid_t @var{newgid}) +This function sets both the real and effective group ID of the process +to @var{newgid}, provided that the process has appropriate privileges. +@c !!! also sets saved-id + +If the process is not privileged, then @var{newgid} must either be equal +to the real group ID or the saved group ID. In this case, @code{setgid} +sets only the effective group ID and not the real group ID. + +The return values and error conditions for @code{setgid} are the same +as those for @code{setuid}. +@end deftypefun + +@comment unistd.h +@comment BSD +@deftypefun int setregid (gid_t @var{rgid}, fid_t @var{egid}) +This function sets the real group ID of the process to @var{rgid} and +the effective group ID to @var{egid}. If @var{rgid} is @code{-1}, it +means not to change the real group ID; likewise if @var{egid} is +@code{-1}, it means not to change the effective group ID. + +The @code{setregid} function is provided for compatibility with 4.3 BSD +Unix, which does not support saved IDs. You can use this function to +swap the effective and real group IDs of the process. (Privileged +processes are not limited to this usage.) If saved IDs are supported, +you should use that feature instead of using this function. +@xref{Enable/Disable Setuid}. + +The return values and error conditions for @code{setregid} are the same +as those for @code{setreuid}. +@end deftypefun + +The GNU system also lets privileged processes change their supplementary +group IDs. To use @code{setgroups} or @code{initgroups}, your programs +should include the header file @file{grp.h}. +@pindex grp.h + +@comment grp.h +@comment BSD +@deftypefun int setgroups (size_t @var{count}, gid_t *@var{groups}) +This function sets the process's supplementary group IDs. It can only +be called from privileged processes. The @var{count} argument specifies +the number of group IDs in the array @var{groups}. + +This function returns @code{0} if successful and @code{-1} on error. +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item EPERM +The calling process is not privileged. +@end table +@end deftypefun + +@comment grp.h +@comment BSD +@deftypefun int initgroups (const char *@var{user}, gid_t @var{gid}) +The @code{initgroups} function effectively calls @code{setgroups} to +set the process's supplementary group IDs to be the normal default for +the user name @var{user}. The group ID @var{gid} is also included. +@c !!! explain that this works by reading the group file looking for +@c groups USER is a member of. +@end deftypefun + +@node Enable/Disable Setuid +@section Enabling and Disabling Setuid Access + +A typical setuid program does not need its special access all of the +time. It's a good idea to turn off this access when it isn't needed, +so it can't possibly give unintended access. + +If the system supports the saved user ID feature, you can accomplish +this with @code{setuid}. When the game program starts, its real user ID +is @code{jdoe}, its effective user ID is @code{games}, and its saved +user ID is also @code{games}. The program should record both user ID +values once at the beginning, like this: + +@smallexample +user_user_id = getuid (); +game_user_id = geteuid (); +@end smallexample + +Then it can turn off game file access with + +@smallexample +setuid (user_user_id); +@end smallexample + +@noindent +and turn it on with + +@smallexample +setuid (game_user_id); +@end smallexample + +@noindent +Throughout this process, the real user ID remains @code{jdoe} and the +saved user ID remains @code{games}, so the program can always set its +effective user ID to either one. + +On other systems that don't support the saved user ID feature, you can +turn setuid access on and off by using @code{setreuid} to swap the real +and effective user IDs of the process, as follows: + +@smallexample +setreuid (geteuid (), getuid ()); +@end smallexample + +@noindent +This special case is always allowed---it cannot fail. + +Why does this have the effect of toggling the setuid access? Suppose a +game program has just started, and its real user ID is @code{jdoe} while +its effective user ID is @code{games}. In this state, the game can +write the scores file. If it swaps the two uids, the real becomes +@code{games} and the effective becomes @code{jdoe}; now the program has +only @code{jdoe} access. Another swap brings @code{games} back to +the effective user ID and restores access to the scores file. + +In order to handle both kinds of systems, test for the saved user ID +feature with a preprocessor conditional, like this: + +@smallexample +#ifdef _POSIX_SAVED_IDS + setuid (user_user_id); +#else + setreuid (geteuid (), getuid ()); +#endif +@end smallexample + +@node Setuid Program Example +@section Setuid Program Example + +Here's an example showing how to set up a program that changes its +effective user ID. + +This is part of a game program called @code{caber-toss} that +manipulates a file @file{scores} that should be writable only by the game +program itself. The program assumes that its executable +file will be installed with the set-user-ID bit set and owned by the +same user as the @file{scores} file. Typically, a system +administrator will set up an account like @code{games} for this purpose. + +The executable file is given mode @code{4755}, so that doing an +@samp{ls -l} on it produces output like: + +@smallexample +-rwsr-xr-x 1 games 184422 Jul 30 15:17 caber-toss +@end smallexample + +@noindent +The set-user-ID bit shows up in the file modes as the @samp{s}. + +The scores file is given mode @code{644}, and doing an @samp{ls -l} on +it shows: + +@smallexample +-rw-r--r-- 1 games 0 Jul 31 15:33 scores +@end smallexample + +Here are the parts of the program that show how to set up the changed +user ID. This program is conditionalized so that it makes use of the +saved IDs feature if it is supported, and otherwise uses @code{setreuid} +to swap the effective and real user IDs. + +@smallexample +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdlib.h> + + +/* @r{Save the effective and real UIDs.} */ + +static uid_t euid, ruid; + + +/* @r{Restore the effective UID to its original value.} */ + +void +do_setuid (void) +@{ + int status; + +#ifdef _POSIX_SAVED_IDS + status = setuid (euid); +#else + status = setreuid (ruid, euid); +#endif + if (status < 0) @{ + fprintf (stderr, "Couldn't set uid.\n"); + exit (status); + @} +@} + + +@group +/* @r{Set the effective UID to the real UID.} */ + +void +undo_setuid (void) +@{ + int status; + +#ifdef _POSIX_SAVED_IDS + status = setuid (ruid); +#else + status = setreuid (euid, ruid); +#endif + if (status < 0) @{ + fprintf (stderr, "Couldn't set uid.\n"); + exit (status); + @} +@} +@end group + +/* @r{Main program.} */ + +int +main (void) +@{ + /* @r{Save the real and effective user IDs.} */ + ruid = getuid (); + euid = geteuid (); + undo_setuid (); + + /* @r{Do the game and record the score.} */ + @dots{} +@} +@end smallexample + +Notice how the first thing the @code{main} function does is to set the +effective user ID back to the real user ID. This is so that any other +file accesses that are performed while the user is playing the game use +the real user ID for determining permissions. Only when the program +needs to open the scores file does it switch back to the original +effective user ID, like this: + +@smallexample +/* @r{Record the score.} */ + +int +record_score (int score) +@{ + FILE *stream; + char *myname; + + /* @r{Open the scores file.} */ + do_setuid (); + stream = fopen (SCORES_FILE, "a"); + undo_setuid (); + +@group + /* @r{Write the score to the file.} */ + if (stream) + @{ + myname = cuserid (NULL); + if (score < 0) + fprintf (stream, "%10s: Couldn't lift the caber.\n", myname); + else + fprintf (stream, "%10s: %d feet.\n", myname, score); + fclose (stream); + return 0; + @} + else + return -1; +@} +@end group +@end smallexample + +@node Tips for Setuid +@section Tips for Writing Setuid Programs + +It is easy for setuid programs to give the user access that isn't +intended---in fact, if you want to avoid this, you need to be careful. +Here are some guidelines for preventing unintended access and +minimizing its consequences when it does occur: + +@itemize @bullet +@item +Don't have @code{setuid} programs with privileged user IDs such as +@code{root} unless it is absolutely necessary. If the resource is +specific to your particular program, it's better to define a new, +nonprivileged user ID or group ID just to manage that resource. + +@item +Be cautious about using the @code{system} and @code{exec} functions in +combination with changing the effective user ID. Don't let users of +your program execute arbitrary programs under a changed user ID. +Executing a shell is especially bad news. Less obviously, the +@code{execlp} and @code{execvp} functions are a potential risk (since +the program they execute depends on the user's @code{PATH} environment +variable). + +If you must @code{exec} another program under a changed ID, specify an +absolute file name (@pxref{File Name Resolution}) for the executable, +and make sure that the protections on that executable and @emph{all} +containing directories are such that ordinary users cannot replace it +with some other program. + +@item +Only use the user ID controlling the resource in the part of the program +that actually uses that resource. When you're finished with it, restore +the effective user ID back to the actual user's user ID. +@xref{Enable/Disable Setuid}. + +@item +If the @code{setuid} part of your program needs to access other files +besides the controlled resource, it should verify that the real user +would ordinarily have permission to access those files. You can use the +@code{access} function (@pxref{Access Permission}) to check this; it +uses the real user and group IDs, rather than the effective IDs. +@end itemize + +@node Who Logged In +@section Identifying Who Logged In +@cindex login name, determining +@cindex user ID, determining + +You can use the functions listed in this section to determine the login +name of the user who is running a process, and the name of the user who +logged in the current session. See also the function @code{getuid} and +friends (@pxref{Reading Persona}). + +The @code{getlogin} function is declared in @file{unistd.h}, while +@code{cuserid} and @code{L_cuserid} are declared in @file{stdio.h}. +@pindex stdio.h +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun {char *} getlogin (void) +The @code{getlogin} function returns a pointer to a string containing the +name of the user logged in on the controlling terminal of the process, +or a null pointer if this information cannot be determined. The string +is statically allocated and might be overwritten on subsequent calls to +this function or to @code{cuserid}. +@end deftypefun + +@comment stdio.h +@comment POSIX.1 +@deftypefun {char *} cuserid (char *@var{string}) +The @code{cuserid} function returns a pointer to a string containing a +user name associated with the effective ID of the process. If +@var{string} is not a null pointer, it should be an array that can hold +at least @code{L_cuserid} characters; the string is returned in this +array. Otherwise, a pointer to a string in a static area is returned. +This string is statically allocated and might be overwritten on +subsequent calls to this function or to @code{getlogin}. +@end deftypefun + +@comment stdio.h +@comment POSIX.1 +@deftypevr Macro int L_cuserid +An integer constant that indicates how long an array you might need to +store a user name. +@end deftypevr + +These functions let your program identify positively the user who is +running or the user who logged in this session. (These can differ when +setuid programs are involved; @xref{Process Persona}.) The user cannot +do anything to fool these functions. + +For most purposes, it is more useful to use the environment variable +@code{LOGNAME} to find out who the user is. This is more flexible +precisely because the user can set @code{LOGNAME} arbitrarily. +@xref{Standard Environment}. + +@node User Database +@section User Database +@cindex user database +@cindex password database +@pindex /etc/passwd + +This section describes all about how to search and scan the database of +registered users. The database itself is kept in the file +@file{/etc/passwd} on most systems, but on some systems a special +network server gives access to it. + +@menu +* User Data Structure:: What each user record contains. +* Lookup User:: How to look for a particular user. +* Scanning All Users:: Scanning the list of all users, one by one. +* Writing a User Entry:: How a program can rewrite a user's record. +@end menu + +@node User Data Structure +@subsection The Data Structure that Describes a User + +The functions and data structures for accessing the system user database +are declared in the header file @file{pwd.h}. +@pindex pwd.h + +@comment pwd.h +@comment POSIX.1 +@deftp {Data Type} {struct passwd} +The @code{passwd} data structure is used to hold information about +entries in the system user data base. It has at least the following members: + +@table @code +@item char *pw_name +The user's login name. + +@item char *pw_passwd. +The encrypted password string. + +@item uid_t pw_uid +The user ID number. + +@item gid_t pw_gid +The user's default group ID number. + +@item char *pw_gecos +A string typically containing the user's real name, and possibly other +information such as a phone number. + +@item char *pw_dir +The user's home directory, or initial working directory. This might be +a null pointer, in which case the interpretation is system-dependent. + +@item char *pw_shell +The user's default shell, or the initial program run when the user logs in. +This might be a null pointer, indicating that the system default should +be used. +@end table +@end deftp + +@node Lookup User +@subsection Looking Up One User +@cindex converting user ID to user name +@cindex converting user name to user ID + +You can search the system user database for information about a +specific user using @code{getpwuid} or @code{getpwnam}. These +functions are declared in @file{pwd.h}. + +@comment pwd.h +@comment POSIX.1 +@deftypefun {struct passwd *} getpwuid (uid_t @var{uid}) +This function returns a pointer to a statically-allocated structure +containing information about the user whose user ID is @var{uid}. This +structure may be overwritten on subsequent calls to @code{getpwuid}. + +A null pointer value indicates there is no user in the data base with +user ID @var{uid}. +@end deftypefun + +@comment pwd.h +@comment POSIX.1 +@deftypefun {struct passwd *} getpwnam (const char *@var{name}) +This function returns a pointer to a statically-allocated structure +containing information about the user whose user name is @var{name}. +This structure may be overwritten on subsequent calls to +@code{getpwnam}. + +A null pointer value indicates there is no user named @var{name}. +@end deftypefun + +@node Scanning All Users +@subsection Scanning the List of All Users +@cindex scanning the user list + +This section explains how a program can read the list of all users in +the system, one user at a time. The functions described here are +declared in @file{pwd.h}. + +You can use the @code{fgetpwent} function to read user entries from a +particular file. + +@comment pwd.h +@comment SVID +@deftypefun {struct passwd *} fgetpwent (FILE *@var{stream}) +This function reads the next user entry from @var{stream} and returns a +pointer to the entry. The structure is statically allocated and is +rewritten on subsequent calls to @code{fgetpwent}. You must copy the +contents of the structure if you wish to save the information. + +This stream must correspond to a file in the same format as the standard +password database file. This function comes from System V. +@end deftypefun + +The way to scan all the entries in the user database is with +@code{setpwent}, @code{getpwent}, and @code{endpwent}. + +@comment pwd.h +@comment SVID, BSD +@deftypefun void setpwent (void) +This function initializes a stream which @code{getpwent} uses to read +the user database. +@end deftypefun + +@comment pwd.h +@comment POSIX.1 +@deftypefun {struct passwd *} getpwent (void) +The @code{getpwent} function reads the next entry from the stream +initialized by @code{setpwent}. It returns a pointer to the entry. The +structure is statically allocated and is rewritten on subsequent calls +to @code{getpwent}. You must copy the contents of the structure if you +wish to save the information. +@end deftypefun + +@comment pwd.h +@comment SVID, BSD +@deftypefun void endpwent (void) +This function closes the internal stream used by @code{getpwent}. +@end deftypefun + +@node Writing a User Entry +@subsection Writing a User Entry + +@comment pwd.h +@comment SVID +@deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream}) +This function writes the user entry @code{*@var{p}} to the stream +@var{stream}, in the format used for the standard user database +file. The return value is zero on success and nonzero on failure. + +This function exists for compatibility with SVID. We recommend that you +avoid using it, because it makes sense only on the assumption that the +@code{struct passwd} structure has no members except the standard ones; +on a system which merges the traditional Unix data base with other +extended information about users, adding an entry using this function +would inevitably leave out much of the important information. + +The function @code{putpwent} is declared in @file{pwd.h}. +@end deftypefun + +@node Group Database +@section Group Database +@cindex group database +@pindex /etc/group + +This section describes all about how to search and scan the database of +registered groups. The database itself is kept in the file +@file{/etc/group} on most systems, but on some systems a special network +service provides access to it. + +@menu +* Group Data Structure:: What each group record contains. +* Lookup Group:: How to look for a particular group. +* Scanning All Groups:: Scanning the list of all groups. +@end menu + +@node Group Data Structure +@subsection The Data Structure for a Group + +The functions and data structures for accessing the system group +database are declared in the header file @file{grp.h}. +@pindex grp.h + +@comment grp.h +@comment POSIX.1 +@deftp {Data Type} {struct group} +The @code{group} structure is used to hold information about an entry in +the system group database. It has at least the following members: + +@table @code +@item char *gr_name +The name of the group. + +@item gid_t gr_gid +The group ID of the group. + +@item char **gr_mem +A vector of pointers to the names of users in the group. Each user name +is a null-terminated string, and the vector itself is terminated by a +null pointer. +@end table +@end deftp + +@node Lookup Group +@subsection Looking Up One Group +@cindex converting group name to group ID +@cindex converting group ID to group name + +You can search the group database for information about a specific +group using @code{getgrgid} or @code{getgrnam}. These functions are +declared in @file{grp.h}. + +@comment grp.h +@comment POSIX.1 +@deftypefun {struct group *} getgrgid (gid_t @var{gid}) +This function returns a pointer to a statically-allocated structure +containing information about the group whose group ID is @var{gid}. +This structure may be overwritten by subsequent calls to +@code{getgrgid}. + +A null pointer indicates there is no group with ID @var{gid}. +@end deftypefun + +@comment grp.h +@comment SVID, BSD +@deftypefun {struct group *} getgrnam (const char *@var{name}) +This function returns a pointer to a statically-allocated structure +containing information about the group whose group name is @var{name}. +This structure may be overwritten by subsequent calls to +@code{getgrnam}. + +A null pointer indicates there is no group named @var{name}. +@end deftypefun + +@node Scanning All Groups +@subsection Scanning the List of All Groups +@cindex scanning the group list + +This section explains how a program can read the list of all groups in +the system, one group at a time. The functions described here are +declared in @file{grp.h}. + +You can use the @code{fgetgrent} function to read group entries from a +particular file. + +@comment grp.h +@comment SVID +@deftypefun {struct group *} fgetgrent (FILE *@var{stream}) +The @code{fgetgrent} function reads the next entry from @var{stream}. +It returns a pointer to the entry. The structure is statically +allocated and is rewritten on subsequent calls to @code{fgetgrent}. You +must copy the contents of the structure if you wish to save the +information. + +The stream must correspond to a file in the same format as the standard +group database file. +@end deftypefun + +The way to scan all the entries in the group database is with +@code{setgrent}, @code{getgrent}, and @code{endgrent}. + +@comment grp.h +@comment SVID, BSD +@deftypefun void setgrent (void) +This function initializes a stream for reading from the group data base. +You use this stream by calling @code{getgrent}. +@end deftypefun + +@comment grp.h +@comment SVID, BSD +@deftypefun {struct group *} getgrent (void) +The @code{getgrent} function reads the next entry from the stream +initialized by @code{setgrent}. It returns a pointer to the entry. The +structure is statically allocated and is rewritten on subsequent calls +to @code{getgrent}. You must copy the contents of the structure if you +wish to save the information. +@end deftypefun + +@comment grp.h +@comment SVID, BSD +@deftypefun void endgrent (void) +This function closes the internal stream used by @code{getgrent}. +@end deftypefun + +@node Database Example +@section User and Group Database Example + +Here is an example program showing the use of the system database inquiry +functions. The program prints some information about the user running +the program. + +@smallexample +@include db.c.texi +@end smallexample + +Here is some output from this program: + +@smallexample +I am Throckmorton Snurd. +My login name is snurd. +My uid is 31093. +My home directory is /home/fsg/snurd. +My default shell is /bin/sh. +My default group is guest (12). +The members of this group are: + friedman + tami +@end smallexample diff --git a/math.h b/math.h new file mode 100644 index 0000000000..f837293f81 --- /dev/null +++ b/math.h @@ -0,0 +1 @@ +#include <math/math.h> diff --git a/math/.cvsignore b/math/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/math/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/math/Makefile b/math/Makefile new file mode 100644 index 0000000000..c86d44a072 --- /dev/null +++ b/math/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for math. +# +subdir := math + +headers := math.h __math.h huge_val.h nan.h + + +routines := acos asin atan cos sin tan cosh sinh tanh exp fabs ldexp \ + log log10 floor sqrt fmod frexp pow atan2 ceil modf \ + isinf isnan finite infnan copysign drem logb \ + rint hypot cabs cbrt expm1 log1p acosh asinh atanh \ + isinfl isnanl +tests := # test-math +install-lib := libm.a + + +include ../Rules + +$(objpfx)libm.a: $(dep-dummy-lib); $(make-dummy-lib) +lib: $(objpfx)libm.a diff --git a/math/finite.c b/math/finite.c new file mode 100644 index 0000000000..48f8f8011a --- /dev/null +++ b/math/finite.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +#undef __finite + +/* Return nonzero if VALUE is finite and not NaN. */ +int +DEFUN(__finite, (value), double value) +{ + return !__isinf (value) && !__isnan (value); +} + +weak_alias (__finite, finite) diff --git a/math/math.h b/math/math.h new file mode 100644 index 0000000000..51ba57c088 --- /dev/null +++ b/math/math.h @@ -0,0 +1,317 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.5 MATHEMATICS <math.h> + */ + +#ifndef _MATH_H + +#define _MATH_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_Emath +#include <errno.h> + +/* Get machine-dependent HUGE_VAL value (returned on overflow). */ +#include <huge_val.h> + +/* Get machine-dependent NAN value (returned for some domain errors). */ +#ifdef __USE_GNU +#include <nan.h> +#endif + + +/* Trigonometric functions. */ + +/* Arc cosine of X. */ +extern double acos __P ((double __x)) __attribute__ ((__const__)); +/* Arc sine of X. */ +extern double asin __P ((double __x)) __attribute__ ((__const__)); +/* Arc tangent of X. */ +extern double atan __P ((double __x)) __attribute__ ((__const__)); +/* Arc tangent of Y/X. */ +extern double atan2 __P ((double __y, double __x)) __attribute__ ((__const__)); + +/* Cosine of X. */ +extern double cos __P ((double __x)) __attribute__ ((__const__)); +/* Sine of X. */ +extern double sin __P ((double __x)) __attribute__ ((__const__)); +/* Tangent of X. */ +extern double tan __P ((double __x)) __attribute__ ((__const__)); + + +/* Hyperbolic functions. */ + +/* Hyperbolic cosine of X. */ +extern double cosh __P ((double __x)) __attribute__ ((__const__)); +/* Hyperbolic sine of X. */ +extern double sinh __P ((double __x)) __attribute__ ((__const__)); +/* Hyperbolic tangent of X. */ +extern double tanh __P ((double __x)) __attribute__ ((__const__)); + +#ifdef __USE_MISC +/* Hyperbolic arc cosine of X. */ +extern double acosh __P ((double __x)) __attribute__ ((__const__)); +/* Hyperbolic arc sine of X. */ +extern double asinh __P ((double __x)) __attribute__ ((__const__)); +/* Hyperbolic arc tangent of X. */ +extern double atanh __P ((double __x)) __attribute__ ((__const__)); +#endif + +/* Exponential and logarithmic functions. */ + +/* Exponentional function of X. */ +extern double exp __P ((double __x)) __attribute__ ((__const__)); + +/* Break VALUE into a normalized fraction and an integral power of 2. */ +extern double frexp __P ((double __value, int *__exp)); + +/* X times (two to the EXP power). */ +extern double ldexp __P ((double __x, int __exp)) __attribute__ ((__const__)); + +/* Natural logarithm of X. */ +extern double log __P ((double __x)) __attribute__ ((__const__)); + +/* Base-ten logarithm of X. */ +extern double log10 __P ((double __x)) __attribute__ ((__const__)); + +#ifdef __USE_MISC +/* Return exp(X) - 1. */ +extern double __expm1 __P ((double __x)) __attribute__ ((__const__)); +extern double expm1 __P ((double __x)) __attribute__ ((__const__)); + +/* Return log(1 + X). */ +extern double log1p __P ((double __x)) __attribute__ ((__const__)); +#endif + +/* Break VALUE into integral and fractional parts. */ +extern double modf __P ((double __value, double *__iptr)); + + +/* Power functions. */ + +/* Return X to the Y power. */ +extern double pow __P ((double __x, double __y)) __attribute__ ((__const__)); + +/* Return the square root of X. */ +extern double sqrt __P ((double __x)) __attribute__ ((__const__)); + +#ifdef __USE_MISC +/* Return the cube root of X. */ +extern double cbrt __P ((double __x)) __attribute__ ((__const__)); +#endif + + +/* Nearest integer, absolute value, and remainder functions. */ + +/* Smallest integral value not less than X. */ +extern double ceil __P ((double __x)) __attribute__ ((__const__)); + +/* Absolute value of X. */ +extern double fabs __P ((double __x)) __attribute__ ((__const__)); + +/* Largest integer not greater than X. */ +extern double floor __P ((double __x)) __attribute__ ((__const__)); + +/* Floating-point modulo remainder of X/Y. */ +extern double fmod __P ((double __x, double __y)) __attribute__ ((__const__)); + + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +extern int __isinf __P ((double __value)) __attribute__ ((__const__)); + +/* Return nonzero if VALUE is not a number. */ +extern int __isnan __P ((double __value)) __attribute__ ((__const__)); + +/* Return nonzero if VALUE is finite and not NaN. */ +extern int __finite __P ((double __value)) __attribute__ ((__const__)); +#ifdef __OPTIMIZE__ +#define __finite(value) (!__isinf(value)) +#endif + +/* Deal with an infinite or NaN result. + If ERROR is ERANGE, result is +Inf; + if ERROR is - ERANGE, result is -Inf; + otherwise result is NaN. + This will set `errno' to either ERANGE or EDOM, + and may return an infinity or NaN, or may do something else. */ +extern double __infnan __P ((int __error)); + +/* Return X with its signed changed to Y's. */ +extern double __copysign __P ((double __x, double __y)) + __attribute__ ((__const__)); + +/* Return X times (2 to the Nth power). */ +extern double __scalb __P ((double __x, int __n)) + __attribute__ ((__const__)); + +#ifdef __OPTIMIZE__ +#define __scalb(x, n) ldexp ((x), (n)) +#endif + +/* Return the remainder of X/Y. */ +extern double __drem __P ((double __x, double __y)) + __attribute__ ((__const__)); + +/* Return the base 2 signed integral exponent of X. */ +extern double __logb __P ((double __x)) __attribute__ ((__const__)); + +#ifdef __USE_MISC + +/* Return the integer nearest X in the direction of the + prevailing rounding mode. */ +extern double __rint __P ((double __x)) __attribute__ ((__const__)); +extern double rint __P ((double __x)) __attribute__ ((__const__)); + +/* Return `sqrt(X*X + Y*Y)'. */ +extern double hypot __P ((double __x, double __y)) __attribute__ ((__const__)); + +struct __cabs_complex +{ + double __x, __y; +}; + +/* Return `sqrt(X*X + Y*Y)'. */ +extern double cabs __P ((struct __cabs_complex)) __attribute__ ((__const__)); + +extern int isinf __P ((double __value)) __attribute__ ((__const__)); +extern int isnan __P ((double __value)) __attribute__ ((__const__)); +extern int finite __P ((double __value)) __attribute__ ((__const__)); +extern double infnan __P ((int __error)) __attribute__ ((__const__)); +extern double copysign __P ((double __x, double __y)) + __attribute__ ((__const__)); +extern double scalb __P ((double __x, int __n)) __attribute__ ((__const__)); +extern double drem __P ((double __x, double __y)) __attribute__ ((__const__)); +extern double logb __P ((double __x)) __attribute__ ((__const__)); + +#ifdef __OPTIMIZE__ +#define isinf(value) __isinf(value) +#define isnan(value) __isnan(value) +#define infnan(error) __infnan(error) +#define finite(value) __finite(value) +#define copysign(x, y) __copysign((x), (y)) +#define scalb(x, n) __scalb((x), (n)) +#define drem(x, y) __drem((x), (y)) +#define logb(x) __logb(x) +#endif /* Optimizing. */ + +#endif /* Use misc. */ + + +#if 0 +/* The "Future Library Directions" section of the + ANSI Standard reserves these as `float' and + `long double' versions of the above functions. */ + +extern float acosf __P ((float __x)) __attribute__ ((__const__)); +extern float asinf __P ((float __x)) __attribute__ ((__const__)); +extern float atanf __P ((float __x)) __attribute__ ((__const__)); +extern float atan2f __P ((float __y, float __x)) __attribute__ ((__const__)); +extern float cosf __P ((float __x)) __attribute__ ((__const__)); +extern float sinf __P ((float __x)) __attribute__ ((__const__)); +extern float tanf __P ((float __x)) __attribute__ ((__const__)); +extern float coshf __P ((float __x)) __attribute__ ((__const__)); +extern float sinhf __P ((float __x)) __attribute__ ((__const__)); +extern float tanhf __P ((float __x)) __attribute__ ((__const__)); +extern float expf __P ((float __x)) __attribute__ ((__const__)); +extern float frexpf __P ((float __value, int *__exp)); +extern float ldexpf __P ((float __x, int __exp)) __attribute__ ((__const__)); +extern float logf __P ((float __x)) __attribute__ ((__const__)); +extern float log10f __P ((float __x)) __attribute__ ((__const__)); +extern float modff __P ((float __value, float *__iptr)); +extern float powf __P ((float __x, float __y)) __attribute__ ((__const__)); +extern float sqrtf __P ((float __x)) __attribute__ ((__const__)); +extern float ceilf __P ((float __x)) __attribute__ ((__const__)); +extern float fabsf __P ((float __x)) __attribute__ ((__const__)); +extern float floorf __P ((float __x)) __attribute__ ((__const__)); +extern float fmodf __P ((float __x, float __y)) __attribute__ ((__const__)); + +extern __long_double_t acosl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t asinl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t atanl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t atan2l __P ((__long_double_t __y, __long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t cosl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t sinl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t tanl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t coshl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t sinhl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t tanhl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t expl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t frexpl __P ((__long_double_t __value, int *__exp)); +extern __long_double_t ldexpl __P ((__long_double_t __x, int __exp)) + __attribute__ ((__const__)); +extern __long_double_t logl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t log10l __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t modfl __P ((__long_double_t __value, + __long_double_t *__ip)); +extern __long_double_t powl __P ((__long_double_t __x, __long_double_t __y)) + __attribute__ ((__const__)); +extern __long_double_t sqrtl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t ceill __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t fabsl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t floorl __P ((__long_double_t __x)) + __attribute__ ((__const__)); +extern __long_double_t fmodl __P ((__long_double_t __x, __long_double_t __y)) + __attribute__ ((__const__)); +#endif /* 0 */ + +/* Get machine-dependent inline versions (if there are any). */ +#include <__math.h> + +__END_DECLS + + +#ifdef __USE_BSD +/* Some useful constants. */ +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log 2e */ +#define M_LOG10E 0.43429448190325182765 /* log 10e */ +#define M_LN2 0.69314718055994530942 /* log e2 */ +#define M_LN10 2.30258509299404568402 /* log e10 */ +#define M_PI 3.14159265358979323846 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif + + +#endif /* math.h */ diff --git a/math/test-math.c b/math/test-math.c new file mode 100644 index 0000000000..a82daed4e4 --- /dev/null +++ b/math/test-math.c @@ -0,0 +1,148 @@ +#include <ansidecl.h> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +void print_trig_stuff __P ((void)); + +int +DEFUN_VOID(main) +{ + CONST char str[] = "123.456"; + double x,h,li,lr,a,lrr; + + x = atof (str); + + printf ("%g %g\n", x, pow (10.0, 3.0)); + + x = sinh(2.0); + + printf("sinh(2.0) = %g\n", x); + + x = sinh(3.0); + + printf("sinh(3.0) = %g\n", x); + + h = hypot(2.0,3.0); + + printf("h=%g\n", h); + + a = atan2(3.0, 2.0); + + printf("atan2(3,2) = %g\n", a); + + lr = pow(h,4.0); + + printf("pow(%g,4.0) = %g\n", h, lr); + + lrr = lr; + + li = 4.0 * a; + + lr = lr / exp(a*5.0); + + printf("%g / exp(%g * 5) = %g\n", lrr, a, lr); + + lrr = li; + + li += 5.0 * log(h); + + printf("%g + 5*log(%g) = %g\n", lrr, h, li); + + printf("cos(%g) = %g, sin(%g) = %g\n", li, cos(li), li, sin(li)); + + x = drem(10.3435,6.2831852); + + printf("drem(10.3435,6.2831852) = %g\n", x); + + x = drem(-10.3435,6.2831852); + + printf("drem(-10.3435,6.2831852) = %g\n", x); + + x = drem(-10.3435,-6.2831852); + + printf("drem(-10.3435,-6.2831852) = %g\n", x); + + x = drem(10.3435,-6.2831852); + + printf("drem(10.3435,-6.2831852) = %g\n", x); + + + printf("x%8.6gx\n", .5); + printf("x%-8.6gx\n", .5); + printf("x%6.6gx\n", .5); + + { + double x = atof ("-1e-17-"); + printf ("%g %c= %g %s!\n", + x, + x == -1e-17 ? '=' : '!', + -1e-17, + x == -1e-17 ? "Worked" : "Failed"); + } + + print_trig_stuff (); + + return 0; +} + + +#define PI 3.14159265358979323846264338327 + +const double RAD[5] = { 0, PI/2, PI, (3*PI)/2, 2*PI }; +const int DEG[5] = { 0, 90, 180, 360 }; + +#define PRINT_IT_1_ARG(_func, _arg, _value) \ + (_value) = (_func)((_arg)); \ + if (errno) { \ + errno = 0; \ + printf("%s = ERROR %s\n", #_func, strerror(errno)); \ + } else \ + printf("%s(%g) = %g\n", #_func, _arg, (_value)); \ + +#define PRINT_IT_2_ARG(_func, _arg1, _arg2, _value) \ + (_value) = (_func)((_arg1),(_arg2)); \ + if (errno) { \ + errno = 0; \ + printf("%s = ERROR %s\n", #_func, strerror(errno)); \ + } else \ + printf("%s(%g, %g) = %g\n", #_func, _arg1, _arg2, (_value)); \ + +void +DEFUN_VOID (print_trig_stuff) +{ + double value, arg1, arg2; + int i; + + puts ("\n\nMath Test"); + + errno = 0; /* automatically reset on error condition */ + for (i=0; i<4; i++) + { + PRINT_IT_1_ARG (sin, RAD[i], value); + PRINT_IT_1_ARG (cos, RAD[i], value); + PRINT_IT_1_ARG (tan, RAD[i], value); + PRINT_IT_1_ARG (asin, RAD[i], value); + PRINT_IT_1_ARG (acos, RAD[i], value); + PRINT_IT_1_ARG (atan, RAD[i], value); + PRINT_IT_2_ARG (atan2, RAD[i], -RAD[i % 4], value); + } + + arg1 = 16; + arg2 = 3; + PRINT_IT_1_ARG (exp, arg1, value); + PRINT_IT_1_ARG (log, arg1, value); + PRINT_IT_1_ARG (log10, arg1, value); + PRINT_IT_2_ARG (pow, arg1, arg2, value); + PRINT_IT_1_ARG (sqrt, arg1, value); + PRINT_IT_1_ARG (cbrt, arg1, value); + PRINT_IT_2_ARG (hypot, arg1, arg2, value); + PRINT_IT_1_ARG (expm1, arg1, value); + PRINT_IT_1_ARG (log1p, arg1, value); + PRINT_IT_1_ARG (sinh, arg1, value); + PRINT_IT_1_ARG (cosh, arg1, value); + PRINT_IT_1_ARG (tanh, arg1, value); + PRINT_IT_1_ARG (asinh, arg1, value); + PRINT_IT_1_ARG (acosh, arg1, value); + PRINT_IT_1_ARG (atanh, arg1, value); +} diff --git a/memory.h b/memory.h new file mode 100644 index 0000000000..1ec3e63fc9 --- /dev/null +++ b/memory.h @@ -0,0 +1 @@ +#include <string/memory.h> diff --git a/misc/Makefile b/misc/Makefile new file mode 100644 index 0000000000..33ddfda39e --- /dev/null +++ b/misc/Makefile @@ -0,0 +1,67 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for misc portion of the library. +# + +subdir := misc + +headers := sys/uio.h sys/ioctl.h sys/ptrace.h ioctls.h sys/file.h \ + a.out.h nlist.h stab.h stab.def sgtty.h sys/dir.h sys/cdefs.h \ + ttyent.h syscall.h syslog.h sys/syslog.h paths.h sys/reboot.h \ + sys/mman.h sys/param.h fstab.h + +routines := brk sbrk sstk ioctl \ + readv writev \ + setreuid setregid \ + seteuid setegid \ + getpagesize \ + getdtsz \ + gethostname sethostname getdomain setdomain \ + select \ + acct chroot fsync sync reboot \ + gethostid sethostid \ + mknod \ + swapon vhangup mktemp mkstemp \ + ualarm usleep \ + gtty stty \ + ptrace \ + nlist fstab \ + utimes \ + truncate ftruncate \ + chflags fchflags \ + insremque getttyent getusershell getpass ttyslot \ + syslog syscall daemon \ + mmap munmap mprotect msync madvise +aux := progname init-misc +distribute := bsd-compat.c +extra-objs := bsd-compat.o +install-lib := libbsd-compat.a libg.a +non-lib.a := libbsd-compat.a + +include ../Rules + +$(objpfx)libbsd-compat.a: $(objpfx)bsd-compat.o + rm -f $@ + ln $< $@ + +lib: $(objpfx)libbsd-compat.a + +$(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib) +lib: $(objpfx)libg.a diff --git a/misc/bsd-compat.c b/misc/bsd-compat.c new file mode 100644 index 0000000000..03c43eec57 --- /dev/null +++ b/misc/bsd-compat.c @@ -0,0 +1,50 @@ +/* BSD-compatible versions of functions where BSD and POSIX.1 conflict. + +Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define _BSD_SOURCE + +#include <ansidecl.h> +#include <sys/types.h> +#include <unistd.h> +#include <gnu-stabs.h> +#include <limits.h> +#include <setjmp.h> + +#undef getpgrp +function_alias(getpgrp, __getpgrp, pid_t, (pid), + DEFUN(getpgrp, (pid), pid_t pid)) + +/* These entry points allow for things compiled for another C library + that want the BSD-compatible definitions. (Of course, their jmp_buf + must be big enough.) */ + +#undef longjmp +#ifdef __STDC__ +#define void __NORETURN void +#endif +function_alias_void(longjmp, siglongjmp, (env, val), + DEFUN(longjmp, (env, val), CONST jmp_buf env AND int val)) + +#undef setjmp +int +DEFUN(setjmp, (env), jmp_buf env) +{ + return sigsetjmp (env, 1); +} diff --git a/misc/daemon.c b/misc/daemon.c new file mode 100644 index 0000000000..6b3409cced --- /dev/null +++ b/misc/daemon.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <fcntl.h> +#include <paths.h> +#include <unistd.h> + +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} diff --git a/misc/fstab.c b/misc/fstab.c new file mode 100644 index 0000000000..ac59cab861 --- /dev/null +++ b/misc/fstab.c @@ -0,0 +1,205 @@ +/* + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <errno.h> +#include <fstab.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifndef EFTYPE +#define EFTYPE EINVAL +#endif + +static FILE *_fs_fp; +static struct fstab _fs_fstab; + +static void error __P((int)); + +static int +fstabscan __P((void)) +{ + register char *cp; +#define MAXLINELENGTH 1024 + static char line[MAXLINELENGTH]; + char subline[MAXLINELENGTH]; + int typexx; + + 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 void +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/misc/fstab.h b/misc/fstab.h new file mode 100644 index 0000000000..2a176bdb83 --- /dev/null +++ b/misc/fstab.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1980, 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. + * + * @(#)fstab.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _FSTAB_H_ +#define _FSTAB_H_ + +/* + * File system table, see fstab(5). + * + * Used by dump, mount, umount, swapon, fsck, df, ... + * + * For ufs fs_spec field is the block special name. Programs that want to + * use the character special name must create that name by prepending a 'r' + * after the right most slash. Quota files are always named "quotas", so + * if type is "rq", then use concatenation of fs_file and "quotas" to locate + * quota file. + */ +#define _PATH_FSTAB "/etc/fstab" +#define FSTAB "/etc/fstab" /* deprecated */ + +#define FSTAB_RW "rw" /* read/write device */ +#define FSTAB_RQ "rq" /* read/write with quotas */ +#define FSTAB_RO "ro" /* read-only device */ +#define FSTAB_SW "sw" /* swap device */ +#define FSTAB_XX "xx" /* ignore totally */ + +struct fstab { + char *fs_spec; /* block special device name */ + char *fs_file; /* file system path prefix */ + char *fs_vfstype; /* File system type, ufs, nfs */ + char *fs_mntops; /* Mount options ala -o */ + char *fs_type; /* FSTAB_* from fs_mntops */ + int fs_freq; /* dump frequency, in days */ + int fs_passno; /* pass number on parallel dump */ +}; + +#include <sys/cdefs.h> + +__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)); +__END_DECLS + +#endif /* !_FSTAB_H_ */ diff --git a/misc/getpass.c b/misc/getpass.c new file mode 100644 index 0000000000..ec535c1cca --- /dev/null +++ b/misc/getpass.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <termios.h> +#include <unistd.h> + +/* It is desireable to use this bit on systems that have it. + The only bit of terminal state we want to twiddle is echoing, which is + done in software; there is no need to change the state of the terminal + hardware. */ + +#ifndef TCSASOFT +#define TCSASOFT 0 +#endif + +char * +getpass (prompt) + const char *prompt; +{ + FILE *in, *out; + struct termios t; + int echo_off; + static char *buf = NULL; + static size_t bufsize = 0; + ssize_t nread; + + /* Try to write to and read from the terminal if we can. + If we can't open the terminal, use stderr and stdin. */ + + in = fopen ("/dev/tty", "w+"); + if (in == NULL) + { + in = stdin; + out = stderr; + } + else + out = in; + + /* Turn echoing off if it is on now. */ + + if (tcgetattr (fileno (in), &t) == 0) + { + if (t.c_lflag & ECHO) + { + t.c_lflag &= ~ECHO; + echo_off = tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0; + t.c_lflag |= ECHO; + } + else + echo_off = 0; + } + else + echo_off = 0; + + /* Write the prompt. */ + fputs (prompt, out); + fflush (out); + + /* Read the password. */ + nread = __getline (&buf, &bufsize, in); + if (nread < 0 && buf != NULL) + buf[0] = '\0'; + else if (buf[nread - 1] == '\n') + /* Remove the newline. */ + buf[nread - 1] = '\0'; + + /* Restore echoing. */ + if (echo_off) + (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t); + + if (in != stdin) + /* We opened the terminal; now close it. */ + fclose (in); + + return buf; +} diff --git a/misc/getttyent.c b/misc/getttyent.c new file mode 100644 index 0000000000..f9b1e0d854 --- /dev/null +++ b/misc/getttyent.c @@ -0,0 +1,199 @@ +/* + * 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[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <ttyent.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +static char zapchar; +static FILE *tf; + +struct ttyent * +getttynam(tty) + const char *tty; +{ + register struct ttyent *t; + + setttyent(); + while (t = getttyent()) + if (!strcmp(tty, t->ty_name)) + break; + endttyent(); + return (t); +} + +struct ttyent * +getttyent() +{ + static struct ttyent tty; + register int c; + register char *p; +#define MAXLINELENGTH 100 + static char line[MAXLINELENGTH]; + static char *skip(), *value(); + + if (!tf && !setttyent()) + return (NULL); + for (;;) { + if (!fgets(p = line, sizeof(line), tf)) + return (NULL); + /* skip lines that are too big */ + if (!index(p, '\n')) { + while ((c = getc(tf)) != '\n' && c != EOF) + ; + continue; + } + while (isspace(*p)) + ++p; + if (*p && *p != '#') + break; + } + + zapchar = 0; + tty.ty_name = p; + p = skip(p); + if (!*(tty.ty_getty = p)) + tty.ty_getty = tty.ty_type = NULL; + else { + p = skip(p); + if (!*(tty.ty_type = p)) + tty.ty_type = NULL; + else + p = skip(p); + } + tty.ty_status = 0; + tty.ty_window = NULL; + +#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1]) +#define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' + for (; *p; p = skip(p)) { + if (scmp(_TTYS_OFF)) + tty.ty_status &= ~TTY_ON; + else if (scmp(_TTYS_ON)) + tty.ty_status |= TTY_ON; + else if (scmp(_TTYS_SECURE)) + tty.ty_status |= TTY_SECURE; + else if (vcmp(_TTYS_WINDOW)) + tty.ty_window = value(p); + else + break; + } + + if (zapchar == '#' || *p == '#') + while ((c = *++p) == ' ' || c == '\t') + ; + tty.ty_comment = p; + if (*p == 0) + tty.ty_comment = 0; + if (p = index(p, '\n')) + *p = '\0'; + return (&tty); +} + +#define QUOTED 1 + +/* + * Skip over the current field, removing quotes, and return a pointer to + * the next field. + */ +static char * +skip(p) + register char *p; +{ + register char *t; + register int c, q; + + for (q = 0, t = p; (c = *p) != '\0'; p++) { + if (c == '"') { + q ^= QUOTED; /* obscure, but nice */ + continue; + } + if (q == QUOTED && *p == '\\' && *(p+1) == '"') + p++; + *t++ = *p; + if (q == QUOTED) + continue; + if (c == '#') { + zapchar = c; + *p = 0; + break; + } + if (c == '\t' || c == ' ' || c == '\n') { + zapchar = c; + *p++ = 0; + while ((c = *p) == '\t' || c == ' ' || c == '\n') + p++; + break; + } + } + *--t = '\0'; + return (p); +} + +static char * +value(p) + register char *p; +{ + + return ((p = index(p, '=')) ? ++p : NULL); +} + +int +setttyent() +{ + + if (tf) { + (void)rewind(tf); + return (1); + } else if (tf = fopen(_PATH_TTYS, "r")) + return (1); + return (0); +} + +int +endttyent() +{ + int rval; + + if (tf) { + rval = !(fclose(tf) == EOF); + tf = NULL; + return (rval); + } + return (1); +} diff --git a/misc/getusershell.c b/misc/getusershell.c new file mode 100644 index 0000000000..6782c3efe9 --- /dev/null +++ b/misc/getusershell.c @@ -0,0 +1,137 @@ +/* + * 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[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <unistd.h> +#include <paths.h> + +/* + * Local shells should NOT be added here. They should be added in + * /etc/shells. + */ + +static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; +static char **curshell, **shells, *strings; +static char **initshells __P((void)); + +/* + * Get a list of shells from _PATH_SHELLS, if it exists. + */ +char * +getusershell() +{ + char *ret; + + if (curshell == NULL) + curshell = initshells(); + ret = *curshell; + if (ret != NULL) + curshell++; + return (ret); +} + +void +endusershell() +{ + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + curshell = NULL; +} + +void +setusershell() +{ + + curshell = initshells(); +} + +static char ** +initshells() +{ + register char **sp, *cp; + register FILE *fp; + struct stat statb; + + if (shells != NULL) + free(shells); + shells = NULL; + if (strings != NULL) + free(strings); + strings = NULL; + if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) + return (okshells); + if (fstat(fileno(fp), &statb) == -1) { + (void)fclose(fp); + return (okshells); + } + if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) { + (void)fclose(fp); + return (okshells); + } + shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if (shells == NULL) { + (void)fclose(fp); + free(strings); + strings = NULL; + return (okshells); + } + sp = shells; + cp = strings; + while (fgets(cp, statb.st_size - (cp - strings), fp) != NULL) { + while (*cp != '#' && *cp != '/' && *cp != '\0') + cp++; + if (*cp == '#' || *cp == '\0') + continue; + *sp++ = cp; + while (!isspace(*cp) && *cp != '#' && *cp != '\0') + cp++; + *cp++ = '\0'; + } + *sp = NULL; + (void)fclose(fp); + return (shells); +} diff --git a/misc/init-misc.c b/misc/init-misc.c new file mode 100644 index 0000000000..9fb876beb0 --- /dev/null +++ b/misc/init-misc.c @@ -0,0 +1,42 @@ +/* Define and initialize `__progname'. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +char *__progname = (char *) ""; + +void +__init_misc (argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + if (argv && argv[0]) + { + char *p = strrchr (argv[0], '/'); + if (p == NULL) + __progname = argv[0]; + else + __progname = p + 1; + } +} + +#ifdef HAVE_GNU_LD +text_set_element (__libc_subinit, __init_misc); +#endif diff --git a/misc/insremque.c b/misc/insremque.c new file mode 100644 index 0000000000..d3b9370fdc --- /dev/null +++ b/misc/insremque.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> + +struct qelem + { + struct qelem *q_forw; + struct qelem *q_back; + char q_data[1]; + }; + +/* Insert ELEM into a doubly-linked list, after PREV. */ + +void +DEFUN(insque, (elem, prev) , + struct qelem *elem AND struct qelem *prev) +{ + struct qelem *next = prev->q_forw; + prev->q_forw = elem; + if (next != NULL) + next->q_back = elem; + elem->q_forw = next; + elem->q_back = prev; +} + +/* Unlink ELEM from the doubly-linked list that it is in. */ + +void +DEFUN(remque, (elem), + struct qelem *elem) +{ + struct qelem *next = elem->q_forw; + struct qelem *prev = elem->q_back; + if (next != NULL) + next->q_back = prev; + if (prev != NULL) + prev->q_forw = next; +} diff --git a/misc/ioctltst.c b/misc/ioctltst.c new file mode 100644 index 0000000000..3e8ea997eb --- /dev/null +++ b/misc/ioctltst.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <netinet/in.h> + +/* + * open a socket, get the process group information of the socket, and use the + * socket to get the network interface configuration list + */ +main() +{ + int sock; + int ioctl_result; + + /* get a socket */ + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) + { + perror("Cannot create socket"); + exit(1); + } + + /* use ioctl() to get the process group information */ + { + int get_process_group; + + ioctl_result = ioctl(sock, SIOCGPGRP, (char *) &get_process_group); + + if (ioctl_result < 0) + { + int my_errno = errno; + + fprintf(stderr, "errno %d ", my_errno); + perror("ioctl(get process group)"); + } + } + + /* use ioctl() to get the interface configuration list */ + { + static struct ifconf ifc; /* init to 0 */ + + ioctl_result = ioctl(sock, SIOCGIFCONF, (char *) &ifc); + + if (ioctl_result < 0) + { + int my_errno = errno; + + fprintf(stderr, "errno %d ", my_errno); + perror("ioctl(get interface configuration list)"); + } + } +} diff --git a/misc/nlist.h b/misc/nlist.h new file mode 100644 index 0000000000..67879b52cc --- /dev/null +++ b/misc/nlist.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _NLIST_H + +#define _NLIST_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Structure describing a symbol-table entry. */ +struct nlist +{ + char *n_name; + unsigned char n_type; + char n_other; + short int n_desc; + unsigned long int n_value; +}; + +#define N_NLIST_DECLARED +#include <a.out.h> + + +/* Search the executable FILE for symbols matching those in NL, + which is terminated by an element with a NULL `n_un.n_name' member, + and fill in the elements of NL. */ +extern int nlist __P ((__const char *__file, struct nlist * __nl)); + + +__END_DECLS + +#endif /* nlist.h */ diff --git a/misc/paths.h b/misc/paths.h new file mode 100644 index 0000000000..5f7a6b4cd5 --- /dev/null +++ b/misc/paths.h @@ -0,0 +1,69 @@ +/* + * 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. + * + * @(#)paths.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _PATHS_H_ +#define _PATHS_H_ + +/* Default search path. */ +#define _PATH_DEFPATH "/usr/bin:/bin" +/* All standard utilities path. */ +#define _PATH_STDPATH \ + "/usr/bin:/bin:/usr/sbin:/sbin:/usr/contrib/bin:/usr/old/bin" + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_CONSOLE "/dev/console" +#define _PATH_CSHELL "/bin/csh" +#define _PATH_DEVDB "/var/run/dev.db" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_DRUM "/dev/drum" +#define _PATH_KMEM "/dev/kmem" +#define _PATH_MAILDIR "/var/mail" +#define _PATH_MAN "/usr/share/man" +#define _PATH_MEM "/dev/mem" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +#define _PATH_SHELLS "/etc/shells" +#define _PATH_TTY "/dev/tty" +#define _PATH_UNIX "/vmunix" +#define _PATH_VI "/usr/bin/vi" + +/* Provide trailing slash, since mostly used for building pathnames. */ +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/tmp/" +#define _PATH_VARDB "/var/db/" +#define _PATH_VARRUN "/var/run/" +#define _PATH_VARTMP "/var/tmp/" + +#endif /* !_PATHS_H_ */ diff --git a/misc/progname.c b/misc/progname.c new file mode 100644 index 0000000000..265ca5c3a9 --- /dev/null +++ b/misc/progname.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_GNU_LD + +#include <ansidecl.h> +#include <string.h> + +char *program_invocation_name; +char *program_invocation_short_name; + +static void +DEFUN(set_progname, (argc, argv, envp), + int argc AND char **argv AND char **envp) +{ + char *p; + + if (argv && argv[0]) + { + program_invocation_name = argv[0]; + p = strrchr (argv[0], '/'); + if (p == NULL) + program_invocation_short_name = argv[0]; + else + program_invocation_short_name = p + 1; + } + else + program_invocation_name = program_invocation_short_name = 0; + + (void) &set_progname; /* Avoid "defined but not used" warning. */ +} + +text_set_element (__libc_subinit, set_progname); + +#endif diff --git a/misc/sgtty.h b/misc/sgtty.h new file mode 100644 index 0000000000..f8ed36d0d6 --- /dev/null +++ b/misc/sgtty.h @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SGTTY_H +#define _SGTYY_H 1 +#include <features.h> + +#include <sys/ioctl.h> + +__BEGIN_DECLS + +/* Fill in *PARAMS with terminal parameters associated with FD. */ +extern int gtty __P ((int __fd, struct sgttyb * __params)); + +/* Set the terminal parameters associated with FD to *PARAMS. */ +extern int stty __P ((int __fd, __const struct sgttyb * __params)); + + +__END_DECLS + +#endif /* sgtty.h */ diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h new file mode 100644 index 0000000000..8336aa4038 --- /dev/null +++ b/misc/sys/cdefs.h @@ -0,0 +1,104 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_CDEFS_H + +#define _SYS_CDEFS_H 1 +#include <features.h> + +/* Some user header file might have defined this before. */ +#undef __P + +#ifdef __GNUC__ + +#define __P(args) args /* GCC can always grok prototypes. */ +#define __DOTS , ... + +#else /* Not GCC. */ + +#define __inline /* No inline functions. */ + +#if (defined (__STDC__) && __STDC__) || defined (__cplusplus) + +#define __P(args) args +#define __const const +#define __signed signed +#define __volatile volatile +#define __DOTS , ... + +#else /* Not ANSI C or C++. */ + +#define __P(args) () /* No prototypes. */ +#define __const /* No ANSI C keywords. */ +#define __signed +#define __volatile +#define __DOTS + +#endif /* ANSI C or C++. */ + +#endif /* GCC. */ + +/* For these things, GCC behaves the ANSI way normally, + and the non-ANSI way under -traditional. */ + +#if defined (__STDC__) && __STDC__ + +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +/* This is not a typedef so `const __ptr_t' does the right thing. */ +#define __ptr_t void * +typedef long double __long_double_t; + +#else + +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#define __ptr_t char * +typedef double __long_double_t; + +#endif + +/* The BSD header files use the ANSI keywords unmodified. (This means that + old programs may lose if they use the new keywords as identifiers.) We + define them to their __ versions, which are taken care of above. */ + +#ifdef __USE_BSD +#define const __const +#define signed __signed +#define volatile __volatile +#endif + +/* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif + +/* GCC2 has various useful declarations that can be made with the + `__attribute__' syntax. All of the ways we use this do fine if + they are omitted for compilers that don't understand it. */ +#if !defined (__GNUC__) || __GNUC__ < 2 +#define __attribute__(xyz) /* Ignore. */ +#endif + +#endif /* sys/cdefs.h */ diff --git a/misc/sys/dir.h b/misc/sys/dir.h new file mode 100644 index 0000000000..cd78d5d313 --- /dev/null +++ b/misc/sys/dir.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_DIR_H + +#define _SYS_DIR_H 1 +#include <features.h> + +#include <dirent.h> + +#define direct dirent + +#endif /* sys/dir.h */ diff --git a/misc/sys/file.h b/misc/sys/file.h new file mode 100644 index 0000000000..51d07bc160 --- /dev/null +++ b/misc/sys/file.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_FILE_H + +#define _SYS_FILE_H 1 +#include <features.h> + +#ifndef _FCNTL_H +#include <fcntl.h> +#endif + +__BEGIN_DECLS + + +/* Alternate names for values for the WHENCE argument to `lseek'. + These are the same as SEEK_SET, SEEK_CUR, and SEEK_END, respectively. */ +#define L_SET 0 /* Seek from beginning of file. */ +#define L_INCR 1 /* Seek from current position. */ +#define L_XTND 2 /* Seek from end of file. */ + + +/* Operations for the `flock' call. */ +#define LOCK_SH 1 /* Shared lock. */ +#define LOCK_EX 2 /* Exclusive lock. */ +#define LOCK_UN 8 /* Unlock. */ + +/* Can be OR'd in to one of the above. */ +#define LOCK_NB 4 /* Don't block when locking. */ + + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +extern int __flock __P ((int __fd, int __operation)); +extern int flock __P ((int __fd, int __operation)); + + +__END_DECLS + +#endif /* sys/file.h */ diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h new file mode 100644 index 0000000000..b37a2740cd --- /dev/null +++ b/misc/sys/ioctl.h @@ -0,0 +1,130 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_IOCTL_H + +#define _SYS_IOCTL_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get the list of `ioctl' requests and related constants. */ +#include <ioctls.h> + +/* On a Unix system, the system <sys/ioctl.h> probably defines some of the + symbols we define in <sys/ttydefaults.h> (usually with the same values). + The code to generate <ioctls.h> has omitted these symbols to avoid the + conflict, but a Unix program expects <sys/ioctl.h> to define them, so we + must include <sys/ttydefaults.h> here. */ +#include <sys/ttydefaults.h> + +#if defined(TIOCGETC) || defined(TIOCSETC) +/* Type of ARG for TIOCGETC and TIOCSETC requests. */ +struct tchars +{ + char t_intrc; /* Interrupt character. */ + char t_quitc; /* Quit character. */ + char t_startc; /* Start-output character. */ + char t_stopc; /* Stop-output character. */ + char t_eofc; /* End-of-file character. */ + char t_brkc; /* Input delimiter character. */ +}; + +#define _IOT_tchars /* Hurd ioctl type field. */ \ + _IOT (_IOTS (char), 6, 0, 0, 0, 0) +#endif + +#if defined(TIOCGLTC) || defined(TIOCSLTC) +/* Type of ARG for TIOCGLTC and TIOCSLTC requests. */ +struct ltchars +{ + char t_suspc; /* Suspend character. */ + char t_dsuspc; /* Delayed suspend character. */ + char t_rprntc; /* Reprint-line character. */ + char t_flushc; /* Flush-output character. */ + char t_werasc; /* Word-erase character. */ + char t_lnextc; /* Literal-next character. */ +}; + +#define _IOT_ltchars /* Hurd ioctl type field. */ \ + _IOT (_IOTS (char), 6, 0, 0, 0, 0) +#endif + +/* Type of ARG for TIOCGETP and TIOCSETP requests (and gtty and stty). */ +struct sgttyb +{ + char sg_ispeed; /* Input speed. */ + char sg_ospeed; /* Output speed. */ + char sg_erase; /* Erase character. */ + char sg_kill; /* Kill character. */ + short int sg_flags; /* Mode flags. */ +}; + +#define _IOT_sgttyb /* Hurd ioctl type field. */ \ + _IOT (_IOTS (char), 6, _IOTS (short int), 1, 0, 0) + +#if defined(TIOCGWINSZ) || defined(TIOCSWINSZ) +/* Type of ARG for TIOCGWINSZ and TIOCSWINSZ requests. */ +struct winsize +{ + unsigned short int ws_row; /* Rows, in characters. */ + unsigned short int ws_col; /* Columns, in characters. */ + + /* These are not actually used. */ + unsigned short int ws_xpixel; /* Horizontal pixels. */ + unsigned short int ws_ypixel; /* Vertical pixels. */ +}; + +#define _IOT_winsize /* Hurd ioctl type field. */ \ + _IOT (_IOTS (unsigned short int), 4, 0, 0, 0, 0) +#endif + +#if defined (TIOCGSIZE) || defined (TIOCSSIZE) +# if defined (TIOCGWINSZ) && TIOCGSIZE == TIOCGWINSZ +/* Many systems that have TIOCGWINSZ define TIOCGSIZE for source + compatibility with Sun; they define `struct ttysize' to have identical + layout as `struct winsize' and #define TIOCGSIZE to be TIOCGWINSZ + (likewise TIOCSSIZE and TIOCSWINSZ). */ +struct ttysize +{ + unsigned short int ts_lines; + unsigned short int ts_cols; + unsigned short int ts_xxx; + unsigned short int ts_yyy; +}; +#define _IOT_ttysize _IOT_winsize +# else +/* Suns use a different layout for `struct ttysize', and TIOCGSIZE and + TIOCGWINSZ are separate commands that do the same thing with different + structures (likewise TIOCSSIZE and TIOCSWINSZ). */ +struct ttysize +{ + int ts_lines, ts_cols; /* Lines and columns, in characters. */ +}; +# endif +#endif + +/* Perform the I/O control operation specified by REQUEST on FD. + One argument may follow; its presence and type depend on REQUEST. + Return value depends on REQUEST. Usually -1 indicates error. */ +extern int __ioctl __P ((int __fd, unsigned long int __request, ...)); +extern int ioctl __P ((int __fd, unsigned long int __request, ...)); + +__END_DECLS + +#endif /* sys/ioctl.h */ diff --git a/misc/sys/ptrace.h b/misc/sys/ptrace.h new file mode 100644 index 0000000000..22e44e3ae0 --- /dev/null +++ b/misc/sys/ptrace.h @@ -0,0 +1,137 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _PTRACE_H + +#define _PTRACE_H 1 +#include <features.h> + +__BEGIN_DECLS + + +/* Type of the REQUEST argument to `ptrace.' */ +enum __ptrace_request +{ + /* Indicate that the process making this request should be traced. + All signals received by this process can be intercepted by its + parent, and its parent can use the other `ptrace' requests. */ + PTRACE_TRACEME = 0, +#define PT_TRACE_ME PTRACE_TRACEME + + /* Return the word in the process's text space at address ADDR. */ + PTRACE_PEEKTEXT, +#define PT_READ_I PTRACE_PEEKTEXT + + /* Return the word in the process's data space at address ADDR. */ + PTRACE_PEEKDATA, +#define PT_READ_D PTRACE_PEEKDATA + + /* Return the word in the process's user area at offset ADDR. */ + PTRACE_PEEKUSER, +#define PT_READ_U PTRACE_PEEKUSER + + /* Write the word DATA into the process's text space at address ADDR. */ + PTRACE_POKETEXT, +#define PT_WRITE_I PTRACE_POKETEXT + + /* Write the word DATA into the process's data space at address ADDR. */ + PTRACE_POKEDATA, +#define PT_WRITE_D PTRACE_POKEDATA + + /* Write the word DATA into the process's user space at offset ADDR. */ + PTRACE_POKEUSER, +#define PT_WRITE_U PTRACE_POKEUSER + + /* Continue the process. */ + PTRACE_CONT, +#define PT_CONTINUE PTRACE_CONT + + /* Kill the process. */ + PTRACE_KILL, +#define PT_KILL PTRACE_KILL + + /* Single step the process. + This is not supported on all machines. */ + PTRACE_SINGLESTEP, +#define PT_STEP PTRACE_SINGLESTEP + + /* Attach to a process that is already running. */ + PTRACE_ATTACH, +#define PT_ATTACH PTRACE_ATTACH + + /* Detach from a process attached to with PTRACE_ATTACH. */ + PTRACE_DETACH, +#define PT_DETACH PTRACE_DETACH + + /* Get the process's registers (not including floating-point registers) + and put them in the `struct regs' (see <machine/regs.h>) at ADDR. */ + PTRACE_GETREGS = 12, + + /* Set the process's registers (not including floating-point registers) + to the contents of the `struct regs' (see <machine/regs.h>) at ADDR. */ + PTRACE_SETREGS, + + /* Get the process's floating point registers and put them + in the `struct fp_status' (see <machine/regs.h>) at ADDR. */ + PTRACE_GETFPREGS = 14, + + /* Set the process's floating point registers to the contents + of the `struct fp_status' (see <machine/regs.h>) at ADDR. */ + PTRACE_SETFPREGS, + + /* Read DATA bytes from the process's data space at address ADDR. + Put the result starting at address ADDR2 in the caller's + address space. */ + PTRACE_READDATA = 16, + + /* Write DATA bytes from ADDR2 in the caller's address space into + the process's data space at address ADDR. */ + PTRACE_WRITEDATA, + + /* Read DATA bytes from the process's text space at address ADDR. + Put the result starting at address ADDR2 in the caller's + address space. */ + PTRACE_READTEXT = 18, + + /* Write DATA bytes from ADDR2 in the caller's address space into + the process's text space at address ADDR. */ + PTRACE_WRITETEXT, + + /* Read the floating-point accelerator unit registers and + put them into the `struct fpa_regs' (see <machine/regs.h>) at ADDR. */ + PTRACE_GETFPAREGS = 20, + + /* Write the floating-point accelerator unit registers from + the contents of the `struct fpa_regs' at ADDR. */ + PTRACE_SETFPAREGS, +}; + +/* Perform process tracing functions. REQUEST is one of the values + above, and determines the action to be taken. + For all requests except PTRACE_TRACEME, PID specifies the process to be + traced. + + PID and the other arguments described above for the various requests should + appear (those that are used for the particular request) as: + pid_t PID, void *ADDR, int DATA, void *ADDR2 + after REQUEST. */ +extern int ptrace __P ((enum __ptrace_request __request __DOTS)); + +__END_DECLS + +#endif /* ptrace.h */ diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h new file mode 100644 index 0000000000..87bfd2ec6f --- /dev/null +++ b/misc/sys/syslog.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 1982, 1986, 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. + * + * @(#)syslog.h 8.1 (Berkeley) 6/2/93 + */ + +#define _PATH_LOG "/dev/log" + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ + /* extract priority */ +#define LOG_PRI(p) ((p) & LOG_PRIMASK) +#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) + +#ifdef SYSLOG_NAMES +#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ + /* mark "facility" */ +#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) +typedef struct _code { + char *c_name; + int c_val; +} CODE; + +CODE prioritynames[] = { + "alert", LOG_ALERT, + "crit", LOG_CRIT, + "debug", LOG_DEBUG, + "emerg", LOG_EMERG, + "err", LOG_ERR, + "error", LOG_ERR, /* DEPRECATED */ + "info", LOG_INFO, + "none", INTERNAL_NOPRI, /* INTERNAL */ + "notice", LOG_NOTICE, + "panic", LOG_EMERG, /* DEPRECATED */ + "warn", LOG_WARNING, /* DEPRECATED */ + "warning", LOG_WARNING, + NULL, -1, +}; +#endif + +/* facility codes */ +#define LOG_KERN (0<<3) /* kernel messages */ +#define LOG_USER (1<<3) /* random user-level messages */ +#define LOG_MAIL (2<<3) /* mail system */ +#define LOG_DAEMON (3<<3) /* system daemons */ +#define LOG_AUTH (4<<3) /* security/authorization messages */ +#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ +#define LOG_LPR (6<<3) /* line printer subsystem */ +#define LOG_NEWS (7<<3) /* network news subsystem */ +#define LOG_UUCP (8<<3) /* UUCP subsystem */ +#define LOG_CRON (9<<3) /* clock daemon */ +#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */ +#define LOG_FTP (11<<3) /* ftp daemon */ + + /* other codes through 15 reserved for system use */ +#define LOG_LOCAL0 (16<<3) /* reserved for local use */ +#define LOG_LOCAL1 (17<<3) /* reserved for local use */ +#define LOG_LOCAL2 (18<<3) /* reserved for local use */ +#define LOG_LOCAL3 (19<<3) /* reserved for local use */ +#define LOG_LOCAL4 (20<<3) /* reserved for local use */ +#define LOG_LOCAL5 (21<<3) /* reserved for local use */ +#define LOG_LOCAL6 (22<<3) /* reserved for local use */ +#define LOG_LOCAL7 (23<<3) /* reserved for local use */ + +#define LOG_NFACILITIES 24 /* current number of facilities */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + /* facility of pri */ +#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) + +#ifdef SYSLOG_NAMES +CODE facilitynames[] = { + "auth", LOG_AUTH, + "authpriv", LOG_AUTHPRIV, + "cron", LOG_CRON, + "daemon", LOG_DAEMON, + "ftp", LOG_FTP, + "kern", LOG_KERN, + "lpr", LOG_LPR, + "mail", LOG_MAIL, + "mark", INTERNAL_MARK, /* INTERNAL */ + "news", LOG_NEWS, + "security", LOG_AUTH, /* DEPRECATED */ + "syslog", LOG_SYSLOG, + "user", LOG_USER, + "uucp", LOG_UUCP, + "local0", LOG_LOCAL0, + "local1", LOG_LOCAL1, + "local2", LOG_LOCAL2, + "local3", LOG_LOCAL3, + "local4", LOG_LOCAL4, + "local5", LOG_LOCAL5, + "local6", LOG_LOCAL6, + "local7", LOG_LOCAL7, + NULL, -1, +}; +#endif + +#ifdef KERNEL +#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */ +#endif + +/* + * arguments to setlogmask. + */ +#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ +#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ + +/* + * Option flags for openlog. + * + * LOG_ODELAY no longer does anything. + * LOG_NDELAY is the inverse of what it used to be. + */ +#define LOG_PID 0x01 /* log the pid with each message */ +#define LOG_CONS 0x02 /* log on the console if errors in sending */ +#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ +#define LOG_NDELAY 0x08 /* don't delay open */ +#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ +#define LOG_PERROR 0x20 /* log to stderr as well */ + +#ifndef KERNEL + +#if 0 +/* + * Don't use va_list in the vsyslog() prototype. Va_list is typedef'd in two + * places (<machine/varargs.h> and <machine/stdarg.h>), so if we include one + * of them here we may collide with the utility's includes. It's unreasonable + * for utilities to have to include one of them to include syslog.h, so we get + * _BSD_VA_LIST_ from <machine/ansi.h> and use it. + */ +#include <machine/ansi.h> +#elif !defined (_BSD_VA_LIST_) +/* In GNU we don't have a <machine/ansi.h> and it would be too painful to + emulate one. */ +#define __need_va_list +#include <stdarg.h> +#define _BSD_VA_LIST_ __gnuc_va_list +#endif + +#include <sys/cdefs.h> + +__BEGIN_DECLS +void closelog __P((void)); +void openlog __P((const char *, int, int)); +int setlogmask __P((int)); +void syslog __P((int, const char *, ...)); +void vsyslog __P((int, const char *, _BSD_VA_LIST_)); +__END_DECLS + +#endif /* !KERNEL */ diff --git a/misc/sys/uio.h b/misc/sys/uio.h new file mode 100644 index 0000000000..301712546f --- /dev/null +++ b/misc/sys/uio.h @@ -0,0 +1,58 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_UIO_H + +#define _SYS_UIO_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_size_t +#include <stddef.h> + + +/* Structure describing a section of memory. */ + +struct iovec +{ + /* Starting address. */ + __ptr_t iov_base; + /* Length in bytes. */ + size_t iov_len; +}; + + +/* Read data from file descriptor FD, and put the result in the + buffers described by VECTOR, which is a vector of COUNT `struct iovec's. + The buffers are filled in the order specified. + Operates just like `read' (see <unistd.h>) except that data are + put in VECTOR instead of a contiguous buffer. */ +int readv __P ((int __fd, __const struct iovec * __vector, size_t __count)); + +/* Write data pointed by the buffers described by VECTOR, which + is a vector of COUNT `struct iovec's, to file descriptor FD. + The data is written in the order specified. + Operates just like `write' (see <unistd.h>) except that the data + are taken from VECTOR instead of a contiguous buffer. */ +int writev __P ((int __fd, __const struct iovec * __vector, size_t __count)); + + +__END_DECLS + +#endif /* sys/uio.h */ diff --git a/misc/syslog.c b/misc/syslog.c new file mode 100644 index 0000000000..ba82e23019 --- /dev/null +++ b/misc/syslog.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/syslog.h> +#include <sys/uio.h> +#include <netdb.h> + +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +static int LogFile = -1; /* fd for log */ +static int connected; /* have done connect */ +static int LogStat = 0; /* status bits, set by openlog() */ +static const char *LogTag = NULL; /* string to tag the entry with */ +static int LogFacility = LOG_USER; /* default facility code */ +static int LogMask = 0xff; /* mask of priorities to be logged */ +extern char *__progname; /* Program name, from crt0. */ + +/* + * syslog, vsyslog -- + * print message on log file; output is intended for syslogd(8). + */ +void +#if __STDC__ +syslog(int pri, const char *fmt, ...) +#else +syslog(pri, fmt, va_alist) + int pri; + char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + vsyslog(pri, fmt, ap); + va_end(ap); +} + +void +vsyslog(pri, fmt, ap) + int pri; + register const char *fmt; + va_list ap; +{ + register int cnt; + register char ch, *p, *t; + time_t now; + int fd, saved_errno; + char *stdp, tbuf[2048], fmt_cpy[1024]; + +#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID + /* Check for invalid bits. */ + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog(INTERNALLOG, + "syslog: unknown facility/priority: %x", pri); + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + /* Check priority against setlogmask values. */ + if (!LOG_MASK(LOG_PRI(pri)) & LogMask) + return; + + saved_errno = errno; + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) + pri |= LogFacility; + + /* Build the message. */ + (void)time(&now); + p = tbuf + sprintf(tbuf, "<%d>", pri); + p += strftime(p, sizeof (tbuf) - (p - tbuf), "%h %e %T ", + localtime(&now)); + if (LogStat & LOG_PERROR) + stdp = p; + if (LogTag == NULL) + LogTag = __progname; + if (LogTag != NULL) + p += sprintf(p, "%s", LogTag); + if (LogStat & LOG_PID) + p += sprintf(p, "[%d]", getpid()); + if (LogTag != NULL) { + *p++ = ':'; + *p++ = ' '; + } + + /* Substitute error message for %m. */ + for (t = fmt_cpy; ch = *fmt; ++fmt) + if (ch == '%' && fmt[1] == 'm') { + ++fmt; + t += sprintf(t, "%s", strerror(saved_errno)); + } else + *t++ = ch; + *t = '\0'; + + p += vsprintf(p, fmt_cpy, ap); + cnt = p - tbuf; + + /* Output to stderr if requested. */ + if (LogStat & LOG_PERROR) { + struct iovec iov[2]; + register struct iovec *v = iov; + + v->iov_base = stdp; + v->iov_len = cnt - (stdp - tbuf); + ++v; + v->iov_base = "\n"; + v->iov_len = 1; + (void)writev(STDERR_FILENO, iov, 2); + } + + /* Get connected, output the message to the local logger. */ + if (!connected) + openlog(LogTag, LogStat | LOG_NDELAY, 0); + if (send(LogFile, tbuf, cnt, 0) >= 0) + return; + + /* + * Output the message to the console; don't worry about blocking, + * if console blocks everything will. Make sure the error reported + * is the one from the syslogd failure. + */ + if (LogStat & LOG_CONS && + (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { + (void)strcat(tbuf, "\r\n"); + cnt += 2; + p = index(tbuf, '>') + 1; + (void)write(fd, p, cnt - (p - tbuf)); + (void)close(fd); + } +} + +static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ + +void +openlog(ident, logstat, logfac) + const char *ident; + int logstat, logfac; +{ + if (ident != NULL) + LogTag = ident; + LogStat = logstat; + if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) + LogFacility = logfac; + + if (LogFile == -1) { + SyslogAddr.sa_family = AF_UNIX; + (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, + sizeof(SyslogAddr.sa_data)); + if (LogStat & LOG_NDELAY) { + if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + return; + (void)fcntl(LogFile, F_SETFD, 1); + } + } + if (LogFile != -1 && !connected) + if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { + (void)close(LogFile); + LogFile = -1; + } else + connected = 1; +} + +void +closelog() +{ + (void)close(LogFile); + LogFile = -1; + connected = 0; +} + +/* setlogmask -- set the log mask level */ +int +setlogmask(pmask) + int pmask; +{ + int omask; + + omask = LogMask; + if (pmask != 0) + LogMask = pmask; + return (omask); +} diff --git a/misc/syslog.h b/misc/syslog.h new file mode 100644 index 0000000000..830b4928ad --- /dev/null +++ b/misc/syslog.h @@ -0,0 +1 @@ +#include <sys/syslog.h> diff --git a/misc/ttyent.h b/misc/ttyent.h new file mode 100644 index 0000000000..e95db259ca --- /dev/null +++ b/misc/ttyent.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ttyent.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TTYENT_H_ +#define _TTYENT_H_ + +#define _PATH_TTYS "/etc/ttys" + +#define _TTYS_OFF "off" +#define _TTYS_ON "on" +#define _TTYS_SECURE "secure" +#define _TTYS_WINDOW "window" + +struct ttyent { + char *ty_name; /* terminal device name */ + char *ty_getty; /* command to execute, usually getty */ + char *ty_type; /* terminal type for termcap */ +#define TTY_ON 0x01 /* enable logins (start ty_getty program) */ +#define TTY_SECURE 0x02 /* allow uid of 0 to login */ + int ty_status; /* status flags */ + char *ty_window; /* command to start up window manager */ + char *ty_comment; /* comment field */ +}; + +#include <sys/cdefs.h> + +__BEGIN_DECLS +struct ttyent *getttyent __P((void)); +struct ttyent *getttynam __P((const char *)); +int setttyent __P((void)); +int endttyent __P((void)); +__END_DECLS + +#endif /* !_TTYENT_H_ */ diff --git a/misc/ttyslot.c b/misc/ttyslot.c new file mode 100644 index 0000000000..3d9fee62fc --- /dev/null +++ b/misc/ttyslot.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)ttyslot.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include <ttyent.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int +ttyslot() +{ + register struct ttyent *ttyp; + register int slot; + register char *p; + int cnt; + char *name; + + setttyent(); + for (cnt = 0; cnt < 3; ++cnt) + if (name = ttyname(cnt)) { + if (p = rindex(name, '/')) + ++p; + else + p = name; + for (slot = 1; ttyp = getttyent(); ++slot) + if (!strcmp(ttyp->ty_name, p)) { + endttyent(); + return(slot); + } + break; + } + endttyent(); + return(0); +} diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000000..0801ec2c96 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,32 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Last modified: 1994-03-25 +# Public domain + +errstatus=0 + +for file in ${1+"$@"} ; do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d in ${1+"$@"} ; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" || errstatus=$? + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/munch-tmpl.c b/munch-tmpl.c new file mode 100644 index 0000000000..731583a6fc --- /dev/null +++ b/munch-tmpl.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdlib.h> + + +EXTERNS + +void +__libc_init (argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + CALLS + +#ifdef HAVE_ELF + { + /* These functions are defined in crti.o to run the .init and .fini + sections, which are used for initializers in ELF. */ + extern void _init __P ((void)), _fini __P ((void)); + atexit (_fini); /* Arrange for _fini to run at exit. */ + _init (); + } +#endif +} diff --git a/munch.awk b/munch.awk new file mode 100644 index 0000000000..1ed68686c1 --- /dev/null +++ b/munch.awk @@ -0,0 +1,11 @@ +BEGIN { special = 0 } + +/EXTERNS/ { ndirs = split(subdirs, dirs) + for (i = 1; i <= ndirs; ++i) + printf "extern void __init_%s __P ((int argc, char **argv, char **envp));\n", dirs[i] + special = 1 } +/CALLS/ { ndirs = split(subdirs, dirs) + for (i = 1; i <= ndirs; ++i) printf " __init_%s (argc, argv, envp);\n", dirs[i] + special = 1 } + +{ if (special == 0) print $0; special = 0 } diff --git a/netdb.h b/netdb.h new file mode 100644 index 0000000000..e31569fe30 --- /dev/null +++ b/netdb.h @@ -0,0 +1 @@ +#include <inet/netdb.h> diff --git a/netinet/in.h b/netinet/in.h new file mode 100644 index 0000000000..9139cfaeee --- /dev/null +++ b/netinet/in.h @@ -0,0 +1 @@ +#include <inet/netinet/in.h> diff --git a/nlist.h b/nlist.h new file mode 100644 index 0000000000..897a93c7fe --- /dev/null +++ b/nlist.h @@ -0,0 +1 @@ +#include <misc/nlist.h> diff --git a/obstack.h b/obstack.h new file mode 100644 index 0000000000..2339cbc4d5 --- /dev/null +++ b/obstack.h @@ -0,0 +1 @@ +#include <malloc/obstack.h> diff --git a/paths.h b/paths.h new file mode 100644 index 0000000000..5e4af7cf3d --- /dev/null +++ b/paths.h @@ -0,0 +1 @@ +#include <misc/paths.h> diff --git a/poll.h b/poll.h new file mode 100644 index 0000000000..778488accb --- /dev/null +++ b/poll.h @@ -0,0 +1 @@ +#include <io/poll.h> diff --git a/posix/.cvsignore b/posix/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/posix/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/posix/Makefile b/posix/Makefile new file mode 100644 index 0000000000..b6851b99f3 --- /dev/null +++ b/posix/Makefile @@ -0,0 +1,84 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for POSIX portion of the library. +# +subdir := posix + +headers := sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h \ + glob.h wordexp.h fnmatch.h gnu/types.h getopt.h \ + posix1_lim.h posix2_lim.h posix_opt.h local_lim.h tar.h \ + utsnamelen.h confname.h waitflags.h waitstatus.h sys/unistd.h + +distribute := confstr.h + +routines := \ + uname \ + times \ + wait waitpid wait3 wait4 \ + alarm sleep pause \ + fork vfork _exit \ + execve fexecve execv execle execl execvp execlp \ + getpid getppid \ + getuid geteuid getgid getegid getgroups setuid setgid \ + getpgid setpgid getpgrp setsid \ + getlogin setlogin \ + pathconf sysconf fpathconf \ + glob fnmatch \ + confstr \ + getopt getopt1 +aux := init-posix +tests := tstgetopt testfnm +others := getconf +install-bin := getconf +install-lib := libposix.a +gpl2lgpl := getopt.c getopt1.c getopt.h # Frob these guys' copying notices. + +include ../Rules + +$(objpfx)libposix.a: $(dep-dummy-lib); $(make-dummy-lib) +lib: $(objpfx)libposix.a + +# Make the standalone glob/fnmatch package. + +glob.tar: glob/ChangeLog glob/COPYING.LIB \ + glob/Makefile.in glob/configure glob/configure.in glob/configure.bat\ + glob/fnmatch.h glob/glob.h glob/fnmatch.c glob/glob.c + tar cho$(verbose)f $@ $^ +glob/%.c: %.c + rm -f $@ + ln -s ../$< $@ +glob/%.h: %.h + rm -f $@ + ln -s ../$< $@ + +glob/configure: glob/configure.in + cd glob; autoconf $(ACFLAGS) + +glob/ChangeLog: ../ChangeLog + changelog-extract --regexp 'posix/(glob|fnmatch).*' < $< > $@.new + chmod a-w $@.new + mv -f $@.new $@ + +%.Z: % + compress -c $< > $@-tmp + mv $@-tmp $@ +%.gz: % + gzip -9v -c $< > $@-tmp + mv $@-tmp $@ diff --git a/posix/confstr.c b/posix/confstr.c new file mode 100644 index 0000000000..5b4a7bea93 --- /dev/null +++ b/posix/confstr.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <confstr.h> + +/* If BUF is not NULL, fill in at most LEN characters of BUF + with the value corresponding to NAME. Return the number + of characters required to hold NAME's entire value. */ +size_t +DEFUN(confstr, (name, buf, len), + int name AND char *buf AND size_t len) +{ + CONST char *string; + size_t string_len; + + switch (name) + { + case _CS_PATH: + { + static CONST char cs_path[] = CS_PATH; + string = cs_path; + string_len = sizeof(cs_path); + } + break; + + default: + errno = EINVAL; + return 0; + } + + if (buf != NULL) + (void) strncpy(buf, string, len); + return string_len; +} diff --git a/posix/execl.c b/posix/execl.c new file mode 100644 index 0000000000..9aa13b958f --- /dev/null +++ b/posix/execl.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute PATH with all arguments after PATH until + a NULL pointer and environment from `environ'. */ +int +DEFUN(execl, (path, arg), CONST char *path AND CONST char *arg DOTS) +{ + CONST char *argv[1024]; + register unsigned int i; + va_list args; + + argv[0] = arg; + + va_start (args, arg); + i = 1; + do + { + argv[i] = va_arg (args, CONST char *); + } while (argv[i++] != NULL); + va_end (args); + + return __execve (path, (char *CONST *) argv, __environ); +} diff --git a/posix/execle.c b/posix/execle.c new file mode 100644 index 0000000000..a36d49a407 --- /dev/null +++ b/posix/execle.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +/* Execute PATH with all arguments after PATH until a NULL pointer, + and the argument after that for environment. */ +int +DEFUN(execle, (path), CONST char *path AND CONST char *arg DOTS) +{ + CONST char *argv[1024], *CONST *envp; + register unsigned int i; + va_list args; + + va_start(args, arg); + argv[0] = arg; + i = 1; + do + { + argv[i] = va_arg(args, CONST char *); + } while (argv[i++] != NULL); + + envp = va_arg(args, CONST char *CONST *); + va_end(args); + + return __execve(path, (char *CONST *) argv, (char *CONST *) envp); +} diff --git a/posix/execlp.c b/posix/execlp.c new file mode 100644 index 0000000000..af09dacafd --- /dev/null +++ b/posix/execlp.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> + +/* Execute FILE, searching in the `PATH' environment variable if + it contains no slashes, with all arguments after FILE until a + NULL pointer and environment from `environ'. */ +int +DEFUN(execlp, (file), CONST char *file DOTS) +{ + CONST char *argv[1024]; + register unsigned int i; + va_list args; + + va_start (args, file); + + i = 0; + do + argv[i] = va_arg (args, CONST char *); + while (argv[i++] != NULL); + + va_end (args); + + return execvp (file, (char *CONST *) argv); +} diff --git a/posix/execv.c b/posix/execv.c new file mode 100644 index 0000000000..1749e24631 --- /dev/null +++ b/posix/execv.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute PATH with arguments ARGV and environment from `environ'. */ +int +DEFUN(execv, (path, argv), CONST char *path AND char *CONST argv[]) +{ + return __execve(path, argv, __environ); +} diff --git a/posix/execvp.c b/posix/execvp.c new file mode 100644 index 0000000000..01ae0d10a9 --- /dev/null +++ b/posix/execvp.c @@ -0,0 +1,112 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <limits.h> +#include <sys/types.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Execute FILE, searching in the `PATH' environment variable if it contains + no slashes, with arguments ARGV and environment from `environ'. */ +int +DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[]) +{ + if (strchr (file, '/') == NULL) + { + char *path, *p; + struct stat st; + size_t len; + uid_t uid; + gid_t gid; + int ngroups; + gid_t groups[NGROUPS_MAX]; + char *name; + + path = getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. + The default search path is the current directory + followed by the path `confstr' returns for `_CS_PATH'. */ + len = confstr (_CS_PATH, (char *) NULL, 0); + path = (char *) __alloca (1 + len); + path[0] = ':'; + (void) confstr (_CS_PATH, path + 1, len); + } + + len = strlen (file) + 1; + name = __alloca (strlen (path) + len); + uid = geteuid (); + gid = getegid (); + ngroups = getgroups (sizeof (groups) / sizeof (groups[0]), groups); + p = path; + do + { + path = p; + p = strchr (path, ':'); + if (p == NULL) + p = strchr (path, '\0'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + of `PATH' means to search the current directory. */ + (void) memcpy (name, file, len); + else + { + /* Construct the pathname to try. */ + (void) memcpy (name, path, p - path); + name[p - path] = '/'; + (void) memcpy (&name[(p - path) + 1], file, len); + } + if (stat (name, &st) == 0 && S_ISREG (st.st_mode)) + { + int bit = S_IXOTH; + if (st.st_uid == uid) + bit = S_IXUSR; + else if (st.st_gid == gid) + bit = S_IXGRP; + else + { + register int i; + for (i = 0; i < ngroups; ++i) + if (st.st_gid == groups[i]) + { + bit = S_IXGRP; + break; + } + } + if (st.st_mode & bit) + { + file = name; + break; + } + } + } + while (*p++ != '\0'); + } + + return __execve (file, argv, __environ); +} diff --git a/posix/fnmatch.c b/posix/fnmatch.c new file mode 100644 index 0000000000..1ef5599e23 --- /dev/null +++ b/posix/fnmatch.c @@ -0,0 +1,200 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <fnmatch.h> +#include <ctype.h> + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifndef errno +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evalutes C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c)) + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + c = FOLD (c); + } + if (FOLD (*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_FILE_NAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD (c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD (*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + cstart = cend = FOLD (cstart); + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + c = FOLD (c); + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + cend = FOLD (cend); + + c = *p++; + } + + if (FOLD (*n) >= cstart && FOLD (*n) <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD (*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/posix/fnmatch.h b/posix/fnmatch.h new file mode 100644 index 0000000000..d9d73b3d86 --- /dev/null +++ b/posix/fnmatch.h @@ -0,0 +1,67 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in <unistd.h>. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/posix/getconf.c b/posix/getconf.c new file mode 100644 index 0000000000..e42b909ed9 --- /dev/null +++ b/posix/getconf.c @@ -0,0 +1,134 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +struct conf + { + CONST char *name; + CONST int call_name; + CONST enum { SYSCONF, CONFSTR, PATHCONF } call; + }; + +static struct conf vars[] = + { + { "LINK_MAX", _PC_LINK_MAX, PATHCONF }, + { "MAX_CANON", _PC_MAX_CANON, PATHCONF }, + { "MAX_INPUT", _PC_MAX_INPUT, PATHCONF }, + { "NAME_MAX", _PC_NAME_MAX, PATHCONF }, + { "PATH_MAX", _PC_PATH_MAX, PATHCONF }, + { "PIPE_BUF", _PC_PIPE_BUF, PATHCONF }, + { "_POSIX_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED, PATHCONF }, + { "_POSIX_NO_TRUNC", _PC_NO_TRUNC, PATHCONF }, + { "_POSIX_VDISABLE", _PC_VDISABLE, PATHCONF }, + + { "ARG_MAX", _SC_ARG_MAX, SYSCONF }, + { "CHILD_MAX", _SC_CHILD_MAX, SYSCONF }, + { "CLK_TCK", _SC_CLK_TCK, SYSCONF }, + { "NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF }, + { "OPEN_MAX", _SC_OPEN_MAX, SYSCONF }, + { "_POSIX_JOB_CONTROL", _SC_JOB_CONTROL, SYSCONF }, + { "_POSIX_SAVED_IDS", _SC_SAVED_IDS, SYSCONF }, + { "_POSIX_VERSION", _SC_VERSION, SYSCONF }, + + { "PATH", _CS_PATH, CONFSTR }, + + { NULL, 0, SYSCONF } + }; + +static CONST char *program; + +static void +DEFUN_VOID(usage) +{ + fprintf (stderr, "Usage: %s variable_name [pathname]\n", program); + exit (2); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + register CONST struct conf *c; + + program = strrchr (argv[0], '/'); + if (program == NULL) + program = argv[0]; + else + ++program; + + if (argc < 2 || argc > 3) + usage (); + + for (c = vars; c->name != NULL; ++c) + if (!strcmp (c->name, argv[1])) + { + long int value; + size_t clen; + char *cvalue; + switch (c->call) + { + case PATHCONF: + if (argc < 3) + usage (); + value = pathconf (argv[2], c->call_name); + if (value == -1) + { + fprintf (stderr, "%s: pathconf: %s: %s\n", + program, argv[2], strerror (errno)); + exit (3); + } + printf ("%ld\n", value); + exit (0); + + case SYSCONF: + if (argc > 2) + usage (); + value = sysconf (c->call_name); + printf ("%ld\n", value); + exit (0); + + case CONFSTR: + if (argc > 2) + usage (); + clen = confstr (c->call_name, (char *) NULL, 0); + cvalue = (char *) malloc (clen); + if (cvalue == NULL) + { + fprintf (stderr, "%s: malloc: %s\n", + program, strerror (errno)); + exit (3); + } + if (confstr (c->call_name, cvalue, clen) != clen) + { + fprintf (stderr, "%s: confstr: %s\n", + program, strerror (errno)); + exit (3); + } + printf ("%.*s\n", (int) clen, cvalue); + exit (0); + } + } + + fprintf (stderr, "%s: Unrecognized variable `%s'\n", program, argv[1]); + exit (2); +} diff --git a/posix/getopt.c b/posix/getopt.c new file mode 100644 index 0000000000..7e7fdc7c3b --- /dev/null +++ b/posix/getopt.c @@ -0,0 +1,759 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 + Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include <stdlib.h> +#endif /* GNU C library. */ + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include <string.h> +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#ifndef __STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0) + optstring = _getopt_initialize (optstring); + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if (nameend - nextchar == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + else + fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/posix/getopt.h b/posix/getopt.h new file mode 100644 index 0000000000..ab50378d09 --- /dev/null +++ b/posix/getopt.h @@ -0,0 +1,133 @@ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if __STDC__ +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/posix/getopt1.c b/posix/getopt1.c new file mode 100644 index 0000000000..644894f7bc --- /dev/null +++ b/posix/getopt1.c @@ -0,0 +1,191 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. The master source lives in /gd/gnu/lib. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#include "getopt.h" + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include <stdlib.h> +#else +char *getenv (); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +#include <stdio.h> + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/posix/glob.c b/posix/glob.c new file mode 100644 index 0000000000..243730d9ae --- /dev/null +++ b/posix/glob.c @@ -0,0 +1,671 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/types.h> + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#ifdef STDC_HEADERS +#include <stddef.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#ifndef POSIX +#ifdef _POSIX_VERSION +#define POSIX +#endif +#endif +#endif + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__) +#include <dirent.h> +#ifndef __GNU_LIBRARY__ +#define D_NAMLEN(d) strlen((d)->d_name) +#else /* GNU C library. */ +#define D_NAMLEN(d) ((d)->d_namlen) +#endif /* Not GNU C library. */ +#else /* Not POSIX or HAVE_DIRENT_H. */ +#define direct dirent +#define D_NAMLEN(d) ((d)->d_namlen) +#ifdef HAVE_SYS_NDIR_H +#include <sys/ndir.h> +#endif /* HAVE_SYS_NDIR_H */ +#ifdef HAVE_SYS_DIR_H +#include <sys/dir.h> +#endif /* HAVE_SYS_DIR_H */ +#ifdef HAVE_NDIR_H +#include <ndir.h> +#endif /* HAVE_NDIR_H */ +#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */ + +#if defined (POSIX) && !defined (__GNU_LIBRARY__) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#define REAL_DIR_ENTRY(dp) 1 +#else +#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ + +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) +#include <stdlib.h> +#include <string.h> +#define ANSI_STRING +#else /* No standard headers. */ + +#ifdef HAVE_STRING_H +#include <string.h> +#define ANSI_STRING +#else +#include <strings.h> +#endif +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif + +extern char *malloc (), *realloc (); +extern void free (); + +extern void qsort (); +extern void abort (), exit (); + +#endif /* Standard headers. */ + +#ifndef ANSI_STRING + +#ifndef bzero +extern void bzero (); +#endif +#ifndef bcopy +extern void bcopy (); +#endif + +#define memcpy(d, s, n) bcopy ((s), (d), (n)) +#define strrchr rindex +/* memset is only used for zero here, but let's be paranoid. */ +#define memset(s, better_be_zero, n) \ + ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) +#endif /* Not ANSI_STRING. */ + +#ifndef HAVE_STRCOLL +#define strcoll strcmp +#endif + + +#ifndef __GNU_LIBRARY__ +#ifdef __GNUC__ +__inline +#endif +static char * +my_realloc (p, n) + char *p; + unsigned int n; +{ + /* These casts are the for sake of the broken Ultrix compiler, + which warns of illegal pointer combinations otherwise. */ + if (p == NULL) + return (char *) malloc (n); + return (char *) realloc (p, n); +} +#define realloc my_realloc +#endif + + +#if !defined(__alloca) && !defined(__GNU_LIBRARY__) + +#ifdef __GNUC__ +#undef alloca +#define alloca(n) __builtin_alloca (n) +#else /* Not GCC. */ +#if defined (sparc) || defined (HAVE_ALLOCA_H) +#include <alloca.h> +#else /* Not sparc or HAVE_ALLOCA_H. */ +#ifndef _AIX +extern char *alloca (); +#endif /* Not _AIX. */ +#endif /* sparc or HAVE_ALLOCA_H. */ +#endif /* GCC. */ + +#define __alloca alloca + +#endif + +#ifndef STDC_HEADERS +#undef size_t +#define size_t unsigned int +#endif + +/* Some system header files erroneously define these. + We want our own definitions from <fnmatch.h> to take precedence. */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD +#include <fnmatch.h> + +/* Some system header files erroneously define these. + We want our own definitions from <glob.h> to take precedence. */ +#undef GLOB_ERR +#undef GLOB_MARK +#undef GLOB_NOSORT +#undef GLOB_DOOFFS +#undef GLOB_NOCHECK +#undef GLOB_APPEND +#undef GLOB_NOESCAPE +#undef GLOB_PERIOD +#include <glob.h> + +__ptr_t (*__glob_opendir_hook) __P ((const char *directory)); +const char *(*__glob_readdir_hook) __P ((__ptr_t stream)); +void (*__glob_closedir_hook) __P ((__ptr_t stream)); + +static int glob_pattern_p __P ((const char *pattern, int quote)); +static int glob_in_dir __P ((const char *pattern, const char *directory, + int flags, + int (*errfunc) __P ((const char *, int)), + glob_t *pglob)); +static int prefix_array __P ((const char *prefix, char **array, size_t n)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +int +glob (pattern, flags, errfunc, pglob) + const char *pattern; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + const char *filename; + char *dirname; + size_t dirlen; + int status; + int oldcount; + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { + errno = EINVAL; + return -1; + } + + /* Find the filename. */ + filename = strrchr (pattern, '/'); + if (filename == NULL) + { + filename = pattern; + dirname = (char *) "."; + dirlen = 0; + } + else if (filename == pattern) + { + /* "/pattern". */ + dirname = (char *) "/"; + dirlen = 1; + ++filename; + } + else + { + dirlen = filename - pattern; + dirname = (char *) __alloca (dirlen + 1); + memcpy (dirname, pattern, dirlen); + dirname[dirlen] = '\0'; + ++filename; + } + + if (filename[0] == '\0' && dirlen > 1) + /* "pattern/". Expand "pattern", appending slashes. */ + { + int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (val == 0) + pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK); + return val; + } + + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + + oldcount = pglob->gl_pathc; + + if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) + { + /* The directory name contains metacharacters, so we + have to glob for the directory, and then glob for + the pattern in each directory found. */ + glob_t dirs; + register int i; + + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | + GLOB_NOSORT), + errfunc, &dirs); + if (status != 0) + return status; + + /* We have successfully globbed the preceding directory name. + For each name we found, call glob_in_dir on it and FILENAME, + appending the results to PGLOB. */ + for (i = 0; i < dirs.gl_pathc; ++i) + { + int oldcount; + +#ifdef SHELL + { + /* Make globbing interruptible in the bash shell. */ + extern int interrupt_state; + + if (interrupt_state) + { + globfree (&dirs); + globfree (&files); + return GLOB_ABEND; + } + } +#endif /* SHELL. */ + + oldcount = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + (flags | GLOB_APPEND) & ~GLOB_NOCHECK, + errfunc, pglob); + if (status == GLOB_NOMATCH) + /* No matches in this directory. Try the next. */ + continue; + + if (status != 0) + { + globfree (&dirs); + globfree (pglob); + return status; + } + + /* Stick the directory on the front of each name. */ + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + } + + flags |= GLOB_MAGCHAR; + + if (pglob->gl_pathc == oldcount) + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + size_t len = strlen (pattern) + 1; + char *patcopy = (char *) malloc (len); + if (patcopy == NULL) + return GLOB_NOSPACE; + memcpy (patcopy, pattern, len); + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + 1 + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + { + free (patcopy); + return GLOB_NOSPACE; + } + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + pglob->gl_pathv[pglob->gl_pathc++] = patcopy; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + } + else + return GLOB_NOMATCH; + } + else + { + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + if (status != 0) + return status; + + if (dirlen > 0) + { + /* Stick the directory on the front of each name. */ + if (prefix_array (dirname, + &pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount)) + { + globfree (pglob); + return GLOB_NOSPACE; + } + } + } + + if (!(flags & GLOB_NOSORT)) + /* Sort the vector. */ + qsort ((__ptr_t) & pglob->gl_pathv[oldcount], + pglob->gl_pathc - oldcount, + sizeof (char *), collated_compare); + + return 0; +} + + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +void +globfree (pglob) + register glob_t *pglob; +{ + if (pglob->gl_pathv != NULL) + { + register int i; + for (i = 0; i < pglob->gl_pathc; ++i) + if (pglob->gl_pathv[i] != NULL) + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); + } +} + + +/* Do a collated comparison of A and B. */ +static int +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; +{ + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; + + if (s1 == s2) + return 0; + if (s1 == NULL) + return 1; + if (s2 == NULL) + return -1; + return strcoll (s1, s2); +} + + +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's + elements in place. Return nonzero if out of memory, zero if successful. + A slash is inserted between DIRNAME and each elt of ARRAY, + unless DIRNAME is just "/". Each old element of ARRAY is freed. */ +static int +prefix_array (dirname, array, n) + const char *dirname; + char **array; + size_t n; +{ + register size_t i; + size_t dirlen = strlen (dirname); + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; + + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) + free ((__ptr_t) array[--i]); + return 1; + } + + memcpy (new, dirname, dirlen); + new[dirlen] = '/'; + memcpy (&new[dirlen + 1], array[i], eltlen); + free ((__ptr_t) array[i]); + array[i] = new; + } + + return 0; +} + + +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +static int +glob_pattern_p (pattern, quote) + const char *pattern; + int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote) + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} + + +/* Like `glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +static int +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + __ptr_t stream; + + struct globlink + { + struct globlink *next; + char *name; + }; + struct globlink *names = NULL; + size_t nfound = 0; + + if (!glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE))) + { + stream = NULL; + flags |= GLOB_NOCHECK; + } + else + { + flags |= GLOB_MAGCHAR; + + stream = (__glob_opendir_hook ? (*__glob_opendir_hook) (directory) + : (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if ((errfunc != NULL && (*errfunc) (directory, errno)) || + (flags & GLOB_ERR)) + return GLOB_ABEND; + } + else + while (1) + { + const char *name; + size_t len; + + if (__glob_readdir_hook) + { + name = (*__glob_readdir_hook) (stream); + if (name == NULL) + break; + len = 0; + } + else + { + struct dirent *d = readdir ((DIR *) stream); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + name = d->d_name; +#ifdef HAVE_D_NAMLEN + len = d->d_namlen; +#else + len = 0; +#endif + } + + if (fnmatch (pattern, name, + (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | + ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)) == 0) + { + struct globlink *new + = (struct globlink *) __alloca (sizeof (struct globlink)); + if (len == 0) + len = strlen (name); + new->name + = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (new->name == NULL) + goto memory_error; + memcpy ((__ptr_t) new->name, name, len); + if (flags & GLOB_MARK) + new->name[len++] = '/'; + new->name[len] = '\0'; + new->next = names; + names = new; + ++nfound; + } + } + } + + if (nfound == 0 && (flags & GLOB_NOCHECK)) + { + size_t len = strlen (pattern); + nfound = 1; + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->next = NULL; + names->name = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1); + if (names->name == NULL) + goto memory_error; + memcpy (names->name, pattern, len); + if (flags & GLOB_MARK) + names->name[len++] = '/'; + names->name[len] = '\0'; + } + + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + + if (stream != NULL) + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + return nfound == 0 ? GLOB_NOMATCH : 0; + + memory_error: + { + int save = errno; + if (__glob_closedir_hook) + (*__glob_closedir_hook) (stream); + else + (void) closedir ((DIR *) stream); + errno = save; + } + while (names != NULL) + { + if (names->name != NULL) + free ((__ptr_t) names->name); + names = names->next; + } + return GLOB_NOSPACE; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/posix/glob.h b/posix/glob.h new file mode 100644 index 0000000000..05ad47f05d --- /dev/null +++ b/posix/glob.h @@ -0,0 +1,97 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GLOB_H + +#define _GLOB_H 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#undef __ptr_t +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(protos) protos +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(protos) () +#undef const +#define const +#define __ptr_t char * +#endif /* C++ or ANSI C. */ + +/* Bits set in the FLAGS argument to `glob'. */ +#define GLOB_ERR (1 << 0)/* Return on read errors. */ +#define GLOB_MARK (1 << 1)/* Append a slash to each name. */ +#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ +#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ +#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ +#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ +#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ +#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ +#define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|GLOB_PERIOD) + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE) +#define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ +#endif + +/* Error returns from `glob'. */ +#define GLOB_NOSPACE 1 /* Ran out of memory. */ +#define GLOB_ABEND 2 /* Read error. */ +#define GLOB_NOMATCH 3 /* No matches found. */ + +/* Structure describing a globbing run. */ +typedef struct + { + int gl_pathc; /* Count of paths matched by the pattern. */ + char **gl_pathv; /* List of matched pathnames. */ + int gl_offs; /* Slots to reserve in `gl_pathv'. */ + int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ + } glob_t; + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +extern int glob __P ((const char *__pattern, int __flags, + int (*__errfunc) __P ((const char *, int)), + glob_t *__pglob)); + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +extern void globfree __P ((glob_t *__pglob)); + + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +/* If they are not NULL, `glob' uses these functions to read directories. */ +extern __ptr_t (*__glob_opendir_hook) __P ((const char *__directory)); +extern const char *(*__glob_readdir_hook) __P ((__ptr_t __stream)); +extern void (*__glob_closedir_hook) __P ((__ptr_t __stream)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* glob.h */ diff --git a/posix/glob/.cvsignore b/posix/glob/.cvsignore new file mode 100644 index 0000000000..56631abf19 --- /dev/null +++ b/posix/glob/.cvsignore @@ -0,0 +1 @@ +ChangeLog diff --git a/posix/glob/Makefile.in b/posix/glob/Makefile.in new file mode 100644 index 0000000000..8c091b33ac --- /dev/null +++ b/posix/glob/Makefile.in @@ -0,0 +1,66 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 92, 93, 94, 95 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = @srcdir@ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = @srcdir@ + +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ + +# Information determined by configure. +DEFS = @DEFS@ + +# How to invoke ar. +AR = @AR@ +ARFLAGS = rv + +# How to invoke ranlib. +RANLIB = @RANLIB@ + +.PHONY: all +all: libglob.a + +libglob.a: glob.o fnmatch.o + $(AR) $(ARFLAGS) $@ glob.o fnmatch.o + $(RANLIB) $@ + +# For some reason, Unix make wants the dependencies on the source files. +# Otherwise it refuses to use an implicit rule! +# And, get this: it doesn't work to use $(srcdir)/foo.c!! +glob.o: $(srcdir)/glob.h $(srcdir)/fnmatch.h glob.c +fnmatch.o: $(srcdir)/fnmatch.h fnmatch.c + +.c.o: + $(CC) -I. -I$(srcdir) -c \ + $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean distclean +clean glob-clean: + -rm -f libglob.a *.o core +distclean glob-realclean: clean + -rm -f TAGS tags Makefile config.status config.h config.log +realcean: distclean + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff --git a/posix/glob/configure b/posix/glob/configure new file mode 100755 index 0000000000..38315221a1 --- /dev/null +++ b/posix/glob/configure @@ -0,0 +1,1123 @@ +#!/bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 1.11 +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +# This configure script is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This script is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Save the original args to write them into config.status later. +configure_args="$*" + +# Only options that might do something get documented. +ac_usage="Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +--build=BUILD configure for building on BUILD [BUILD=HOST] +--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) +--enable-FEATURE[=ARG] include FEATURE [ARG=yes] +--exec-prefix=PREFIX install host dependent files in PREFIX [/usr/local] +--help print this message +--host=HOST configure for HOST [guessed] +--prefix=PREFIX install host independent files in PREFIX [/usr/local] +--quiet, --silent do not print \`checking for...' messages +--srcdir=DIR find the sources in DIR [configure dir or ..] +--target=TARGET configure for TARGET [TARGET=HOST] +--verbose print results of checks +--version print the version of autoconf that created configure +--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) +--x-includes=DIR X include files are in DIR +--x-libraries=DIR X library files are in DIR" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +exec_prefix= +host=NONE +no_create= +nonopt=NONE +norecursion= +prefix= +program_prefix= +program_suffix= +program_transform_name= +silent= +srcdir= +target=NONE +verbose= +x_includes= +x_libraries= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + # Accept (but ignore some of) the important Cygnus configure + # options, so we can diagnose typos. + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + # For backward compatibility, recognize -exec-prefix and --exec_prefix. + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + with_gas=yes ;; # Obsolete; use --with-gas. + + -help | --help | --hel | --he) + cat << EOF +$ac_usage +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + with_fp=no ;; # Obsolete; use --without-fp. + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) + norecursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 1.11" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) with_x=yes ;; # Obsolete; use --with-x. + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) echo "configure: $ac_option: invalid option; use --help to show usage" >&2; exit 1 + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" >&2 + fi + if test "x$nonopt" != xNONE; then + echo "configure: can only configure for one host and one target at a time" >&2; exit 1 + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + echo "configure: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" >&2; exit 1 +fi + +trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15 +trap 'rm -fr confdefs* $ac_clean_files' 0 + +# Save the original args if we used an alternate arg parser. +ac_configure_temp="${configure_args-$*}" +# Strip out --no-create and --norecursion so they don't pile up. +configure_args= +for ac_arg in $ac_configure_temp; do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) ;; + *) configure_args="$configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = 'set'; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = 'set'; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=fnmatch.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then `..'. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +fi +if test ! -r $srcdir/$ac_unique_file; then + if test x$ac_srcdir_defaulted = xyes; then + echo "configure: can not find sources in ${ac_confdir} or .." >&2; exit 1 + else + echo "configure: can not find sources in ${srcdir}" >&2; exit 1 + fi +fi +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='${CPP}' +ac_compile='${CC-cc} $CFLAGS $LDFLAGS conftest.${ac_ext} -o conftest $LIBS >/dev/null 2>&1' + + if test -z "$RANLIB"; then + # Extract the first word of `ranlib', so it can be a program name with args. + set ac_dummy ranlib; ac_word=$2 + test -n "$silent" || echo "checking for $ac_word" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +test -z "$RANLIB" && RANLIB=":" +test -n "$RANLIB" && test -n "$verbose" && echo " setting RANLIB to $RANLIB" + +test -n "$silent" || echo "checking how to run the C preprocessor" +if test -z "$CPP"; then + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and ``${CC-cc}'' will simply confuse + # make. It must be expanded now. + CPP="${CC-cc} -E" + cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdio.h> +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdio.h> +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +test -n "$verbose" && echo " setting CPP to $CPP" + test -n "$silent" || echo "checking for AIX" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#ifdef _AIX + yes +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining _ALL_SOURCE" +echo "#define" _ALL_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_ALL_SOURCE=1" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for POSIXized ISC" +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + ISC=1 # If later tests want to check for ISC. + +{ +test -n "$verbose" && \ +echo " defining _POSIX_SOURCE" +echo "#define" _POSIX_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_POSIX_SOURCE=1" +} + + if test -n "$GCC"; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +fi + +test -n "$silent" || echo "checking for minix/config.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <minix/config.h> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + MINIX=1 + +fi +rm -f conftest* + +# The Minix shell can't assign to the same variable on the same line! +if test -n "$MINIX"; then + +{ +test -n "$verbose" && \ +echo " defining _POSIX_SOURCE" +echo "#define" _POSIX_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_POSIX_SOURCE=1" +} + + +{ +test -n "$verbose" && \ +echo " defining" _POSIX_1_SOURCE to be "2" +echo "#define" _POSIX_1_SOURCE "2" >> confdefs.h +DEFS="$DEFS -D_POSIX_1_SOURCE=2" +} + + +{ +test -n "$verbose" && \ +echo " defining _MINIX" +echo "#define" _MINIX "1" >> confdefs.h +DEFS="$DEFS -D_MINIX=1" +} + +fi + +test -n "$silent" || echo "checking for ANSI C header files" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +echo '#include "confdefs.h" +#include <string.h>' > conftest.${ac_ext} +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "memchr" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +echo '#include "confdefs.h" +#include <stdlib.h>' > conftest.${ac_ext} +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "free" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining STDC_HEADERS" +echo "#define" STDC_HEADERS "1" >> confdefs.h +DEFS="$DEFS -DSTDC_HEADERS=1" +} + + +fi +rm -f conftest* + + +fi +rm -fr conftest* + +fi +rm -f conftest* + + +fi +rm -f conftest* + +for ac_hdr in memory.h unistd.h string.h +do +ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./' '[A-Z]__'` +test -n "$silent" || echo "checking for ${ac_hdr}" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <${ac_hdr}> +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining ${ac_tr_hdr}" +echo "#define" ${ac_tr_hdr} "1" >> confdefs.h +DEFS="$DEFS -D${ac_tr_hdr}=1" +} + + +fi +rm -f conftest* +done + +test -n "$silent" || echo "checking for directory library header" +ac_dir_header= +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for dirent.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <dirent.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining DIRENT" +echo "#define" DIRENT "1" >> confdefs.h +DEFS="$DEFS -DDIRENT=1" +} + ac_dir_header=dirent.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/ndir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <sys/ndir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSNDIR" +echo "#define" SYSNDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSNDIR=1" +} + ac_dir_header=sys/ndir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/dir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <sys/dir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSDIR" +echo "#define" SYSDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSDIR=1" +} + ac_dir_header=sys/dir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for ndir.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <ndir.h> +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NDIR" +echo "#define" NDIR "1" >> confdefs.h +DEFS="$DEFS -DNDIR=1" +} + ac_dir_header=ndir.h + +fi +rm -f conftest* +fi + +test -n "$silent" || echo "checking for closedir return value" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <sys/types.h> +#include <$ac_dir_header> +int closedir(); main() { exit(closedir(opendir(".")) != 0); } +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + +{ +test -n "$verbose" && \ +echo " defining VOID_CLOSEDIR" +echo "#define" VOID_CLOSEDIR "1" >> confdefs.h +DEFS="$DEFS -DVOID_CLOSEDIR=1" +} + +fi +rm -fr conftest* + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +test -n "$silent" || echo "checking for working alloca.h" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <alloca.h> +int main() { return 0; } +int t() { char *p = alloca(2 * sizeof(int));; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_ALLOCA_H" +echo "#define" HAVE_ALLOCA_H "1" >> confdefs.h +DEFS="$DEFS -DHAVE_ALLOCA_H=1" +} + + +fi +rm -f conftest* + +ac_decl="#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#if HAVE_ALLOCA_H +#include <alloca.h> +#else +#ifdef _AIX + #pragma alloca +#else +char *alloca (); +#endif +#endif +#endif +" +test -n "$silent" || echo "checking for alloca" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +$ac_decl +int main() { return 0; } +int t() { char *p = (char *) alloca(1);; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_ALLOCA" +echo "#define" HAVE_ALLOCA "1" >> confdefs.h +DEFS="$DEFS -DHAVE_ALLOCA=1" +} + + +else + rm -rf conftest* + ac_alloca_missing=1 +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" + +#if defined(CRAY) && ! defined(CRAY2) +winnitude +#else +lossage +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "winnitude" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + test -n "$silent" || echo "checking for _getb67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__getb67) || defined (__stub____getb67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char _getb67(); _getb67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "_getb67" +echo "#define" CRAY_STACKSEG_END "_getb67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=_getb67" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for GETB67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_GETB67) || defined (__stub___GETB67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char GETB67(); GETB67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "GETB67" +echo "#define" CRAY_STACKSEG_END "GETB67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=GETB67" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for getb67" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getb67) || defined (__stub___getb67) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char getb67(); getb67(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining" CRAY_STACKSEG_END to be "getb67" +echo "#define" CRAY_STACKSEG_END "getb67" >> confdefs.h +DEFS="$DEFS -DCRAY_STACKSEG_END=getb67" +} + + +fi +rm -f conftest* + +fi +rm -f conftest* + +fi +rm -f conftest* + + +fi +rm -f conftest* + + +fi +rm -f conftest* + +if test -n "$ac_alloca_missing"; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.o + +{ +test -n "$verbose" && \ +echo " defining C_ALLOCA" +echo "#define" C_ALLOCA "1" >> confdefs.h +DEFS="$DEFS -DC_ALLOCA=1" +} + + + test -n "$silent" || echo "checking stack direction for C alloca" + test -n "$silent" || echo "checking whether cross-compiling" +# If we cannot run a trivial program, we must be cross compiling. +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +main(){exit(0);} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + cross_compiling=1 +fi +rm -fr conftest* + +if test -n "$cross_compiling" +then + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "0" +echo "#define" STACK_DIRECTION "0" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=0" +} + +else +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "1" +echo "#define" STACK_DIRECTION "1" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=1" +} + + +else + +{ +test -n "$verbose" && \ +echo " defining" STACK_DIRECTION to be "-1" +echo "#define" STACK_DIRECTION "-1" >> confdefs.h +DEFS="$DEFS -DSTACK_DIRECTION=-1" +} + +fi +fi +rm -fr conftest* +fi + +test -n "$silent" || echo "checking for strcoll" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <string.h> +main () +{ + exit (strcoll ("abc", "def") >= 0 || + strcoll ("ABC", "DEF") >= 0 || + strcoll ("123", "456") >= 0); +} +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + +{ +test -n "$verbose" && \ +echo " defining HAVE_STRCOLL" +echo "#define" HAVE_STRCOLL "1" >> confdefs.h +DEFS="$DEFS -DHAVE_STRCOLL=1" +} + + +fi +rm -fr conftest* +ac_save_LIBS="${LIBS}" +LIBS="${LIBS} -lseq" +ac_have_lib="" +test -n "$silent" || echo "checking for -lseq" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" + +int main() { return 0; } +int t() { main();; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_have_lib="1" + +fi +rm -f conftest* +LIBS="${ac_save_LIBS}" +if test -n "${ac_have_lib}"; then + :; LIBS="$LIBS -lseq" +else + :; +fi + + +test -n "$silent" || echo "checking for Xenix" +cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#if defined(M_XENIX) && !defined(M_UNIX) + yes +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + XENIX=1 + +fi +rm -f conftest* + +if test -n "$XENIX"; then + LIBS="$LIBS -lx" + case "$DEFS" in + *SYSNDIR*) ;; + *) LIBS="-ldir $LIBS" ;; # Make sure -ldir precedes any -lx. + esac +fi + + +# The preferred way to propogate these variables is regular @ substitutions. +if test -n "$prefix"; then + ac_prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" +else + prefix=/usr/local +fi +if test -n "$exec_prefix"; then + ac_prsub="$ac_prsub +s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%exec_prefix\\1=\\2$exec_prefix%" +else + exec_prefix='${prefix}' # Let make expand it. +fi + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +# Quote sed substitution magic chars in DEFS. +cat >conftest.def <<EOF +$DEFS +EOF +ac_escape_ampersand_and_backslash='s%[&\\]%\\&%g' +DEFS=`sed "$ac_escape_ampersand_and_backslash" <conftest.def` +rm -f conftest.def +# Substitute for predefined variables. + +trap 'rm -f config.status; exit 1' 1 2 15 +echo creating config.status +rm -f config.status +cat > config.status <<EOF +#!/bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $configure_args + +ac_cs_usage="Usage: config.status [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo running \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create + exec \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "config.status generated by autoconf version 1.11" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +trap 'rm -f Makefile; exit 1' 1 2 15 +RANLIB='$RANLIB' +CPP='$CPP' +ALLOCA='$ALLOCA' +LIBS='$LIBS' +srcdir='$srcdir' +top_srcdir='$top_srcdir' +prefix='$prefix' +exec_prefix='$exec_prefix' +DEFS='$DEFS' +ac_prsub='$ac_prsub' +ac_vpsub='$ac_vpsub' +extrasub='$extrasub' +EOF +cat >> config.status <<\EOF + +ac_given_srcdir=$srcdir + +CONFIG_FILES=${CONFIG_FILES-"Makefile"} +for ac_file in .. ${CONFIG_FILES}; do if test "x$ac_file" != x..; then + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/$ac_dir" + else + ac_dir_suffix= + fi + + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dir_suffix"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + comment_str="Generated automatically from `echo $ac_file|sed 's|.*/||'`.in by configure." + case "$ac_file" in + *.c | *.h | *.C | *.cc | *.m ) echo "/* $comment_str */" > "$ac_file" ;; + * ) echo "# $comment_str" > "$ac_file" ;; + esac + sed -e " +$ac_prsub +$ac_vpsub +$extrasub +s%@RANLIB@%$RANLIB%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g +s%@LIBS@%$LIBS%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@prefix@%$prefix%g +s%@exec_prefix@%$exec_prefix%g +s%@DEFS@%$DEFS% +" $ac_given_srcdir/${ac_file}.in >> $ac_file +fi; done + + +exit 0 +EOF +chmod +x config.status +# Some shells look in PATH for config.status without the "./". +test -n "$no_create" || ${CONFIG_SHELL-/bin/sh} ./config.status + diff --git a/posix/glob/configure.bat b/posix/glob/configure.bat new file mode 100644 index 0000000000..f3b0720c43 --- /dev/null +++ b/posix/glob/configure.bat @@ -0,0 +1,23 @@ +@echo off +echo Configuring glob for GO32 +rem This batch file assumes a unix-type "sed" program + +echo # Makefile generated by "configure.bat"> Makefile + +if exist config.sed del config.sed + +echo "s/@srcdir@/./ ">> config.sed +echo "s/@RANLIB@/ranlib/ ">> config.sed +echo "s/@LDFLAGS@// ">> config.sed +echo "s/@DEFS@/-DHAVE_CONFIG_H -I../ ">> config.sed +echo "s/@REMOTE@/s/ ">> config.sed +echo "s/@ALLOCA@// ">> config.sed +echo "s/@LIBS@// ">> config.sed +echo "s/@LIBOBJS@// ">> config.sed +echo "s/^Makefile *:/_Makefile:/ ">> config.sed +echo "s/^config.h *:/_config.h:/ ">> config.sed + +sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed +sed -f config2.sed Makefile.in >> Makefile +del config.sed +del config2.sed diff --git a/posix/glob/configure.in b/posix/glob/configure.in new file mode 100644 index 0000000000..3c85100778 --- /dev/null +++ b/posix/glob/configure.in @@ -0,0 +1,19 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(fnmatch.c) dnl A distinctive file to look for in srcdir. +AC_PREREQ(2.1) dnl Minimum Autoconf version required. +AC_PROG_CC +AC_CHECK_PROG(AR, ar, ar, ar) +AC_PROG_RANLIB +AC_PROG_CPP dnl Later checks need this. +dnl These two want to come early. +AC_AIX +AC_MINIX +AC_CONST +AC_ISC_POSIX +AC_HEADER_STDC +AC_CHECK_HEADERS(memory.h unistd.h string.h) +AC_HEADER_DIRENT +AC_FUNC_CLOSEDIR_VOID +AC_FUNC_ALLOCA +AC_FUNC_STRCOLL +AC_OUTPUT(Makefile) diff --git a/posix/gnu/types.h b/posix/gnu/types.h new file mode 100644 index 0000000000..30f753f72d --- /dev/null +++ b/posix/gnu/types.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GNU_TYPES_H + +#define _GNU_TYPES_H 1 + + +/* Convenience types. */ +typedef unsigned char __u_char; +typedef unsigned short __u_short; +typedef unsigned int __u_int; +typedef unsigned long __u_long; +#ifdef __GNUC__ +typedef unsigned long long int __u_quad_t; +typedef long long int __quad_t; +typedef __quad_t *__qaddr_t; +#else +typedef struct +{ + long val[2]; +} __quad_t; +typedef struct +{ + __u_long val[2]; +} __u_quad_t; +#endif +typedef int __dev_t; /* Type of device numbers. */ +typedef unsigned int __uid_t; /* Type of user identifications. */ +typedef unsigned int __gid_t; /* Type of group identifications. */ +typedef unsigned int __ino_t; /* Type of file serial numbers. */ +typedef unsigned int __mode_t; /* Type of file attribute bitmasks. */ +typedef unsigned short int __nlink_t; /* Type of file link counts. */ +typedef long int __off_t; /* Type of file sizes and offsets. */ +typedef int __pid_t; /* Type of process identifications. */ +typedef int __ssize_t; /* Type of a byte count, or error. */ +typedef __u_quad_t __fsid_t; /* Type of file system IDs. */ + +/* Everythin' else. */ +typedef long int __daddr_t; /* The type of a disk address. */ +typedef char *__caddr_t; +typedef long int __time_t; +typedef long int __swblk_t; /* Type of a swap block maybe? */ + +/* fd_set for select. */ + +/* Number of descriptors that can fit in an `fd_set'. */ +#define __FD_SETSIZE 256 + +/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ +#define __NFDBITS (sizeof (unsigned long int) * 8) +#define __FDELT(d) ((d) / __NFDBITS) +#define __FDMASK(d) (1 << ((d) % __NFDBITS)) + +typedef struct + { + /* Some braindead old software uses this member name. */ + unsigned long int fds_bits[(__FD_SETSIZE + (__NFDBITS - 1)) / __NFDBITS]; + } __fd_set; + +/* This line MUST be split! Otherwise m4 will not change it. */ +#define __FD_ZERO(set) \ + ((void) memset ((__ptr_t) (set), 0, sizeof (fd_set))) +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + + +#endif /* gnu/types.h */ diff --git a/posix/id.c b/posix/id.c new file mode 100644 index 0000000000..d886e68573 --- /dev/null +++ b/posix/id.c @@ -0,0 +1,173 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <grp.h> +#include <pwd.h> +#include <limits.h> +#include <sys/types.h> + + +static void +DEFUN(print_grpname, (id, parens), + gid_t id AND int parens) +{ + CONST struct group *CONST g = getgrgid(id); + if (g == NULL) + { + if (parens) + return; + else + { + fprintf(stderr, "Couldn't find name for group %d\n", id); + exit(EXIT_FAILURE); + } + } + + if (parens) + printf("(%s)", g->gr_name); + else + puts(g->gr_name); +} + +static void +DEFUN(print_pwdname, (id, parens), + uid_t id AND int parens) +{ + CONST struct passwd *CONST p = getpwuid(id); + if (p == NULL) + { + if (parens) + return; + else + { + fprintf(stderr, "Couldn't find name for user %d\n", (int) id); + exit(EXIT_FAILURE); + } + } + + if (parens) + printf("(%s)", p->pw_name); + else + puts(p->pw_name); +} + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + int print_gid = 1, print_uid = 1; + int real = 0, name = 0; + int error = 0; + register int c; + + uid_t ruid = getuid(), euid = geteuid(); + gid_t rgid = getgid(), egid = getegid(); + + while ((c = getopt(argc, argv, "gurn")) != -1) + switch (c) + { + default: + error = 1; + break; + + case 'g': + print_gid = 1; + print_uid = 0; + break; + + case 'u': + print_uid = 1; + print_gid = 0; + break; + + case 'r': + real = 1; + break; + + case 'n': + name = 1; + break; + } + + if (error || argc != optind) + { + fputs("Usage: id [-gurn]\n", stderr); + exit(EXIT_FAILURE); + } + + if (print_uid && !print_gid) + { + CONST uid_t uid = real ? ruid : euid; + if (name) + print_pwdname(uid, 0); + else + printf("%d\n", (int) uid); + } + else if (print_gid && !print_uid) + { + CONST gid_t gid = real ? rgid : egid; + if (name) + print_grpname(gid, 0); + else + printf("%d\n", (int) gid); + } + else + { +#if NGROUPS_MAX > 0 + gid_t groups[NGROUPS_MAX]; + int ngroups; + ngroups = getgroups(NGROUPS_MAX, groups); +#endif + + printf("uid=%d", (int) ruid); + print_pwdname(ruid, 1); + printf(" gid=%d", (int) rgid); + print_grpname(rgid, 1); + if (euid != ruid) + { + printf(" euid=%d", (int) euid); + print_pwdname(euid, 1); + } + if (egid != rgid) + { + printf(" egid=%d", (int) egid); + print_grpname(egid, 1); + } + +#if NGROUPS > 0 + if (ngroups > 0) + { + register size_t i; + printf(" groups=%d", (int) groups[0]); + print_grpname(groups[0], 1); + for (i = 1; i < ngroups; ++i) + { + printf(", %d", (int) groups[i]); + print_grpname(groups[i], 1); + } + } +#endif + + putchar('\n'); + } + + exit(EXIT_SUCCESS); +} diff --git a/posix/posix1_lim.h b/posix/posix1_lim.h new file mode 100644 index 0000000000..acbfa64481 --- /dev/null +++ b/posix/posix1_lim.h @@ -0,0 +1,87 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.9.2 Minimum Values Added to <limits.h> + */ + +#ifndef _POSIX1_LIMITS_H + +#define _POSIX1_LIMITS_H 1 + + +/* These are the standard-mandated minimum values. */ + +/* Maximum length of arguments to `execve', including environment. */ +#define _POSIX_ARG_MAX 4096 + +/* Maximum simultaneous processes per real user ID. */ +#define _POSIX_CHILD_MAX 6 + +/* Maximum link count of a file. */ +#define _POSIX_LINK_MAX 8 + +/* Number of bytes in a terminal canonical input queue. */ +#define _POSIX_MAX_CANON 255 + +/* Number of bytes for which space will be + available in a terminal input queue. */ +#define _POSIX_MAX_INPUT 255 + +/* Number of simultaneous supplementary group IDs per process. */ +#define _POSIX_NGROUPS_MAX 0 + +/* Number of files one process can have open at once. */ +#define _POSIX_OPEN_MAX 16 + +/* Number of bytes in a filename. */ +#define _POSIX_NAME_MAX 14 + +/* Number of bytes in a pathname. */ +#define _POSIX_PATH_MAX 255 + +/* Number of bytes than can be written atomically to a pipe. */ +#define _POSIX_PIPE_BUF 512 + +/* Largest value of a `ssize_t'. */ +#define _POSIX_SSIZE_MAX 32767 + +/* Number of streams a process can have open at once. */ +#define _POSIX_STREAM_MAX 8 + +/* Maximum length of a timezone name (element of `tzname'). */ +#define _POSIX_TZNAME_MAX 3 + + +/* Get the implementation-specific values for the above. */ +#include <local_lim.h> + + +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + + +/* This value is a guaranteed minimum maximum. + The current maximum can be got from `sysconf'. */ + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX _POSIX_NGROUPS_MAX +#endif + +#endif /* posix1_limits.h */ diff --git a/posix/posix2_lim.h b/posix/posix2_lim.h new file mode 100644 index 0000000000..05565024f6 --- /dev/null +++ b/posix/posix2_lim.h @@ -0,0 +1,82 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _POSIX2_LIMITS_H + +#define _POSIX2_LIMITS_H 1 + + +/* The maximum `ibase' and `obase' values allowed by the `bc' utility. */ +#define _POSIX2_BC_BASE_MAX 99 + +/* The maximum number of elements allowed in an array by the `bc' utility. */ +#define _POSIX2_BC_DIM_MAX 2048 + +/* The maximum `scale' value allowed by the `bc' utility. */ +#define _POSIX2_BC_SCALE_MAX 99 + +/* The maximum length of a string constant accepted by the `bc' utility. */ +#define _POSIX2_BC_STRING_MAX 1000 + +/* The maximum number of weights that can be assigned to an entry of + the LC_COLLATE category `order' keyword in a locale definition. */ +#define _POSIX2_EQUIV_CLASS_MAX 2 + +/* The maximum number of expressions that can be nested + within parentheses by the `expr' utility. */ +#define _POSIX2_EXPR_NEST_MAX 32 + +/* The maximum length, in bytes, of an input line. */ +#define _POSIX2_LINE_MAX 2048 + +/* The maximum number of repeated occurrences of a regular expression + permitted when using the interval notation `\{M,N\}'. */ +#define _POSIX2_RE_DUP_MAX 255 + + +/* These values are implementation-specific, + and may vary within the implementation. + Their precise values can be obtained from sysconf. */ + +#ifndef BC_BASE_MAX +#define BC_BASE_MAX _POSIX2_BC_BASE_MAX +#endif +#ifndef BC_DIM_MAX +#define BC_DIM_MAX _POSIX2_BC_DIM_MAX +#endif +#ifndef BC_SCALE_MAX +#define BC_SCALE_MAX _POSIX2_BC_SCALE_MAX +#endif +#ifndef BC_STRING_MAX +#define BC_STRING_MAX _POSIX2_BC_STRING_MAX +#endif +#ifndef EQUIV_CLASS_MAX +#define EQUIV_CLASS_MAX _POSIX2_EQUIV_CLASS_MAX +#endif +#ifndef EXPR_NEST_MAX +#define EXPR_NEST_MAX _POSIX2_EXPR_NEST_MAX +#endif +#ifndef LINE_MAX +#define LINE_MAX _POSIX2_LINE_MAX +#endif +#ifndef RE_DUP_MAX +#define RE_DUP_MAX _POSIX2_RE_DUP_MAX +#endif + + +#endif /* posix2_limits.h */ diff --git a/posix/sys/times.h b/posix/sys/times.h new file mode 100644 index 0000000000..b58be8a333 --- /dev/null +++ b/posix/sys/times.h @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 4.5.2 Process Times <sys/times.h> + */ + +#ifndef _SYS_TIMES_H + +#define _SYS_TIMES_H 1 +#include <features.h> + +#define __need_clock_t +#include <time.h> + + +__BEGIN_DECLS + +/* Structure describing CPU time used by a process and its children. */ +struct tms + { + clock_t tms_utime; /* User CPU time. */ + clock_t tms_stime; /* System CPU time. */ + + clock_t tms_cutime; /* User CPU time of dead children. */ + clock_t tms_cstime; /* System CPU time of dead children. */ + }; + + +/* Store the CPU time used by this process and all its + dead children (and their dead children) in BUFFER. + Return the elapsed real time, or (clock_t) -1 for errors. + All times are in CLK_TCKths of a second. */ +extern clock_t __times __P ((struct tms *__buffer)); +extern clock_t times __P ((struct tms *__buffer)); + +__END_DECLS + +#endif /* sys/times.h */ diff --git a/posix/sys/types.h b/posix/sys/types.h new file mode 100644 index 0000000000..b231de93c5 --- /dev/null +++ b/posix/sys/types.h @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.6 Primitive System Data Types <sys/types.h> + */ + +#ifndef _SYS_TYPES_H + +#define _SYS_TYPES_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +#ifdef __USE_BSD +#define u_char __u_char +#define u_short __u_short +#define u_int __u_int +#define u_long __u_long +#define quad_t __quad_t +#define u_quad_t __u_quad_t +#define fsid_t __fsid_t +#endif + +#define dev_t __dev_t +#define gid_t __gid_t +#define ino_t __ino_t +#define mode_t __mode_t +#define nlink_t __nlink_t +#define off_t __off_t +#define pid_t __pid_t +#define uid_t __uid_t +#ifndef ssize_t +#define ssize_t __ssize_t +#endif + +#ifdef __USE_BSD +#define daddr_t __daddr_t +#define caddr_t __caddr_t +#endif + +#define __need_time_t +#include <time.h> + +#define __need_size_t +#include <stddef.h> + +#ifdef __USE_MISC +/* Old compatibility names for C types. */ +typedef unsigned short int ushort; +typedef unsigned int uint; +#endif + +#ifdef __USE_BSD +/* These size-specific names are used by some of the inet code. */ + +typedef int int32_t; +typedef short int int16_t; +typedef char int8_t; +typedef unsigned int u_int32_t; +typedef unsigned short int u_int16_t; +typedef unsigned char u_int8_t; +#endif + + +#ifdef __USE_BSD + +#define FD_SETSIZE __FD_SETSIZE +#define NFDBITS __NFDBITS +#define fd_set __fd_set +#define FD_ZERO(set) __FD_ZERO(set) +#define FD_SET(d, set) __FD_SET((d), (set)) +#define FD_CLR(d, set) __FD_CLR((d), (set)) +#define FD_ISSET(d, set)__FD_ISSET((d), (set)) + +/* This being here makes the `select' prototype valid whether or not + we have already included <sys/time.h> to define `struct timeval'. */ +struct timeval; + +/* Check the first NFDS descriptors each in READFDS (if not NULL) for read + readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS + (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out + after waiting the interval specified therein. Returns the number of ready + descriptors, or -1 for errors. */ +extern int __select __P ((int __nfds, __fd_set *__readfds, + __fd_set *__writefds, __fd_set *__exceptfds, + struct timeval *__timeout)); +extern int select __P ((int __nfds, __fd_set *__readfds, + __fd_set *__writefds, __fd_set *__exceptfds, + struct timeval *__timeout)); + +#endif /* Use BSD. */ + + +__END_DECLS + +#endif /* sys/types.h */ diff --git a/posix/sys/unistd.h b/posix/sys/unistd.h new file mode 100644 index 0000000000..1e823fbd53 --- /dev/null +++ b/posix/sys/unistd.h @@ -0,0 +1 @@ +#include <unistd.h> diff --git a/posix/sys/utsname.h b/posix/sys/utsname.h new file mode 100644 index 0000000000..16435baf86 --- /dev/null +++ b/posix/sys/utsname.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 4.4 System Identification <sys/utsname.h> + */ + +#ifndef _SYS_UTSNAME_H + +#define _SYS_UTSNAME_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <utsnamelen.h> +#ifndef _UTSNAME_NODENAME_LENGTH +#define _UTSNAME_NODENAME_LENGTH _UTSNAME_LENGTH +#endif + +/* Structure describing the system and machine. */ +struct utsname + { + /* Name of the implementation of the operating system. */ + char sysname[_UTSNAME_LENGTH]; + + /* Name of this node on the network. */ + char nodename[_UTSNAME_NODENAME_LENGTH]; + + /* Current release level of this implementation. */ + char release[_UTSNAME_LENGTH]; + /* Current version level of this release. */ + char version[_UTSNAME_LENGTH]; + + /* Name of the hardware type the system is running on. */ + char machine[_UTSNAME_LENGTH]; + }; + +#ifdef __USE_SVID +#define SYS_NMLN _UTSNAME_LENGTH +#endif + + +/* Put information about the system in NAME. */ +extern int uname __P ((struct utsname *__name)); + + +__END_DECLS + +#endif /* sys/utsname.h */ diff --git a/posix/sys/wait.h b/posix/sys/wait.h new file mode 100644 index 0000000000..b7800d7090 --- /dev/null +++ b/posix/sys/wait.h @@ -0,0 +1,151 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 3.2.1 Wait for Process Termination <sys/wait.h> + */ + +#ifndef _SYS_WAIT_H + +#define _SYS_WAIT_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +/* This will define the `W*' macros for the flag + bits to `waitpid', `wait3', and `wait4'. */ +#include <waitflags.h> + +#ifdef __USE_BSD + +/* Lots of hair to allow traditional BSD use of `union wait' + as well as POSIX.1 use of `int' for the status word. */ + +#ifdef __GNUC__ +#define __WAIT_INT(status) \ + (__extension__ ({ union { __typeof(status) __in; int __i; } __u; \ + __u.__in = (status); __u.__i; })) +#else +#define __WAIT_INT(status) (*(int *) &(status)) +#endif + +/* This is the type of the argument to `wait'. + + NOTE: Since this functionality is volatile, I'm disabling the use of it for + now. + +With GCC 2.6.1 and later, the funky union causes redeclarations with either + `int *' or `union wait *' to be allowed without complaint. + __WAIT_STATUS_DEFN is the type used in the actual function + definitions. */ + +#if (!defined (__GNUC__) || __GNUC__ < 2 || \ + /*(__GNUC__ == 2 && __GNUC_MINOR__ < 6)*/ 1) +#define __WAIT_STATUS __ptr_t +#define __WAIT_STATUS_DEFN __ptr_t +#else +/* This works in GCC 2.6.1 and later. */ +typedef union + { + union wait *__uptr; + int *__iptr; + } __WAIT_STATUS __attribute__ ((transparent_union)); +#define __WAIT_STATUS_DEFN int * +#endif + +#else /* Don't use BSD. */ + +#define __WAIT_INT(status) (status) +#define __WAIT_STATUS int * +#define __WAIT_STATUS_DEFN int * + +#endif /* Use BSD. */ + +/* This will define all the `__W*' macros. */ +#include <waitstatus.h> + +#define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status)) +#define WTERMSIG(status) __WTERMSIG(__WAIT_INT(status)) +#define WSTOPSIG(status) __WSTOPSIG(__WAIT_INT(status)) +#define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status)) +#define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status)) +#define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status)) + +#ifdef __USE_BSD +#define WCOREFLAG __WCOREFLAG +#define WCOREDUMP(status) __WCOREDUMP(__WAIT_INT(status)) +#define W_EXITCODE(ret, sig) __W_EXITCODE(ret, sig) +#define W_STOPCODE(sig) __W_STOPCODE(sig) +#endif + + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +extern __pid_t __wait __P ((__WAIT_STATUS __stat_loc)); +extern __pid_t wait __P ((__WAIT_STATUS __stat_loc)); + +#ifdef __USE_BSD +/* Special values for the PID argument to `waitpid' and `wait4'. */ +#define WAIT_ANY (-1) /* Any process. */ +#define WAIT_MYPGRP 0 /* Any process in my process group. */ +#endif + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is + set in OPTIONS, return status for stopped children; otherwise don't. */ +extern __pid_t __waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +extern __pid_t waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +#ifdef __USE_BSD +/* This being here makes the prototypes valid whether or not + we have already included <sys/resource.h> to define `struct rusage'. */ +struct rusage; + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not + nil, store information about the child's resource usage there. If the + WUNTRACED bit is set in OPTIONS, return status for stopped children; + otherwise don't. */ +extern __pid_t __wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); +extern __pid_t wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); + +/* PID is like waitpid. Other args are like wait3. */ +extern __pid_t __wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +extern __pid_t wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +#endif /* Use BSD. */ + + +__END_DECLS + +#endif /* sys/wait.h */ diff --git a/posix/tar.h b/posix/tar.h new file mode 100644 index 0000000000..e5e9901bdf --- /dev/null +++ b/posix/tar.h @@ -0,0 +1,110 @@ +/* Extended tar format from POSIX.1. + Copyright (C) 1992 Free Software Foundation, Inc. + Written by David J. MacKenzie. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _TAR_H + +#define _TAR_H 1 + +/* A tar archive consists of 512-byte blocks. + Each file in the archive has a header block followed by 0+ data blocks. + Two blocks of NUL bytes indicate the end of the archive. */ + +/* The fields of header blocks: + All strings are stored as ISO 646 (approximately ASCII) strings. + + Fields are numeric unless otherwise noted below; numbers are ISO 646 + representations of octal numbers, with leading zeros as needed. + + linkname is only valid when typeflag==LNKTYPE. It doesn't use prefix; + files that are links to pathnames >100 chars long can not be stored + in a tar archive. + + If typeflag=={LNKTYPE,SYMTYPE,DIRTYPE} then size must be 0. + + devmajor and devminor are only valid for typeflag=={BLKTYPE,CHRTYPE}. + + chksum contains the sum of all 512 bytes in the header block, + treating each byte as an 8-bit unsigned value and treating the + 8 bytes of chksum as blank characters. + + uname and gname are used in preference to uid and gid, if those + names exist locally. + + Field Name Byte Offset Length in Bytes Field Type + name 0 100 NUL-terminated if NUL fits + mode 100 8 + uid 108 8 + gid 116 8 + size 124 12 + mtime 136 12 + chksum 148 8 + typeflag 156 1 see below + linkname 157 100 NUL-terminated if NUL fits + magic 257 6 must be TMAGIC (NUL term.) + version 263 2 must be TVERSION + uname 265 32 NUL-terminated + gname 297 32 NUL-terminated + devmajor 329 8 + devminor 337 8 + prefix 345 155 NUL-terminated if NUL fits + + If the first character of prefix is '\0', the file name is name; + otherwise, it is prefix/name. Files whose pathnames don't fit in that + length can not be stored in a tar archive. */ + +/* The bits in mode: */ +#define TSUID 04000 +#define TSGID 02000 +#define TSVTX 01000 +#define TUREAD 00400 +#define TUWRITE 00200 +#define TUEXEC 00100 +#define TGREAD 00040 +#define TGWRITE 00020 +#define TGEXEC 00010 +#define TOREAD 00004 +#define TOWRITE 00002 +#define TOEXEC 00001 + +/* The values for typeflag: + Values 'A'-'Z' are reserved for custom implementations. + All other values are reserved for future POSIX.1 revisions. */ + +#define REGTYPE '0' /* Regular file (preferred code). */ +#define AREGTYPE '\0' /* Regular file (alternate code). */ +#define LNKTYPE '1' /* Hard link. */ +#define SYMTYPE '2' /* Symbolic link (hard if not supported). */ +#define CHRTYPE '3' /* Character special. */ +#define BLKTYPE '4' /* Block special. */ +#define DIRTYPE '5' /* Directory. */ +#define FIFOTYPE '6' /* Named pipe. */ +#define CONTTYPE '7' /* Contiguous file */ + /* (regular file if not supported). */ + +/* Contents of magic field and its length. */ +#define TMAGIC "ustar" +#define TMAGLEN 6 + +/* Contents of the version field and its length. */ +#define TVERSION "00" +#define TVERSLEN 2 + +#endif /* tar.h */ diff --git a/posix/testfnm.args b/posix/testfnm.args new file mode 100644 index 0000000000..4a52662d5d --- /dev/null +++ b/posix/testfnm.args @@ -0,0 +1 @@ +*LIB* lib diff --git a/posix/testfnm.c b/posix/testfnm.c new file mode 100644 index 0000000000..648dbd3961 --- /dev/null +++ b/posix/testfnm.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include "fnmatch.h" + +int +main (c, v) + int c; + char **v; +{ + printf ("%d\n", fnmatch (v[1], v[2], FNM_PERIOD)); + printf ("%d\n", fnmatch (v[1], v[2], FNM_CASEFOLD|FNM_PERIOD)); + exit (0); +} diff --git a/posix/tstgetopt.args b/posix/tstgetopt.args new file mode 100644 index 0000000000..023e102a24 --- /dev/null +++ b/posix/tstgetopt.args @@ -0,0 +1 @@ +-a -b -cfoobar diff --git a/posix/tstgetopt.c b/posix/tstgetopt.c new file mode 100644 index 0000000000..fd2d4d0469 --- /dev/null +++ b/posix/tstgetopt.c @@ -0,0 +1,41 @@ +#include <ansidecl.h> +#include <unistd.h> +#include <stdio.h> + +int main (int argc, char **argv) +{ + int aflag = 0; + int bflag = 0; + char *cvalue = NULL; + int index; + int c; + + while ((c = getopt (argc, argv, "abc:")) >= 0) + switch (c) { + case 'a': + aflag = 1; + break; + case 'b': + bflag = 1; + break; + case 'c': + cvalue = optarg; + break; + case '?': +#if 0 + fprintf (stderr, "Unknown option %c.\n", optopt); +#else + fputs ("Unknown option.\n", stderr); +#endif + return -1; + default: + fprintf (stderr, "This should never happen!\n"); + return -1; + } + + printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue); + + for (index = optind; index < argc; index++) + printf ("Non-option argument %s\n", argv[index]); + return 0; +} diff --git a/posix/unistd.h b/posix/unistd.h new file mode 100644 index 0000000000..7143fe1606 --- /dev/null +++ b/posix/unistd.h @@ -0,0 +1,642 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.10 Symbolic Constants <unistd.h> + */ + +#ifndef _UNISTD_H + +#define _UNISTD_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* These may be used to determine what facilities are present at compile time. + Their values can be obtained at run time from sysconf. */ + +/* POSIX Standard approved as IEEE Std 1003.1 as of August, 1988. */ +#define _POSIX_VERSION 199009L + +/* These are not #ifdef __USE_POSIX2 because they are + in the theoretically application-owned namespace. */ + +#define _POSIX2_C_VERSION 199912L /* Invalid until 1003.2 is done. */ + +/* If defined, the implementation supports the + C Language Bindings Option. */ +#define _POSIX2_C_BIND 1 + +/* If defined, the implementation supports the + C Language Development Utilities Option. */ +#define _POSIX2_C_DEV 1 + +/* If defined, the implementation supports the + Software Development Utilities Option. */ +#define _POSIX2_SW_DEV 1 + + +/* Get values of POSIX options: + + If these symbols are defined, the corresponding features are + always available. If not, they may be available sometimes. + The current values can be obtained with `sysconf'. + + _POSIX_JOB_CONTROL Job control is supported. + _POSIX_SAVED_IDS Processes have a saved set-user-ID + and a saved set-group-ID. + + If any of these symbols is defined as -1, the corresponding option is not + true for any file. If any is defined as other than -1, the corresponding + option is true for all files. If a symbol is not defined at all, the value + for a specific file can be obtained from `pathconf' and `fpathconf'. + + _POSIX_CHOWN_RESTRICTED Only the super user can use `chown' to change + the owner of a file. `chown' can only be used + to change the group ID of a file to a group of + which the calling process is a member. + _POSIX_NO_TRUNC Pathname components longer than + NAME_MAX generate an error. + _POSIX_VDISABLE If defined, if the value of an element of the + `c_cc' member of `struct termios' is + _POSIX_VDISABLE, no character will have the + effect associated with that element. + */ + +#include <posix_opt.h> + + +/* Standard file descriptors. */ +#define STDIN_FILENO 0 /* Standard input. */ +#define STDOUT_FILENO 1 /* Standard output. */ +#define STDERR_FILENO 2 /* Standard error output. */ + + +/* All functions that are not declared anywhere else. */ + +#include <gnu/types.h> + +#ifndef ssize_t +#define ssize_t __ssize_t +#endif + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + + +/* Values for the second argument to access. + These may be OR'd together. */ +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ + +/* Test for access to NAME. */ +extern int __access __P ((__const char *__name, int __type)); +extern int access __P ((__const char *__name, int __type)); + + +/* Values for the WHENCE argument to lseek. */ +#ifndef _STDIO_H /* <stdio.h> has the same definitions. */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ +#endif + +/* Move FD's file position to OFFSET bytes from the + beginning of the file (if WHENCE is SEEK_SET), + the current position (if WHENCE is SEEK_CUR), + or the end of the file (if WHENCE is SEEK_END). + Return the new file position. */ +extern __off_t __lseek __P ((int __fd, __off_t __offset, int __whence)); +extern __off_t lseek __P ((int __fd, __off_t __offset, int __whence)); + +/* Close the file descriptor FD. */ +extern int __close __P ((int __fd)); +extern int close __P ((int __fd)); + +/* Read NBYTES into BUF from FD. Return the + number read, -1 for errors or 0 for EOF. */ +extern ssize_t __read __P ((int __fd, __ptr_t __buf, size_t __nbytes)); +extern ssize_t read __P ((int __fd, __ptr_t __buf, size_t __nbytes)); + +/* Write N bytes of BUF to FD. Return the number written, or -1. */ +extern ssize_t __write __P ((int __fd, __const __ptr_t __buf, size_t __n)); +extern ssize_t write __P ((int __fd, __const __ptr_t __buf, size_t __n)); + + +/* Create a one-way communication channel (pipe). + If successul, two file descriptors are stored in PIPEDES; + bytes written on PIPEDES[1] can be read from PIPEDES[0]. + Returns 0 if successful, -1 if not. */ +extern int __pipe __P ((int __pipedes[2])); +extern int pipe __P ((int __pipedes[2])); + +/* Schedule an alarm. In SECONDS seconds, the process will get a SIGALRM. + If SECONDS is zero, any currently scheduled alarm will be cancelled. + The function returns the number of seconds remaining until the last + alarm scheduled would have signaled, or zero if there wasn't one. + There is no return value to indicate an error, but you can set `errno' + to 0 and check its value after calling `alarm', and this might tell you. + The signal may come late due to processor scheduling. */ +extern unsigned int alarm __P ((unsigned int __seconds)); + +/* Make the process sleep for SECONDS seconds, or until a signal arrives + and is not ignored. The function returns the number of seconds less + than SECONDS which it actually slept (thus zero if it slept the full time). + If a signal handler does a `longjmp' or modifies the handling of the + SIGALRM signal while inside `sleep' call, the handling of the SIGALRM + signal afterwards is undefined. There is no return value to indicate + error, but if `sleep' returns SECONDS, it probably didn't work. */ +extern unsigned int sleep __P ((unsigned int __seconds)); + + +/* Suspend the process until a signal arrives. + This always returns -1 and sets `errno' to EINTR. */ +extern int pause __P ((void)); + + +/* Change the owner and group of FILE. */ +extern int __chown __P ((__const char *__file, + __uid_t __owner, __gid_t __group)); +extern int chown __P ((__const char *__file, + __uid_t __owner, __gid_t __group)); + +#ifdef __USE_BSD +/* Change the owner and group of the file that FD is open on. */ +extern int __fchown __P ((int __fd, + __uid_t __owner, __gid_t __group)); +extern int fchown __P ((int __fd, + __uid_t __owner, __gid_t __group)); +#endif /* Use BSD. */ + +/* Change the process's working directory to PATH. */ +extern int __chdir __P ((__const char *__path)); +extern int chdir __P ((__const char *__path)); + +#ifdef __USE_BSD +/* Change the process's working directory to the one FD is open on. */ +extern int fchdir __P ((int __fd)); +#endif + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +extern char *getcwd __P ((char *__buf, size_t __size)); + +#ifdef __USE_GNU +/* Return a malloc'd string containing the current directory name. + If the environment variable `PWD' is set, and its value is correct, + that value is used. */ +extern char *get_current_dir_name __P ((void)); +#endif + +#ifdef __USE_BSD +/* Put the absolute pathname of the current working directory in BUF. + If successful, return BUF. If not, put an error message in + BUF and return NULL. BUF should be at least PATH_MAX bytes long. */ +extern char *getwd __P ((char *__buf)); +#endif + + +/* Duplicate FD, returning a new file descriptor on the same file. */ +extern int __dup __P ((int __fd)); +extern int dup __P ((int __fd)); + +/* Duplicate FD to FD2, closing FD2 and making it open on the same file. */ +extern int __dup2 __P ((int __fd, int __fd2)); +extern int dup2 __P ((int __fd, int __fd2)); + +/* NULL-terminated array of "NAME=VALUE" environment variables. */ +extern char **__environ; +extern char **environ; + + +/* Replace the current process, executing PATH with arguments ARGV and + environment ENVP. ARGV and ENVP are terminated by NULL pointers. */ +extern int __execve __P ((__const char *__path, char *__const __argv[], + char *__const __envp[])); +extern int execve __P ((__const char *__path, char *__const __argv[], + char *__const __envp[])); + +#ifdef __USE_GNU +/* Execute the file FD refers to, overlaying the running program image. + ARGV and ENVP are passed to the new program, as for `execve'. */ +extern int fexecve __P ((int __fd, + char *const __argv[], char *const __envp[])); + +#endif + + +/* Execute PATH with arguments ARGV and environment from `environ'. */ +extern int execv __P ((__const char *__path, char *__const __argv[])); + +/* Execute PATH with all arguments after PATH until a NULL pointer, + and the argument after that for environment. */ +extern int execle __P ((__const char *__path, __const char *__arg,...)); + +/* Execute PATH with all arguments after PATH until + a NULL pointer and environment from `environ'. */ +extern int execl __P ((__const char *__path, __const char *__arg,...)); + +/* Execute FILE, searching in the `PATH' environment variable if it contains + no slashes, with arguments ARGV and environment from `environ'. */ +extern int execvp __P ((__const char *__file, char *__const __argv[])); + +/* Execute FILE, searching in the `PATH' environment variable if + it contains no slashes, with all arguments after FILE until a + NULL pointer and environment from `environ'. */ +extern int execlp __P ((__const char *__file, ...)); + + +/* Terminate program execution with the low-order 8 bits of STATUS. */ +extern void _exit __P ((int __status)) __attribute__ ((__noreturn__)); + + +/* Get the `_PC_*' symbols for the NAME argument to `pathconf' and `fpathconf'; + the `_SC_*' symbols for the NAME argument to `sysconf'; + and the `_CS_*' symbols for the NAME argument to `confstr'. */ +#include <confname.h> + +/* Get file-specific configuration information about PATH. */ +extern long int __pathconf __P ((__const char *__path, int __name)); +extern long int pathconf __P ((__const char *__path, int __name)); + +/* Get file-specific configuration about descriptor FD. */ +extern long int __fpathconf __P ((int __fd, int __name)); +extern long int fpathconf __P ((int __fd, int __name)); + +/* Get the value of the system variable NAME. */ +extern long int __sysconf __P ((int __name)); +extern long int sysconf __P ((int __name)); + +#ifdef __USE_POSIX2 +/* Get the value of the string-valued system variable NAME. */ +extern size_t confstr __P ((int __name, char *__buf, size_t __len)); +#endif + + +/* Get the process ID of the calling process. */ +extern __pid_t __getpid __P ((void)); +extern __pid_t getpid __P ((void)); + +/* Get the process ID of the calling process's parent. */ +extern __pid_t __getppid __P ((void)); +extern __pid_t getppid __P ((void)); + +/* Get the process group ID of the calling process. */ +extern __pid_t getpgrp __P ((void)); + +/* Set the process group ID of the process matching PID to PGID. + If PID is zero, the current process's process group ID is set. + If PGID is zero, the process ID of the process is used. */ +extern int setpgid __P ((__pid_t __pid, __pid_t __pgid)); + +/* Get the process group ID of process PID. */ +extern __pid_t __getpgid __P ((__pid_t __pid)); +#ifdef __USE_GNU +extern __pid_t getpgid __P ((__pid_t __pid)); +#endif + +#ifdef __USE_BSD +/* Another name for `setpgid'. */ +extern int setpgrp __P ((__pid_t __pid, __pid_t __pgrp)); +#endif /* Use BSD. */ + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +extern __pid_t __setsid __P ((void)); +extern __pid_t setsid __P ((void)); + +/* Get the real user ID of the calling process. */ +extern __uid_t __getuid __P ((void)); +extern __uid_t getuid __P ((void)); + +/* Get the effective user ID of the calling process. */ +extern __uid_t __geteuid __P ((void)); +extern __uid_t geteuid __P ((void)); + +/* Get the real group ID of the calling process. */ +extern __gid_t __getgid __P ((void)); +extern __gid_t getgid __P ((void)); + +/* Get the effective group ID of the calling process. */ +extern __gid_t __getegid __P ((void)); +extern __gid_t getegid __P ((void)); + +/* If SIZE is zero, return the number of supplementary groups + the calling process is in. Otherwise, fill in the group IDs + of its supplementary groups in LIST and return the number written. */ +extern int __getgroups __P ((int __size, __gid_t __list[])); +extern int getgroups __P ((int __size, __gid_t __list[])); + +/* Set the user ID of the calling process to UID. + If the calling process is the super-user, set the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID. */ +extern int __setuid __P ((__uid_t __uid)); +extern int setuid __P ((__uid_t __uid)); + +#ifdef __USE_BSD +/* Set the real user ID of the calling process to RUID, + and the effective user ID of the calling process to EUID. */ +extern int __setreuid __P ((__uid_t __ruid, __uid_t __euid)); +extern int setreuid __P ((__uid_t __ruid, __uid_t __euid)); + +/* Set the effective user ID of the calling process to UID. */ +extern int seteuid __P ((__uid_t __uid)); +#endif /* Use BSD. */ + +/* Set the group ID of the calling process to GID. + If the calling process is the super-user, set the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID. */ +extern int __setgid __P ((__gid_t __gid)); +extern int setgid __P ((__gid_t __gid)); + +#ifdef __USE_BSD +/* Set the real group ID of the calling process to RGID, + and the effective group ID of the calling process to EGID. */ +extern int __setregid __P ((__gid_t __rgid, __gid_t __egid)); +extern int setregid __P ((__gid_t __rgid, __gid_t __egid)); + +/* Set the effective group ID of the calling process to GID. */ +extern int setegid __P ((__gid_t __gid)); +#endif /* Use BSD. */ + + +/* Clone the calling process, creating an exact copy. + Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +extern __pid_t __fork __P ((void)); +extern __pid_t fork __P ((void)); + +#ifdef __USE_BSD +/* Clone the calling process, but without copying the whole address space. + The the calling process is suspended until the the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +extern __pid_t __vfork __P ((void)); +extern __pid_t vfork __P ((void)); +#endif /* Use BSD. */ + + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +extern char *ttyname __P ((int __fd)); + +/* Return 1 if FD is a valid descriptor associated + with a terminal, zero if not. */ +extern int __isatty __P ((int __fd)); +extern int isatty __P ((int __fd)); + + +/* Make a link to FROM named TO. */ +extern int __link __P ((__const char *__from, __const char *__to)); +extern int link __P ((__const char *__from, __const char *__to)); + +#ifdef __USE_BSD +/* Make a symbolic link to FROM named TO. */ +extern int __symlink __P ((__const char *__from, __const char *__to)); +extern int symlink __P ((__const char *__from, __const char *__to)); + +/* Read the contents of the symbolic link PATH into no more than + LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +extern int __readlink __P ((__const char *__path, char *__buf, size_t __len)); +extern int readlink __P ((__const char *__path, char *__buf, size_t __len)); +#endif /* Use BSD. */ + +/* Remove the link NAME. */ +extern int __unlink __P ((__const char *__name)); +extern int unlink __P ((__const char *__name)); + +/* Remove the directory PATH. */ +extern int __rmdir __P ((__const char *__path)); +extern int rmdir __P ((__const char *__path)); + + +/* Return the foreground process group ID of FD. */ +extern __pid_t tcgetpgrp __P ((int __fd)); + +/* Set the foreground process group ID of FD set PGRP_ID. */ +extern int tcsetpgrp __P ((int __fd, __pid_t __pgrp_id)); + + +/* Return the login name of the user. */ +extern char *getlogin __P ((void)); + +#ifdef __USE_BSD +/* Set the login name returned by `getlogin'. */ +extern int setlogin __P ((__const char *__name)); +#endif + + +#ifdef __USE_POSIX2 +/* Process the arguments in ARGV (ARGC of them, minus + the program name) for options given in OPTS. + + If `opterr' is zero, no messages are generated + for invalid options; it defaults to 1. + `optind' is the current index into ARGV. + `optarg' is the argument corresponding to the current option. + Return the option character from OPTS just read. + Return -1 when there are no more options. + For unrecognized options, or options missing arguments, + `optopt' is set to the option letter, and '?' is returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is optional. + This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument scanning, + explicitly telling `getopt' that there are no more options. + + If OPTS begins with `--', then non-option arguments + are treated as arguments to the option '\0'. + This behavior is specific to the GNU `getopt'. */ +extern int getopt __P ((int __argc, char *__const * __argv, + __const char *__opts)); +extern int opterr; +extern int optind; +extern int optopt; +extern char *optarg; +#endif + + +#ifdef __USE_BSD + +/* Put the name of the current host in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +extern int __gethostname __P ((char *__name, size_t __len)); +extern int gethostname __P ((char *__name, size_t __len)); + +/* Set the name of the current host to NAME, which is LEN bytes long. + This call is restricted to the super-user. */ +extern int sethostname __P ((__const char *__name, size_t __len)); + +/* Return the current machine's Internet number. */ +extern long int gethostid __P ((void)); + +/* Set the current machine's Internet number to ID. + This call is restricted to the super-user. */ +extern int sethostid __P ((long int __id)); + + +/* Return the number of bytes in a page. This is the system's page size, + which is not necessarily the same as the hardware page size. */ +extern size_t __getpagesize __P ((void)); +extern size_t getpagesize __P ((void)); + + +/* Return the maximum number of file descriptors + the current process could possibly have. */ +extern int __getdtablesize __P ((void)); +extern int getdtablesize __P ((void)); + + +/* Truncate FILE to LENGTH bytes. */ +extern int truncate __P ((__const char *__file, __off_t __length)); + +/* Truncate the file FD is open on to LENGTH bytes. */ +extern int ftruncate __P ((int __fd, __off_t __length)); + + +/* Make all changes done to FD actually appear on disk. */ +extern int fsync __P ((int __fd)); + +/* Make all changes done to all files actually appear on disk. */ +extern int sync __P ((void)); + + +/* Revoke access permissions to all processes currently communicating + with the control terminal, and then send a SIGHUP signal to the process + group of the control terminal. */ +extern int vhangup __P ((void)); + + +/* Turn accounting on if NAME is an existing file. The system will then write + a record for each process as it terminates, to this file. If NAME is NULL, + turn accounting off. This call is restricted to the super-user. */ +extern int acct __P ((__const char *__name)); + +/* Make PATH be the root directory (the starting point for absolute paths). + This call is restricted to the super-user. */ +extern int chroot __P ((__const char *__path)); + +/* Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user. */ +extern int swapon __P ((__const char *__path)); + +/* Reboot or halt the system. */ +extern int reboot __P ((int __howto)); + + +/* Successive calls return the shells listed in `/etc/shells'. */ +extern char *getusershell __P ((void)); +extern void endusershell __P ((void)); /* Discard cached info. */ +extern void setusershell __P ((void)); /* Rewind and re-read the file. */ + + +/* Prompt with PROMPT and read a string from the terminal without echoing. + Uses /dev/tty if possible; otherwise stderr and stdin. */ +extern char *getpass __P ((const char *__prompt)); + +/* Put the program in the background, and dissociate from the controlling + terminal. If NOCHDIR is zero, do `chdir ("/")'. If NOCLOSE is zero, + redirects stdin, stdout, and stderr to /dev/null. */ +extern int daemon __P ((int __nochdir, int __noclose)); + +#endif /* Use BSD. */ + + +#ifdef __USE_MISC + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique file name. */ +extern char *mktemp __P ((char *__template)); + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns a file descriptor open on the file for reading and writing, + or -1 if it cannot create a uniquely-named file. */ +extern int mkstemp __P ((char *__template)); + + +/* Invoke `system call' number SYSNO, passing it the remaining arguments. + This is completely system-dependent, and not often useful. + + In Unix, `syscall' sets `errno' for all errors and most calls return -1 + for errors; in many systems you cannot pass arguments or get return + values for all system calls (`pipe', `fork', and `getppid' typically + among them). + + In Mach, all system calls take normal arguments and always return an + error code (zero for success). */ +extern int syscall __P ((int __sysno, ...)); + +#endif /* Use misc. */ + + +#if defined (__USE_MISC) && !defined (F_LOCK) +/* NOTE: These declarations also appear in <fcntl.h>; be sure to keep both + files consistent. Some systems have them there and some here, and some + software depends on the macros being defined without including both. */ + +/* `lockf' is a simpler interface to the locking facilities of `fcntl'. + LEN is always relative to the current file position. + The CMD argument is one of the following. */ + +#define F_ULOCK 0 /* Unlock a previously locked region. */ +#define F_LOCK 1 /* Lock a region for exclusive use. */ +#define F_TLOCK 2 /* Test and lock a region for exclusive use. */ +#define F_TEST 3 /* Test a region for other processes locks. */ + +extern int lockf __P ((int __fd, int __cmd, __off_t __len)); +#endif /* Use misc and F_LOCK not already defined. */ + + +#ifdef __USE_GNU + +/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno' + set to EINTR. */ + +#define TEMP_FAILURE_RETRY(expression) \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; }) + +#endif + +__END_DECLS + +#endif /* unistd.h */ diff --git a/posix/wordexp.c b/posix/wordexp.c new file mode 100644 index 0000000000..1922e44642 --- /dev/null +++ b/posix/wordexp.c @@ -0,0 +1,184 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <wordexp.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> + + +/* We do word expansion with a pipe to the shell. + The shell command `sh [-P] [-u] -w "words ..."' expands words. + If -P, command substitution is an error. + If -u, reference to an undefined variable is an error. + The shell writes on its stdout: + %u\0 Number of words. + %u\0 Number of bytes in all words together (not counting \0s). + word1\0 + word2\0 + ... + wordN\0 + */ + +#define SHELL_PATH "/bin/sh" +#define SHELL_NAME "sh" + + +int +DEFUN(wordexp, (string, pwordexp, flags), + CONST char *string AND wordexp_t *pwordexp AND int flags) +{ + int error; + pid_t pid; + int d[2]; + int status; + + FILE *f; + size_t wordc, start, buflen; + char *buf; + + /* Create the pipe through which we will communicate to the shell. */ + if (pipe (d) < 0) + return -1; + + pid = fork (); + if (pid < 0) + return -1; + + if (pid == 0) + { + /* Child. Run the shell. */ + + CONST char *argv[5]; + + close (d[STDIN_FILENO]); + dup2 (d[STDOUT_FILENO], STDOUT_FILENO); + if (!(flags & WRDE_SHOWERR)) + close (STDERR_FILENO); + + i = 0; + argv[i++] = SHELL_NAME; + if (flags & WRDE_NOCMD) + argv[i++] = "-P"; + if (flags & WRDE_UNDEF) + argv[i++] = "-u"; + argv[i++] = "-w"; + argv[i++] = string; + argv[i++] = NULL; + + execv (SHELL_PATH, argv); + _exit (WRDE_NOSPACE); + } + + /* Parent. */ + + buf = NULL; + error = WRDE_NOSPACE; + + close (d[STDOUT_FILENO]); + f = fdopen (d[STDIN_FILENO]); + if (f == NULL) + goto lose; + + /* Read the number of words and number of bytes from the shell. */ + if (fscanf (f, "%u", &wordc) != 1 || getc (f) != '\0' || + fscanf (f, "%u", &buflen) != 1 || getc (f) != '\0') + goto lose; + + /* Read the words from the shell, and wait for it to return. */ + buflen += wordc; + buf = malloc (buflen); + if (buf == NULL || + fread (buf, buflen, 1, f) != 1 || + waitpid (pid, &status, 0) != pid) + goto lose; + + if (WIFEXITED (status)) + { + if (WEXITSTATUS (status) != 0) + { + error = WEXITSTATUS (status); + goto lose; + } + } + else + goto lose; + + /* Pack the structure. */ + + start = 0; + if (flags & WRDE_DOOFFS) + start += pwordexp->we_offs; + if (flags & WRDE_APPEND) + start += pwordexp->we_wordc; + wordc = start + wordc + 1; + + if (flags & WRDE_APPEND) + wordv = (char **) realloc ((PTR) pwordexp->we_wordv, + wordc * sizeof (char *)); + else + wordv = (char **) malloc (wordc * sizeof (char *)); + if (wordv == NULL) + goto lose; + + if (flags & WRDE_DOOFFS) + for (i = 0; i < pwordexp->we_offs; ++i) + wordv[i] = NULL; + + for (i = start; i < wordc; ++i) + { + pwordexp->we_wordv[i] = buf; + buf = strchr (buf, '\0') + 1; + } + wordv[i] = NULL; + + if (flags & WRDE_REUSE) + { + free (pwordexp->we_wordv[0]); + if (!(flags & WRDE_APPEND)) + free (pwordexp->we_wordv); + } + + pwordexp->we_wordc = wordc; + pwordexp->we_wordv = wordv; + + return 0; + + lose: + { + int save; + save = errno; + (void) kill (pid, SIGKILL); + free (buf); + (void) waitpid (pid, (int *) NULL, 0); + errno = save; + return error; + } +} + + +void +DEFUN(wordexp, (pwordexp), wordexp_t *pwordexp) +{ + /* All the other elts point into the first. */ + free (pwordexp->we_wordv[0]); + free (pwordexp->we_wordv); +} diff --git a/posix/wordexp.h b/posix/wordexp.h new file mode 100644 index 0000000000..02b1788197 --- /dev/null +++ b/posix/wordexp.h @@ -0,0 +1,66 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _WORDEXP_H + +#define _WORDEXP_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Bits set in the FLAGS argument to `wordexp'. */ +enum + { + WRDE_DOOFFS = (1 << 0), /* Insert PWORDEXP->we_offs NULLs. */ + WRDE_APPEND = (1 << 1), /* Append to results of a previous call. */ + WRDE_NOCMD = (1 << 2), /* Don't do command substitution. */ + WRDE_REUSE = (1 << 3), /* Reuse storage in PWORDEXP. */ + WRDE_SHOWERR = (1 << 4), /* Don't redirect stderr to /dev/null. */ + WRDE_UNDEF = (1 << 5), /* Error for expanding undefined variables. */ + __WRDE_FLAGS = (WRDE_DOOFFS | WRDE_APPEND | WRDE_NOCMD | + WRDE_REUSE | WRDE_SHOWERR | WRDE_UNDEF), + }; + +/* Structure describing a word-expansion run. */ +typedef struct + { + int we_wordc; /* Count of words matched. */ + char **we_wordv; /* List of expanded words. */ + int we_offs; /* Slots to reserve in `we_wordv'. */ + } wordexp_t; + +/* Possible nonzero return values from `wordexp'. */ +enum + { + WRDE_NOSPACE = 1, /* Ran out of memory. */ + WRDE_BADCHAR, /* A metachar appears in the wrong place. */ + WRDE_BADVAL, /* Undefined var reference with WRDE_UNDEF. */ + WRDE_CMDSUB, /* Command substitution with WRDE_NOCMD. */ + WRDE_SYNTAX /* Shell syntax error. */ + }; + +/* Do word expansion of WORDS into PWORDEXP. */ +extern int wordexp __P ((__const char *__words, wordexp_t * __pwordexp, + int __flags)); + +/* Free the storage allocated by a `wordexp' call. */ +extern void wordfree __P ((wordexp_t *)); + +__END_DECLS + +#endif /* wordexp.h */ diff --git a/posix1_lim.h b/posix1_lim.h new file mode 100644 index 0000000000..2999802ec3 --- /dev/null +++ b/posix1_lim.h @@ -0,0 +1 @@ +#include <posix/posix1_lim.h> diff --git a/posix2_lim.h b/posix2_lim.h new file mode 100644 index 0000000000..34c4d90df5 --- /dev/null +++ b/posix2_lim.h @@ -0,0 +1 @@ +#include <posix/posix2_lim.h> diff --git a/printf.h b/printf.h new file mode 100644 index 0000000000..8996ff4b17 --- /dev/null +++ b/printf.h @@ -0,0 +1 @@ +#include <stdio/printf.h> diff --git a/printsources b/printsources new file mode 100755 index 0000000000..062b837c5a --- /dev/null +++ b/printsources @@ -0,0 +1,29 @@ +#! /bin/csh -f + +# +# Prints all the files given as arguments. +# Files that will fit on less than a printed page +# are concatenated together. Bigger ones are pr'd. +# + + +set tocat='' topr='' + +foreach file ($*) + set lines=`wc -l $file | sed "s/$file//"` + if ($lines > 40) then + set topr=($topr $file) + else + set tocat=($tocat $file) + endif +end + + +if ("$topr" != '') pr $topr + +if ("$tocat" != '') foreach file ($tocat) + echo -n "==================== $file ======================" + cat $file +end + +exit 0 diff --git a/protocols/routed.h b/protocols/routed.h new file mode 100644 index 0000000000..2e97bfd187 --- /dev/null +++ b/protocols/routed.h @@ -0,0 +1 @@ +#include <protocols/routed.h> diff --git a/protocols/rwhod.h b/protocols/rwhod.h new file mode 100644 index 0000000000..6fc35a0c41 --- /dev/null +++ b/protocols/rwhod.h @@ -0,0 +1 @@ +#include <protocols/rwhod.h> diff --git a/protocols/talkd.h b/protocols/talkd.h new file mode 100644 index 0000000000..4fd7a34fdf --- /dev/null +++ b/protocols/talkd.h @@ -0,0 +1 @@ +#include <protocols/talkd.h> diff --git a/protocols/timed.h b/protocols/timed.h new file mode 100644 index 0000000000..58dbafeaf2 --- /dev/null +++ b/protocols/timed.h @@ -0,0 +1 @@ +#include <protocols/timed.h> @@ -0,0 +1 @@ +#include <pwd/pwd.h> diff --git a/pwd/Makefile b/pwd/Makefile new file mode 100644 index 0000000000..b33700a95f --- /dev/null +++ b/pwd/Makefile @@ -0,0 +1,26 @@ +# Copyright (C) 1991 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for pwd portion of the library. +# +subdir := pwd + +routines := pwdopen pwdread fgetpwent getpw getpwent getpwnam getpwuid putpwent + +include ../Rules diff --git a/pwd/fgetpwent.c b/pwd/fgetpwent.c new file mode 100644 index 0000000000..4a21cbb59a --- /dev/null +++ b/pwd/fgetpwent.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> + +/* Read one entry from the given stream. */ +struct passwd * +DEFUN(fgetpwent, (stream), FILE *stream) +{ + static PTR info = NULL; + if (info == NULL) + { + info = __pwdalloc(); + if (info == NULL) + return(NULL); + } + + return(__pwdread(stream, info)); +} diff --git a/pwd/getpw.c b/pwd/getpw.c new file mode 100644 index 0000000000..5bd5c8267a --- /dev/null +++ b/pwd/getpw.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + + +/* Re-construct the password-file line for the given uid + in the given buffer. This knows the format that the caller + will expect, but this need not be the format of the password file. */ +int +DEFUN(getpw, (uid, buf), __uid_t uid AND register char *buf) +{ + register struct passwd *p; + + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + p = getpwuid (uid); + if (p == NULL) + return -1; + + if (sprintf (buf, "%s:%s:%u:%u:%s:%s:%s", p->pw_name, p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell) < 0) + return -1; + + return 0; +} diff --git a/pwd/getpwent.c b/pwd/getpwent.c new file mode 100644 index 0000000000..1c88950f11 --- /dev/null +++ b/pwd/getpwent.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <pwd.h> + +static FILE *stream = NULL; + +/* Rewind the stream. */ +void +DEFUN_VOID(setpwent) +{ + if (stream != NULL) + rewind(stream); +} + + +/* Close the stream. */ +void +DEFUN_VOID(endpwent) +{ + if (stream != NULL) + { + (void) fclose(stream); + stream = NULL; + } +} + + +/* Return one entry from the password file. */ +struct passwd * +DEFUN_VOID(getpwent) +{ + static PTR info = NULL; + if (info == NULL) + { + info = __pwdalloc(); + if (info == NULL) + return(NULL); + } + + if (stream == NULL) + { + stream = __pwdopen(); + if (stream == NULL) + return(NULL); + } + + return(__pwdread(stream, info)); +} diff --git a/pwd/getpwnam.c b/pwd/getpwnam.c new file mode 100644 index 0000000000..1e7ea5c891 --- /dev/null +++ b/pwd/getpwnam.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> + +/* Search for an entry with a matching name. */ +struct passwd * +DEFUN(getpwnam, (name), register CONST char *name) +{ + static PTR info = NULL; + register FILE *stream; + register struct passwd *p; + + if (info == NULL) + { + info = __pwdalloc(); + if (info == NULL) + return(NULL); + } + + stream = __pwdopen(); + if (stream == NULL) + return(NULL); + + while ((p = __pwdread(stream, info)) != NULL) + if (!strcmp(p->pw_name, name)) + break; + + (void) fclose(stream); + return(p); +} diff --git a/pwd/getpwuid.c b/pwd/getpwuid.c new file mode 100644 index 0000000000..30e40322db --- /dev/null +++ b/pwd/getpwuid.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <pwd.h> +#include <sys/types.h> + +/* Search for an entry with a matching uid. */ +struct passwd * +DEFUN(getpwuid, (uid), register uid_t uid) +{ + static PTR info; + register FILE *stream; + register struct passwd *p; + + if (info == NULL) + { + info = __pwdalloc(); + if (info == NULL) + return(NULL); + } + + stream = __pwdopen(); + if (stream == NULL) + return(NULL); + + while ((p = __pwdread(stream, info)) != NULL) + if (p->pw_uid == uid) + break; + + (void) fclose(stream); + return(p); +} diff --git a/pwd/putpwent.c b/pwd/putpwent.c new file mode 100644 index 0000000000..ad8a81b3a3 --- /dev/null +++ b/pwd/putpwent.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + + +/* Write an entry to the given stream. + This must know the format of the password file. */ +int +DEFUN(putpwent, (p, stream), register CONST struct passwd *p AND FILE *stream) +{ + if (p == NULL || stream == NULL) + { + errno = EINVAL; + return -1; + } + + if (fprintf (stream, "%s:%s:%u:%u:%s:%s:%s\n", + p->pw_name, p->pw_passwd, + p->pw_uid, p->pw_gid, + p->pw_gecos, p->pw_dir, p->pw_shell) < 0) + return(-1); + + return(0); +} diff --git a/pwd/pwd.h b/pwd/pwd.h new file mode 100644 index 0000000000..c72c37df40 --- /dev/null +++ b/pwd/pwd.h @@ -0,0 +1,92 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 9.2.2 User Database Access <pwd.h> + */ + +#ifndef _PWD_H + +#define _PWD_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + + +/* The passwd structure. */ +struct passwd +{ + char *pw_name; /* Username. */ + char *pw_passwd; /* Password. */ + __uid_t pw_uid; /* User ID. */ + __gid_t pw_gid; /* Group ID. */ + char *pw_gecos; /* Real name. */ + char *pw_dir; /* Home directory. */ + char *pw_shell; /* Shell program. */ +}; + + +#if defined(__USE_SVID) || defined(__USE_GNU) +#define __need_FILE +#include <stdio.h> +#endif + +#ifdef __USE_GNU +/* Return a new stream open on the password file. */ +extern FILE *__pwdopen __P ((void)); + +/* Read a password entry from STREAM, filling in P. + Return the `struct passwd' of P if successful, NULL on failure. */ +extern struct passwd *__pwdread __P ((FILE * __stream, __ptr_t __p)); + +/* Return a chunk of memory containing pre-initialized data for __pwdread. */ +extern __ptr_t __pwdalloc __P ((void)); +#endif + + +#if defined(__USE_SVID) || defined(__USE_MISC) +/* Rewind the password-file stream. */ +extern void setpwent __P ((void)); + +/* Close the password-file stream. */ +extern void endpwent __P ((void)); + +/* Read an entry from the password-file stream, opening it if necessary. */ +extern struct passwd *getpwent __P ((void)); +#endif + +#ifdef __USE_SVID +/* Read an entry from STREAM. */ +extern struct passwd *fgetpwent __P ((FILE * __stream)); + +/* Write the given entry onto the given stream. */ +extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); +#endif + +/* Search for an entry with a matching user ID. */ +extern struct passwd *getpwuid __P ((__uid_t __uid)); + +/* Search for an entry with a matching username. */ +extern struct passwd *getpwnam __P ((__const char *__name)); + + +__END_DECLS + +#endif /* pwd.h */ diff --git a/pwd/pwdopen.c b/pwd/pwdopen.c new file mode 100644 index 0000000000..6d35ab9441 --- /dev/null +++ b/pwd/pwdopen.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <pwd.h> + +/* Return a new stream open on the password file. */ +FILE * +DEFUN_VOID(__pwdopen) +{ + return(fopen("/etc/passwd", "r")); +} diff --git a/pwd/pwdread.c b/pwd/pwdread.c new file mode 100644 index 0000000000..0ce27d77b9 --- /dev/null +++ b/pwd/pwdread.c @@ -0,0 +1,116 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <sys/types.h> + + +/* This is the function that all the others are based on. + The format of the password file is known only here. */ + +/* Structure containing info kept by each __pwdread caller. */ +typedef struct + { + char *buf; + size_t buflen; + struct passwd p; + } pwdread_info; + + +/* Return a chunk of memory containing a pre-initialized `pwdread_info'. */ +PTR +DEFUN_VOID(__pwdalloc) +{ + pwdread_info *info = (PTR) malloc (sizeof(pwdread_info)); + if (info == NULL) + return NULL; + info->buf = NULL; + info->buflen = 0; + return info; +} + +/* Read a password entry from STREAM, filling in P. */ +struct passwd * +DEFUN(__pwdread, (stream, p), FILE *stream AND PTR CONST p) +{ + register pwdread_info *CONST info = (pwdread_info *) p; + char *start, *end; + + /* Idiocy checks. */ + if (stream == NULL) + { + errno = EINVAL; + return NULL; + } + + do + if (__getline (&info->buf, &info->buflen, stream) == -1) + return NULL; + while (info->buf[0] == '#'); + + start = info->buf; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->p.pw_name = start; + + start = end + 1; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->p.pw_passwd = start; + + info->p.pw_uid = (uid_t) strtol (end + 1, &end, 10); + if (*end != ':') + return NULL; + info->p.pw_gid = (gid_t) strtol (end + 1, &end, 10); + if (*end != ':') + return NULL; + + start = end + 1; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->p.pw_gecos = start; + + start = end + 1; + end = strchr (start, ':'); + if (end == NULL) + return NULL; + *end = '\0'; + info->p.pw_dir = start; + + start = end + 1; + end = strchr (start, '\n'); + if (end == NULL) + return NULL; + *end = '\0'; + info->p.pw_shell = start; + + return &info->p; +} diff --git a/resolv.h b/resolv.h new file mode 100644 index 0000000000..fc5650d602 --- /dev/null +++ b/resolv.h @@ -0,0 +1 @@ +#include <inet/resolv.h> diff --git a/resolv/Makefile b/resolv/Makefile new file mode 100644 index 0000000000..510f16c179 --- /dev/null +++ b/resolv/Makefile @@ -0,0 +1,31 @@ +# Copyright (C) 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for resolv portion of the library. +# +subdir := resolv + +headers := resolv.h arpa/nameser.h sys/bitypes.h +distribute := ../conf/portability.h + +routines := gethnamaddr getnetbyaddr getnetbyname getnetent getnetnamadr \ + herror nsap_addr res_comp res_debug res_init res_mkquery \ + res_query res_send sethostent + +include ../Rules diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h new file mode 100644 index 0000000000..1a660ade63 --- /dev/null +++ b/resolv/arpa/nameser.h @@ -0,0 +1,347 @@ +/* + * ++Copyright++ 1983, 1989, 1993 + * - + * Copyright (c) 1983, 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. + * - + * 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-- + */ + +/* + * @(#)nameser.h 8.1 (Berkeley) 6/2/93 + * $Id$ + */ + +#ifndef _NAMESER_H_ +#define _NAMESER_H_ + +#include <sys/param.h> +#if (!defined(BSD)) || (BSD < 199306) +# include <sys/bitypes.h> +#else +# include <sys/types.h> +#endif +#include <sys/cdefs.h> + +#ifdef _AUX_SOURCE +#include <sys/types.h> /* ech for A/UX */ +#define res_send ucb_res_send /* already def'd in libc */ +#define _res_close _ucb_res_close /* removing res_send.o from the library */ +#endif /* gives an undefined symbol... */ + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__BIND > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __BIND 19940417 /* interface version stamp */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ +#define HFIXEDSZ 12 /* #/bytes of fixed data in header */ +#define QFIXEDSZ 4 /* #/bytes of fixed data in query */ +#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ +#define INT32SZ 4 /* for systems without 32-bit ints */ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */ + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +/*#define xxx 0x3 /* 0x3 reserved */ +#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */ +#ifdef ALLOW_UPDATES + /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */ +# define UPDATEA 0x9 /* add resource record */ +# define UPDATED 0xa /* delete a specific resource record */ +# define UPDATEDA 0xb /* delete all named resource record */ +# define UPDATEM 0xc /* modify a specific resource record */ +# define UPDATEMA 0xd /* modify all named resource record */ +# define ZONEINIT 0xe /* initial zone transfer */ +# define ZONEREF 0xf /* incremental zone referesh */ +#endif + +/* + * Currently defined response codes + */ +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ +#ifdef ALLOW_UPDATES + /* non standard */ +# define NOCHANGE 0xf /* update failed to change db */ +#endif + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW (-1) +#define CONV_BADFMT (-2) +#define CONV_BADCKSUM (-3) +#define CONV_BADBUFLEN (-4) + +#ifndef BYTE_ORDER +#if (BSD >= 199103) +# include <machine/endian.h> +#else +#ifdef linux +# include <endian.h> +#else +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ + defined(__alpha__) || defined(__alpha) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ + defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ + defined(apollo) || defined(__convex__) || defined(_CRAY) || \ + defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || \ + defined (BIT_ZERO_ON_LEFT) || defined(m68k) +#define BYTE_ORDER BIG_ENDIAN +#endif +#endif /* linux */ +#endif /* BSD */ +#endif /* BYTE_ORDER */ + +#if !defined(BYTE_ORDER) || \ + (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \ + BYTE_ORDER != PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ + error "Undefined or invalid BYTE_ORDER"; +#endif + +/* + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritive answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned pr: 1; /* primary server req'd (!standard) */ + unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned rcode :4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritive answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned pr :1; /* primary server req'd (!standard) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + int16_t r_zone; /* zone number */ + int16_t r_class; /* class number */ + int16_t r_type; /* type number */ + u_int32_t r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +extern u_int16_t _getshort __P((const u_char *)); +extern u_int32_t _getlong __P((const u_char *)); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += INT16SZ; \ +} + +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += INT32SZ; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c new file mode 100644 index 0000000000..55a3fb09a4 --- /dev/null +++ b/resolv/gethnamaddr.c @@ -0,0 +1,736 @@ +/* + * ++Copyright++ 1985, 1988, 1993 + * - + * Copyright (c) 1985, 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <netdb.h> +#include <resolv.h> +#include <ctype.h> +#include <errno.h> +#include <syslog.h> + +#ifndef LOG_AUTH +# define LOG_AUTH 0 +#endif + +#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ + +#if defined(BSD) && (BSD >= 199103) +# include <string.h> +#else +# include "../conf/portability.h" +#endif +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +#define MAXALIASES 35 +#define MAXADDRS 35 + +static const char AskedForGot[] = + "gethostby*.getanswer: asked for \"%s\", got \"%s\""; + +static char *h_addr_ptrs[MAXADDRS + 1]; + +static struct hostent host; +static char *host_aliases[MAXALIASES]; +static char hostbuf[8*1024]; +static struct in_addr host_addr; +static FILE *hostf = NULL; +static int stayopen = 0; + +#ifdef RESOLVSORT +static void addrsort __P((char **, int)); +#endif + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + int32_t al; + char ac; +} align; + +extern int h_errno; + +#ifdef DEBUG +static void +dprintf(msg, num) + char *msg; + int num; +{ + if (_res.options & RES_DEBUG) { + int save = errno; + + printf(msg, num); + errno = save; + } +} +#else +# define dprintf(msg, num) /*nada*/ +#endif + +static struct hostent * +getanswer(answer, anslen, qname, qclass, qtype) + const querybuf *answer; + int anslen; + const char *qname; + int qclass, qtype; +{ + register const HEADER *hp; + register const u_char *cp; + register int n; + const u_char *eom; + char *bp, **ap, **hap; + int type, class, buflen, ancount, qdcount; + int haveanswer, had_error; + int toobig = 0; + char tbuf[MAXDNAME+1]; + + host.h_name = NULL; + eom = answer->buf + anslen; + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = hostbuf; + buflen = sizeof hostbuf; + cp = answer->buf + HFIXEDSZ; + if (qdcount != 1) { + h_errno = NO_RECOVERY; + return (NULL); + } + if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) { + h_errno = NO_RECOVERY; + return (NULL); + } + cp += n + QFIXEDSZ; + if (qtype == T_A) { + /* res_send() has already verified that the query name is the + * same as the one we sent; this just gets the expanded name + * (i.e., with the succeeding search-domain tacked on). + */ + n = strlen(bp) + 1; /* for the \0 */ + host.h_name = bp; + bp += n; + buflen -= n; + /* The qname can be abbreviated, but h_name is now absolute. */ + qname = host.h_name; + } + ap = host_aliases; + *ap = NULL; + host.h_aliases = host_aliases; + hap = h_addr_ptrs; + *hap = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#endif + haveanswer = 0; + had_error = 0; + while (ancount-- > 0 && cp < eom && !had_error) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + had_error++; + continue; + } + cp += n; /* name */ + type = _getshort(cp); + cp += INT16SZ; /* type */ + class = _getshort(cp); + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = _getshort(cp); + cp += INT16SZ; /* len */ + if (class != qclass) { + /* XXX - debug? syslog? */ + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (qtype == T_A && type == T_CNAME) { + if (ap >= &host_aliases[MAXALIASES-1]) + continue; + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if (n < 0) { + had_error++; + continue; + } + cp += n; + if (host.h_name && strcasecmp(host.h_name, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"", + host.h_name, bp); + continue; /* XXX - had_error++ ? */ + } + /* Store alias. */ + *ap++ = bp; + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, tbuf); + host.h_name = bp; + bp += n; + buflen -= n; + continue; + } + if (type != qtype) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", + qname, p_class(qclass), p_type(qtype), + p_type(type)); + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(qname, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, qname, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + had_error++; + break; + } +#if MULTI_PTRS_ARE_ALIASES + cp += n; + if (!haveanswer) + host.h_name = bp; + else if (ap < &host_aliases[MAXALIASES-1]) + *ap++ = bp; + else + n = -1; + if (n != -1) { + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + } + break; +#else + host.h_name = bp; + h_errno = NETDB_SUCCESS; + return (&host); +#endif + case T_A: + if (strcasecmp(host.h_name, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, host.h_name, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (haveanswer) { + if (n != host.h_length) { + cp += n; + continue; + } + } else { + register int nn; + + host.h_length = n; + host.h_addrtype = (class == C_IN) + ? AF_INET + : AF_UNSPEC; + host.h_name = bp; + nn = strlen(bp) + 1; /* for the \0 */ + bp += nn; + buflen -= nn; + } + + bp += sizeof(align) - ((u_long)bp % sizeof(align)); + + if (bp + n >= &hostbuf[sizeof hostbuf]) { + dprintf("size (%d) too big\n", n); + had_error++; + continue; + } + if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (!toobig++) + dprintf("Too many addresses (%d)\n", + MAXADDRS); + cp += n; + continue; + } + bcopy(cp, *hap++ = bp, n); + bp += n; + cp += n; + break; + default: + dprintf("Impossible condition (type=%d)\n", type); + h_errno = NO_RECOVERY; + return (NULL); + } /*switch*/ + if (!had_error) + haveanswer++; + } /*while*/ + if (haveanswer) { + *ap = NULL; + *hap = NULL; +# if defined(RESOLVSORT) + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" + * address in that case, not some random one + */ + if (_res.nsort && haveanswer > 1 && + qclass == C_IN && qtype == T_A) + addrsort(h_addr_ptrs, haveanswer); +# endif /*RESOLVSORT*/ +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + /* nothing */ +#else + host.h_addr = h_addr_ptrs[0]; +#endif /*BSD*/ + if (!host.h_name) { + n = strlen(qname) + 1; /* for the \0 */ + strcpy(bp, qname); + host.h_name = bp; + } + h_errno = NETDB_SUCCESS; + return (&host); + } else { + h_errno = TRY_AGAIN; + return (NULL); + } +} + +struct hostent * +gethostbyname(name) + const char *name; +{ + querybuf buf; + register const char *cp; + int n; + extern struct hostent *_gethtbyname(); + + /* + * if there aren't any dots, it could be a user-level alias. + * this is also done in res_query() since we are not the only + * function that looks up host names. + */ + if (!strchr(name, '.') && (cp = __hostalias(name))) + name = cp; + + /* + * disallow names consisting only of digits/dots, unless + * they end in a dot. + */ + if (isdigit(name[0])) + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-numeric, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (!inet_aton(name, &host_addr)) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + host.h_name = (char *)name; + host.h_aliases = host_aliases; + host_aliases[0] = NULL; + host.h_addrtype = AF_INET; + host.h_length = INT32SZ; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#else + host.h_addr = h_addr_ptrs[0]; +#endif + h_errno = NETDB_SUCCESS; + return (&host); + } + if (!isdigit(*cp) && *cp != '.') + break; + } + + if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { + dprintf("res_search failed (%d)\n", n); + if (errno == ECONNREFUSED) + return (_gethtbyname(name)); + return (NULL); + } + return (getanswer(&buf, n, name, C_IN, T_A)); +} + +struct hostent * +gethostbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + int n; + querybuf buf; + register struct hostent *hp; + char qbuf[MAXDNAME+1]; +#ifdef SUNSECURITY + register struct hostent *rhp; + char **haddr; + u_long old_options; + char hname2[MAXDNAME+1]; +#endif /*SUNSECURITY*/ + extern struct hostent *_gethtbyaddr(); + + if (type != AF_INET) { + errno = EAFNOSUPPORT; + h_errno = NETDB_INTERNAL; + return (NULL); + } + (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", + ((unsigned)addr[3] & 0xff), + ((unsigned)addr[2] & 0xff), + ((unsigned)addr[1] & 0xff), + ((unsigned)addr[0] & 0xff)); + n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + if (n < 0) { + dprintf("res_query failed (%d)\n", n); + if (errno == ECONNREFUSED) + return (_gethtbyaddr(addr, len, type)); + return (NULL); + } + if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR))) + return (NULL); /* h_errno was set by getanswer() */ +#ifdef SUNSECURITY + /* + * turn off search as the name should be absolute, + * 'localhost' should be matched by defnames + */ + strncpy(hname2, hp->h_name, MAXDNAME); + hname2[MAXDNAME] = '\0'; + old_options = _res.options; + _res.options &= ~RES_DNSRCH; + _res.options |= RES_DEFNAMES; + if (!(rhp = gethostbyname(hp->h_name))) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: No A record for %s (verifying [%s])", + hname2, inet_ntoa(*((struct in_addr *)addr))); + _res.options = old_options; + h_errno = HOST_NOT_FOUND; + return (NULL); + } + _res.options = old_options; + for (haddr = rhp->h_addr_list; *haddr; haddr++) + if (!memcmp(*haddr, addr, INADDRSZ)) + break; + if (!*haddr) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: A record of %s != PTR record [%s]", + hname2, inet_ntoa(*((struct in_addr *)addr))); + h_errno = HOST_NOT_FOUND; + return (NULL); + } +#endif /*SUNSECURITY*/ + hp->h_addrtype = type; + hp->h_length = len; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; + host_addr = *(struct in_addr *)addr; + h_errno = NETDB_SUCCESS; + return (hp); +} + +void +_sethtent(f) + int f; +{ + if (!hostf) + hostf = fopen(_PATH_HOSTS, "r" ); + else + rewind(hostf); + stayopen = f; +} + +void +_endhtent() +{ + if (hostf && !stayopen) { + (void) fclose(hostf); + hostf = NULL; + } +} + +struct hostent * +_gethtent() +{ + char *p; + register char *cp, **q; + + if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { + h_errno = NETDB_INTERNAL; + return (NULL); + } +again: + if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + if (*p == '#') + goto again; + if (!(cp = strpbrk(p, "#\n"))) + goto again; + *cp = '\0'; + if (!(cp = strpbrk(p, " \t"))) + goto again; + *cp++ = '\0'; + /* THIS STUFF IS INTERNET SPECIFIC */ + if (!inet_aton(p, &host_addr)) + goto again; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#else + host.h_addr = h_addr_ptrs[0]; +#endif + host.h_length = INT32SZ; + host.h_addrtype = AF_INET; + while (*cp == ' ' || *cp == '\t') + cp++; + host.h_name = cp; + q = host.h_aliases = host_aliases; + if (cp = strpbrk(cp, " \t")) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &host_aliases[MAXALIASES - 1]) + *q++ = cp; + if (cp = strpbrk(cp, " \t")) + *cp++ = '\0'; + } + *q = NULL; + h_errno = NETDB_SUCCESS; + return (&host); +} + +struct hostent * +_gethtbyname(name) + char *name; +{ + register struct hostent *p; + register char **cp; + + _sethtent(0); + while (p = _gethtent()) { + if (strcasecmp(p->h_name, name) == 0) + break; + for (cp = p->h_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + _endhtent(); + return (p); +} + +struct hostent * +_gethtbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + register struct hostent *p; + + _sethtent(0); + while (p = _gethtent()) + if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) + break; + _endhtent(); + return (p); +} + +#ifdef RESOLVSORT +static void +addrsort(ap, num) + char **ap; + int num; +{ + int i, j; + char **p; + short aval[MAXADDRS]; + int needsort = 0; + + p = ap; + for (i = 0; i < num; i++, p++) { + for (j = 0 ; (unsigned)j < _res.nsort; j++) + if (_res.sort_list[j].addr.s_addr == + (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) + break; + aval[i] = j; + if (needsort == 0 && i > 0 && j < aval[i-1]) + needsort = i; + } + if (!needsort) + return; + + while (needsort < num) { + for (j = needsort - 1; j >= 0; j--) { + if (aval[j] > aval[j+1]) { + char *hp; + + i = aval[j]; + aval[j] = aval[j+1]; + aval[j+1] = i; + + hp = ap[j]; + ap[j] = ap[j+1]; + ap[j+1] = hp; + + } else + break; + } + needsort++; + } +} +#endif + +#if defined(BSD43_BSD43_NFS) || defined(sun) +/* some libc's out there are bound internally to these names (UMIPS) */ +void +ht_sethostent(stayopen) + int stayopen; +{ + _sethtent(stayopen); +} + +void +ht_endhostent() +{ + _endhtent(); +} + +struct hostent * +ht_gethostbyname(name) + char *name; +{ + return (_gethtbyname(name)); +} + +struct hostent * +ht_gethostbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + return (_gethtbyaddr(addr, len, type)); +} + +struct hostent * +gethostent() +{ + return (_gethtent()); +} + +void +dns_service() +{ + return; +} + +#undef dn_skipname +dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + return (__dn_skipname(comp_dn, eom)); +} +#endif /*old-style libc with yp junk in it*/ + +#ifdef ultrix +/* more icky libc packaging in ultrix */ +int +local_hostname_length(hostname) + const char *hostname; +{ + int len_host, len_domain; + + if (!*_res.defdname) + res_init(); + len_host = strlen(hostname); + len_domain = strlen(_res.defdname); + if (len_host > len_domain && + !strcasecmp(hostname + len_host - len_domain, _res.defdname) && + hostname[len_host - len_domain - 1] == '.') + return (len_host - len_domain - 1); + return (0); +} +#endif diff --git a/resolv/getnetbyaddr.c b/resolv/getnetbyaddr.c new file mode 100644 index 0000000000..3bc01addb6 --- /dev/null +++ b/resolv/getnetbyaddr.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1983 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[] = "@(#)getnetbyaddr.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> + +extern int _net_stayopen; + +struct netent * +_getnetbyaddr(net, type) + register long net; + register int type; +{ + register struct netent *p; + + setnetent(_net_stayopen); + while (p = getnetent()) + if (p->n_addrtype == type && p->n_net == net) + break; + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/resolv/getnetbyname.c b/resolv/getnetbyname.c new file mode 100644 index 0000000000..1d2029fe6c --- /dev/null +++ b/resolv/getnetbyname.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> + +extern int _net_stayopen; + +struct netent * +_getnetbyname(name) +#if (defined(sun) || defined(DGUX)) + register char *name; +#else + register const char *name; +#endif +{ + register struct netent *p; + register char **cp; + + setnetent(_net_stayopen); + while (p = getnetent()) { + if (strcasecmp(p->n_name, name) == 0) + break; + for (cp = p->n_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/resolv/getnetent.c b/resolv/getnetent.c new file mode 100644 index 0000000000..fb47c30c99 --- /dev/null +++ b/resolv/getnetent.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1983 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 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + * + * from getnetent.c 1.1 (Coimbra) 93/06/02 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <resolv.h> +#include <netdb.h> +#include <string.h> + +#ifndef _PATH_NETWORKS +#define _PATH_NETWORKS "/etc/networks" +#endif + +#define MAXALIASES 35 + +static FILE *netf; +static char line[BUFSIZ+1]; +static struct netent net; +static char *net_aliases[MAXALIASES]; +int _net_stayopen; + +void _setnetent __P((int)); +void _endnetent __P((void)); + +void +setnetent(stayopen) + int stayopen; +{ + + sethostent(stayopen); + _setnetent(stayopen); +} + +void +endnetent() +{ + + endhostent(); + _endnetent(); +} + +void +_setnetent(f) + int f; +{ + + if (netf == NULL) + netf = fopen(_PATH_NETWORKS, "r" ); + else + rewind(netf); + _net_stayopen |= f; +} + +void +_endnetent() +{ + + if (netf) { + fclose(netf); + netf = NULL; + } + _net_stayopen = 0; +} + +struct netent * +getnetent() +{ + char *p; + register char *cp, **q; + + if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) + return (NULL); +again: + p = fgets(line, BUFSIZ, netf); + if (p == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + net.n_name = p; + cp = strpbrk(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = strpbrk(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + net.n_net = inet_network(cp); + net.n_addrtype = AF_INET; + q = net.n_aliases = net_aliases; + if (p != NULL) + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &net_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&net); +} diff --git a/resolv/getnetnamadr.c b/resolv/getnetnamadr.c new file mode 100644 index 0000000000..19a31afee8 --- /dev/null +++ b/resolv/getnetnamadr.c @@ -0,0 +1,294 @@ +/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + */ +/* + * 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[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <netdb.h> +#include <resolv.h> +#include <ctype.h> +#include <errno.h> +#include <string.h> +#include "conf/portability.h" + +extern int h_errno; + +#if defined(mips) && defined(SYSTYPE_BSD43) +extern int errno; +#endif + +struct netent *_getnetbyaddr __P((long net, int type)); +#if defined(sun) +struct netent *_getnetbyname __P((char *name)); +#else +struct netent *_getnetbyname __P((const char *name)); +#endif + +#define BYADDR 0 +#define BYNAME 1 +#define MAXALIASES 35 + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + long al; + char ac; +} align; + +static struct netent * +getnetanswer(answer, anslen, net_i) + querybuf *answer; + int anslen; + int net_i; +{ + + register HEADER *hp; + register u_char *cp; + register int n; + u_char *eom; + int type, class, buflen, ancount, qdcount, haveanswer, i, nchar, + getclass = C_ANY, net_length = 0; + char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, + *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; +static struct netent net_entry; +static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; + + /* + * find first satisfactory answer + * + * answer --> +------------+ ( MESSAGE ) + * | Header | + * +------------+ + * | Question | the question for the name server + * +------------+ + * | Answer | RRs answering the question + * +------------+ + * | Authority | RRs pointing toward an authority + * | Additional | RRs holding additional information + * +------------+ + */ + eom = answer->buf + anslen; + hp = &answer->hdr; + ancount = ntohs(hp->ancount); /* #/records in the answer section */ + qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ + bp = netbuf; + buflen = sizeof(netbuf); + cp = answer->buf + HFIXEDSZ; + if (!qdcount) { + if (hp->aa) + h_errno = HOST_NOT_FOUND; + else + h_errno = TRY_AGAIN; + return (NULL); + } + while (qdcount-- > 0) + cp += __dn_skipname(cp, eom) + QFIXEDSZ; + ap = net_aliases; + *ap = NULL; + net_entry.n_aliases = net_aliases; + haveanswer = 0; + while (--ancount >= 0 && cp < eom) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) + break; + cp += n; + ans[0] = '\0'; + (void)strcpy(&ans[0], bp); + GETSHORT(type, cp); + GETSHORT(class, cp); + cp += INT32SZ; /* TTL */ + GETSHORT(n, cp); + if (class == C_IN && type == T_PTR) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + cp += n; + return (NULL); + } + cp += n; + *ap++ = bp; + bp += strlen(bp) + 1; + net_entry.n_addrtype = + (class == C_IN) ? AF_INET : AF_UNSPEC; + haveanswer++; + } + } + if (haveanswer) { + *ap = NULL; + switch (net_i) { + case BYADDR: + net_entry.n_name = *net_entry.n_aliases; + net_entry.n_net = 0L; + break; + case BYNAME: + in = *net_entry.n_aliases; + net_entry.n_name = &ans[0]; + aux2[0] = '\0'; + for (i = 0; i < 4; i++) { + for (st = in, nchar = 0; + *st != '.'; + st++, nchar++) + ; + if (nchar != 1 || *in != '0' || flag) { + flag = 1; + (void)strncpy(paux1, + (i==0) ? in : in-1, + (i==0) ?nchar : nchar+1); + paux1[(i==0) ? nchar : nchar+1] = '\0'; + pauxt = paux2; + paux2 = strcat(paux1, paux2); + paux1 = pauxt; + } + in = ++st; + } + net_entry.n_net = inet_network(paux2); + break; + } + net_entry.n_aliases++; + return (&net_entry); + } + h_errno = TRY_AGAIN; + return (NULL); +} + +struct netent * +getnetbyaddr(net, net_type) + register long net; + register int net_type; +{ + unsigned int netbr[4]; + int nn, anslen; + querybuf buf; + char qbuf[MAXDNAME]; + unsigned long net2; + struct netent *net_entry; + + if (net_type != AF_INET) + return (_getnetbyaddr(net, net_type)); + + for (nn = 4, net2 = net; net2; net2 >>= 8) + netbr[--nn] = net2 & 0xff; + switch (nn) { + case 3: /* Class A */ + sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); + break; + case 2: /* Class B */ + sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]); + break; + case 1: /* Class C */ + sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1]); + break; + case 0: /* Class D - E */ + sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1], netbr[0]); + break; + } + anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif + if (errno == ECONNREFUSED) + return (_getnetbyaddr(net, net_type)); + return (NULL); + } + net_entry = getnetanswer(&buf, anslen, BYADDR); + if (net_entry) { + unsigned u_net = net; /* maybe net should be unsigned ? */ + + /* Strip trailing zeros */ + while ((u_net & 0xff) == 0 && u_net != 0) + u_net >>= 8; + net_entry->n_net = u_net; + return (net_entry); + } + return (_getnetbyaddr(net, net_type)); +} + +struct netent * +getnetbyname(net) +#if defined(sun) + register char *net; +#else + register const char *net; +#endif +{ + unsigned int netbr[4]; + int anslen; + querybuf buf; + char qbuf[MAXDNAME]; + struct netent *net_entry; + + strcpy(&qbuf[0],net); + anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif + if (errno == ECONNREFUSED) + return (_getnetbyname(net)); + return (_getnetbyname(net)); + } + net_entry = getnetanswer(&buf, anslen, BYNAME); + if (net_entry) + return (net_entry); + return (_getnetbyname(net)); +} diff --git a/resolv/herror.c b/resolv/herror.c new file mode 100644 index 0000000000..872a009a18 --- /dev/null +++ b/resolv/herror.c @@ -0,0 +1,118 @@ +/* + * ++Copyright++ 1987, 1993 + * - + * 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. + * - + * 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[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/uio.h> +#include <netdb.h> +#if defined(BSD) && (BSD >= 199103) +# include <unistd.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +char *h_errlist[] = { + "Resolver Error 0 (no error)", + "Unknown host", /* 1 HOST_NOT_FOUND */ + "Host name lookup failure", /* 2 TRY_AGAIN */ + "Unknown server error", /* 3 NO_RECOVERY */ + "No address associated with name", /* 4 NO_ADDRESS */ +}; +int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; + +extern int h_errno; + +/* + * herror -- + * print the error indicated by the h_errno value. + */ +void +herror(s) + const char *s; +{ + struct iovec iov[4]; + register struct iovec *v = iov; + + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = hstrerror(h_errno); + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + writev(STDERR_FILENO, iov, (v - iov) + 1); +} + +char * +hstrerror(err) + int err; +{ + if (err < 0) + return ("Resolver internal error"); + else if (err < h_nerr) + return (h_errlist[err]); + return ("Unknown resolver error"); +} diff --git a/resolv/nsap_addr.c b/resolv/nsap_addr.c new file mode 100644 index 0000000000..ea1850132a --- /dev/null +++ b/resolv/nsap_addr.c @@ -0,0 +1,97 @@ +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <ctype.h> +#include <resolv.h> + +#include "../conf/portability.h" + +#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_char *start = binary; + 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[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); +} diff --git a/resolv/res_comp.c b/resolv/res_comp.c new file mode 100644 index 0000000000..ad24a984a1 --- /dev/null +++ b/resolv/res_comp.c @@ -0,0 +1,433 @@ +/* + * ++Copyright++ 1985, 1993 + * - + * 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. + * - + * 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[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <resolv.h> +#include <ctype.h> + +#if defined(BSD) && (BSD >= 199103) +# include <unistd.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +static int dn_find __P((u_char *exp_dn, u_char *msg, + u_char **dnptrs, u_char **lastdnptr)); + +/* + * Expand compressed domain name 'comp_dn' to full domain name. + * 'msg' is a pointer to the begining of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. + */ +int +dn_expand(msg, eomorig, comp_dn, exp_dn, length) + const u_char *msg, *eomorig, *comp_dn; + char *exp_dn; + int length; +{ + register const u_char *cp; + register char *dn; + register int n, c; + char *eom; + int len = -1, checked = 0; + + dn = exp_dn; + cp = comp_dn; + eom = exp_dn + length; + /* + * fetch next label in domain name + */ + while (n = *cp++) { + /* + * Check for indirection + */ + switch (n & INDIR_MASK) { + case 0: + if (dn != exp_dn) { + if (dn >= eom) + return (-1); + *dn++ = '.'; + } + if (dn+n >= eom) + return (-1); + checked += n + 1; + while (--n >= 0) { + if ((c = *cp++) == '.') { + if (dn + n + 2 >= eom) + return (-1); + *dn++ = '\\'; + } + *dn++ = c; + if (cp >= eomorig) /* out of range */ + return (-1); + } + break; + + case INDIR_MASK: + if (len < 0) + len = cp - comp_dn + 1; + cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); + if (cp < msg || cp >= eomorig) /* out of range */ + return (-1); + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eomorig - msg) + return (-1); + break; + + default: + return (-1); /* flag error */ + } + } + *dn = '\0'; + for (dn = exp_dn; (c = *dn) != '\0'; dn++) + if (isascii(c) && isspace(c)) + return (-1); + if (len < 0) + len = cp - comp_dn; + return (len); +} + +/* + * Compress domain name 'exp_dn' into 'comp_dn'. + * Return the size of the compressed name or -1. + * 'length' is the size of the array pointed to by 'comp_dn'. + * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] + * is a pointer to the beginning of the message. The list ends with NULL. + * 'lastdnptr' is a pointer to the end of the arrary pointed to + * by 'dnptrs'. Side effect is to update the list of pointers for + * labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. + */ +int +dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) + const char *exp_dn; + u_char *comp_dn, **dnptrs, **lastdnptr; + int length; +{ + register u_char *cp, *dn; + register int c, l; + u_char **cpp, **lpp, *sp, *eob; + u_char *msg; + + dn = (u_char *)exp_dn; + cp = comp_dn; + eob = cp + length; + lpp = cpp = NULL; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + ; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + for (c = *dn++; c != '\0'; ) { + /* look to see if we can use pointers */ + if (msg != NULL) { + if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { + if (cp+1 >= eob) + return (-1); + *cp++ = (l >> 8) | INDIR_MASK; + *cp++ = l % 256; + return (cp - comp_dn); + } + /* not found, save it */ + if (lastdnptr != NULL && cpp < lastdnptr-1) { + *cpp++ = cp; + *cpp = NULL; + } + } + sp = cp++; /* save ptr to length byte */ + do { + if (c == '.') { + c = *dn++; + break; + } + if (c == '\\') { + if ((c = *dn++) == '\0') + break; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = c; + } while ((c = *dn++) != '\0'); + /* catch trailing '.'s but not '..' */ + if ((l = cp - sp - 1) == 0 && c == '\0') { + cp--; + break; + } + if (l <= 0 || l > MAXLABEL) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *sp = l; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = '\0'; + return (cp - comp_dn); +} + +/* + * Skip over a compressed domain name. Return the size or -1. + */ +int +__dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + register const u_char *cp; + register int n; + + cp = comp_dn; + while (cp < eom && (n = *cp++)) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + cp += n; + continue; + case INDIR_MASK: /* indirection */ + cp++; + break; + default: /* illegal type */ + return (-1); + } + break; + } + if (cp > eom) + return (-1); + return (cp - comp_dn); +} + +static int +mklower(ch) + register int ch; +{ + if (isascii(ch) && isupper(ch)) + return (tolower(ch)); + return (ch); +} + +/* + * Search for expanded name from a list of previously compressed names. + * Return the offset from msg if found or -1. + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static int +dn_find(exp_dn, msg, dnptrs, lastdnptr) + u_char *exp_dn, *msg; + u_char **dnptrs, **lastdnptr; +{ + register u_char *dn, *cp, **cpp; + register int n; + u_char *sp; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) { + dn = exp_dn; + sp = cp = *cpp; + while (n = *cp++) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + while (--n >= 0) { + if (*dn == '.') + goto next; + if (*dn == '\\') + dn++; + if (mklower(*dn++) != mklower(*cp++)) + goto next; + } + if ((n = *dn++) == '\0' && *cp == '\0') + return (sp - msg); + if (n == '.') + continue; + goto next; + + case INDIR_MASK: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + return (-1); + } + } + if (*dn == '\0') + return (sp - msg); + next: ; + } + return (-1); +} + +/* + * Routines to insert/extract short/long's. Must account for byte + * order and non-alignment problems. This code at least has the + * advantage of being portable. + * + * used by sendmail. + */ + +u_int16_t +_getshort(msgp) + register const u_char *msgp; +{ + register u_int16_t u; + + GETSHORT(u, msgp); + return (u); +} + +#ifdef NeXT +/* + * nExt machines have some funky library conventions, which we must maintain. + */ +u_int16_t +res_getshort(msgp) + register const u_char *msgp; +{ + return (_getshort(msgp)); +} +#endif + +u_int32_t +_getlong(msgp) + register const u_char *msgp; +{ + register u_int32_t u; + + GETLONG(u, msgp); + return (u); +} + +void +#if defined(__STDC__) || defined(__cplusplus) +__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */ +#else +__putshort(s, msgp) + register u_int16_t s; + register u_char *msgp; +#endif +{ + PUTSHORT(s, msgp); +} + +void +__putlong(l, msgp) + register u_int32_t l; + register u_char *msgp; +{ + PUTLONG(l, msgp); +} + +#ifdef ultrix +/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here. + * there is more gunk of this kind over in res_debug.c. + */ +#undef putshort +void +#if defined(__STDC__) || defined(__cplusplus) +putshort(register u_short s, register u_char *msgp) +#else +putshort(s, msgp) + register u_short s; + register u_char *msgp; +#endif +{ + __putshort(s, msgp); +} +#undef putlong +void +putlong(l, msgp) + register u_int32_t l; + register u_char *msgp; +{ + __putlong(l, msgp); +} + +#undef dn_skipname +dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + return (__dn_skipname(comp_dn, eom)); +} +#endif /* Ultrix 4.0 hackery */ diff --git a/resolv/res_debug.c b/resolv/res_debug.c new file mode 100644 index 0000000000..254e1efc39 --- /dev/null +++ b/resolv/res_debug.c @@ -0,0 +1,814 @@ +/* + * ++Copyright++ 1985, 1990, 1993 + * - + * Copyright (c) 1985, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <resolv.h> +#if defined(BSD) && (BSD >= 199103) +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include "../conf/options.h" +#endif + +const char *_res_opcodes[] = { + "QUERY", + "IQUERY", + "CQUERYM", + "CQUERYU", /* experimental */ + "NOTIFY", /* experimental */ + "5", + "6", + "7", + "8", + "UPDATEA", + "UPDATED", + "UPDATEDA", + "UPDATEM", + "UPDATEMA", + "ZONEINIT", + "ZONEREF", +}; + +const char *_res_resultcodes[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "NOCHANGE", +}; + +static char retbuf[16]; + +static const char * +dewks(wks) + int wks; +{ + switch (wks) { + case 5: return "rje"; + case 7: return "echo"; + case 9: return "discard"; + case 11: return "systat"; + case 13: return "daytime"; + case 15: return "netstat"; + case 17: return "qotd"; + case 19: return "chargen"; + case 20: return "ftp-data"; + case 21: return "ftp"; + case 23: return "telnet"; + case 25: return "smtp"; + case 37: return "time"; + case 39: return "rlp"; + case 42: return "name"; + case 43: return "whois"; + case 53: return "domain"; + case 57: return "apts"; + case 59: return "apfs"; + case 67: return "bootps"; + case 68: return "bootpc"; + case 69: return "tftp"; + case 77: return "rje"; + case 79: return "finger"; + case 87: return "link"; + case 95: return "supdup"; + case 100: return "newacct"; + case 101: return "hostnames"; + case 102: return "iso-tsap"; + case 103: return "x400"; + case 104: return "x400-snd"; + case 105: return "csnet-ns"; + case 109: return "pop-2"; + case 111: return "sunrpc"; + case 113: return "auth"; + case 115: return "sftp"; + case 117: return "uucp-path"; + case 119: return "nntp"; + case 121: return "erpc"; + case 123: return "ntp"; + case 133: return "statsrv"; + case 136: return "profile"; + case 144: return "NeWS"; + case 161: return "snmp"; + case 162: return "snmp-trap"; + case 170: return "print-srv"; + default: (void) sprintf(retbuf, "%d", wks); return (retbuf); + } +} + +static const char * +deproto(protonum) + int protonum; +{ + switch (protonum) { + case 1: return "icmp"; + case 2: return "igmp"; + case 3: return "ggp"; + case 5: return "st"; + case 6: return "tcp"; + case 7: return "ucl"; + case 8: return "egp"; + case 9: return "igp"; + case 11: return "nvp-II"; + case 12: return "pup"; + case 16: return "chaos"; + case 17: return "udp"; + default: (void) sprintf(retbuf, "%d", protonum); return (retbuf); + } +} + +static const u_char * +do_rrset(msg, cp, cnt, pflag, file, hs) + int cnt, pflag; + const u_char *cp, *msg; + const char *hs; + FILE *file; +{ + int n; + int sflag; + + /* + * Print answer records. + */ + sflag = (_res.pfcode & pflag); + if (n = ntohs(cnt)) { + if ((!_res.pfcode) || + ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + fprintf(file, hs); + while (--n >= 0) { + if ((!_res.pfcode) || sflag) { + cp = p_rr(cp, msg, file); + } else { + unsigned int dlen; + cp += __dn_skipname(cp, cp + MAXCDNAME); + cp += INT16SZ; + cp += INT16SZ; + cp += INT32SZ; + dlen = _getshort((u_char*)cp); + cp += INT16SZ; + cp += dlen; + } + if ((cp - msg) > PACKETSZ) + return (NULL); + } + if ((!_res.pfcode) || + ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + putc('\n', file); + } + return (cp); +} + +void +__p_query(msg) + const u_char *msg; +{ + __fp_query(msg, stdout); +} + +#ifdef ultrix +/* ultrix 4.0's packaging has some icky packaging. alias for it here. + * there is more junk of this kind over in res_comp.c. + */ +void +p_query(msg) + const u_char *msg; +{ + __p_query(msg); +} +#endif + +/* + * Print the current options. + * This is intended to be primarily a debugging routine. + */ +void +__fp_resstat(statp, file) + struct __res_state *statp; + FILE *file; +{ + register u_long mask; + + fprintf(file, ";; res options:"); + if (!statp) + statp = &_res; + for (mask = 1; mask != 0; mask <<= 1) + if (statp->options & mask) + fprintf(file, " %s", p_option(mask)); + putc('\n', file); +} + +/* + * Print the contents of a query. + * This is intended to be primarily a debugging routine. + */ +void +__fp_nquery(msg, len, file) + const u_char *msg; + int len; + FILE *file; +{ + register const u_char *cp, *endMark; + register const HEADER *hp; + register int n; + +#define TruncTest(x) if (x >= endMark) goto trunc +#define ErrorTest(x) if (x == NULL) goto error + + /* + * Print header fields. + */ + hp = (HEADER *)msg; + cp = msg + HFIXEDSZ; + endMark = cp + len; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { + fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", + _res_opcodes[hp->opcode], + _res_resultcodes[hp->rcode], + ntohs(hp->id)); + putc('\n', file); + } + putc(';', file); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { + fprintf(file, "; flags:"); + if (hp->qr) + fprintf(file, " qr"); + if (hp->aa) + fprintf(file, " aa"); + if (hp->tc) + fprintf(file, " tc"); + if (hp->rd) + fprintf(file, " rd"); + if (hp->ra) + fprintf(file, " ra"); + if (hp->pr) + fprintf(file, " pr"); + } + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { + fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); + fprintf(file, ", Ans: %d", ntohs(hp->ancount)); + fprintf(file, ", Auth: %d", ntohs(hp->nscount)); + fprintf(file, ", Addit: %d", ntohs(hp->arcount)); + } + if ((!_res.pfcode) || (_res.pfcode & + (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { + putc('\n',file); + } + /* + * Print question records. + */ + if (n = ntohs(hp->qdcount)) { + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ";; QUESTIONS:\n"); + while (--n >= 0) { + fprintf(file, ";;\t"); + TruncTest(cp); + cp = p_cdname(cp, msg, file); + ErrorTest(cp); + TruncTest(cp); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", type = %s", + __p_type(_getshort((u_char*)cp))); + cp += INT16SZ; + TruncTest(cp); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", class = %s\n", + __p_class(_getshort((u_char*)cp))); + cp += INT16SZ; + putc('\n', file); + } + } + /* + * Print authoritative answer records + */ + TruncTest(cp); + cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, + ";; ANSWERS:\n"); + ErrorTest(cp); + + /* + * print name server records + */ + TruncTest(cp); + cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, + ";; AUTHORITY RECORDS:\n"); + ErrorTest(cp); + + TruncTest(cp); + /* + * print additional records + */ + cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, + ";; ADDITIONAL RECORDS:\n"); + ErrorTest(cp); + return; + trunc: + fprintf(file, "\n;; ...truncated\n"); + return; + error: + fprintf(file, "\n;; ...malformed\n"); +} + +void +__fp_query(msg, file) + const u_char *msg; + FILE *file; +{ + fp_nquery(msg, PACKETSZ, file); +} + +const u_char * +__p_cdnname(cp, msg, len, file) + const u_char *cp, *msg; + int len; + FILE *file; +{ + char name[MAXDNAME]; + int n; + + if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) + return (NULL); + if (name[0] == '\0') + putc('.', file); + else + fputs(name, file); + return (cp + n); +} + +const u_char * +__p_cdname(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + return (p_cdnname(cp, msg, PACKETSZ, file)); +} + +/* XXX: the rest of these functions need to become length-limited, too. (vix) + */ + +const u_char * +__p_fqname(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + char name[MAXDNAME]; + int n, len; + + if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) + return (NULL); + if (name[0] == '\0') { + putc('.', file); + } else { + fputs(name, file); + if (name[strlen(name) - 1] != '.') + putc('.', file); + } + return (cp + n); +} + +/* + * Print resource record fields in human readable form. + */ +const u_char * +__p_rr(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + int type, class, dlen, n, c; + struct in_addr inaddr; + const u_char *cp1, *cp2; + u_int32_t tmpttl, t; + int lcnt; + + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); /* compression error */ + type = _getshort((u_char*)cp); + cp += INT16SZ; + class = _getshort((u_char*)cp); + cp += INT16SZ; + tmpttl = _getlong((u_char*)cp); + cp += INT32SZ; + dlen = _getshort((u_char*)cp); + cp += INT16SZ; + cp1 = cp; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) + fprintf(file, "\t%lu", tmpttl); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) + fprintf(file, "\t%s", __p_class(class)); + fprintf(file, "\t%s", __p_type(type)); + /* + * Print type specific data, if appropriate + */ + switch (type) { + case T_A: + switch (class) { + case C_IN: + case C_HS: + bcopy(cp, (char *)&inaddr, INADDRSZ); + if (dlen == 4) { + fprintf(file, "\t%s", inet_ntoa(inaddr)); + cp += dlen; + } else if (dlen == 7) { + char *address; + u_char protocol; + u_short port; + + address = inet_ntoa(inaddr); + cp += INADDRSZ; + protocol = *(u_char*)cp; + cp += sizeof(u_char); + port = _getshort((u_char*)cp); + cp += INT16SZ; + fprintf(file, "\t%s\t; proto %d, port %d", + address, protocol, port); + } + break; + default: + cp += dlen; + } + break; + case T_CNAME: + case T_MB: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_HINFO: + case T_ISDN: + cp2 = cp + dlen; + if (n = *cp++) { + fprintf(file, "\t%.*s", n, cp); + cp += n; + } + if ((cp < cp2) && (n = *cp++)) { + fprintf(file, "\t%.*s", n, cp); + cp += n; + } else if (type == T_HINFO) + fprintf(file, "\n;; *** Warning *** OS-type missing"); + break; + + case T_SOA: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + fputs(" (\n", file); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; serial\n", t); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); + break; + + case T_MX: + case T_AFSDB: + case T_RT: + fprintf(file, "\t%d ", _getshort((u_char*)cp)); + cp += INT16SZ; + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_PX: + fprintf(file, "\t%d ", _getshort((u_char*)cp)); + cp += INT16SZ; + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_TXT: + case T_X25: + (void) fputs("\t\"", file); + cp2 = cp1 + dlen; + while (cp < cp2) { + if (n = (unsigned char) *cp++) { + for (c = n; c > 0 && cp < cp2; c--) + if ((*cp == '\n') || (*cp == '"')) { + (void) putc('\\', file); + (void) putc(*cp++, file); + } else + (void) putc(*cp++, file); + } + } + putc('"', file); + break; + + case T_NSAP: + (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); + cp += dlen; + break; + + case T_MINFO: + case T_RP: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_UINFO: + putc('\t', file); + fputs((char *)cp, file); + cp += dlen; + break; + + case T_UID: + case T_GID: + if (dlen == 4) { + fprintf(file, "\t%u", _getlong((u_char*)cp)); + cp += INT32SZ; + } + break; + + case T_WKS: + if (dlen < INT32SZ + 1) + break; + bcopy(cp, (char *)&inaddr, INADDRSZ); + cp += INT32SZ; + fprintf(file, "\t%s %s ( ", + inet_ntoa(inaddr), + deproto((int) *cp)); + cp += sizeof(u_char); + n = 0; + lcnt = 0; + while (cp < cp1 + dlen) { + c = *cp++; + do { + if (c & 0200) { + if (lcnt == 0) { + fputs("\n\t\t\t", file); + lcnt = 5; + } + fputs(dewks(n), file); + putc(' ', file); + lcnt--; + } + c <<= 1; + } while (++n & 07); + } + putc(')', file); + break; + +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: + { + int NumBytes = 8; + u_char *DataPtr; + int i; + + if (dlen < NumBytes) NumBytes = dlen; + fprintf(file, "\tFirst %d bytes of hex data:", + NumBytes); + for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) + fprintf(file, " %x", *DataPtr); + cp += dlen; + } + break; +#endif /* ALLOW_T_UNSPEC */ + + default: + fprintf(file, "\t?%d?", type); + cp += dlen; + } +#if 0 + fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); +#else + putc('\n', file); +#endif + if (cp - cp1 != dlen) { + fprintf(file, ";; packet size error (found %d, dlen was %d)\n", + cp - cp1, dlen); + cp = NULL; + } + return (cp); +} + +static char nbuf[40]; + +/* + * Return a string for the type + */ +const char * +__p_type(type) + int type; +{ + switch (type) { + case T_A: return "A"; + case T_NS: return "NS"; + case T_CNAME: return "CNAME"; + case T_SOA: return "SOA"; + case T_MB: return "MB"; + case T_MG: return "MG"; + case T_MR: return "MR"; + case T_NULL: return "NULL"; + case T_WKS: return "WKS"; + case T_PTR: return "PTR"; + case T_HINFO: return "HINFO"; + case T_MINFO: return "MINFO"; + case T_MX: return "MX"; + case T_TXT: return "TXT"; + case T_RP: return "RP"; + case T_AFSDB: return "AFSDB"; + case T_X25: return "X25"; + case T_ISDN: return "ISDN"; + case T_RT: return "RT"; + case T_NSAP: return "NSAP"; + case T_NSAP_PTR: return "NSAP_PTR"; + case T_SIG: return "SIG"; + case T_KEY: return "KEY"; + case T_PX: return "PX"; + case T_GPOS: return "GPOS"; + case T_AAAA: return "AAAA"; + case T_LOC: return "LOC"; + case T_AXFR: return "AXFR"; + case T_MAILB: return "MAILB"; + case T_MAILA: return "MAILA"; + case T_ANY: return "ANY"; + case T_UINFO: return "UINFO"; + case T_UID: return "UID"; + case T_GID: return "GID"; +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: return "UNSPEC"; +#endif /* ALLOW_T_UNSPEC */ + default: (void)sprintf(nbuf, "%d", type); return (nbuf); + } +} + +/* + * Return a mnemonic for class + */ +const char * +__p_class(class) + int class; +{ + switch (class) { + case C_IN: return "IN"; + case C_HS: return "HS"; + case C_ANY: return "ANY"; + default: (void)sprintf(nbuf, "%d", class); return (nbuf); + } +} + +/* + * Return a mnemonic for an option + */ +const char * +__p_option(option) + u_long option; +{ + switch (option) { + case RES_INIT: return "init"; + case RES_DEBUG: return "debug"; + case RES_AAONLY: return "aaonly"; + case RES_USEVC: return "usevc"; + case RES_PRIMARY: return "primry"; + case RES_IGNTC: return "igntc"; + case RES_RECURSE: return "recurs"; + case RES_DEFNAMES: return "defnam"; + case RES_STAYOPEN: return "styopn"; + case RES_DNSRCH: return "dnsrch"; + case RES_INSECURE1: return "insecure1"; + case RES_INSECURE2: return "insecure2"; + default: sprintf(nbuf, "?0x%x?", option); return (nbuf); + } +} + +/* + * Return a mnemonic for a time to live + */ +char * +__p_time(value) + u_int32_t value; +{ + int secs, mins, hours, days; + register char *p; + + if (value == 0) { + strcpy(nbuf, "0 secs"); + return (nbuf); + } + + secs = value % 60; + value /= 60; + mins = value % 60; + value /= 60; + hours = value % 24; + value /= 24; + days = value; + value = 0; + +#define PLURALIZE(x) x, (x == 1) ? "" : "s" + p = nbuf; + if (days) { + (void)sprintf(p, "%d day%s", PLURALIZE(days)); + while (*++p); + } + if (hours) { + if (days) + *p++ = ' '; + (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); + while (*++p); + } + if (mins) { + if (days || hours) + *p++ = ' '; + (void)sprintf(p, "%d min%s", PLURALIZE(mins)); + while (*++p); + } + if (secs || ! (days || hours || mins)) { + if (days || hours || mins) + *p++ = ' '; + (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); + } + return (nbuf); +} diff --git a/resolv/res_init.c b/resolv/res_init.c new file mode 100644 index 0000000000..0092dbcfbc --- /dev/null +++ b/resolv/res_init.c @@ -0,0 +1,609 @@ +/* + * ++Copyright++ 1985, 1989, 1993 + * - + * 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. + * - + * 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[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <ctype.h> +#include <resolv.h> +#if defined(BSD) && (BSD >= 199103) +# include <unistd.h> +# include <stdlib.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +/* + * Marc Majka 1994/04/16 + * Allan Nathanson 1994/10/29 (BIND 4.9.3.x) + * + * NetInfo resolver configuration directory support. + * + * Allow a NetInfo directory to be created in the hierarchy which + * contains the same information as the resolver configuration file. + * + * - The local domain name is stored as the value of the "domain" property. + * - The Internet address(es) of the name server(s) are stored as values + * of the "nameserver" property. + * - The name server addresses are stored as values of the "nameserver" + * property. + * - The search list for host-name lookup is stored as values of the + * "search" property. + * - The sortlist comprised of IP address netmask pairs are stored as + * values of the "sortlist" property. The IP address and optional netmask + * should be seperated by a slash (/) character. + * - Internal resolver variables can be set from the value of the "options" + * property. + * + */ +#if defined(NeXT) +# include <netinfo/ni.h> +# define NI_PATH_RESCONF "/locations/resolver" +# define NI_TIMEOUT 10 +static int netinfo_res_init __P((int *haveenv, int *havesearch)); +#endif + +#if defined(USE_OPTIONS_H) +# include "../conf/options.h" +#endif + +static void res_setoptions __P((char *, char *)); + +#ifdef RESOLVSORT +static u_int32_t net_mask __P((struct in_addr)); +#endif + +#if !defined(isascii) /* XXX - could be a function */ +# define isascii(c) (!(c & 0200)) +#endif + +/* + * Resolver state default settings. + */ + +struct __res_state _res; + +/* + * Set up default settings. If the configuration file exist, the values + * there will have precedence. Otherwise, the server address is set to + * INADDR_ANY and the default domain name comes from the gethostname(). + * + * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 + * rather than INADDR_ANY ("0.0.0.0") as the default name server address + * since it was noted that INADDR_ANY actually meant ``the first interface + * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, + * it had to be "up" in order for you to reach your own name server. It + * was later decided that since the recommended practice is to always + * install local static routes through 127.0.0.1 for all your network + * interfaces, that we could solve this problem without a code change. + * + * The configuration file should always be used, since it is the only way + * to specify a default domain. If you are running a server on your local + * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" + * in the configuration file. + * + * Return 0 if completes successfully, -1 on error + */ +res_init() +{ + register FILE *fp; + register char *cp, **pp; + register int n, dots; + char buf[BUFSIZ]; + int nserv = 0; /* number of nameserver records read from file */ + int haveenv = 0; + int havesearch = 0; +#ifdef RESOLVSORT + int nsort = 0; + char *net; +#endif + + /* + * These three fields used to be statically initialized. This made + * it hard to use this code in a shared library. It is necessary, + * now that we're doing dynamic initialization here, that we preserve + * the old semantics: if an application modifies one of these three + * fields of _res before res_init() is called, res_init() will not + * alter them. Of course, if an application is setting them to + * _zero_ before calling res_init(), hoping to override what used + * to be the static default, we can't detect it and unexpected results + * will follow. Zero for any of these fields would make no sense, + * so one can safely assume that the applications were already getting + * unexpected results. + */ + if (!_res.retrans) + _res.retrans = RES_TIMEOUT; + if (!_res.retry) + _res.retry = 4; + if (!_res.options) + _res.options = RES_DEFAULT; + +#ifdef USELOOPBACK + _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); +#else + _res.nsaddr.sin_addr.s_addr = INADDR_ANY; +#endif + _res.nsaddr.sin_family = AF_INET; + _res.nsaddr.sin_port = htons(NAMESERVER_PORT); + _res.nscount = 1; + _res.ndots = 1; + _res.pfcode = 0; + + /* Allow user to override the local domain definition */ + if ((cp = getenv("LOCALDOMAIN")) != NULL) { + (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + haveenv++; + + /* + * Set search list to be blank-separated strings + * from rest of env value. Permits users of LOCALDOMAIN + * to still have a search list, and anyone to set the + * one that they want to use as an individual (even more + * important now that the rfc1535 stuff restricts searches) + */ + cp = _res.defdname; + pp = _res.dnsrch; + *pp++ = cp; + for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { + if (*cp == '\n') /* silly backwards compat */ + break; + else if (*cp == ' ' || *cp == '\t') { + *cp = 0; + n = 1; + } else if (n) { + *pp++ = cp; + n = 0; + havesearch = 1; + } + } + /* null terminate last domain if there are excess */ + while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') + cp++; + *cp = '\0'; + *pp++ = 0; + } + +#define MATCH(line, name) \ + (!strncmp(line, name, sizeof(name) - 1) && \ + (line[sizeof(name) - 1] == ' ' || \ + line[sizeof(name) - 1] == '\t')) + +#ifdef NeXT + if (netinfo_res_init(&haveenv, &havesearch) == 0) +#endif + if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { + /* read the config file */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + /* skip comments */ + if (*buf == ';' || *buf == '#') + continue; + /* read default domain name */ + if (MATCH(buf, "domain")) { + if (haveenv) /* skip if have from environ */ + continue; + cp = buf + sizeof("domain") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp == '\0') || (*cp == '\n')) + continue; + strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) + *cp = '\0'; + havesearch = 0; + continue; + } + /* set search list */ + if (MATCH(buf, "search")) { + if (haveenv) /* skip if have from environ */ + continue; + cp = buf + sizeof("search") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp == '\0') || (*cp == '\n')) + continue; + strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + if ((cp = strchr(_res.defdname, '\n')) != NULL) + *cp = '\0'; + /* + * Set search list to be blank-separated strings + * on rest of line. + */ + cp = _res.defdname; + pp = _res.dnsrch; + *pp++ = cp; + for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { + if (*cp == ' ' || *cp == '\t') { + *cp = 0; + n = 1; + } else if (n) { + *pp++ = cp; + n = 0; + } + } + /* null terminate last domain if there are excess */ + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cp = '\0'; + *pp++ = 0; + havesearch = 1; + continue; + } + /* read nameservers to query */ + if (MATCH(buf, "nameserver") && nserv < MAXNS) { + struct in_addr a; + + cp = buf + sizeof("nameserver") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { + _res.nsaddr_list[nserv].sin_addr = a; + _res.nsaddr_list[nserv].sin_family = AF_INET; + _res.nsaddr_list[nserv].sin_port = + htons(NAMESERVER_PORT); + nserv++; + } + continue; + } +#ifdef RESOLVSORT + if (MATCH(buf, "sortlist")) { + struct in_addr a; + + cp = buf + sizeof("sortlist") - 1; + while (nsort < MAXRESOLVSORT) { + while (*cp == ' ' || *cp == '\t') + cp++; + if (*cp == '\0' || *cp == '\n' || *cp == ';') + break; + net = cp; + while (*cp && *cp != '/' && + isascii(*cp) && !isspace(*cp)) + cp++; + n = *cp; + *cp = 0; + if (inet_aton(net, &a)) { + _res.sort_list[nsort].addr = a; + if (n == '/') { + *cp++ = n; + net = cp; + while (*cp && isascii(*cp) && !isspace(*cp)) + cp++; + n = *cp; + *cp = 0; + if (inet_aton(net, &a)) { + _res.sort_list[nsort].mask = a.s_addr; + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + nsort++; + } + *cp++ = n; + } + continue; + } +#endif + if (MATCH(buf, "options")) { + res_setoptions(buf + sizeof("options") - 1, "conf"); + continue; + } + } + if (nserv > 1) + _res.nscount = nserv; +#ifdef RESOLVSORT + _res.nsort = nsort; +#endif + (void) fclose(fp); + } + if (_res.defdname[0] == 0 && + gethostname(buf, sizeof(_res.defdname) - 1) == 0 && + (cp = strchr(buf, '.')) != NULL) + strcpy(_res.defdname, cp + 1); + + /* find components of local domain that might be searched */ + if (havesearch == 0) { + pp = _res.dnsrch; + *pp++ = _res.defdname; + *pp = NULL; + +#ifndef RFC1535 + dots = 0; + for (cp = _res.defdname; *cp; cp++) + dots += (*cp == '.'); + + cp = _res.defdname; + while (pp < _res.dnsrch + MAXDFLSRCH) { + if (dots < LOCALDOMAINPARTS) + break; + cp = strchr(cp, '.') + 1; /* we know there is one */ + *pp++ = cp; + dots--; + } + *pp = NULL; +#ifdef DEBUG + if (_res.options & RES_DEBUG) { + printf(";; res_init()... default dnsrch list:\n"); + for (pp = _res.dnsrch; *pp; pp++) + printf(";;\t%s\n", *pp); + printf(";;\t..END..\n"); + } +#endif /* DEBUG */ +#endif /* !RFC1535 */ + } + + if ((cp = getenv("RES_OPTIONS")) != NULL) + res_setoptions(cp, "env"); + _res.options |= RES_INIT; + return (0); +} + +static void +res_setoptions(options, source) + char *options, *source; +{ + char *cp = options; + int i; + +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_setoptions(\"%s\", \"%s\")...\n", + options, source); +#endif + while (*cp) { + /* skip leading and inner runs of spaces */ + while (*cp == ' ' || *cp == '\t') + cp++; + /* search for and process individual options */ + if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { + i = atoi(cp + sizeof("ndots:") - 1); + if (i <= RES_MAXNDOTS) + _res.ndots = i; + else + _res.ndots = RES_MAXNDOTS; +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";;\tndots=%d\n", _res.ndots); +#endif + } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { +#ifdef DEBUG + if (!(_res.options & RES_DEBUG)) { + printf(";; res_setoptions(\"%s\", \"%s\")..\n", + options, source); + _res.options |= RES_DEBUG; + } + printf(";;\tdebug\n"); +#endif + } else { + /* XXX - print a warning here? */ + } + /* skip to next run of spaces */ + while (*cp && *cp != ' ' && *cp != '\t') + cp++; + } +} + +#ifdef RESOLVSORT +static u_int32_t +net_mask(in) /* XXX - should really use system's version of this */ + struct in_addr in; +{ + register u_int32_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (htonl(IN_CLASSA_NET)); + else if (IN_CLASSB(i)) + return (htonl(IN_CLASSB_NET)); + return (htonl(IN_CLASSC_NET)); +} +#endif + +#ifdef NeXT +static int +netinfo_res_init(haveenv, havesearch) + int *haveenv; + int *havesearch; +{ + register int n; + void *domain, *parent; + ni_id dir; + ni_status status; + ni_namelist nl; + int nserv = 0; +#ifdef RESOLVSORT + int nsort = 0; +#endif + + status = ni_open(NULL, ".", &domain); + if (status == NI_OK) { + ni_setreadtimeout(domain, NI_TIMEOUT); + ni_setabort(domain, 1); + + /* climb the NetInfo hierarchy to find a resolver directory */ + while (status == NI_OK) { + status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF); + if (status == NI_OK) { + /* found a resolver directory */ + + if (*haveenv == 0) { + /* get the default domain name */ + status = ni_lookupprop(domain, &dir, "domain", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + (void)strncpy(_res.defdname, + nl.ni_namelist_val[0], + sizeof(_res.defdname) - 1); + _res.defdname[sizeof(_res.defdname) - 1] = '\0'; + ni_namelist_free(&nl); + *havesearch = 0; + } + + /* get search list */ + status = ni_lookupprop(domain, &dir, "search", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + (void)strncpy(_res.defdname, + nl.ni_namelist_val[0], + sizeof(_res.defdname) - 1); + _res.defdname[sizeof(_res.defdname) - 1] = '\0'; + /* copy */ + for (n = 0; + n < nl.ni_namelist_len && n < MAXDNSRCH; + n++) { + /* duplicate up to MAXDNSRCH servers */ + char *cp = nl.ni_namelist_val[n]; + _res.dnsrch[n] = + strcpy((char *)malloc(strlen(cp) + 1), cp); + } + ni_namelist_free(&nl); + *havesearch = 1; + } + } + + /* get list of nameservers */ + status = ni_lookupprop(domain, &dir, "nameserver", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + /* copy up to MAXNS servers */ + for (n = 0; + n < nl.ni_namelist_len && nserv < MAXNS; + n++) { + struct in_addr a; + + if (inet_aton(nl.ni_namelist_val[n], &a)) { + _res.nsaddr_list[nserv].sin_addr = a; + _res.nsaddr_list[nserv].sin_family = AF_INET; + _res.nsaddr_list[nserv].sin_port = + htons(NAMESERVER_PORT); + nserv++; + } + } + ni_namelist_free(&nl); + } + + if (nserv > 1) + _res.nscount = nserv; + +#ifdef RESOLVSORT + /* get sort order */ + status = ni_lookupprop(domain, &dir, "sortlist", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + + /* copy up to MAXRESOLVSORT address/netmask pairs */ + for (n = 0; + n < nl.ni_namelist_len && nsort < MAXRESOLVSORT; + n++) { + char ch; + char *cp; + struct in_addr a; + + cp = strchr(nl.ni_namelist_val[n], '/'); + if (cp != NULL) { + ch = *cp; + *cp = '\0'; + } + + if (inet_aton(nl.ni_namelist_val[n], &a)) { + _res.sort_list[nsort].addr = a; + if (*cp && ch == '/') { + *cp++ = ch; + if (inet_aton(cp, &a)) { + _res.sort_list[nsort].mask = a.s_addr; + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + nsort++; + } + } + ni_namelist_free(&nl); + } + + _res.nsort = nsort; +#endif + + /* get resolver options */ + status = ni_lookupprop(domain, &dir, "options", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + res_setoptions(nl.ni_namelist_val[0], "conf"); + ni_namelist_free(&nl); + } + + ni_free(domain); + return(1); /* using DNS configuration from NetInfo */ + } + + status = ni_open(domain, "..", &parent); + ni_free(domain); + if (status == NI_OK) + domain = parent; + } + } + return(0); /* if not using DNS configuration from NetInfo */ +} +#endif /* NeXT */ diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c new file mode 100644 index 0000000000..0695670925 --- /dev/null +++ b/resolv/res_mkquery.c @@ -0,0 +1,247 @@ +/* + * ++Copyright++ 1985, 1993 + * - + * 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. + * - + * 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[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <resolv.h> +#if defined(BSD) && (BSD >= 199103) +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +/* + * Form all types of queries. + * Returns the size of the result or -1. + */ +int +res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) + int op; /* opcode of query */ + const char *dname; /* domain name */ + int class, type; /* class and type of query */ + const u_char *data; /* resource record data */ + int datalen; /* length of data */ + const u_char *newrr_in; /* new rr for modify or append */ + u_char *buf; /* buffer to put query */ + int buflen; /* size of buffer */ +{ + register HEADER *hp; + register u_char *cp; + register int n; + struct rrec *newrr = (struct rrec *) newrr_in; + u_char *dnptrs[20], **dpp, **lastdnptr; + +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_mkquery(%d, %s, %d, %d)\n", + op, dname, class, type); +#endif + if (!(_res.options & RES_INIT)) { + if (res_init() == -1) + return (-1); + } + /* + * Initialize header fields. + */ + if ((buf == NULL) || (buflen < HFIXEDSZ)) + return (-1); + bzero(buf, HFIXEDSZ); + hp = (HEADER *) buf; + hp->id = htons(++_res.id); + hp->opcode = op; + hp->pr = (_res.options & RES_PRIMARY) != 0; + hp->rd = (_res.options & RES_RECURSE) != 0; + hp->rcode = NOERROR; + cp = buf + HFIXEDSZ; + buflen -= HFIXEDSZ; + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; + /* + * perform opcode specific processing + */ + switch (op) { + case QUERY: /*FALLTHROUGH*/ + case NS_NOTIFY_OP: + if ((buflen -= QFIXEDSZ) < 0) + return (-1); + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + hp->qdcount = htons(1); + if (op == QUERY || data == NULL) + break; + /* + * Make an additional record for completion domain. + */ + buflen -= RRFIXEDSZ; + n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(T_NULL, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(0, cp); + cp += INT16SZ; + hp->arcount = htons(1); + break; + + case IQUERY: + /* + * Initialize answer section + */ + if (buflen < 1 + RRFIXEDSZ + datalen) + return (-1); + *cp++ = '\0'; /* no domain name */ + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(datalen, cp); + cp += INT16SZ; + if (datalen) { + bcopy(data, cp, datalen); + cp += datalen; + } + hp->ancount = htons(1); + break; + +#ifdef ALLOW_UPDATES + /* + * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA + * (Record to be modified is followed by its replacement in msg.) + */ + case UPDATEM: + case UPDATEMA: + + case UPDATED: + /* + * The res code for UPDATED and UPDATEDA is the same; user + * calls them differently: specifies data for UPDATED; server + * ignores data if specified for UPDATEDA. + */ + case UPDATEDA: + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(datalen, cp); + cp += INT16SZ; + if (datalen) { + bcopy(data, cp, datalen); + cp += datalen; + } + if ( (op == UPDATED) || (op == UPDATEDA) ) { + hp->ancount = htons(0); + break; + } + /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ + + case UPDATEA: /* Add new resource record */ + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(newrr->r_type, cp); + cp += INT16SZ; + __putshort(newrr->r_class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(newrr->r_size, cp); + cp += INT16SZ; + if (newrr->r_size) { + bcopy(newrr->r_data, cp, newrr->r_size); + cp += newrr->r_size; + } + hp->ancount = htons(0); + break; +#endif /* ALLOW_UPDATES */ + default: + return (-1); + } + return (cp - buf); +} diff --git a/resolv/res_query.c b/resolv/res_query.c new file mode 100644 index 0000000000..0d11889595 --- /dev/null +++ b/resolv/res_query.c @@ -0,0 +1,384 @@ +/* + * ++Copyright++ 1988, 1993 + * - + * 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. + * - + * 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[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <stdio.h> +#include <netdb.h> +#include <resolv.h> +#include <ctype.h> +#include <errno.h> +#if defined(BSD) && (BSD >= 199306) +# include <stdlib.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +char *__hostalias __P((const char *)); +int h_errno; + +/* + * Formulate a normal query, send, and await answer. + * Returned answer is placed in supplied buffer "answer". + * Perform preliminary check of answer, returning success only + * if no error is indicated and the answer count is nonzero. + * Return the size of the response on success, -1 on error. + * Error number is left in h_errno. + * + * Caller must parse answer and determine whether it answers the question. + */ +int +res_query(name, class, type, answer, anslen) + const char *name; /* domain name */ + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer buffer */ +{ + u_char buf[MAXPACKET]; + register HEADER *hp = (HEADER *) answer; + int n; + + hp->rcode = NOERROR; /* default */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query(%s, %d, %d)\n", name, class, type); +#endif + + n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, + buf, sizeof(buf)); + if (n <= 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query: mkquery failed\n"); +#endif + h_errno = NO_RECOVERY; + return (n); + } + n = res_send(buf, n, answer, anslen); + if (n < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query: send error\n"); +#endif + h_errno = TRY_AGAIN; + return (n); + } + + if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; rcode = %d, ancount=%d\n", hp->rcode, + ntohs(hp->ancount)); +#endif + switch (hp->rcode) { + case NXDOMAIN: + h_errno = HOST_NOT_FOUND; + break; + case SERVFAIL: + h_errno = TRY_AGAIN; + break; + case NOERROR: + h_errno = NO_DATA; + break; + case FORMERR: + case NOTIMP: + case REFUSED: + default: + h_errno = NO_RECOVERY; + break; + } + return (-1); + } + return (n); +} + +/* + * Formulate a normal query, send, and retrieve answer in supplied buffer. + * Return the size of the response on success, -1 on error. + * If enabled, implement search rules until answer or unrecoverable failure + * is detected. Error code, if any, is left in h_errno. + */ +int +res_search(name, class, type, answer, anslen) + const char *name; /* domain name */ + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer */ +{ + register const char *cp, * const *domain; + HEADER *hp = (HEADER *) answer; + u_int dots; + int trailing_dot, ret, saved_herrno; + int got_nodata = 0, got_servfail = 0, tried_as_is = 0; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } + errno = 0; + h_errno = HOST_NOT_FOUND; /* default, if we never query */ + dots = 0; + for (cp = name; *cp; cp++) + dots += (*cp == '.'); + trailing_dot = 0; + if (cp > name && *--cp == '.') + trailing_dot++; + + /* + * if there aren't any dots, it could be a user-level alias + */ + if (!dots && (cp = __hostalias(name)) != NULL) + return (res_query(cp, class, type, answer, anslen)); + + /* + * If there are dots in the name already, let's just give it a try + * 'as is'. The threshold can be set with the "ndots" option. + */ + saved_herrno = -1; + if (dots >= _res.ndots) { + ret = res_querydomain(name, NULL, class, type, answer, anslen); + if (ret > 0) + return (ret); + saved_herrno = h_errno; + tried_as_is++; + } + + /* + * We do at least one level of search if + * - there is no dot and RES_DEFNAME is set, or + * - there is at least one dot, there is no trailing dot, + * and RES_DNSRCH is set. + */ + if ((!dots && (_res.options & RES_DEFNAMES)) || + (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { + int done = 0; + + for (domain = (const char * const *)_res.dnsrch; + *domain && !done; + domain++) { + + ret = res_querydomain(name, *domain, class, type, + answer, anslen); + if (ret > 0) + return (ret); + + /* + * If no server present, give up. + * If name isn't found in this domain, + * keep trying higher domains in the search list + * (if that's enabled). + * On a NO_DATA error, keep trying, otherwise + * a wildcard entry of another type could keep us + * from finding this entry higher in the domain. + * If we get some other error (negative answer or + * server failure), then stop searching up, + * but try the input name below in case it's + * fully-qualified. + */ + if (errno == ECONNREFUSED) { + h_errno = TRY_AGAIN; + return (-1); + } + + switch (h_errno) { + case NO_DATA: + got_nodata++; + /* FALLTHROUGH */ + case HOST_NOT_FOUND: + /* keep trying */ + break; + case TRY_AGAIN: + if (hp->rcode == SERVFAIL) { + /* try next search element, if any */ + got_servfail++; + break; + } + /* FALLTHROUGH */ + default: + /* anything else implies that we're done */ + done++; + } + + /* if we got here for some reason other than DNSRCH, + * we only wanted one iteration of the loop, so stop. + */ + if (!(_res.options & RES_DNSRCH)) + done++; + } + } + + /* if we have not already tried the name "as is", do that now. + * note that we do this regardless of how many dots were in the + * name or whether it ends with a dot. + */ + if (!tried_as_is) { + ret = res_querydomain(name, NULL, class, type, answer, anslen); + if (ret > 0) + return (ret); + } + + /* if we got here, we didn't satisfy the search. + * if we did an initial full query, return that query's h_errno + * (note that we wouldn't be here if that query had succeeded). + * else if we ever got a nodata, send that back as the reason. + * else send back meaningless h_errno, that being the one from + * the last DNSRCH we did. + */ + if (saved_herrno != -1) + h_errno = saved_herrno; + else if (got_nodata) + h_errno = NO_DATA; + else if (got_servfail) + h_errno = TRY_AGAIN; + return (-1); +} + +/* + * Perform a call on res_query on the concatenation of name and domain, + * removing a trailing dot from name if domain is NULL. + */ +int +res_querydomain(name, domain, class, type, answer, anslen) + const char *name, *domain; + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer */ +{ + char nbuf[2*MAXDNAME+2]; + const char *longname = nbuf; + int n; + +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_querydomain(%s, %s, %d, %d)\n", + name, domain?domain:"<Nil>", class, type); +#endif + if (domain == NULL) { + /* + * Check for trailing '.'; + * copy without '.' if present. + */ + n = strlen(name) - 1; + if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) { + bcopy(name, nbuf, n); + nbuf[n] = '\0'; + } else + longname = name; + } else + sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); + + return (res_query(longname, class, type, answer, anslen)); +} + +char * +__hostalias(name) + register const char *name; +{ + register char *cp1, *cp2; + FILE *fp; + char *file; + char buf[BUFSIZ]; + static char abuf[MAXDNAME]; + + file = getenv("HOSTALIASES"); + if (file == NULL || (fp = fopen(file, "r")) == NULL) + return (NULL); + buf[sizeof(buf) - 1] = '\0'; + while (fgets(buf, sizeof(buf), fp)) { + for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) + ; + if (!*cp1) + break; + *cp1 = '\0'; + if (!strcasecmp(buf, name)) { + while (isspace(*++cp1)) + ; + if (!*cp1) + break; + for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) + ; + abuf[sizeof(abuf) - 1] = *cp2 = '\0'; + strncpy(abuf, cp1, sizeof(abuf) - 1); + fclose(fp); + return (abuf); + } + } + fclose(fp); + return (NULL); +} diff --git a/resolv/res_send.c b/resolv/res_send.c new file mode 100644 index 0000000000..03055d3619 --- /dev/null +++ b/resolv/res_send.c @@ -0,0 +1,746 @@ +/* + * ++Copyright++ 1985, 1989, 1993 + * - + * 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. + * - + * 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[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + + /* change this to "0" + * if you talk to a lot + * of multi-homed SunOS + * ("broken") name servers. + */ +#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */ + +/* + * Send query to name server and wait for reply. + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> + +#include <stdio.h> +#include <errno.h> +#include <resolv.h> +#if defined(BSD) && (BSD >= 199306) +# include <stdlib.h> +# include <string.h> +#else +# include "../conf/portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +void _res_close __P((void)); + +static int s = -1; /* socket used for communications */ +static int connected = 0; /* is the socket connected */ +static int vc = 0; /* is the socket a virtual ciruit? */ + +#ifndef FD_SET +/* XXX - should be in portability.h */ +#define NFDBITS 32 +#define FD_SETSIZE 32 +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#endif + +#ifndef DEBUG +# define Dprint(cond, args) /*empty*/ +# define DprintQ(cond, args, query) /*empty*/ +# define Aerror(file, string, error, address) /*empty*/ +# define Perror(file, string, error) /*empty*/ +#else +# define Dprint(cond, args) if (cond) {fprintf args;} else {} +# define DprintQ(cond, args, query) if (cond) {\ + fprintf args;\ + __p_query(query);\ + } else {} + static void + Aerror(file, string, error, address) + FILE *file; + char *string; + int error; + struct sockaddr_in address; + { + int save = errno; + + if (_res.options & RES_DEBUG) { + fprintf(file, "res_send: %s ([%s].%u): %s\n", + string, + inet_ntoa(address.sin_addr), + ntohs(address.sin_port), + strerror(error)); + } + errno = save; + } + static void + Perror(file, string, error) + FILE *file; + char *string; + int error; + { + int save = errno; + + if (_res.options & RES_DEBUG) { + fprintf(file, "res_send: %s: %s\n", + string, strerror(error)); + } + errno = save; + } +#endif + +static res_send_qhook Qhook = NULL; +static res_send_rhook Rhook = NULL; + +void +res_send_setqhook(hook) + res_send_qhook hook; +{ + + Qhook = hook; +} + +void +res_send_setrhook(hook) + res_send_rhook hook; +{ + + Rhook = hook; +} + +/* int + * res_isourserver(ina) + * looks up "ina" in _res.ns_addr_list[] + * returns: + * 0 : not found + * >0 : found + * author: + * paul vixie, 29may94 + */ +int +res_isourserver(inp) + const struct sockaddr_in *inp; +{ + struct sockaddr_in ina; + register int ns, ret; + + ina = *inp; + ret = 0; + for (ns = 0; ns < _res.nscount; ns++) { + register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; + + if (srv->sin_family == ina.sin_family && + srv->sin_port == ina.sin_port && + (srv->sin_addr.s_addr == INADDR_ANY || + srv->sin_addr.s_addr == ina.sin_addr.s_addr)) { + ret++; + break; + } + } + return (ret); +} + +/* int + * res_nameinquery(name, type, class, buf, eom) + * look for (name,type,class) in the query section of packet (buf,eom) + * returns: + * -1 : format error + * 0 : not found + * >0 : found + * author: + * paul vixie, 29may94 + */ +int +res_nameinquery(name, type, class, buf, eom) + const char *name; + register int type, class; + const u_char *buf, *eom; +{ + register const u_char *cp = buf + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf)->qdcount); + + while (qdcount-- > 0) { + char tname[MAXDNAME+1]; + register int n, ttype, tclass; + + n = dn_expand(buf, eom, cp, tname, sizeof tname); + if (n < 0) + return (-1); + cp += n; + ttype = _getshort(cp); cp += INT16SZ; + tclass = _getshort(cp); cp += INT16SZ; + if (ttype == type && + tclass == class && + strcasecmp(tname, name) == 0) + return (1); + } + return (0); +} + +/* int + * res_queriesmatch(buf1, eom1, buf2, eom2) + * is there a 1:1 mapping of (name,type,class) + * in (buf1,eom1) and (buf2,eom2)? + * returns: + * -1 : format error + * 0 : not a 1:1 mapping + * >0 : is a 1:1 mapping + * author: + * paul vixie, 29may94 + */ +int +res_queriesmatch(buf1, eom1, buf2, eom2) + const u_char *buf1, *eom1; + const u_char *buf2, *eom2; +{ + register const u_char *cp = buf1 + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf1)->qdcount); + + if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) + return (0); + while (qdcount-- > 0) { + char tname[MAXDNAME+1]; + register int n, ttype, tclass; + + n = dn_expand(buf1, eom1, cp, tname, sizeof tname); + if (n < 0) + return (-1); + cp += n; + ttype = _getshort(cp); cp += INT16SZ; + tclass = _getshort(cp); cp += INT16SZ; + if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) + return (0); + } + return (1); +} + +int +res_send(buf, buflen, ans, anssiz) + const u_char *buf; + int buflen; + u_char *ans; + int anssiz; +{ + HEADER *hp = (HEADER *) buf; + HEADER *anhp = (HEADER *) ans; + int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; + register int n; + u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ + + DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), + (stdout, ";; res_send()\n"), buf); + if (!(_res.options & RES_INIT) && res_init() == -1) + return (-1); + v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; + gotsomewhere = 0; + connreset = 0; + terrno = ETIMEDOUT; + badns = 0; + + /* + * Send request, RETRY times, or until successful + */ + for (try = 0; try < _res.retry; try++) { + for (ns = 0; ns < _res.nscount; ns++) { + struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; + same_ns: + if (badns & (1 << ns)) { + _res_close(); + goto next_ns; + } + + if (Qhook) { + int done = 0, loops = 0; + + do { + res_sendhookact act; + + act = (*Qhook)(&nsap, &buf, &buflen, + ans, anssiz, &resplen); + switch (act) { + case res_goahead: + done = 1; + break; + case res_nextns: + _res_close(); + goto next_ns; + case res_done: + return (resplen); + case res_modified: + /* give the hook another try */ + if (++loops < 42) /*doug adams*/ + break; + /*FALLTHROUGH*/ + case res_error: + /*FALLTHROUGH*/ + default: + return (-1); + } + } while (!done); + } + + Dprint(_res.options & RES_DEBUG, + (stdout, ";; Querying server (# %d) address = %s\n", + ns + 1, inet_ntoa(nsap->sin_addr))); + + if (v_circuit) { + int truncated; + struct iovec iov[2]; + u_short len; + u_char *cp; + + /* + * Use virtual circuit; + * at most one attempt per server. + */ + try = _res.retry; + truncated = 0; + if ((s < 0) || (!vc)) { + if (s >= 0) + _res_close(); + + s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC); + if (s < 0) { + terrno = errno; + Perror(stderr, "socket(vc)", errno); + return (-1); + } + if (connect(s, (struct sockaddr *)nsap, + sizeof(struct sockaddr)) < 0) { + terrno = errno; + Aerror(stderr, "connect/vc", + errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + vc = 1; + } + /* + * Send length & message + */ + putshort((u_short)buflen, (u_char*)&len); + iov[0].iov_base = (caddr_t)&len; + iov[0].iov_len = INT16SZ; + iov[1].iov_base = (caddr_t)buf; + iov[1].iov_len = buflen; + if (writev(s, iov, 2) != (INT16SZ + buflen)) { + terrno = errno; + Perror(stderr, "write failed", errno); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + /* + * Receive length & response + */ + cp = ans; + len = INT16SZ; + while ((n = read(s, (char *)cp, (int)len)) > 0) { + cp += n; + if ((len -= n) <= 0) + break; + } + if (n <= 0) { + terrno = errno; + Perror(stderr, "read failed", errno); + _res_close(); + /* + * A long running process might get its TCP + * connection reset if the remote server was + * restarted. Requery the server instead of + * trying a new one. When there is only one + * server, this means that a query might work + * instead of failing. We only allow one reset + * per query to prevent looping. + */ + if (terrno == ECONNRESET && !connreset) { + connreset = 1; + _res_close(); + goto same_ns; + } + _res_close(); + goto next_ns; + } + resplen = _getshort(ans); + if (resplen > anssiz) { + Dprint(_res.options & RES_DEBUG, + (stdout, ";; response truncated\n") + ); + truncated = 1; + len = anssiz; + } else + len = resplen; + cp = ans; + while (len != 0 && + (n = read(s, (char *)cp, (int)len)) > 0) { + cp += n; + len -= n; + } + if (n <= 0) { + terrno = errno; + Perror(stderr, "read(vc)", errno); + _res_close(); + goto next_ns; + } + if (truncated) { + /* + * Flush rest of answer + * so connection stays in synch. + */ + anhp->tc = 1; + len = resplen - anssiz; + while (len != 0) { + char junk[PACKETSZ]; + + n = (len > sizeof(junk) + ? sizeof(junk) + : len); + if ((n = read(s, junk, n)) > 0) + len -= n; + else + break; + } + } + } else { + /* + * Use datagrams. + */ + struct timeval timeout; + fd_set dsmask; + struct sockaddr_in from; + int fromlen; + + if ((s < 0) || vc) { + if (vc) + _res_close(); + s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC); + if (s < 0) { + bad_dg_sock: terrno = errno; + Perror(stderr, "socket(dg)", errno); + return (-1); + } + connected = 0; + } + /* + * On a 4.3BSD+ machine (client and server, + * actually), sending to a nameserver datagram + * port with no nameserver will cause an + * ICMP port unreachable message to be returned. + * If our datagram socket is "connected" to the + * server, we get an ECONNREFUSED error on the next + * socket operation, and select returns if the + * error message is received. We can thus detect + * the absence of a nameserver without timing out. + * If we have sent queries to at least two servers, + * however, we don't want to remain connected, + * as we wish to receive answers from the first + * server to respond. + */ + if (_res.nscount == 1 || (try == 0 && ns == 0)) { + /* + * Connect only if we are sure we won't + * receive a response from another server. + */ + if (!connected) { + if (connect(s, (struct sockaddr *)nsap, + sizeof(struct sockaddr) + ) < 0) { + Aerror(stderr, + "connect(dg)", + errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + connected = 1; + } + if (send(s, (char*)buf, buflen, 0) != buflen) { + Perror(stderr, "send", errno); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + } else { + /* + * Disconnect if we want to listen + * for responses from more than one server. + */ + if (connected) { +#if defined(BSD) && (BSD >= 199103) + struct sockaddr_in no_addr; + + no_addr.sin_family = AF_INET; + no_addr.sin_addr.s_addr = INADDR_ANY; + no_addr.sin_port = 0; + (void) connect(s, + (struct sockaddr *) + &no_addr, + sizeof(no_addr)); +#else + int s1 = socket(AF_INET, SOCK_DGRAM, + PF_UNSPEC); + if (s1 < 0) + goto bad_dg_sock; + (void) dup2(s1, s); + (void) close(s1); + Dprint(_res.options & RES_DEBUG, + (stdout, ";; new DG socket\n")) +#endif + connected = 0; + errno = 0; + } + if (sendto(s, (char*)buf, buflen, 0, + (struct sockaddr *)nsap, + sizeof(struct sockaddr)) + != buflen) { + Aerror(stderr, "sendto", errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + } + + /* + * Wait for reply + */ + timeout.tv_sec = (_res.retrans << try); + if (try > 0) + timeout.tv_sec /= _res.nscount; + if ((long) timeout.tv_sec <= 0) + timeout.tv_sec = 1; + timeout.tv_usec = 0; + wait: + FD_ZERO(&dsmask); + FD_SET(s, &dsmask); + n = select(s+1, &dsmask, (fd_set *)NULL, + (fd_set *)NULL, &timeout); + if (n < 0) { + Perror(stderr, "select", errno); + _res_close(); + goto next_ns; + } + if (n == 0) { + /* + * timeout + */ + Dprint(_res.options & RES_DEBUG, + (stdout, ";; timeout\n")); + gotsomewhere = 1; + _res_close(); + goto next_ns; + } + fromlen = sizeof(struct sockaddr_in); + resplen = recvfrom(s, (char*)ans, anssiz, 0, + (struct sockaddr *)&from, &fromlen); + if (resplen <= 0) { + Perror(stderr, "recvfrom", errno); + _res_close(); + goto next_ns; + } + gotsomewhere = 1; + if (hp->id != anhp->id) { + /* + * response from old query, ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; old answer:\n"), + ans); + goto wait; + } +#if CHECK_SRVR_ADDR + if (!(_res.options & RES_INSECURE1) && + !res_isourserver(&from)) { + /* + * response from wrong server? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; not our server:\n"), + ans); + goto wait; + } +#endif + if (!(_res.options & RES_INSECURE2) && + !res_queriesmatch(buf, buf + buflen, + ans, ans + anssiz)) { + /* + * response contains wrong query? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; wrong query name:\n"), + ans); + goto wait; + } + if (anhp->rcode == SERVFAIL || + anhp->rcode == NOTIMP || + anhp->rcode == REFUSED) { + DprintQ(_res.options & RES_DEBUG, + (stdout, "server rejected query:\n"), + ans); + badns |= (1 << ns); + _res_close(); + /* don't retry if called from dig */ + if (!_res.pfcode) + goto next_ns; + } + if (!(_res.options & RES_IGNTC) && anhp->tc) { + /* + * get rest of answer; + * use TCP with same server. + */ + Dprint(_res.options & RES_DEBUG, + (stdout, ";; truncated answer\n")); + v_circuit = 1; + _res_close(); + goto same_ns; + } + } /*if vc/dg*/ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; got answer:\n"), + ans); + /* + * If using virtual circuits, we assume that the first server + * is preferred over the rest (i.e. it is on the local + * machine) and only keep that one open. + * If we have temporarily opened a virtual circuit, + * or if we haven't been asked to keep a socket open, + * close the socket. + */ + if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || + !(_res.options & RES_STAYOPEN)) { + _res_close(); + } + if (Rhook) { + int done = 0, loops = 0; + + do { + res_sendhookact act; + + act = (*Rhook)(nsap, buf, buflen, + ans, anssiz, &resplen); + switch (act) { + case res_goahead: + case res_done: + done = 1; + break; + case res_nextns: + _res_close(); + goto next_ns; + case res_modified: + /* give the hook another try */ + if (++loops < 42) /*doug adams*/ + break; + /*FALLTHROUGH*/ + case res_error: + /*FALLTHROUGH*/ + default: + return (-1); + } + } while (!done); + + } + return (resplen); + next_ns: ; + } /*foreach ns*/ + } /*foreach retry*/ + _res_close(); + if (!v_circuit) + if (!gotsomewhere) + errno = ECONNREFUSED; /* no nameservers found */ + else + errno = ETIMEDOUT; /* no answer obtained */ + else + errno = terrno; + return (-1); +} + +/* + * This routine is for closing the socket if a virtual circuit is used and + * the program wants to close it. This provides support for endhostent() + * which expects to close the socket. + * + * This routine is not expected to be user visible. + */ +void +_res_close() +{ + if (s >= 0) { + (void) close(s); + s = -1; + connected = 0; + vc = 0; + } +} diff --git a/resolv/resolv.h b/resolv/resolv.h new file mode 100644 index 0000000000..d62bdf8ef9 --- /dev/null +++ b/resolv/resolv.h @@ -0,0 +1,240 @@ +/* + * ++Copyright++ 1983, 1987, 1989, 1993 + * - + * Copyright (c) 1983, 1987, 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. + * - + * 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-- + */ + +/* + * @(#)resolv.h 8.1 (Berkeley) 6/2/93 + * $Id$ + */ + +#ifndef _RESOLV_H_ +#define _RESOLV_H_ + +#include <sys/param.h> +#if (!defined(BSD)) || (BSD < 199306) +# include <sys/bitypes.h> +#else +# include <sys/types.h> +#endif +#include <sys/cdefs.h> +#include <stdio.h> + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__RES > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __RES 19941130 + +/* + * Resolver configuration file. + * Normally not present, but may contain the address of the + * inital name server(s) to query and the domain search list. + */ + +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif + +/* + * Global defines and variables for resolver stub. + */ +#define MAXNS 3 /* max # name servers we'll track */ +#define MAXDFLSRCH 3 /* # default domain levels to try */ +#define MAXDNSRCH 6 /* max # domains in search path */ +#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ + +#define RES_TIMEOUT 5 /* min. seconds between retries */ +#define MAXRESOLVSORT 10 /* number of net to sort on */ +#define RES_MAXNDOTS 15 /* should reflect bit field size */ + +struct __res_state { + int retrans; /* retransmition time interval */ + int retry; /* number of times to retransmit */ + u_long options; /* option flags - see below. */ + int nscount; /* number of name servers */ + struct sockaddr_in + nsaddr_list[MAXNS]; /* address of name server */ +#define nsaddr nsaddr_list[0] /* for backward compatibility */ + u_short id; /* current packet id */ + char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ + char defdname[MAXDNAME]; /* default domain */ + u_long pfcode; /* RES_PRF_ flags - see below. */ + unsigned ndots:4; /* threshold for initial abs. query */ + unsigned nsort:4; /* number of elements in sort_list[] */ + char unused[3]; + struct { + struct in_addr addr; + u_int32_t mask; + } sort_list[MAXRESOLVSORT]; +}; + +/* + * Resolver options (keep these in synch with res_debug.c, please) + */ +#define RES_INIT 0x00000001 /* address initialized */ +#define RES_DEBUG 0x00000002 /* print debug messages */ +#define RES_AAONLY 0x00000004 /* authoritative answers only */ +#define RES_USEVC 0x00000008 /* use virtual circuit */ +#define RES_PRIMARY 0x00000010 /* query primary server only */ +#define RES_IGNTC 0x00000020 /* ignore trucation errors */ +#define RES_RECURSE 0x00000040 /* recursion desired */ +#define RES_DEFNAMES 0x00000080 /* use default domain name */ +#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */ +#define RES_DNSRCH 0x00000200 /* search up local domain tree */ +#define RES_INSECURE1 0x00000400 /* type 1 security disabled */ +#define RES_INSECURE2 0x00000800 /* type 2 security disabled */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) + +/* + * Resolver "pfcode" values. Used by dig. + */ +#define RES_PRF_STATS 0x00000001 +/* 0x00000002 */ +#define RES_PRF_CLASS 0x00000004 +#define RES_PRF_CMD 0x00000008 +#define RES_PRF_QUES 0x00000010 +#define RES_PRF_ANS 0x00000020 +#define RES_PRF_AUTH 0x00000040 +#define RES_PRF_ADD 0x00000080 +#define RES_PRF_HEAD1 0x00000100 +#define RES_PRF_HEAD2 0x00000200 +#define RES_PRF_TTLID 0x00000400 +#define RES_PRF_HEADX 0x00000800 +#define RES_PRF_QUERY 0x00001000 +#define RES_PRF_REPLY 0x00002000 +#define RES_PRF_INIT 0x00004000 +/* 0x00008000 */ + +/* hooks are still experimental as of 4.9.2 */ +typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } + res_sendhookact; + +typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns, + const u_char **query, + int *querylen, + u_char *ans, + int anssiz, + int *resplen)); + +typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns, + const u_char *query, + int querylen, + u_char *ans, + int anssiz, + int *resplen)); + +extern struct __res_state _res; + +/* Private routines shared between libc/net, named, nslookup and others. */ +#define dn_skipname __dn_skipname +#define fp_query __fp_query +#define fp_nquery __fp_nquery +#define hostalias __hostalias +#define putlong __putlong +#define putshort __putshort +#define p_class __p_class +#define p_time __p_time +#define p_type __p_type +#define p_cdnname __p_cdnname +#define p_cdname __p_cdname +#define p_fqname __p_fqname +#define p_rr __p_rr +#define p_option __p_option +#define res_isourserver __res_isourserver +#define res_nameinquery __res_nameinquery +#define res_queriesmatch __res_queriesmatch +__BEGIN_DECLS +int __dn_skipname __P((const u_char *, const u_char *)); +void __fp_resstat __P((struct __res_state *, FILE *)); +void __fp_query __P((const u_char *, FILE *)); +void __fp_nquery __P((const u_char *, int, FILE *)); +char *__hostalias __P((const char *)); +void __putlong __P((u_int32_t, u_char *)); +void __putshort __P((u_int16_t, u_char *)); +char *__p_time __P((u_int32_t)); +void __p_query __P((const u_char *)); +const u_char *__p_cdnname __P((const u_char *, const u_char *, int, FILE *)); +const u_char *__p_cdname __P((const u_char *, const u_char *, FILE *)); +const u_char *__p_fqname __P((const u_char *, const u_char *, FILE *)); +const u_char *__p_rr __P((const u_char *, const u_char *, FILE *)); +const char *__p_type __P((int)); +const char *__p_class __P((int)); +const char *__p_option __P((u_long option)); +int dn_comp __P((const char *, u_char *, int, u_char **, u_char **)); +int dn_expand __P((const u_char *, const u_char *, const u_char *, + char *, int)); +int res_init __P((void)); +int res_query __P((const char *, int, int, u_char *, int)); +int res_search __P((const char *, int, int, u_char *, int)); +int res_querydomain __P((const char *, const char *, int, int, + u_char *, int)); +int res_mkquery __P((int, const char *, int, int, const u_char *, int, + const u_char *, u_char *, int)); +int res_send __P((const u_char *, int, u_char *, int)); +int res_isourserver __P((const struct sockaddr_in *)); +int res_nameinquery __P((const char *, int, int, + const u_char *, const u_char *)); +int res_queriesmatch __P((const u_char *, const u_char *, + const u_char *, const u_char *)); +/* XXX - these last two don't belong in the resolver */ +u_int inet_nsap_addr __P((const char *, u_char *, int maxlen)); +char *inet_nsap_ntoa __P((int, const u_char *, char *ascii)); +__END_DECLS + +#endif /* !_RESOLV_H_ */ diff --git a/resolv/sethostent.c b/resolv/sethostent.c new file mode 100644 index 0000000000..709b518a40 --- /dev/null +++ b/resolv/sethostent.c @@ -0,0 +1,80 @@ +/* + * ++Copyright++ 1985, 1993 + * - + * 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. + * - + * 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[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + +void +sethostent(stayopen) + int stayopen; +{ + if (stayopen) + _res.options |= RES_STAYOPEN | RES_USEVC; +} + +void +endhostent() +{ + _res.options &= ~(RES_STAYOPEN | RES_USEVC); + _res_close(); +} diff --git a/resolv/sys/bitypes.h b/resolv/sys/bitypes.h new file mode 100644 index 0000000000..3a9860f713 --- /dev/null +++ b/resolv/sys/bitypes.h @@ -0,0 +1,3 @@ +/* The GNU <sys/types.h> defines all the necessary types. */ + +#include <sys/types.h> diff --git a/resource/Makefile b/resource/Makefile new file mode 100644 index 0000000000..4b9bdaaaa1 --- /dev/null +++ b/resource/Makefile @@ -0,0 +1,26 @@ +# Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +subdir := resource + +headers := sys/resource.h resourcebits.h sys/vlimit.h sys/vtimes.h + +routines := getrlimit setrlimit getrusage ulimit vlimit vtimes \ + getpriority setpriority nice + +include ../Rules diff --git a/resource/sys/resource.h b/resource/sys/resource.h new file mode 100644 index 0000000000..9bef483359 --- /dev/null +++ b/resource/sys/resource.h @@ -0,0 +1,154 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_RESOURCE_H + +#define _SYS_RESOURCE_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get the system-dependent definitions of RLIM_*. */ +#include <resourcebits.h> + +struct rlimit + { + /* The current (soft) limit. */ + int rlim_cur; + /* The hard limit. */ + int rlim_max; + }; + +/* Value used to indicate that there is no limit. */ +#define RLIM_INFINITY 0x7fffffff + +/* Put the soft and hard limits for RESOURCE in *RLIMITS. + Returns 0 if successful, -1 if not (and sets errno). */ +int getrlimit __P ((enum __rlimit_resource __resource, + struct rlimit * __rlimits)); + +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int setrlimit __P ((enum __rlimit_resource __resource, + struct rlimit * __rlimits)); + + +/* Whose usage statistics do you want? */ +enum __rusage_who +/* The macro definitions are necessary because some programs want + to test for operating system features with #ifdef RUSAGE_SELF. + In ANSI C the reflexive definition is a no-op. */ + { + /* The calling process. */ + RUSAGE_SELF = 0, +#define RUSAGE_SELF RUSAGE_SELF + /* All of its terminated child processes. */ + RUSAGE_CHILDREN = -1, +#define RUSAGE_CHILDREN RUSAGE_CHILDREN + }; + +#include <sys/time.h> /* For `struct timeval'. */ + +/* Structure which says how much of each resource has been used. */ +struct rusage + { + /* Total amount of user time used. */ + struct timeval ru_utime; + /* Total amount of system time used. */ + struct timeval ru_stime; + /* Maximum resident set size (in kilobytes). */ + long ru_maxrss; + /* Amount of sharing of text segment memory + with other processes (kilobyte-seconds). */ + long ru_ixrss; + /* Amount of data segment memory used (kilobyte-seconds). */ + long ru_idrss; + /* Amount of stack memory used (kilobyte-seconds). */ + long ru_isrss; + /* Number of soft page faults (i.e. those serviced by reclaiming + a page from the list of pages awaiting reallocation. */ + long ru_minflt; + /* Number of hard page faults (i.e. those that required I/O). */ + long ru_majflt; + /* Number of times a process was swapped out of physical memory. */ + long ru_nswap; + /* Number of input operations via the file system. Note: This + and `ru_oublock' do not include operations with the cache. */ + long ru_inblock; + /* Number of output operations via the file system. */ + long ru_oublock; + /* Number of IPC messages sent. */ + long ru_msgsnd; + /* Number of IPC messages received. */ + long ru_msgrcv; + /* Number of signals delivered. */ + long ru_nsignals; + /* Number of voluntary context switches, i.e. because the process + gave up the process before it had to (usually to wait for some + resource to be available). */ + long ru_nvcsw; + /* Number of involuntary context switches, i.e. a higher priority process + became runnable or the current process used up its time slice. */ + long ru_nivcsw; + }; + +/* Return resource usage information on process indicated by WHO + and put it in *USAGE. Returns 0 for success, -1 for failure. */ +int __getrusage __P ((enum __rusage_who __who, struct rusage * __usage)); +int getrusage __P ((enum __rusage_who __who, struct rusage * __usage)); + +/* Function depends on CMD: + 1 = Return the limit on the size of a file, in units of 512 bytes. + 2 = Set the limit on the size of a file to NEWLIMIT. Only the + super-user can increase the limit. + 3 = Return the maximum possible address of the data segment. + 4 = Return the maximum number of files that the calling process can open. + Returns -1 on errors. */ +long int __ulimit __P ((int __cmd, long int __newlimit)); +long int ulimit __P ((int __cmd, long int __newlimit)); + + +/* Priority limits. */ +#define PRIO_MIN -20 /* Minimum priority a process can have. */ +#define PRIO_MAX 20 /* Maximum priority a process can have. */ + +/* The type of the WHICH argument to `getpriority' and `setpriority', + indicating what flavor of entity the WHO argument specifies. */ +enum __priority_which + { + PRIO_PROCESS = 0, /* WHO is a process ID. */ + PRIO_PGRP = 1, /* WHO is a process group ID. */ + PRIO_USER = 2, /* WHO is a user ID. */ + }; + +/* Return the highest priority of any process specified by WHICH and WHO + (see above); if WHO is zero, the current process, process group, or user + (as specified by WHO) is used. A lower priority number means higher + priority. Priorities range from PRIO_MIN to PRIO_MAX (above). */ +extern int getpriority __P ((enum __priority_which __which, int __who)); + +/* Set the priority of all processes specified by WHICH and WHO (see above) + to PRIO. Returns 0 on success, -1 on errors. */ +extern int setpriority __P ((enum __priority_which __which, int __who, + int __prio)); + + +__END_DECLS + +#endif /* resource.h */ diff --git a/resource/sys/vlimit.h b/resource/sys/vlimit.h new file mode 100644 index 0000000000..db0fdaeac5 --- /dev/null +++ b/resource/sys/vlimit.h @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_VLIMIT_H + +#define _SYS_VLIMIT_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* This interface is obsolete, and is superseded by <sys/resource.h>. */ + +/* Kinds of resource limit. */ +enum __vlimit_resource +{ + /* Setting this non-zero makes it impossible to raise limits. + Only the super-use can set it to zero. + + This is not implemented in recent versions of BSD, nor by + the GNU C library. */ + LIM_NORAISE, + + /* CPU time available for each process (seconds). */ + LIM_CPU, + + /* Largest file which can be created (bytes). */ + LIM_FSIZE, + + /* Maximum size of the data segment (bytes). */ + LIM_DATA, + + /* Maximum size of the stack segment (bytes). */ + LIM_STACK, + + /* Largest core file that will be created (bytes). */ + LIM_CORE, + + /* Resident set size (bytes). */ + LIM_MAXRSS +}; + +/* This means no limit. */ +#define INFINITY 0x7fffffff + + +/* Set the soft limit for RESOURCE to be VALUE. + Returns 0 for success, -1 for failure. */ +int vlimit __P ((enum __vlimit_resource __resource, int __value)); + + +__END_DECLS + +#endif /* vlimit.h */ diff --git a/resource/sys/vtimes.h b/resource/sys/vtimes.h new file mode 100644 index 0000000000..e83d34c101 --- /dev/null +++ b/resource/sys/vtimes.h @@ -0,0 +1,69 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_VTIMES_H + +#define _SYS_VTIMES_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* This interface is obsolete; use `getrusage' instead. */ + +/* Granularity of the `vm_utime' and `vm_stime' fields of a `struct vtimes'. + (This is the frequency of the machine's power supply, in Hz.) */ +#define VTIMES_UNITS_PER_SECOND 60 + +struct vtimes +{ + /* User time used in units of 1/VTIMES_UNITS_PER_SECOND seconds. */ + int vm_utime; + /* System time used in units of 1/VTIMES_UNITS_PER_SECOND seconds. */ + int vm_stime; + + /* Amount of data and stack memory used (kilobyte-seconds). */ + unsigned int vm_idsrss; + /* Amount of text memory used (kilobyte-seconds). */ + unsigned int vm_ixrss; + /* Maximum resident set size (text, data, and stack) (kilobytes). */ + int vm_maxrss; + + /* Number of hard page faults (i.e. those that required I/O). */ + int vm_majflt; + /* Number of soft page faults (i.e. those serviced by reclaiming + a page from the list of pages awaiting reallocation. */ + int vm_minflt; + + /* Number of times a process was swapped out of physical memory. */ + int vm_nswap; + + /* Number of input operations via the file system. Note: This + and `ru_oublock' do not include operations with the cache. */ + int vm_inblk; + /* Number of output operations via the file system. */ + int vm_oublk; +}; + +/* If CURRENT is not NULL, write statistics for the current process into + *CURRENT. If CHILD is not NULL, write statistics for all terminated child + processes into *CHILD. Returns 0 for success, -1 for failure. */ +int vtimes __P ((struct vtimes * __current, struct vtimes * __child)); + +__END_DECLS + +#endif /* sys/vtimes.h */ diff --git a/rpc/auth.h b/rpc/auth.h new file mode 100644 index 0000000000..5721091a56 --- /dev/null +++ b/rpc/auth.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/auth.h> diff --git a/rpc/auth_unix.h b/rpc/auth_unix.h new file mode 100644 index 0000000000..36299392ba --- /dev/null +++ b/rpc/auth_unix.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/auth_unix.h> diff --git a/rpc/clnt.h b/rpc/clnt.h new file mode 100644 index 0000000000..b4493d1d90 --- /dev/null +++ b/rpc/clnt.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/clnt.h> diff --git a/rpc/netdb.h b/rpc/netdb.h new file mode 100644 index 0000000000..a9d93e13ad --- /dev/null +++ b/rpc/netdb.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/netdb.h> diff --git a/rpc/pmap_clnt.h b/rpc/pmap_clnt.h new file mode 100644 index 0000000000..dfe537c96f --- /dev/null +++ b/rpc/pmap_clnt.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/pmap_clnt.h> diff --git a/rpc/pmap_prot.h b/rpc/pmap_prot.h new file mode 100644 index 0000000000..06d7d378cf --- /dev/null +++ b/rpc/pmap_prot.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/pmap_prot.h> diff --git a/rpc/pmap_rmt.h b/rpc/pmap_rmt.h new file mode 100644 index 0000000000..1585c13039 --- /dev/null +++ b/rpc/pmap_rmt.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/pmap_rmt.h> diff --git a/rpc/rpc.h b/rpc/rpc.h new file mode 100644 index 0000000000..1b5c5cd8de --- /dev/null +++ b/rpc/rpc.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/rpc.h> diff --git a/rpc/rpc_msg.h b/rpc/rpc_msg.h new file mode 100644 index 0000000000..3c63730c1f --- /dev/null +++ b/rpc/rpc_msg.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/rpc_msg.h> diff --git a/rpc/svc.h b/rpc/svc.h new file mode 100644 index 0000000000..68aa67b429 --- /dev/null +++ b/rpc/svc.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/svc.h> diff --git a/rpc/svc_auth.h b/rpc/svc_auth.h new file mode 100644 index 0000000000..e2c226312e --- /dev/null +++ b/rpc/svc_auth.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/svc_auth.h> diff --git a/rpc/types.h b/rpc/types.h new file mode 100644 index 0000000000..53df7e666b --- /dev/null +++ b/rpc/types.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/types.h> diff --git a/rpc/xdr.h b/rpc/xdr.h new file mode 100644 index 0000000000..4c9083d08a --- /dev/null +++ b/rpc/xdr.h @@ -0,0 +1 @@ +#include <sunrpc/rpc/xdr.h> diff --git a/set-hooks.h b/set-hooks.h new file mode 100644 index 0000000000..10d0b10176 --- /dev/null +++ b/set-hooks.h @@ -0,0 +1,56 @@ +/* Macros for using symbol sets for running lists of functions. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SET_HOOKS_H + +#define __need_size_t +#include <stddef.h> +#include <sys/cdefs.h> + +/* Define a hook variable called NAME. Functions put on this hook take + arguments described by PROTO. Use `text_set_element (NAME, FUNCTION)' + from gnu-stabs.h to add a function to the hook. */ + +#define DEFINE_HOOK(NAME, PROTO) \ + typedef void __##NAME##_hook_function_t PROTO; \ + symbol_set_define (NAME) + +#define DECLARE_HOOK(NAME, PROTO) \ + typedef void __##NAME##_hook_function_t PROTO;\ + symbol_set_declare (NAME) + +/* Run all the functions hooked on the set called NAME. + Each function is called like this: `function ARGS'. */ + +#define RUN_HOOK(NAME, ARGS) \ +do { \ + void *const *ptr; \ + for (ptr = symbol_set_first_element (NAME); \ + ! symbol_set_end_p (NAME, ptr); ++ptr) \ + (*(__##NAME##_hook_function_t *) *ptr) ARGS; \ +} while (0) + +/* Define a hook variable with NAME and PROTO, and a function called RUNNER + which calls each function on the hook in turn, with ARGS. */ + +#define DEFINE_HOOK_RUNNER(name, runner, proto, args) \ +DEFINE_HOOK (name, proto); void runner proto { RUN_HOOK (name, args); } + + +#endif diff --git a/set-init.c b/set-init.c new file mode 100644 index 0000000000..34c0dbd804 --- /dev/null +++ b/set-init.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdlib.h> +#include "set-hooks.h" + +DEFINE_HOOK_RUNNER (__libc_subinit, __libc_subinit_runner, + (int argc, char **argv, char **envp), (argc, argv, envp)) + +void +__libc_init (argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + __libc_subinit_runner (argc, argv, envp); + +#ifdef HAVE_ELF + { + /* These functions are defined in crti.o to run the .init and .fini + sections, which are used for initializers in ELF. */ + extern void _init __P ((void)), _fini __P ((void)); + atexit (_fini); /* Arrange for _fini to run at exit. */ + _init (); + } +#endif +} diff --git a/setjmp.h b/setjmp.h new file mode 100644 index 0000000000..c78a964566 --- /dev/null +++ b/setjmp.h @@ -0,0 +1 @@ +#include <setjmp/setjmp.h> diff --git a/setjmp/Makefile b/setjmp/Makefile new file mode 100644 index 0000000000..4a7e4aa85a --- /dev/null +++ b/setjmp/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for setjmp/longjmp routines +# +subdir := setjmp + +headers := setjmp.h jmp_buf.h + +routines := setjmp sigjmp bsd-setjmp bsd-_setjmp \ + longjmp __longjmp + +tests := tst-setjmp + + +include ../Rules diff --git a/setjmp/longjmp.c b/setjmp/longjmp.c new file mode 100644 index 0000000000..d4e4ef7740 --- /dev/null +++ b/setjmp/longjmp.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stddef.h> +#include <setjmp.h> +#include <signal.h> + + +/* Set the signal mask to the one specified in ENV, and jump + to the position specified in ENV, causing the setjmp + call there to return VAL, or 1 if VAL is 0. */ +void +longjmp (sigjmp_buf env, int val) +{ + if (env[0].__mask_was_saved) + /* Restore the saved signal mask. */ + (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask, + (sigset_t *) NULL); + + /* Call the machine-dependent function to restore machine state. */ + __longjmp (env[0].__jmpbuf, val ?: 1); +} + +weak_alias (longjmp, _longjmp) +weak_alias (longjmp, siglongjmp) diff --git a/setjmp/setjmp.h b/setjmp/setjmp.h new file mode 100644 index 0000000000..479cf973ec --- /dev/null +++ b/setjmp/setjmp.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.6 NON-LOCAL JUMPS <setjmp.h> + */ + +#ifndef _SETJMP_H + +#define _SETJMP_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get the machine-dependent definition of `__jmp_buf'. */ +#include <jmp_buf.h> +#include <sigset.h> /* Get `__sigset_t'. */ + +/* Calling environment, plus possibly a saved signal mask. */ +typedef struct + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf'. + Do not move this member or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + __sigset_t __saved_mask; /* Saved signal mask. */ + } jmp_buf[1]; + + +/* Store the calling environment in ENV, also saving the + signal mask if SAVEMASK is nonzero. Return 0. + This is the internal name for `sigsetjmp'. */ +extern int __sigsetjmp __P ((jmp_buf __env, int __savemask)); + +#ifndef __FAVOR_BSD +/* Set ENV to the current position and return 0, not saving the signal mask. + This is just like `sigsetjmp (ENV, 0)'. + The ANSI C standard says `setjmp' is a macro. */ +#define setjmp(env) __sigsetjmp ((env), 0) +#else +/* We are in 4.3 BSD-compatibility mode in which `setjmp' + saves the signal mask like `sigsetjmp (ENV, 1)'. */ +#define setjmp(env) __sigsetjmp ((env), 1) +#endif /* Favor BSD. */ + +#ifdef __USE_BSD +/* Set ENV to the current position and return 0, not saving the signal mask. + This is the 4.3 BSD name for ANSI `setjmp'. */ +#define _setjmp(env) __sigsetjmp ((env), 0) +#endif + + +/* Jump to the environment saved in ENV, making the + `setjmp' call there return VAL, or 1 if VAL is 0. */ +extern void longjmp __P ((jmp_buf __env, int __val)) + __attribute__ ((__noreturn__)); +#ifdef __USE_BSD +/* Same. Usually `_longjmp' is used with `_setjmp', which does not save + the signal mask. But it is how ENV was saved that determines whether + `longjmp' restores the mask; `_longjmp' is just an alias. */ +extern void _longjmp __P ((jmp_buf __env, int __val)) + __attribute__ ((__noreturn__)); +#endif /* Use BSD. */ + +/* Internal machine-dependent function to restore context sans signal mask. */ +extern void __longjmp __P ((__jmp_buf __env, int __val)) + __attribute__ ((__noreturn__)); + +/* Internal function to possibly save the current mask of blocked signals + in ENV, and always set the flag saying whether or not it was saved. + This is used by the machine-dependent definition of `__sigsetjmp'. + Always returns zero, for convenience. */ +extern int __sigjmp_save __P ((jmp_buf __env, int __savemask)); + + +#ifdef __USE_POSIX +/* Use the same type for `jmp_buf' and `sigjmp_buf'. + The `__mask_was_saved' flag determines whether + or not `longjmp' will restore the signal mask. */ +typedef jmp_buf sigjmp_buf; + +/* Store the calling environment in ENV, also saving the + signal mask if SAVEMASK is nonzero. Return 0. */ +#define sigsetjmp(env, savemask) __sigsetjmp ((env), (savemask)) + +/* Jump to the environment saved in ENV, making the + sigsetjmp call there return VAL, or 1 if VAL is 0. + Restore the signal mask if that sigsetjmp call saved it. + This is just an alias `longjmp'. */ +extern void siglongjmp __P ((sigjmp_buf __env, int __val)) + __attribute__ ((__noreturn__)); +#endif /* Use POSIX. */ + +__END_DECLS + +#endif /* setjmp.h */ diff --git a/setjmp/sigjmp.c b/setjmp/sigjmp.c new file mode 100644 index 0000000000..a01c4120da --- /dev/null +++ b/setjmp/sigjmp.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <setjmp.h> +#include <signal.h> + +/* This function is called by the `sigsetjmp' macro + before doing a `__setjmp' on ENV[0].__jmpbuf. + Always return zero. */ + +int +DEFUN(__sigjmp_save, (env, savemask), sigjmp_buf env AND int savemask) +{ + env[0].__mask_was_saved = (savemask && + __sigprocmask (SIG_BLOCK, (sigset_t *) NULL, + &env[0].__saved_mask) == 0); + + return 0; +} diff --git a/setjmp/tst-setjmp.c b/setjmp/tst-setjmp.c new file mode 100644 index 0000000000..ef6e1f5f9f --- /dev/null +++ b/setjmp/tst-setjmp.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <setjmp.h> +#include <stdlib.h> + +static jmp_buf env; +static int last_value = -1, lose = 0; + +void +DEFUN(jump, (val), int val) +{ + longjmp(env, val); +} + +int +DEFUN_VOID(main) +{ + int value; + + value = setjmp(env); + if (value != last_value + 1) + { + fputs("Shouldn't have ", stdout); + lose = 1; + } + last_value = value; + switch (value) + { + case 0: + puts("Saved environment."); + jump(0); + default: + printf("Jumped to %d.\n", value); + if (value < 10) + jump(value + 1); + } + + if (lose || value != 10) + puts("Test FAILED!"); + else + puts("Test succeeded!"); + exit(lose ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/sgtty.h b/sgtty.h new file mode 100644 index 0000000000..ffb62401cb --- /dev/null +++ b/sgtty.h @@ -0,0 +1 @@ +#include <misc/sgtty.h> diff --git a/signal.h b/signal.h new file mode 100644 index 0000000000..d9939c4e83 --- /dev/null +++ b/signal.h @@ -0,0 +1 @@ +#include <signal/signal.h> diff --git a/signal/.cvsignore b/signal/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/signal/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/signal/Makefile b/signal/Makefile new file mode 100644 index 0000000000..a6e89ad43c --- /dev/null +++ b/signal/Makefile @@ -0,0 +1,40 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for signal routines. +# +subdir := signal + +headers := signal.h sys/signal.h signum.h sigcontext.h sigaction.h sigset.h + +routines := signal raise killpg \ + sigaction sigprocmask kill \ + sigpending sigsuspend \ + sigblock sigsetmask sigpause sigvec \ + sigstack sigaltstack sigintr \ + sigsetops sigempty sigfillset sigaddset sigdelset sigismem \ + sigreturn \ + gsignal ssignal + +tests := tst-signal + +distribute := sigsetops.h + + +include ../Rules diff --git a/signal/gsignal.c b/signal/gsignal.c new file mode 100644 index 0000000000..f5b79a991d --- /dev/null +++ b/signal/gsignal.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <signal.h> + +#undef gsignal + +int +gsignal (sig) + int sig; +{ + return raise (sig); +} diff --git a/signal/sigaddset.c b/signal/sigaddset.c new file mode 100644 index 0000000000..b9ac34dd5b --- /dev/null +++ b/signal/sigaddset.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "sigsetops.h" + +/* Add SIGNO to SET. */ +int +DEFUN(sigaddset, (set, signo), sigset_t *set AND int signo) +{ + if (set == NULL || signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + return __sigaddset (set, signo); +} diff --git a/signal/sigdelset.c b/signal/sigdelset.c new file mode 100644 index 0000000000..07e880f9c4 --- /dev/null +++ b/signal/sigdelset.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "sigsetops.h" + +/* Add SIGNO to SET. */ +int +DEFUN(sigdelset, (set, signo), sigset_t *set AND int signo) +{ + if (set == NULL || signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + return __sigdelset (set, signo); +} diff --git a/signal/sigempty.c b/signal/sigempty.c new file mode 100644 index 0000000000..0ec129ded4 --- /dev/null +++ b/signal/sigempty.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "sigsetops.h" + +/* Clear all signals from SET. */ +int +DEFUN(sigemptyset, (set), sigset_t *set) +{ + if (set == NULL) + { + errno = EINVAL; + return -1; + } + + return __sigemptyset (set); +} diff --git a/signal/sigfillset.c b/signal/sigfillset.c new file mode 100644 index 0000000000..88c1833b55 --- /dev/null +++ b/signal/sigfillset.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "sigsetops.h" + +/* Set all signals in SET. */ +int +DEFUN(sigfillset, (set), sigset_t *set) +{ + if (set == NULL) + { + errno = EINVAL; + return -1; + } + + return __sigfillset (set); +} diff --git a/signal/sigismem.c b/signal/sigismem.c new file mode 100644 index 0000000000..36c04db5e2 --- /dev/null +++ b/signal/sigismem.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "sigsetops.h" + +/* Return 1 if SIGNO is in SET, 0 if not. */ +int +DEFUN(sigismember, (set, signo), CONST sigset_t *set AND int signo) +{ + if (set == NULL || signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + return __sigismember (set, signo); +} diff --git a/signal/signal.h b/signal/signal.h new file mode 100644 index 0000000000..a6db005721 --- /dev/null +++ b/signal/signal.h @@ -0,0 +1,248 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.7 SIGNAL HANDLING <signal.h> + */ + +#ifndef _SIGNAL_H + +#if !defined(__need_sig_atomic_t) && !defined(__need_sigset_t) +#define _SIGNAL_H 1 +#include <features.h> +#endif + +__BEGIN_DECLS + +#define __need_size_t +#include <stddef.h> + +#include <gnu/types.h> +#include <sigset.h> /* __sigset_t, __sig_atomic_t. */ + +#if !defined(__sig_atomic_t_defined) && \ + (defined(_SIGNAL_H) || defined(__need_sig_atomic_t)) +/* An integral type that can be modified atomically, without the + possibility of a signal arriving in the middle of the operation. */ +typedef __sig_atomic_t sig_atomic_t; +#endif /* `sig_atomic_t' undefined and <signal.h> or need `sig_atomic_t'. */ +#undef __need_sig_atomic_t + +#ifdef _SIGNAL_H + +#include <signum.h> + +/* Type of a signal handler. */ +typedef void (*__sighandler_t) __P ((int)); + +/* Set the handler for the signal SIG to HANDLER, + returning the old handler, or SIG_ERR on error. */ +extern __sighandler_t signal __P ((int __sig, __sighandler_t __handler)); + +/* Send signal SIG to process number PID. If PID is zero, + send SIG to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. */ +extern int __kill __P ((__pid_t __pid, int __sig)); +#ifdef __USE_POSIX +extern int kill __P ((__pid_t __pid, int __sig)); +#endif /* Use POSIX. */ + +#ifdef __USE_BSD +/* Send SIG to all processes in process group PGRP. + If PGRP is zero, send SIG to all processes in + the current process's process group. */ +extern int killpg __P ((__pid_t __pgrp, int __sig)); +#endif /* Use BSD. */ + +/* Raise signal SIG, i.e., send SIG to yourself. */ +extern int raise __P ((int __sig)); + +#ifdef __USE_SVID +/* SVID names for the same things. */ +extern __sighandler_t ssignal __P ((int __sig, __sighandler_t __handler)); +extern int gsignal __P ((int __sig)); +#endif /* Use SVID. */ + +#ifdef __USE_MISC +/* Print a message describing the meaning of the given signal number. */ +extern void psignal __P ((int __sig, __const char *__s)); +#endif /* Use misc. */ + + +/* Block signals in MASK, returning the old mask. */ +extern int __sigblock __P ((int __mask)); + +/* Set the mask of blocked signals to MASK, returning the old mask. */ +extern int __sigsetmask __P ((int __mask)); + +/* Set the mask of blocked signals to MASK, + wait for a signal to arrive, and then restore the mask. */ +extern int __sigpause __P ((int __mask)); + +#ifdef __USE_BSD +#define sigmask(sig) __sigmask(sig) + +extern int sigblock __P ((int __mask)); +extern int sigsetmask __P ((int __mask)); +extern int sigpause __P ((int __mask)); +#endif /* Use BSD. */ + + +#ifdef __USE_MISC +#define NSIG _NSIG +#endif + +#ifdef __USE_GNU +typedef __sighandler_t sighandler_t; +#endif + +#endif /* <signal.h> included. */ + + +#ifdef __USE_POSIX + +#if !defined(__sigset_t_defined) && \ + (defined(_SIGNAL_H) || defined(__need_sigset_t)) +typedef __sigset_t sigset_t; +#define __sigset_t_defined 1 +#endif /* `sigset_t' not defined and <signal.h> or need `sigset_t'. */ +#undef __need_sigset_t + +#ifdef _SIGNAL_H + +/* Clear all signals from SET. */ +extern int sigemptyset __P ((sigset_t *__set)); + +/* Set all signals in SET. */ +extern int sigfillset __P ((sigset_t *__set)); + +/* Add SIGNO to SET. */ +extern int sigaddset __P ((sigset_t *__set, int __signo)); + +/* Remove SIGNO from SET. */ +extern int sigdelset __P ((sigset_t *__set, int __signo)); + +/* Return 1 if SIGNO is in SET, 0 if not. */ +extern int sigismember __P ((__const sigset_t *__set, int signo)); + +#ifdef __OPTIMIZE__ +/* <sigset.h> defines the __ versions as macros that do the work. */ +#define sigemptyset(set) __sigemptyset(set) +#define sigfillset(set) __sigfillset(set) +#define sigaddset(set, signo) __sigaddset(set, signo) +#define sigdelset(set, signo) __sigdelset(set, signo) +#define sigismember(set, signo) __sigismember(set, signo) +#endif + +/* Get the system-specific definitions of `struct sigaction' + and the `SA_*' and `SIG_*'. constants. */ +#include <sigaction.h> + +/* Get and/or change the set of blocked signals. */ +extern int __sigprocmask __P ((int __how, + __const sigset_t *__set, sigset_t *__oset)); +extern int sigprocmask __P ((int __how, + __const sigset_t *__set, sigset_t *__oset)); + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +extern int sigsuspend __P ((__const sigset_t *__set)); + +/* Get and/or set the action for signal SIG. */ +extern int __sigaction __P ((int __sig, __const struct sigaction *__act, + struct sigaction *__oact)); +extern int sigaction __P ((int __sig, __const struct sigaction *__act, + struct sigaction *__oact)); + +/* Put in SET all signals that are blocked and waiting to be delivered. */ +extern int sigpending __P ((sigset_t *__set)); + +#endif /* <signal.h> included. */ + +#endif /* Use POSIX. */ + +#if defined(_SIGNAL_H) && defined(__USE_BSD) + +/* Structure passed to `sigvec'. */ +struct sigvec + { + __sighandler_t sv_handler; /* Signal handler. */ + int sv_mask; /* Mask of signals to be blocked. */ + + int sv_flags; /* Flags (see below). */ +#define sv_onstack sv_flags /* 4.2 BSD compatibility. */ + }; + +/* Bits in `sv_flags'. */ +#define SV_ONSTACK (1 << 0)/* Take the signal on the signal stack. */ +#define SV_INTERRUPT (1 << 1)/* Do not restart system calls. */ +#define SV_RESETHAND (1 << 2)/* Reset handler to SIG_DFL on receipt. */ + + +/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member + of VEC. The signals in `sv_mask' will be blocked while the handler runs. + If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be + reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, + it is filled in with the old information for SIG. */ +extern int __sigvec __P ((int __sig, __const struct sigvec *__vec, + struct sigvec *__ovec)); +extern int sigvec __P ((int __sig, __const struct sigvec *__vec, + struct sigvec *__ovec)); + + +/* If INTERRUPT is nonzero, make signal SIG interrupt system calls + (causing them to fail with EINTR); if INTERRUPT is zero, make system + calls be restarted after signal SIG. */ +extern int siginterrupt __P ((int __sig, int __interrupt)); + + +/* Structure describing a signal stack. */ +struct sigstack + { + __ptr_t ss_sp; /* Signal stack pointer. */ + int ss_onstack; /* Nonzero if executing on this stack. */ + }; + +/* Run signals handlers on the stack specified by SS (if not NULL). + If OSS is not NULL, it is filled in with the old signal stack status. */ +extern int sigstack __P ((__const struct sigstack *__ss, + struct sigstack *__oss)); + +/* Alternate interface. */ +struct sigaltstack + { + __ptr_t ss_sp; + size_t ss_size; + int ss_flags; + }; + +extern int sigaltstack __P ((__const struct sigaltstack *__ss, + struct sigaltstack *__oss)); + +/* Get machine-dependent `struct sigcontext' and signal subcodes. */ +#include <sigcontext.h> + +/* Restore the state saved in SCP. */ +extern int __sigreturn __P ((struct sigcontext *__scp)); +extern int sigreturn __P ((struct sigcontext *__scp)); + +#endif /* signal.h included and use BSD. */ + +__END_DECLS + +#endif /* signal.h */ diff --git a/signal/sigsetops.c b/signal/sigsetops.c new file mode 100644 index 0000000000..758ddd1e22 --- /dev/null +++ b/signal/sigsetops.c @@ -0,0 +1,6 @@ +/* Define the real-function versions of all inline functions + defined in signal.h (or sigset.h). */ + +#define _EXTERN_INLINE + +#include "signal.h" diff --git a/signal/sigsetops.h b/signal/sigsetops.h new file mode 100644 index 0000000000..972aa69c63 --- /dev/null +++ b/signal/sigsetops.h @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Definitions relevant to functions that operate on `sigset_t's. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <string.h> + +#define BITS (_NSIG - 1) +#define ELT(signo) (((signo) - 1) / BITS) +#define MASK(signo) (1 << (((signo) - 1) % BITS)) + +#undef sigemptyset +#undef sigfillset +#undef sigaddset +#undef sigdelset +#undef sigismember diff --git a/signal/ssignal.c b/signal/ssignal.c new file mode 100644 index 0000000000..54ab7f0f45 --- /dev/null +++ b/signal/ssignal.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <signal.h> + +#undef ssignal + +__sighandler_t +ssignal (sig, func) + int sig; + __sighandler_t func; +{ + return signal (sig, func); +} diff --git a/signal/sys/signal.h b/signal/sys/signal.h new file mode 100644 index 0000000000..2e602dad89 --- /dev/null +++ b/signal/sys/signal.h @@ -0,0 +1 @@ +#include <signal.h> diff --git a/signal/tst-signal.c b/signal/tst-signal.c new file mode 100644 index 0000000000..f622842f7a --- /dev/null +++ b/signal/tst-signal.c @@ -0,0 +1,44 @@ +#include <ansidecl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int win = 0; + +void +DEFUN(handler, (sig), int sig) +{ + printf("Received signal %d (%s).\n", sig, strsignal(sig)); + win = 1; +} + +int +DEFUN_VOID(main) +{ + if (signal(SIGTERM, handler) == SIG_ERR) + { + perror("signal: SIGTERM"); + exit(EXIT_FAILURE); + } + + puts("Set handler."); + + printf("Sending myself signal %d.\n", SIGTERM); + fflush(stdout); + + if (raise(SIGTERM) < 0) + { + perror("raise: SIGTERM"); + exit(EXIT_FAILURE); + } + + if (!win) + { + puts("Didn't get any signal. Test FAILED!"); + exit(EXIT_FAILURE); + } + + puts("Got a signal. Test succeeded."); + exit(EXIT_SUCCESS); +} diff --git a/socket/Makefile b/socket/Makefile new file mode 100644 index 0000000000..fa33a9d454 --- /dev/null +++ b/socket/Makefile @@ -0,0 +1,30 @@ +# Copyright (C) 1991, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for socket portion of the library. +# +subdir := socket + +headers := sys/socket.h sys/un.h sockaddrcom.h + +routines := accept bind connect getpeername getsockname getsockopt \ + listen recv recvfrom recvmsg send sendmsg sendto \ + setsockopt shutdown socket socketpair + +include ../Rules diff --git a/socket/sys/socket.h b/socket/sys/socket.h new file mode 100644 index 0000000000..65217216a0 --- /dev/null +++ b/socket/sys/socket.h @@ -0,0 +1,310 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_SOCKET_H + +#define _SYS_SOCKET_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_size_t +#include <stddef.h> + + +/* Types of sockets. */ +enum __socket_type +{ + SOCK_STREAM = 1, /* Sequenced, reliable, connection-based + byte streams. */ + SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams + of fixed maximum length. */ + SOCK_RAW = 3, /* Raw protocol interface. */ + SOCK_RDM = 4, /* Reliably-delivered messages. */ + SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, + datagrams of fixed maximum length. */ +}; + +/* Protocol families. */ +#define PF_UNSPEC 0 /* Unspecified. */ +#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ +#define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */ +#define PF_INET 2 /* IP protocol family. */ +#define PF_IMPLINK 3 /* ARPAnet IMP protocol. */ +#define PF_PUP 4 /* PUP protocols. */ +#define PF_CHAOS 5 /* MIT Chaos protocols. */ +#define PF_NS 6 /* Xerox NS protocols. */ +#define PF_ISO 7 /* ISO protocols. */ +#define PF_OSI PF_ISO +#define PF_ECMA 8 /* ECMA protocols. */ +#define PF_DATAKIT 9 /* AT&T Datakit protocols. */ +#define PF_CCITT 10 /* CCITT protocols (X.25 et al). */ +#define PF_SNA 11 /* IBM SNA protocol. */ +#define PF_DECnet 12 /* DECnet protocols. */ +#define PF_DLI 13 /* Direct data link interface. */ +#define PF_LAT 14 /* DEC Local Area Transport protocol. */ +#define PF_HYLINK 15 /* NSC Hyperchannel protocol. */ +#define PF_APPLETALK 16 /* Don't use this. */ +#define PF_ROUTE 17 /* Internal Routing Protocol. */ +#define PF_LINK 18 /* Link layer interface. */ +#define PF_XTP 19 /* eXpress Transfer Protocol (no AF). */ +#define PF_COIP 20 /* Connection-oriented IP, aka ST II. */ +#define PF_CNT 21 /* Computer Network Technology. */ +#define PF_RTIP 22 /* Help Identify RTIP packets. **/ +#define PF_IPX 23 /* Novell Internet Protocol. */ +#define PF_SIP 24 /* Simple Internet Protocol. */ +#define PF_PIP 25 /* Help Identify PIP packets. */ +#define PF_MAX 26 + +/* Address families. */ +#define AF_UNSPEC PF_UNSPEC +#define AF_LOCAL PF_LOCAL +#define AF_UNIX PF_UNIX +#define AF_INET PF_INET +#define AF_IMPLINK PF_IMPLINK +#define AF_PUP PF_PUP +#define AF_CHAOS PF_CHAOS +#define AF_NS PF_NS +#define AF_ISO PF_ISO +#define AF_OSI PF_OSI +#define AF_ECMA PF_ECMA +#define AF_DATAKIT PF_DATAKIT +#define AF_CCITT PF_CCITT +#define AF_SNA PF_SNA +#define AF_DECnet PF_DECnet +#define AF_DLI PF_DLI +#define AF_LAT PF_LAT +#define AF_HYLINK PF_HYLINK +#define AF_APPLETALK PF_APPLETALK +#define AF_ROUTE PF_ROUTE +#define AF_LINK PF_LINK +#define pseudo_AF_XTP PF_XTP +#define AF_COIP PF_COIP +#define AF_CNT PF_CNT +#define pseudo_AF_RTIP PF_RTIP +#define AF_IPX PF_IPX +#define AF_SIP PF_SIP +#define pseudo_AF_PIP PF_PIP +#define AF_MAX PF_MAX + + +/* Get the definition of the macro to define the common sockaddr members. */ +#include <sockaddrcom.h> + +/* Structure describing a generic socket address. */ +struct sockaddr + { + __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ + char sa_data[14]; /* Address data. */ + }; + +/* This is the type we use for generic socket address arguments. + + NOTE: Since this functionality is volatile, I'm disabling the use of it for + now. + + With GCC 2.6 and later, the funky union causes redeclarations or uses with + any of the listed types to be allowed without complaint. */ +#if (!defined (__GNUC__) || __GNUC__ < 2 || \ + /*(__GNUC__ == 2 && __GNUC_MINOR__ < 6)*/ 1) +#define __SOCKADDR_ARG struct sockaddr * +#else +/* Bring these names into being at top-level scope, in case they have not been + defined yet. Add more `struct sockaddr_AF' types here as necessary. */ +struct sockaddr_in; +struct sockaddr_un; +struct sockaddr_ns; +typedef union { struct sockaddr *__sa; + struct sockaddr_in *__sa_in; + struct sockaddr_un *__sa_un; + struct sockaddr_ns *__sa_ns; + } __SOCKADDR_ARG __attribute__ ((transparent_union)); +#endif + + +/* Create a new socket of type TYPE in domain DOMAIN, using + protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. + Returns a file descriptor for the new socket, or -1 for errors. */ +extern int socket __P ((int __domain, enum __socket_type __type, + int __protocol)); + +/* Create two new sockets, of type TYPE in domain DOMAIN and using + protocol PROTOCOL, which are connected to each other, and put file + descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, + one will be chosen automatically. Returns 0 on success, -1 for errors. */ +extern int socketpair __P ((int __domain, enum __socket_type __type, + int __protocol, int __fds[2])); + +/* Give the socket FD the local address ADDR (which is LEN bytes long). */ +extern int bind __P ((int __fd, __SOCKADDR_ARG __addr, size_t __len)); + +/* Put the local address of FD into *ADDR and its length in *LEN. */ +extern int getsockname __P ((int __fd, __SOCKADDR_ARG __addr, + size_t *__len)); + +/* Open a connection on socket FD to peer at ADDR (which LEN bytes long). + For connectionless socket types, just set the default address to send to + and the only address from which to accept transmissions. + Return 0 on success, -1 for errors. */ +extern int connect __P ((int __fd, __SOCKADDR_ARG __addr, size_t __len)); + +/* Put the address of the peer connected to socket FD into *ADDR + (which is *LEN bytes long), and its actual length into *LEN. */ +extern int getpeername __P ((int __fd, __SOCKADDR_ARG __addr, + size_t *__len)); + + +/* Bits in the FLAGS argument to `send', `recv', et al. */ +enum + { + MSG_OOB = 0x01, /* Process out-of-band data. */ + MSG_PEEK = 0x02, /* Peek at incoming messages. */ + MSG_DONTROUTE = 0x04, /* Don't use local routing. */ + MSG_EOR = 0x08, /* Data completes record. */ + MSG_TRUNC = 0x10, /* Data discarded before delivery. */ + MSG_CTRUNC = 0x20, /* Control data lost before delivery. */ + MSG_WAITALL = 0x40, /* Wait for full request or error. */ + MSG_DONTWAIT = 0x80, /* This message should be nonblocking. */ + }; + +/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ +extern int send __P ((int __fd, __ptr_t __buf, size_t __n, int __flags)); + +/* Read N bytes into BUF from socket FD. + Returns the number read or -1 for errors. */ +extern int recv __P ((int __fd, __ptr_t __buf, size_t __n, int __flags)); + +/* Send N bytes of BUF on socket FD to peer at address ADDR (which is + ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ +extern int sendto __P ((int __fd, __ptr_t __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, size_t __addr_len)); + +/* Read N bytes into BUF through socket FD. + If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of + the sender, and store the actual size of the address in *ADDR_LEN. + Returns the number of bytes read or -1 for errors. */ +extern int recvfrom __P ((int __fd, __ptr_t __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, size_t *__addr_len)); + + + +/* Structure describing messages sent by + `sendmsg' and received by `recvmsg'. */ +struct msghdr + { + __ptr_t msg_name; /* Address to send to/receive from. */ + size_t msg_namelen; /* Length of address data. */ + + struct iovec *msg_iov; /* Vector of data to send/receive into. */ + size_t msg_iovlen; /* Number of elements in the vector. */ + + __ptr_t msg_accrights; /* Access rights information. */ + size_t msg_accrightslen; /* Length of access rights information. */ + }; + +/* Send a message described MESSAGE on socket FD. + Returns the number of bytes sent, or -1 for errors. */ +extern int sendmsg __P ((int __fd, __const struct msghdr *__message, + int __flags)); + +/* Receive a message as described by MESSAGE from socket FD. + Returns the number of bytes read or -1 for errors. */ +extern int recvmsg __P ((int __fd, struct msghdr *__message, int __flags)); + + +/* Protocol number used to manipulate socket-level options + with `getsockopt' and `setsockopt'. */ +#define SOL_SOCKET 0xffff + +/* Socket-level options for `getsockopt' and `setsockopt'. */ +enum + { + SO_DEBUG = 0x0001, /* Record debugging information. */ + SO_ACCEPTCONN = 0x0002, /* Accept connections on socket. */ + SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */ + SO_KEEPALIVE = 0x0008, /* Keep connections alive and send + SIGPIPE when they die. */ + SO_DONTROUTE = 0x0010, /* Don't do local routing. */ + SO_BROADCAST = 0x0020, /* Allow transmission of + broadcast messages. */ + SO_USELOOPBACK = 0x0040, /* Use the software loopback to avoid + hardware use when possible. */ + SO_LINGER = 0x0080, /* Block on close of a reliable + socket to transmit pending data. */ + SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */ + + SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */ + + SO_SNDBUF = 0x1001, /* Send buffer size. */ + SO_RCVBUF = 0x1002, /* Receive buffer. */ + SO_SNDLOWAT = 0x1003, /* Send low-water mark. */ + SO_RCVLOWAT = 0x1004, /* Receive low-water mark. */ + SO_SNDTIMEO = 0x1005, /* Send timeout. */ + SO_RCVTIMEO = 0x1006, /* Receive timeout. */ + + SO_ERROR = 0x1007, /* Get and clear error status. */ + SO_STYLE = 0x1008, /* Get socket connection style. */ + SO_TYPE = SO_STYLE, /* Compatible name for SO_STYLE. */ + }; + +/* Structure used to manipulate the SO_LINGER option. */ +struct linger + { + int l_onoff; /* Nonzero to linger on close. */ + int l_linger; /* Time to linger. */ + }; + + +/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL + into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's + actual length. Returns 0 on success, -1 for errors. */ +extern int getsockopt __P ((int __fd, int __level, int __optname, + __ptr_t __optval, size_t *__optlen)); + +/* Set socket FD's option OPTNAME at protocol level LEVEL + to *OPTVAL (which is OPTLEN bytes long). + Returns 0 on success, -1 for errors. */ +extern int setsockopt __P ((int __fd, int __level, int __optname, + __ptr_t __optval, size_t __optlen)); + + +/* Prepare to accept connections on socket FD. + N connection requests will be queued before further requests are refused. + Returns 0 on success, -1 for errors. */ +extern int listen __P ((int __fd, unsigned int __n)); + +/* Await a connection on socket FD. + When a connection arrives, open a new socket to communicate with it, + set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting + peer and *ADDR_LEN to the address's actual length, and return the + new socket's descriptor, or -1 for errors. */ +extern int accept __P ((int __fd, __SOCKADDR_ARG __addr, + size_t *__addr_len)); + +/* Shut down all or part of the connection open on socket FD. + HOW determines what to shut down: + 0 = No more receptions; + 1 = No more transmissions; + 2 = No more receptions or transmissions. + Returns 0 on success, -1 for errors. */ +extern int shutdown __P ((int __fd, int __how)); + + +__END_DECLS + +#endif /* sys/socket.h */ diff --git a/socket/sys/un.h b/socket/sys/un.h new file mode 100644 index 0000000000..022a286bb5 --- /dev/null +++ b/socket/sys/un.h @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_UN_H + +#define _SYS_UN_H 1 + +/* Get the definition of the macro to define the common sockaddr members. */ +#include <sockaddrcom.h> + +/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ +struct sockaddr_un + { + __SOCKADDR_COMMON (sun_); + char sun_path[108]; /* Path name. */ + }; + +#endif /* sys/un.h */ diff --git a/stdio.h b/stdio.h new file mode 100644 index 0000000000..a82be070c3 --- /dev/null +++ b/stdio.h @@ -0,0 +1 @@ +#include <stdio/stdio.h> diff --git a/stdio/.cvsignore b/stdio/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/stdio/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/stdio/Makefile b/stdio/Makefile new file mode 100644 index 0000000000..579426186f --- /dev/null +++ b/stdio/Makefile @@ -0,0 +1,114 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Specific makefile for stdio. +# +subdir := stdio + +headers := stdio.h stdio_lim.h printf.h + +routines := \ + ctermid cuserid \ + feof ferror clearerr fileno \ + newstream fopen freopen fdopen fopncook fmemopen \ + setbuf setvbuf setbuffer setlinebuf \ + fseek ftell rewind fgetpos fsetpos \ + vfprintf vprintf printf_fp reg-printf printf-prs _itoa \ + vsnprintf vsprintf vasprintf \ + fprintf printf snprintf sprintf asprintf \ + dprintf vdprintf \ + vfscanf vscanf vsscanf \ + fscanf scanf sscanf \ + fread fwrite \ + ungetc \ + fgetc getc getchar getw \ + fputc putc putchar putw \ + fgets gets fputs puts \ + getdelim getline \ + perror psignal \ + tmpfile tmpnam tempnam tempname \ + fclose fflush \ + remove rename \ + memstream obstream \ + internals sysd-stdio pipestream stdio_init libc_fatal + +# Several mpn functions from GNU MP are used by the printf_fp function. +mpn-routines := add_1 add_n addmul_1 cmp divmod divmod_1 udiv_qrnnd \ + lshift rshift mod_1 mul mul_1 mul_n sub_n submul_1 +mpn-headers = longlong.h gmp.h gmp-impl.h gmp-mparam.h asm-syntax.h + +routines := $(strip $(routines) $(mpn-routines)) \ + dbl2mpn ldbl2mpn \ + mpn2flt mpn2dbl mpn2ldbl +aux := errlist siglist defs glue mp_clz_tab fpioconst +distribute = $(mpn-headers) gen-mpn-copy _itoa.h fpioconst.h + +tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \ + temptest tst-fileno test-fwrite \ + xbug errnobug \ + bug1 bug2 bug3 bug4 bug5 bug6 bug7 + + +include ../Rules + + +ifdef gmp-srcdir + +gmp-srcdir := $(firstword $(filter-out ..//%,$(..)$(gmp-srcdir) $(gmp-srcdir))) + +# Copy the mpn source files we use from the GNU MP source directory. +# `gmp-srcdir' is set by doing `configure --with-gmp=DIR'. +# (Do not try this at home. You need an as yet unreleased version of GNU MP.) + +mpn-sysdep := $(addsuffix .c,$(mpn-routines)) \ + $(addsuffix .S,$(mpn-routines)) \ + $(addsuffix .s,$(mpn-routines)) gmp-mparam.h asm-syntax.h + +mpn-try := $(addprefix $(gmp-srcdir)/mpn/*/,$(mpn-sysdep)) +mpn-found := $(wildcard $(mpn-try)) +mpn-found := $(filter-out $(patsubst %.S,%.s,$(filter %.s,$(mpn-found))),\ + $(mpn-found)) + +include mpn-copy.mk +%.mk: gen-%; sh $< > $@ + +mpn-copy-1 := $(patsubst $(gmp-srcdir)/mpn/%,$(sysdep_dir)/%,$(mpn-found)) +mpn-copy-sysdep := $(mpn-copy-sysdep) $(mpn-copy-1) +$(mpn-copy-1): $(sysdep_dir)/%: $(ignore gmp2glibc.sed) $(gmp-srcdir)/mpn/% + $(gmp2glibc) + +mpn-stuff = $(mpn-copy-sysdep) $(mpn-copy) + +# chmod so I don't edit them by mistake. +define gmp2glibc +$(ignore sed -f $^ > $@-tmp) +cp $< $@-tmp +chmod a-w $@-tmp +mv -f $@-tmp $@ +endef + +mpn-copy = $(filter-out $(mpn-sysdep),$(mpn-headers) mp_clz_tab.c) +$(mpn-copy): %: $(ignore gmp2glibc.sed) $(gmp-srcdir)/%; $(gmp2glibc) + +.PHONY: copy-mpn clean-mpn +copy-mpn: $(mpn-stuff) +clean-mpn: + rm -f $(mpn-stuff) + +endif diff --git a/stdio/_itoa.c b/stdio/_itoa.c new file mode 100644 index 0000000000..b781b1ea88 --- /dev/null +++ b/stdio/_itoa.c @@ -0,0 +1,45 @@ +/* Internal function for converting integers to ASCII. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include "_itoa.h" + +/* Lower-case digits. */ +CONST char _itoa_lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +/* Upper-case digits. */ +CONST char _itoa_upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +char * +DEFUN(_itoa, (value, buflim, base, upper_case), + unsigned long long int value AND char *buflim AND + unsigned int base AND int upper_case) +{ + /* Base-36 digits for numbers. */ + CONST char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits; + + register char *bp = buflim; + + while (value > 0) + { + *--bp = digits[value % base]; + value /= base; + } + + return bp; +} diff --git a/stdio/_itoa.h b/stdio/_itoa.h new file mode 100644 index 0000000000..791ce6c87f --- /dev/null +++ b/stdio/_itoa.h @@ -0,0 +1,54 @@ +/* Internal function for converting integers to ASCII. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _ITOA_H +#define _ITOA_H +#include <sys/cdefs.h> + +extern const char _itoa_lower_digits[], _itoa_upper_digits[]; + +/* Convert VALUE into ASCII in base BASE (2..36). + Write backwards starting the character just before BUFLIM. + Return the address of the first (left-to-right) character in the number. + Use upper case letters iff UPPER_CASE is nonzero. */ + +extern char *_itoa __P ((unsigned long long int value, char *buflim, + unsigned int base, int upper_case)); + +#if defined (__GNUC__) && defined (__OPTIMIZE__) +extern __inline char * +_itoa (unsigned long long int value, char *buflim, + unsigned int base, int upper_case) +{ + /* Base-36 digits for numbers. */ + const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits; + + register char *bp = buflim; + + while (value > 0) + { + *--bp = digits[value % base]; + value /= base; + } + + return bp; +} +#endif + +#endif /* itoa.h */ diff --git a/stdio/asprintf.c b/stdio/asprintf.c new file mode 100644 index 0000000000..9b69800f73 --- /dev/null +++ b/stdio/asprintf.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output from FORMAT to a string which is + allocated with malloc and stored in *STRING_PTR. */ +/* VARARGS2 */ +int +DEFUN(asprintf, (string_ptr, format), + char **string_ptr AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vasprintf(string_ptr, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/bug1.c b/stdio/bug1.c new file mode 100644 index 0000000000..755bc4231b --- /dev/null +++ b/stdio/bug1.c @@ -0,0 +1,28 @@ +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + +int +DEFUN_VOID(main) +{ + char *bp; + size_t size; + FILE *stream; + int lose = 0; + + stream = open_memstream (&bp, &size); + fprintf (stream, "hello"); + fflush (stream); + printf ("buf = %s, size = %d\n", bp, size); + lose |= size != 5; + lose |= strncmp (bp, "hello", size); + fprintf (stream, ", world"); + fclose (stream); + printf ("buf = %s, size = %d\n", bp, size); + lose |= size != 12; + lose |= strncmp (bp, "hello, world", 12); + + puts (lose ? "Test FAILED!" : "Test succeeded."); + + return lose; +} diff --git a/stdio/bug1.input b/stdio/bug1.input new file mode 100644 index 0000000000..5595fa46c0 --- /dev/null +++ b/stdio/bug1.input @@ -0,0 +1 @@ +95 diff --git a/stdio/bug2.c b/stdio/bug2.c new file mode 100644 index 0000000000..2b34c890bf --- /dev/null +++ b/stdio/bug2.c @@ -0,0 +1,12 @@ +#include <ansidecl.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + int i; + puts ("This should print \"wow = I\" for I from 0 to 39 inclusive."); + for (i = 0; i < 40; i++) + printf ("%s = %d\n", "wow", i); + return 0; +} diff --git a/stdio/bug3.c b/stdio/bug3.c new file mode 100644 index 0000000000..0f3c7f1087 --- /dev/null +++ b/stdio/bug3.c @@ -0,0 +1,52 @@ +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + +int +DEFUN_VOID(main) +{ + FILE *f; + int i; + + f = fopen("bugtest", "w+"); + for (i=0; i<9000; i++) + putc ('x', f); + fseek (f, 8180L, 0); + fwrite ("Where does this text go?", 1, 24, f); + fflush (f); + + rewind (f); + for (i=0; i<9000; i++) + { + int j; + + if ((j = getc(f)) != 'x') + { + if (i != 8180) + { + printf ("Test FAILED!"); + return 1; + } + else + { + char buf[25]; + + buf[0] = j; + fread (buf + 1, 1, 23, f); + buf[24] = '\0'; + if (strcmp (buf, "Where does this text go?") != 0) + { + printf ("%s\nTest FAILED!\n", buf); + return 1; + } + i += 23; + } + } + } + + fclose(f); + + puts ("Test succeeded."); + + return 0; +} diff --git a/stdio/bug4.c b/stdio/bug4.c new file mode 100644 index 0000000000..8e67f1d7b9 --- /dev/null +++ b/stdio/bug4.c @@ -0,0 +1,50 @@ +#ifdef _LIBC +#include <ansidecl.h> +#endif +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +int stdio_block_read = 1, stdio_block_write = 1; + +int +DEFUN(main, (argc, argv), + int argc AND char **argv) +{ + FILE *f; + int i; + char buffer[31]; + + while ((i = getopt (argc, argv, "rw")) != EOF) + switch (i) + { + case 'r': + stdio_block_read = 0; + break; + case 'w': + stdio_block_write = 0; + break; + } + + f = fopen("bugtest", "w+"); + for (i=0; i<9000; i++) { + putc('x', f); + } + fseek(f, 8180L, 0); + fwrite("Where does this text come from?", 1, 31, f); + fseek(f, 8180L, 0); + fread(buffer, 1, 31, f); + fwrite(buffer, 1, 31, stdout); + fclose(f); + + if (!memcmp (buffer, "Where does this text come from?", 31)) + { + puts ("\nTest succeeded."); + return 0; + } + else + { + puts ("\nTest FAILED!"); + return 1; + } +} diff --git a/stdio/bug5.c b/stdio/bug5.c new file mode 100644 index 0000000000..218af31352 --- /dev/null +++ b/stdio/bug5.c @@ -0,0 +1,60 @@ +/* If stdio is working correctly, after this is run infile and outfile + will have the same contents. If the bug (found in GNU C library 0.3) + exhibits itself, outfile will be missing the 2nd through 1023rd + characters. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static char buf[8192]; + +int +DEFUN_VOID(main) +{ + FILE *in; + FILE *out; + static char inname[] = "infile"; + static char outname[] = "outfile"; + int i; + + /* Create a test file. */ + in = fopen (inname, "w+"); + if (in == NULL) + { + perror (inname); + return 1; + } + for (i = 0; i < 1000; ++i) + fprintf (in, "%d\n", i); + + out = fopen (outname, "w"); + if (out == NULL) + { + perror (outname); + return 1; + } + if (fseek (in, 0L, SEEK_SET) != 0) + abort (); + putc (getc (in), out); + i = fread (buf, 1, sizeof (buf), in); + if (i == 0) + { + perror ("fread"); + return 1; + } + if (fwrite (buf, 1, i, out) != i) + { + perror ("fwrite"); + return 1; + } + fclose (in); + fclose (out); + + puts ("There should be no further output from this test."); + fflush (stdout); + execlp ("cmp", "cmp", inname, outname, (char *) NULL); + perror ("execlp: cmp"); + exit (1); +} diff --git a/stdio/bug6.c b/stdio/bug6.c new file mode 100644 index 0000000000..4a37ab2584 --- /dev/null +++ b/stdio/bug6.c @@ -0,0 +1,27 @@ +#include <ansidecl.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + char buf[80]; + int i; + int lost = 0; + + scanf ("%2s", buf); + lost |= (buf[0] != 'X' || buf[1] != 'Y' || buf[2] != '\0'); + if (lost) + puts ("test of %2s failed."); + scanf (" "); + scanf ("%d", &i); + lost |= (i != 1234); + if (lost) + puts ("test of %d failed."); + scanf ("%c", buf); + lost |= (buf[0] != 'L'); + if (lost) + puts ("test of %c failed.\n"); + + puts (lost ? "Test FAILED!" : "Test succeeded."); + return lost; +} diff --git a/stdio/bug6.input b/stdio/bug6.input new file mode 100644 index 0000000000..d996e399c3 --- /dev/null +++ b/stdio/bug6.input @@ -0,0 +1 @@ +XY 1234L diff --git a/stdio/bug7.c b/stdio/bug7.c new file mode 100644 index 0000000000..af06f8d6a5 --- /dev/null +++ b/stdio/bug7.c @@ -0,0 +1,53 @@ +/* Regression test for fseek and freopen bugs. */ + +#include <stdio.h> + +int +main () +{ + int lose = 0; + char filename[] = "/tmp/foo"; + FILE *fp; + + fp = fopen (filename, "w+"); + fprintf (fp, "Hello world!\n"); + fflush (fp); + fseek (fp, 5L, SEEK_SET); + if (fseek (fp, -1L, SEEK_CUR) < 0) + { + printf ("seek failed\n"); + lose = 1; + } + fclose (fp); + remove (filename); + + { + FILE *file1; + FILE *file2; + char filename1[] = "/tmp/foo"; + char filename2[] = "/tmp/bar"; + int ch; + + file1 = fopen (filename1, "w"); + fclose (file1); + + file2 = fopen (filename2, "w"); + fputc ('x', file2); + fclose (file2); + + file1 = fopen (filename1, "r"); + file2 = freopen (filename2, "r", file1); + if ((ch = fgetc (file2)) != 'x') + { + printf ("wrong character in reopened file, value = %d\n", ch); + lose = 1; + } + fclose (file1); + fclose (file2); + remove (filename1); + remove (filename2); + } + + puts (lose ? "Test FAILED!" : "Test succeeded."); + return lose; +} diff --git a/stdio/clearerr.c b/stdio/clearerr.c new file mode 100644 index 0000000000..1a9feaa413 --- /dev/null +++ b/stdio/clearerr.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +#undef clearerr + + +/* Clear the EOF and error indicators for STREAM. */ +void +DEFUN(clearerr, (stream), FILE *stream) +{ + __clearerr(stream); +} diff --git a/stdio/dprintf.c b/stdio/dprintf.c new file mode 100644 index 0000000000..fc9faa4ca2 --- /dev/null +++ b/stdio/dprintf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output to D, according to the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(dprintf, (d, format), int d AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vdprintf(d, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/errnobug.c b/stdio/errnobug.c new file mode 100644 index 0000000000..cf17be30a2 --- /dev/null +++ b/stdio/errnobug.c @@ -0,0 +1,60 @@ +/* Regression test for reported old bug that errno is clobbered + by the first successful output to a stream on an unseekable object. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +int +main (void) +{ + int fd[2]; + FILE *f; + + /* Get a stream that cannot seek. */ + + if (pipe (fd)) + { + perror ("pipe"); + return 1; + } + f = fdopen (fd[1], "w"); + if (f == NULL) + { + perror ("fdopen"); + return 1; + } + + errno = 0; + if (fputs ("fnord", f)) + { + perror ("fputs"); + return 1; + } + + if (errno) + { + perror ("errno gratuitously set -- TEST FAILED"); + return 1; + } + + puts ("Test succeeded."); + return 0; +} diff --git a/stdio/fclose.c b/stdio/fclose.c new file mode 100644 index 0000000000..becb85802f --- /dev/null +++ b/stdio/fclose.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Close a stream. */ +int +DEFUN(fclose, (stream), register FILE *stream) +{ + int status; + + if (stream == NULL) + { + /* Close all streams. */ + register FILE *f; + for (f = __stdio_head; f != NULL; f = f->__next) + if (__validfp(f)) + (void) fclose(f); + return 0; + } + + if (!__validfp(stream)) + { + errno = EINVAL; + return EOF; + } + + if (stream->__mode.__write && + /* Flush the buffer. */ + __flshfp (stream, EOF) == EOF) + return EOF; + + /* Free the buffer's storage. */ + if (stream->__buffer != NULL && !stream->__userbuf) + free(stream->__buffer); + + /* Close the system file descriptor. */ + if (stream->__io_funcs.__close != NULL) + status = (*stream->__io_funcs.__close)(stream->__cookie); + else if (!stream->__seen && stream->__cookie != NULL) + status = __stdio_close(stream->__cookie); + else + status = 0; + + /* Nuke the stream, making it available for re-use. */ + __invalidate(stream); + + return status < 0 ? EOF : 0; +} diff --git a/stdio/feof.c b/stdio/feof.c new file mode 100644 index 0000000000..c18300f6b5 --- /dev/null +++ b/stdio/feof.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +#undef feof + + +/* Return non-zero if STREAM has its EOF indicator set. */ +int +DEFUN(feof, (stream), FILE *stream) +{ + if (!__validfp(stream)) + { + errno = EINVAL; + return(-1); + } + + return(stream->__eof); +} diff --git a/stdio/ferror.c b/stdio/ferror.c new file mode 100644 index 0000000000..ed8f74401a --- /dev/null +++ b/stdio/ferror.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +#undef ferror + + +/* Return non-zero if STREAM has its error indicator set. */ +int +DEFUN(ferror, (stream), FILE *stream) +{ + if (!__validfp(stream)) + { + errno = EINVAL; + return(-1); + } + + return(stream->__error); +} diff --git a/stdio/fflush.c b/stdio/fflush.c new file mode 100644 index 0000000000..a6d52ba3e7 --- /dev/null +++ b/stdio/fflush.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +/* Flush STREAM's buffer. + If STREAM is NULL, flush the buffers of all streams that are writing. */ +int +DEFUN(fflush, (stream), register FILE *stream) +{ + if (stream == NULL) + { + int lossage = 0; + for (stream = __stdio_head; stream != NULL; stream = stream->__next) + if (__validfp(stream) && stream->__mode.__write) + lossage |= fflush(stream) == EOF; + return lossage ? EOF : 0; + } + + if (!__validfp(stream) || !stream->__mode.__write) + { + errno = EINVAL; + return EOF; + } + + return __flshfp(stream, EOF); +} diff --git a/stdio/fgetc.c b/stdio/fgetc.c new file mode 100644 index 0000000000..7f01090294 --- /dev/null +++ b/stdio/fgetc.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Read a character from STREAM. */ +int +DEFUN(fgetc, (stream), FILE *stream) +{ + if (!__validfp(stream) || !stream->__mode.__read) + { + errno = EINVAL; + return EOF; + } + + return __getc(stream); +} diff --git a/stdio/fgetpos.c b/stdio/fgetpos.c new file mode 100644 index 0000000000..cb6a1588ba --- /dev/null +++ b/stdio/fgetpos.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +#undef fgetpos + + +/* Put the current position of STREAM in *POS. */ +int +DEFUN(fgetpos, (stream, pos), FILE *stream AND fpos_t *pos) +{ + if (!__validfp(stream) || pos == NULL) + { + errno = EINVAL; + return(-1); + } + + *pos = ftell(stream); + if (*pos < 0L) + return(-1); + return(0); +} diff --git a/stdio/fgets.c b/stdio/fgets.c new file mode 100644 index 0000000000..e9e53c88dd --- /dev/null +++ b/stdio/fgets.c @@ -0,0 +1,121 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +/* Reads characters from STREAM into S, until either a newline character + is read, N - 1 characters have been read, or EOF is seen. Returns + the newline, unlike gets. Finishes by appending a null character and + returning S. If EOF is seen before any characters have been written + to S, the function returns NULL without appending the null character. + If there is a file error, always return NULL. */ +char * +DEFUN(fgets, (s, n, stream), char *s AND int n AND register FILE *stream) +{ + register char *p = s; + + if (!__validfp(stream) || s == NULL || n <= 0) + { + errno = EINVAL; + return NULL; + } + + if (ferror (stream)) + return NULL; + + if (stream->__buffer == NULL && stream->__userbuf) + { + /* Unbuffered stream. Not much optimization to do. */ + register int c = 0; + while (--n > 0 && (c = getc (stream)) != EOF) + if ((*p++ = c) == '\n') + break; + if (c == EOF && (p == s || ferror (stream))) + return NULL; + *p = '\0'; + return s; + } + + /* Leave space for the null. */ + --n; + + if (n > 0 && + (!stream->__seen || stream->__buffer == NULL || stream->__pushed_back)) + { + /* Do one with getc to allocate a buffer. */ + int c = getc (stream); + if (c == EOF) + return NULL; + *p++ = c; + if (c == '\n') + { + *p = '\0'; + return s; + } + else + --n; + } + + while (n > 0) + { + size_t i; + char *found; + + i = stream->__get_limit - stream->__bufp; + if (i == 0) + { + /* Refill the buffer. */ + int c = __fillbf (stream); + if (c == EOF) + break; + *p++ = c; + --n; + if (c == '\n') + { + *p = '\0'; + return s; + } + i = stream->__get_limit - stream->__bufp; + } + + if (i > n) + i = n; + + found = (char *) __memccpy ((PTR) p, stream->__bufp, '\n', i); + + if (found != NULL) + { + stream->__bufp += found - p; + p = found; + break; + } + + stream->__bufp += i; + n -= i; + p += i; + } + + if (p == s) + return NULL; + + *p = '\0'; + return ferror (stream) ? NULL : s; +} diff --git a/stdio/fileno.c b/stdio/fileno.c new file mode 100644 index 0000000000..da55300c8b --- /dev/null +++ b/stdio/fileno.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +/* Return the system file descriptor associated with STREAM. */ +int +DEFUN(fileno, (stream), FILE *stream) +{ + extern void __stdio_check_funcs __P ((FILE *)); + + if (! __validfp (stream)) + { + errno = EINVAL; + return -1; + } + + __stdio_check_funcs (stream); + + if (stream->__io_funcs.__fileno == NULL) + { +#ifdef EOPNOTSUPP + errno = EOPNOTSUPP; +#else + errno = ENOSYS; +#endif + return -1; + } + + return (*stream->__io_funcs.__fileno) (stream->__cookie); +} diff --git a/stdio/fmemopen.c b/stdio/fmemopen.c new file mode 100644 index 0000000000..42a137a2c8 --- /dev/null +++ b/stdio/fmemopen.c @@ -0,0 +1,108 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Defined in fopen.c. */ +extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr)); + +/* Open a new stream that will read and/or write from the buffer in + S, which is of LEN bytes. If the mode indicates appending, the + buffer pointer is set to point to the first '\0' in the buffer. + If S is NULL, the buffer is allocated by malloc and will be freed + when the stream is closed. The only purpose of this is to write + things and then read what's been written. If LEN is zero, writes will + always return errors and reads will always return end-of-file. + + The stream is set up such that seeks and tells will always fail and + once the buffer is full of written characters or empty of characters + to read, attempted writes always return an output error and attempted + reads always return end-of-file. */ +FILE * +DEFUN(fmemopen, (s, len, mode), + PTR s AND size_t len AND CONST char *mode) +{ + __io_mode m; + register FILE *stream; + + if (!__getmode (mode, &m)) + return NULL; + + stream = __newstream (); + if (stream == NULL) + return NULL; + + stream->__mode = m; + + /* Input gets EOF. */ + stream->__room_funcs.__input = NULL; + /* Output gets error. */ + stream->__room_funcs.__output = NULL; + + /* Do nothing for close. */ + stream->__io_funcs.__close = NULL; + /* Can't seek outside the buffer. */ + stream->__io_funcs.__seek = NULL; + /* There is no associated file descriptor to fetch. */ + stream->__io_funcs.__fileno = NULL; + + stream->__seen = 1; + + stream->__userbuf = s != NULL && len > 0; + if (s == NULL) + { + s = malloc (len); + if (s == NULL) + { + int save = errno; + (void) fclose (stream); + errno = save; + return NULL; + } + } + + stream->__buffer = (char *) s; + stream->__bufsize = len; + + stream->__bufp = stream->__buffer; + stream->__get_limit = (stream->__buffer + + (stream->__mode.__read ? stream->__bufsize : 0)); + stream->__put_limit = (stream->__buffer + + (stream->__mode.__write ? stream->__bufsize : 0)); + stream->__cookie = NULL; + + if (stream->__mode.__append) + { + char *p = memchr (stream->__bufp, '\0', + stream->__get_limit - stream->__bufp); + if (p == NULL) + stream->__bufp = stream->__get_limit; + else + stream->__bufp = p; + } + else if (stream->__mode.__truncate) + memset ((PTR) stream->__buffer, 0, len); + + return stream; +} diff --git a/stdio/fopen.c b/stdio/fopen.c new file mode 100644 index 0000000000..fba6ac436a --- /dev/null +++ b/stdio/fopen.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +#define badmode() return ((errno = EINVAL), 0) + +/* Dissect the given mode string into an __io_mode. */ +int +DEFUN(__getmode, (mode, mptr), CONST char *mode AND __io_mode *mptr) +{ + register unsigned char i; + + if (mode == NULL) + badmode (); + + memset ((PTR) mptr, 0, sizeof (*mptr)); + + switch (*mode) + { + case 'a': + mptr->__write = mptr->__create = mptr->__append = 1; + break; + case 'w': + mptr->__write = mptr->__create = mptr->__truncate = 1; + break; + case 'r': + mptr->__read = 1; + break; + default: + badmode (); + } + + for (i = 1; i < 3; ++i) + { + ++mode; + if (*mode == '\0') + break; + switch (*mode) + { + case '+': + mptr->__read = mptr->__write = 1; + break; + case 'b': + mptr->__binary = 1; + break; + } + } + + if (!mptr->__read && !mptr->__write) + badmode (); + + mptr->__exclusive = *mode == 'x'; + + return 1; +} + +/* Open a new stream on the given file. */ +FILE * +DEFUN(fopen, (filename, mode), CONST char *filename AND CONST char *mode) +{ + FILE *stream; + __io_mode m; + + if (filename == NULL) + { + errno = EINVAL; + return NULL; + } + + if (!__getmode (mode, &m)) + return NULL; + + stream = __newstream (); + if (stream == NULL) + return NULL; + + if (__stdio_open (filename, m, &stream->__cookie)) + { + int save = errno; + (void) fclose (stream); + errno = save; + return NULL; + } + + stream->__mode = m; + + return stream; +} diff --git a/stdio/fopncook.c b/stdio/fopncook.c new file mode 100644 index 0000000000..b61bdda959 --- /dev/null +++ b/stdio/fopncook.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + + +/* Defined in fopen.c. */ +extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr)); + +/* Open a new stream on the given magic cookie descriptor. */ +FILE * +DEFUN(fopencookie, (cookie, mode, functions), + PTR cookie AND CONST char *mode AND __io_functions functions) +{ + __io_mode m; + FILE *f; + + if (!__getmode (mode, &m)) + return NULL; + + f = __newstream (); + if (f == NULL) + return NULL; + + f->__cookie = cookie; + f->__mode = m; + f->__io_funcs = functions; + f->__room_funcs = __default_room_functions; + f->__seen = 1; + + return f; +} diff --git a/stdio/fpioconst.c b/stdio/fpioconst.c new file mode 100644 index 0000000000..231cae34ed --- /dev/null +++ b/stdio/fpioconst.c @@ -0,0 +1,401 @@ +/* Table of MP integer constants 10^(2^i), used for floating point <-> decimal. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "fpioconst.h" +#include <gmp-mparam.h> /* This defines BITS_PER_MP_LIMB. */ + +/* First page : 32-bit limbs + Second page : 64-bit limbs + Last page : table of pointers + */ + +#if BITS_PER_MP_LIMB == 32 + +/* Table with constants of 10^(2^i), i=0..12 for 32-bit limbs. */ + +static const mp_limb _ten_p0[] = + { 0x00000000, 0x00000000, 0x0000000a }; +static const mp_limb _ten_p1[] = + { 0x00000000, 0x00000000, 0x00000064 }; +static const mp_limb _ten_p2[] = + { 0x00000000, 0x00000000, 0x00002710 }; +static const mp_limb _ten_p3[] = + { 0x00000000, 0x00000000, 0x05f5e100 }; +static const mp_limb _ten_p4[] = + { 0x00000000, 0x00000000, 0x6fc10000, 0x002386f2 }; +static const mp_limb _ten_p5[] = + { 0x00000000, 0x00000000, 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee }; +static const mp_limb _ten_p6[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, + 0xdaa797ed, 0xe93ff9f4, 0x00184f03 }; +static const mp_limb _ten_p7[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x2e953e01, 0x03df9909, 0x0f1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, + 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e }; +static const mp_limb _ten_p8[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x982e7c01, 0xbed3875b, + 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, 0xd595d80f, 0x26b2716e, + 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17, + 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7 }; +static const mp_limb _ten_p9[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xfc6cf801, 0x77f27267, 0x8f9546dc, 0x5d96976f, 0xb83a8a97, 0xc31e1ad9, + 0x46c40513, 0x94e65747, 0xc88976c1, 0x4475b579, 0x28f8733b, 0xaa1da1bf, + 0x703ed321, 0x1e25cfea, 0xb21a2f22, 0xbc51fb2e, 0x96e14f5d, 0xbfa3edac, + 0x329c57ae, 0xe7fc7153, 0xc3fc0695, 0x85a91924, 0xf95f635e, 0xb2908ee0, + 0x93abade4, 0x1366732a, 0x9449775c, 0x69be5b0e, 0x7343afac, 0xb099bc81, + 0x45a71d46, 0xa2699748, 0x8cb07303, 0x8a0b1f13, 0x8cab8a97, 0xc1d238d9, + 0x633415d4, 0x0000001c }; +static const mp_limb _ten_p10[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2919f001, 0xf55b2b72, + 0x6e7c215b, 0x1ec29f86, 0x991c4e87, 0x15c51a88, 0x140ac535, 0x4c7d1e1a, + 0xcc2cd819, 0x0ed1440e, 0x896634ee, 0x7de16cfb, 0x1e43f61f, 0x9fce837d, + 0x231d2b9c, 0x233e55c7, 0x65dc60d7, 0xf451218b, 0x1c5cd134, 0xc9635986, + 0x922bbb9f, 0xa7e89431, 0x9f9f2a07, 0x62be695a, 0x8e1042c4, 0x045b7a74, + 0x1abe1de3, 0x8ad822a5, 0xba34c411, 0xd814b505, 0xbf3fdeb3, 0x8fc51a16, + 0xb1b896bc, 0xf56deeec, 0x31fb6bfd, 0xb6f4654b, 0x101a3616, 0x6b7595fb, + 0xdc1a47fe, 0x80d98089, 0x80bda5a5, 0x9a202882, 0x31eb0f66, 0xfc8f1f90, + 0x976a3310, 0xe26a7b7e, 0xdf68368a, 0x3ce3a0b8, 0x8e4262ce, 0x75a351a2, + 0x6cb0b6c9, 0x44597583, 0x31b5653f, 0xc356e38a, 0x35faaba6, 0x0190fba0, + 0x9fc4ed52, 0x88bc491b, 0x1640114a, 0x005b8041, 0xf4f3235e, 0x1e8d4649, + 0x36a8de06, 0x73c55349, 0xa7e6bd2a, 0xc1a6970c, 0x47187094, 0xd2db49ef, + 0x926c3f5b, 0xae6209d4, 0x2d433949, 0x34f4a3c6, 0xd4305d94, 0xd9d61a05, + 0x00000325 }; +static const mp_limb _ten_p11[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x1333e001, 0xe3096865, 0xb27d4d3f, 0x49e28dcf, 0xec2e4721, 0xee87e354, + 0xb6067584, 0x368b8abb, 0xa5e5a191, 0x2ed56d55, 0xfd827773, 0xea50d142, + 0x51b78db2, 0x98342c9e, 0xc850dabc, 0x866ed6f1, 0x19342c12, 0x92794987, + 0xd2f869c2, 0x66912e4a, 0x71c7fd8f, 0x57a7842d, 0x235552eb, 0xfb7fedcc, + 0xf3861ce0, 0x38209ce1, 0x9713b449, 0x34c10134, 0x8c6c54de, 0xa7a8289c, + 0x2dbb6643, 0xe3cb64f3, 0x8074ff01, 0xe3892ee9, 0x10c17f94, 0xa8f16f92, + 0xa8281ed6, 0x967abbb3, 0x5a151440, 0x9952fbed, 0x13b41e44, 0xafe609c3, + 0xa2bca416, 0xf111821f, 0xfb1264b4, 0x91bac974, 0xd6c7d6ab, 0x8e48ff35, + 0x4419bd43, 0xc4a65665, 0x685e5510, 0x33554c36, 0xab498697, 0x0dbd21fe, + 0x3cfe491d, 0x982da466, 0xcbea4ca7, 0x9e110c7b, 0x79c56b8a, 0x5fc5a047, + 0x84d80e2e, 0x1aa9f444, 0x730f203c, 0x6a57b1ab, 0xd752f7a6, 0x87a7dc62, + 0x944545ff, 0x40660460, 0x77c1a42f, 0xc9ac375d, 0xe866d7ef, 0x744695f0, + 0x81428c85, 0xa1fc6b96, 0xd7917c7b, 0x7bf03c19, 0x5b33eb41, 0x5715f791, + 0x8f6cae5f, 0xdb0708fd, 0xb125ac8e, 0x785ce6b7, 0x56c6815b, 0x6f46eadb, + 0x4eeebeee, 0x195355d8, 0xa244de3c, 0x9d7389c0, 0x53761abd, 0xcf99d019, + 0xde9ec24b, 0x0d76ce39, 0x70beb181, 0x2e55ecee, 0xd5f86079, 0xf56d9d4b, + 0xfb8886fb, 0x13ef5a83, 0x408f43c5, 0x3f3389a4, 0xfad37943, 0x58ccf45c, + 0xf82df846, 0x415c7f3e, 0x2915e818, 0x8b3d5cf4, 0x6a445f27, 0xf8dbb57a, + 0xca8f0070, 0x8ad803ec, 0xb2e87c34, 0x038f9245, 0xbedd8a6c, 0xc7c9dee0, + 0x0eac7d56, 0x2ad3fa14, 0xe0de0840, 0xf775677c, 0xf1bd0ad5, 0x92be221e, + 0x87fa1fb9, 0xce9d04a4, 0xd2c36fa9, 0x3f6f7024, 0xb028af62, 0x907855ee, + 0xd83e49d6, 0x4efac5dc, 0xe7151aab, 0x77cd8c6b, 0x0a753b7d, 0x0af908b4, + 0x8c983623, 0xe50f3027, 0x94222771, 0x1d08e2d6, 0xf7e928e6, 0xf2ee5ca6, + 0x1b61b93c, 0x11eb962b, 0x9648b21c, 0xce2bcba1, 0x34f77154, 0x7bbebe30, + 0xe526a319, 0x8ce329ac, 0xde4a74d2, 0xb5dc53d5, 0x0009e8b3 }; +static const mp_limb _ten_p12[] = + { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a67c001, 0xd4724e8d, + 0x8efe7ae7, 0xf89a1e90, 0xef084117, 0x54e05154, 0x13b1bb51, 0x506be829, + 0xfb29b172, 0xe599574e, 0xf0da6146, 0x806c0ed3, 0xb86ae5be, 0x45155e93, + 0xc0591cc2, 0x7e1e7c34, 0x7c4823da, 0x1d1f4cce, 0x9b8ba1e8, 0xd6bfdf75, + 0xe341be10, 0xc2dfae78, 0x016b67b2, 0x0f237f1a, 0x3dbeabcd, 0xaf6a2574, + 0xcab3e6d7, 0x142e0e80, 0x61959127, 0x2c234811, 0x87009701, 0xcb4bf982, + 0xf8169c84, 0x88052f8c, 0x68dde6d4, 0xbc131761, 0xff0b0905, 0x54ab9c41, + 0x7613b224, 0x1a1c304e, 0x3bfe167b, 0x441c2d47, 0x4f6cea9c, 0x78f06181, + 0xeb659fb8, 0x30c7ae41, 0x947e0d0e, 0xa1ebcad7, 0xd97d9556, 0x2130504d, + 0x1a8309cb, 0xf2acd507, 0x3f8ec72a, 0xfd82373a, 0x95a842bc, 0x280f4d32, + 0xf3618ac0, 0x811a4f04, 0x6dc3a5b4, 0xd3967a1b, 0x15b8c898, 0xdcfe388f, + 0x454eb2a0, 0x8738b909, 0x10c4e996, 0x2bd9cc11, 0x3297cd0c, 0x655fec30, + 0xae0725b1, 0xf4090ee8, 0x037d19ee, 0x398c6fed, 0x3b9af26b, 0xc994a450, + 0xb5341743, 0x75a697b2, 0xac50b9c1, 0x3ccb5b92, 0xffe06205, 0xa8329761, + 0xdfea5242, 0xeb83cadb, 0xe79dadf7, 0x3c20ee69, 0x1e0a6817, 0x7021b97a, + 0x743074fa, 0x176ca776, 0x77fb8af6, 0xeca19beb, 0x92baf1de, 0xaf63b712, + 0xde35c88b, 0xa4eb8f8c, 0xe137d5e9, 0x40b464a0, 0x87d1cde8, 0x42923bbd, + 0xcd8f62ff, 0x2e2690f3, 0x095edc16, 0x59c89f1b, 0x1fa8fd5d, 0x5138753d, + 0x390a2b29, 0x80152f18, 0x2dd8d925, 0xf984d83e, 0x7a872e74, 0xc19e1faf, + 0xed4d542d, 0xecf9b5d0, 0x9462ea75, 0xc53c0adf, 0x0caea134, 0x37a2d439, + 0xc8fa2e8a, 0x2181327e, 0x6e7bb827, 0x2d240820, 0x50be10e0, 0x5893d4b8, + 0xab312bb9, 0x1f2b2322, 0x440b3f25, 0xbf627ede, 0x72dac789, 0xb608b895, + 0x78787e2a, 0x86deb3f0, 0x6fee7aab, 0xbb9373f4, 0x27ecf57b, 0xf7d8b57e, + 0xfca26a9f, 0x3d04e8d2, 0xc9df13cb, 0x3172826a, 0xcd9e8d7c, 0xa8fcd8e0, + 0xb2c39497, 0x307641d9, 0x1cc939c1, 0x2608c4cf, 0xb6d1c7bf, 0x3d326a7e, + 0xeeaf19e6, 0x8e13e25f, 0xee63302b, 0x2dfe6d97, 0x25971d58, 0xe41d3cc4, + 0x0a80627c, 0xab8db59a, 0x9eea37c8, 0xe90afb77, 0x90ca19cf, 0x9ee3352c, + 0x3613c850, 0xfe78d682, 0x788f6e50, 0x5b060904, 0xb71bd1a4, 0x3fecb534, + 0xb32c450c, 0x20c33857, 0xa6e9cfda, 0x0239f4ce, 0x48497187, 0xa19adb95, + 0xb492ed8a, 0x95aca6a8, 0x4dcd6cd9, 0xcf1b2350, 0xfbe8b12a, 0x1a67778c, + 0x38eb3acc, 0xc32da383, 0xfb126ab1, 0xa03f40a8, 0xed5bf546, 0xe9ce4724, + 0x4c4a74fd, 0x73a130d8, 0xd9960e2d, 0xa2ebd6c1, 0x94ab6feb, 0x6f233b7c, + 0x49126080, 0x8e7b9a73, 0x4b8c9091, 0xd298f999, 0x35e836b5, 0xa96ddeff, + 0x96119b31, 0x6b0dd9bc, 0xc6cc3f8d, 0x282566fb, 0x72b882e7, 0xd6769f3b, + 0xa674343d, 0x00fc509b, 0xdcbf7789, 0xd6266a3f, 0xae9641fd, 0x4e89541b, + 0x11953407, 0x53400d03, 0x8e0dd75a, 0xe5b53345, 0x108f19ad, 0x108b89bc, + 0x41a4c954, 0xe03b2b63, 0x437b3d7f, 0x97aced8e, 0xcbd66670, 0x2c5508c2, + 0x650ebc69, 0x5c4f2ef0, 0x904ff6bf, 0x9985a2df, 0x9faddd9e, 0x5ed8d239, + 0x25585832, 0xe3e51cb9, 0x0ff4f1d4, 0x56c02d9a, 0x8c4ef804, 0xc1a08a13, + 0x13fd01c8, 0xe6d27671, 0xa7c234f4, 0x9d0176cc, 0xd0d73df2, 0x4d8bfa89, + 0x544f10cd, 0x2b17e0b2, 0xb70a5c7d, 0xfd86fe49, 0xdf373f41, 0x214495bb, + 0x84e857fd, 0x00d313d5, 0x0496fcbe, 0xa4ba4744, 0xe8cac982, 0xaec29e6e, + 0x87ec7038, 0x7000a519, 0xaeee333b, 0xff66e42c, 0x8afd6b25, 0x03b4f63b, + 0xbd7991dc, 0x5ab8d9c7, 0x2ed4684e, 0x48741a6c, 0xaf06940d, 0x2fdc6349, + 0xb03d7ecd, 0xe974996f, 0xac7867f9, 0x52ec8721, 0xbcdd9d4a, 0x8edd2d00, + 0x3557de06, 0x41c759f8, 0x3956d4b9, 0xa75409f2, 0x123cd8a1, 0xb6100fab, + 0x3e7b21e2, 0x2e8d623b, 0x92959da2, 0xbca35f77, 0x200c03a5, 0x35fcb457, + 0x1bb6c6e4, 0xf74eb928, 0x3d5d0b54, 0x87cc1d21, 0x4964046f, 0x18ae4240, + 0xd868b275, 0x8bd2b496, 0x1c5563f4, 0xc234d8f5, 0xf868e970, 0xf9151fff, + 0xae7be4a2, 0x271133ee, 0xbb0fd922, 0x25254932, 0xa60a9fc0, 0x104bcd64, + 0x30290145, 0x00000062 }; + +#define LAST_POW10 12 + +#elif BITS_PER_MP_LIMB == 64 + +/* Table with constants of 10^(2^i), i=0..12 for 64-bit limbs. */ + +static const mp_limb _ten_p0[] = + { 0x0000000000000000, 0x000000000000000a }; +static const mp_limb _ten_p1[] = + { 0x0000000000000000, 0x0000000000000064 }; +static const mp_limb _ten_p2[] = + { 0x0000000000000000, 0x0000000000002710 }; +static const mp_limb _ten_p3[] = + { 0x0000000000000000, 0x0000000005f5e100 }; +static const mp_limb _ten_p4[] = + { 0x0000000000000000, 0x002386f26fc10000 }; +static const mp_limb _ten_p5[] = + { 0x0000000000000000, 0x85acef8100000000, 0x000004ee2d6d415b }; +static const mp_limb _ten_p6[] = + { 0x0000000000000000, 0x0000000000000000, 0x6e38ed64bf6a1f01, + 0xe93ff9f4daa797ed, 0x0000000000184f03 }; +static const mp_limb _ten_p7[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x03df99092e953e01, 0x2374e42f0f1538fd, 0xc404dc08d3cff5ec, + 0xa6337f19bccdb0da, 0x0000024ee91f2603 }; +static const mp_limb _ten_p8[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0xbed3875b982e7c01, + 0x12152f87d8d99f72, 0xcf4a6e706bde50c6, 0x26b2716ed595d80f, + 0x1d153624adc666b0, 0x63ff540e3c42d35a, 0x65f9ef17cc5573c0, + 0x80dcc7f755bc28f2, 0x5fdcefcef46eeddc, 0x00000000000553f7 }; +static const mp_limb _ten_p9[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x77f27267fc6cf801, 0x5d96976f8f9546dc, 0xc31e1ad9b83a8a97, + 0x94e6574746c40513, 0x4475b579c88976c1, 0xaa1da1bf28f8733b, + 0x1e25cfea703ed321, 0xbc51fb2eb21a2f22, 0xbfa3edac96e14f5d, + 0xe7fc7153329c57ae, 0x85a91924c3fc0695, 0xb2908ee0f95f635e, + 0x1366732a93abade4, 0x69be5b0e9449775c, 0xb099bc817343afac, + 0xa269974845a71d46, 0x8a0b1f138cb07303, 0xc1d238d98cab8a97, + 0x0000001c633415d4 }; +static const mp_limb _ten_p10[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0xf55b2b722919f001, + 0x1ec29f866e7c215b, 0x15c51a88991c4e87, 0x4c7d1e1a140ac535, + 0x0ed1440ecc2cd819, 0x7de16cfb896634ee, 0x9fce837d1e43f61f, + 0x233e55c7231d2b9c, 0xf451218b65dc60d7, 0xc96359861c5cd134, + 0xa7e89431922bbb9f, 0x62be695a9f9f2a07, 0x045b7a748e1042c4, + 0x8ad822a51abe1de3, 0xd814b505ba34c411, 0x8fc51a16bf3fdeb3, + 0xf56deeecb1b896bc, 0xb6f4654b31fb6bfd, 0x6b7595fb101a3616, + 0x80d98089dc1a47fe, 0x9a20288280bda5a5, 0xfc8f1f9031eb0f66, + 0xe26a7b7e976a3310, 0x3ce3a0b8df68368a, 0x75a351a28e4262ce, + 0x445975836cb0b6c9, 0xc356e38a31b5653f, 0x0190fba035faaba6, + 0x88bc491b9fc4ed52, 0x005b80411640114a, 0x1e8d4649f4f3235e, + 0x73c5534936a8de06, 0xc1a6970ca7e6bd2a, 0xd2db49ef47187094, + 0xae6209d4926c3f5b, 0x34f4a3c62d433949, 0xd9d61a05d4305d94, + 0x0000000000000325 }; +static const mp_limb _ten_p11[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0xe30968651333e001, 0x49e28dcfb27d4d3f, 0xee87e354ec2e4721, + 0x368b8abbb6067584, 0x2ed56d55a5e5a191, 0xea50d142fd827773, + 0x98342c9e51b78db2, 0x866ed6f1c850dabc, 0x9279498719342c12, + 0x66912e4ad2f869c2, 0x57a7842d71c7fd8f, 0xfb7fedcc235552eb, + 0x38209ce1f3861ce0, 0x34c101349713b449, 0xa7a8289c8c6c54de, + 0xe3cb64f32dbb6643, 0xe3892ee98074ff01, 0xa8f16f9210c17f94, + 0x967abbb3a8281ed6, 0x9952fbed5a151440, 0xafe609c313b41e44, + 0xf111821fa2bca416, 0x91bac974fb1264b4, 0x8e48ff35d6c7d6ab, + 0xc4a656654419bd43, 0x33554c36685e5510, 0x0dbd21feab498697, + 0x982da4663cfe491d, 0x9e110c7bcbea4ca7, 0x5fc5a04779c56b8a, + 0x1aa9f44484d80e2e, 0x6a57b1ab730f203c, 0x87a7dc62d752f7a6, + 0x40660460944545ff, 0xc9ac375d77c1a42f, 0x744695f0e866d7ef, + 0xa1fc6b9681428c85, 0x7bf03c19d7917c7b, 0x5715f7915b33eb41, + 0xdb0708fd8f6cae5f, 0x785ce6b7b125ac8e, 0x6f46eadb56c6815b, + 0x195355d84eeebeee, 0x9d7389c0a244de3c, 0xcf99d01953761abd, + 0x0d76ce39de9ec24b, 0x2e55ecee70beb181, 0xf56d9d4bd5f86079, + 0x13ef5a83fb8886fb, 0x3f3389a4408f43c5, 0x58ccf45cfad37943, + 0x415c7f3ef82df846, 0x8b3d5cf42915e818, 0xf8dbb57a6a445f27, + 0x8ad803ecca8f0070, 0x038f9245b2e87c34, 0xc7c9dee0bedd8a6c, + 0x2ad3fa140eac7d56, 0xf775677ce0de0840, 0x92be221ef1bd0ad5, + 0xce9d04a487fa1fb9, 0x3f6f7024d2c36fa9, 0x907855eeb028af62, + 0x4efac5dcd83e49d6, 0x77cd8c6be7151aab, 0x0af908b40a753b7d, + 0xe50f30278c983623, 0x1d08e2d694222771, 0xf2ee5ca6f7e928e6, + 0x11eb962b1b61b93c, 0xce2bcba19648b21c, 0x7bbebe3034f77154, + 0x8ce329ace526a319, 0xb5dc53d5de4a74d2, 0x000000000009e8b3 }; +static const mp_limb _ten_p12[] = + { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0xd4724e8d2a67c001, + 0xf89a1e908efe7ae7, 0x54e05154ef084117, 0x506be82913b1bb51, + 0xe599574efb29b172, 0x806c0ed3f0da6146, 0x45155e93b86ae5be, + 0x7e1e7c34c0591cc2, 0x1d1f4cce7c4823da, 0xd6bfdf759b8ba1e8, + 0xc2dfae78e341be10, 0x0f237f1a016b67b2, 0xaf6a25743dbeabcd, + 0x142e0e80cab3e6d7, 0x2c23481161959127, 0xcb4bf98287009701, + 0x88052f8cf8169c84, 0xbc13176168dde6d4, 0x54ab9c41ff0b0905, + 0x1a1c304e7613b224, 0x441c2d473bfe167b, 0x78f061814f6cea9c, + 0x30c7ae41eb659fb8, 0xa1ebcad7947e0d0e, 0x2130504dd97d9556, + 0xf2acd5071a8309cb, 0xfd82373a3f8ec72a, 0x280f4d3295a842bc, + 0x811a4f04f3618ac0, 0xd3967a1b6dc3a5b4, 0xdcfe388f15b8c898, + 0x8738b909454eb2a0, 0x2bd9cc1110c4e996, 0x655fec303297cd0c, + 0xf4090ee8ae0725b1, 0x398c6fed037d19ee, 0xc994a4503b9af26b, + 0x75a697b2b5341743, 0x3ccb5b92ac50b9c1, 0xa8329761ffe06205, + 0xeb83cadbdfea5242, 0x3c20ee69e79dadf7, 0x7021b97a1e0a6817, + 0x176ca776743074fa, 0xeca19beb77fb8af6, 0xaf63b71292baf1de, + 0xa4eb8f8cde35c88b, 0x40b464a0e137d5e9, 0x42923bbd87d1cde8, + 0x2e2690f3cd8f62ff, 0x59c89f1b095edc16, 0x5138753d1fa8fd5d, + 0x80152f18390a2b29, 0xf984d83e2dd8d925, 0xc19e1faf7a872e74, + 0xecf9b5d0ed4d542d, 0xc53c0adf9462ea75, 0x37a2d4390caea134, + 0x2181327ec8fa2e8a, 0x2d2408206e7bb827, 0x5893d4b850be10e0, + 0x1f2b2322ab312bb9, 0xbf627ede440b3f25, 0xb608b89572dac789, + 0x86deb3f078787e2a, 0xbb9373f46fee7aab, 0xf7d8b57e27ecf57b, + 0x3d04e8d2fca26a9f, 0x3172826ac9df13cb, 0xa8fcd8e0cd9e8d7c, + 0x307641d9b2c39497, 0x2608c4cf1cc939c1, 0x3d326a7eb6d1c7bf, + 0x8e13e25feeaf19e6, 0x2dfe6d97ee63302b, 0xe41d3cc425971d58, + 0xab8db59a0a80627c, 0xe90afb779eea37c8, 0x9ee3352c90ca19cf, + 0xfe78d6823613c850, 0x5b060904788f6e50, 0x3fecb534b71bd1a4, + 0x20c33857b32c450c, 0x0239f4cea6e9cfda, 0xa19adb9548497187, + 0x95aca6a8b492ed8a, 0xcf1b23504dcd6cd9, 0x1a67778cfbe8b12a, + 0xc32da38338eb3acc, 0xa03f40a8fb126ab1, 0xe9ce4724ed5bf546, + 0x73a130d84c4a74fd, 0xa2ebd6c1d9960e2d, 0x6f233b7c94ab6feb, + 0x8e7b9a7349126080, 0xd298f9994b8c9091, 0xa96ddeff35e836b5, + 0x6b0dd9bc96119b31, 0x282566fbc6cc3f8d, 0xd6769f3b72b882e7, + 0x00fc509ba674343d, 0xd6266a3fdcbf7789, 0x4e89541bae9641fd, + 0x53400d0311953407, 0xe5b533458e0dd75a, 0x108b89bc108f19ad, + 0xe03b2b6341a4c954, 0x97aced8e437b3d7f, 0x2c5508c2cbd66670, + 0x5c4f2ef0650ebc69, 0x9985a2df904ff6bf, 0x5ed8d2399faddd9e, + 0xe3e51cb925585832, 0x56c02d9a0ff4f1d4, 0xc1a08a138c4ef804, + 0xe6d2767113fd01c8, 0x9d0176cca7c234f4, 0x4d8bfa89d0d73df2, + 0x2b17e0b2544f10cd, 0xfd86fe49b70a5c7d, 0x214495bbdf373f41, + 0x00d313d584e857fd, 0xa4ba47440496fcbe, 0xaec29e6ee8cac982, + 0x7000a51987ec7038, 0xff66e42caeee333b, 0x03b4f63b8afd6b25, + 0x5ab8d9c7bd7991dc, 0x48741a6c2ed4684e, 0x2fdc6349af06940d, + 0xe974996fb03d7ecd, 0x52ec8721ac7867f9, 0x8edd2d00bcdd9d4a, + 0x41c759f83557de06, 0xa75409f23956d4b9, 0xb6100fab123cd8a1, + 0x2e8d623b3e7b21e2, 0xbca35f7792959da2, 0x35fcb457200c03a5, + 0xf74eb9281bb6c6e4, 0x87cc1d213d5d0b54, 0x18ae42404964046f, + 0x8bd2b496d868b275, 0xc234d8f51c5563f4, 0xf9151ffff868e970, + 0x271133eeae7be4a2, 0x25254932bb0fd922, 0x104bcd64a60a9fc0, + 0x0000006230290145 }; + +#define LAST_POW10 12 + +#else +# error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + +/* Each of array variable above defines one mpn integer which is a power of 10. + This table points to those variables, indexed by the exponent. */ + +const struct mp_power _fpioconst_pow10[LDBL_MAX_10_EXP_LOG + 1] = + { + { _ten_p0, sizeof (_ten_p0) / sizeof (_ten_p0[0]), 4, }, + { _ten_p1, sizeof (_ten_p1) / sizeof (_ten_p0[1]), 7, 4 }, + { _ten_p2, sizeof (_ten_p2) / sizeof (_ten_p0[2]), 14, 10 }, + { _ten_p3, sizeof (_ten_p3) / sizeof (_ten_p0[3]), 27, 24 }, + { _ten_p4, sizeof (_ten_p4) / sizeof (_ten_p0[4]), 54, 50 }, + { _ten_p5, sizeof (_ten_p5) / sizeof (_ten_p0[5]), 107, 103 }, + { _ten_p6, sizeof (_ten_p6) / sizeof (_ten_p0[6]), 213, 210 }, + { _ten_p7, sizeof (_ten_p7) / sizeof (_ten_p0[7]), 426, 422 }, + { _ten_p8, sizeof (_ten_p8) / sizeof (_ten_p0[8]), 851, 848 }, + { _ten_p9, sizeof (_ten_p9) / sizeof (_ten_p0[9]), 1701, 1698 }, + { _ten_p10, sizeof (_ten_p10) / sizeof (_ten_p0[10]), 3402, 3399 }, + { _ten_p11, sizeof (_ten_p11) / sizeof (_ten_p0[11]), 6804, 6800 }, + { _ten_p12, sizeof (_ten_p12) / sizeof (_ten_p0[12]), 13607, 13604 } + }; + +#if LDBL_MAX_10_EXP_LOG > LAST_POW10 +#error "Need to expand 10^(2^i) table for i up to" LDBL_MAX_10_EXP_LOG +#endif diff --git a/stdio/fpioconst.h b/stdio/fpioconst.h new file mode 100644 index 0000000000..8edbdccb17 --- /dev/null +++ b/stdio/fpioconst.h @@ -0,0 +1,52 @@ +/* Header file for constants used in floating point <-> decimal conversions. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FPIOCONST_H +#define _FPIOCONST_H + +#include <float.h> +#include "gmp.h" + + +/* These values are used by __printf_fp, where they are noncritical (if the + value is not large enough, it will just be slower); and by + strtof/strtod/strtold, where it is critical (it's used for overflow + detection). + + XXX These should be defined in <float.h>. For the time being, we have the + IEEE754 values here. */ + +#define LDBL_MAX_10_EXP_LOG 12 /* = floor(log_2(LDBL_MAX_10_EXP)) */ +#define DBL_MAX_10_EXP_LOG 8 /* = floor(log_2(DBL_MAX_10_EXP)) */ +#define FLT_MAX_10_EXP_LOG 5 /* = floor(log_2(FLT_MAX_10_EXP)) */ + + +/* Table of powers of ten. This is used by __printf_fp and by + strtof/strtod/strtold. */ +struct mp_power + { + const mp_limb *array; /* The array with the number representation. */ + mp_size_t arraysize; /* Size of the array. */ + int p_expo; /* Exponent of the number 10^(2^i). */ + int m_expo; /* Exponent of the number 10^-(2^i-1). */ + }; +extern const struct mp_power _fpioconst_pow10[LDBL_MAX_10_EXP_LOG + 1]; + + +#endif /* fpioconst.h */ diff --git a/stdio/fprintf.c b/stdio/fprintf.c new file mode 100644 index 0000000000..bc6d1003b7 --- /dev/null +++ b/stdio/fprintf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output to STREAM from the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(fprintf, (stream, format), + FILE *stream AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vfprintf(stream, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/fputc.c b/stdio/fputc.c new file mode 100644 index 0000000000..36b9501195 --- /dev/null +++ b/stdio/fputc.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Write the character C to STREAM. */ +int +DEFUN(fputc, (c, stream), int c AND FILE *stream) +{ + if (!__validfp(stream) || !stream->__mode.__write) + { + errno = EINVAL; + return EOF; + } + + return __putc(c, stream); +} diff --git a/stdio/fputs.c b/stdio/fputs.c new file mode 100644 index 0000000000..a149a1c329 --- /dev/null +++ b/stdio/fputs.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + + +/* Write the string S to STREAM. */ +int +DEFUN(fputs, (s, stream), CONST char *s AND FILE *stream) +{ + register CONST size_t len = strlen (s); + if (len == 1) + return putc (*s, stream) == EOF ? EOF : 0; + if (fwrite ((PTR) s, 1, len, stream) != len) + return EOF; + return 0; +} diff --git a/stdio/fread.c b/stdio/fread.c new file mode 100644 index 0000000000..347e8446e1 --- /dev/null +++ b/stdio/fread.c @@ -0,0 +1,128 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + + +#define default_func __default_room_functions.__input + +/* Read NMEMB chunks of SIZE bytes each from STREAM into P. */ +size_t +DEFUN(fread, (p, size, nmemb, stream), + PTR p AND size_t size AND size_t nmemb AND register FILE *stream) +{ + register char *ptr = (char *) p; + register size_t to_read = size * nmemb; + size_t bytes = to_read; + + if (!__validfp(stream) || !stream->__mode.__read) + { + errno = EINVAL; + return 0; + } + if (feof(stream) || ferror(stream)) + return 0; + if (p == NULL || to_read == 0) + return 0; + + if (!stream->__seen || stream->__buffer == NULL || stream->__pushed_back) + { + /* This stream has never been seen before, or it has a character + pushed back. Call __fillbf to deal with those cases. Life will + be simpler after this call. */ + int c = __fillbf(stream); + if (c == EOF) + return 0; + *ptr++ = c; + if (--to_read == 0) + return 1; + } + + read_from_buffer:; + if (stream->__bufp < stream->__get_limit) + { + /* First off, empty out the buffer. */ + register size_t copy = stream->__get_limit - stream->__bufp; + if (copy > to_read) + copy = to_read; + to_read -= copy; + if (copy > 20) + memcpy((PTR) ptr, (PTR) stream->__bufp, copy); + else + { + register size_t i; + for (i = 0; i < copy; ++i) + ptr[i] = stream->__bufp[i]; + } + stream->__bufp += copy; + if (to_read == 0) + return nmemb; + ptr += copy; + } + + /* Reading directly into the user's buffer doesn't help when + using a user-specified input buffer filling/expanding function, + so we don't do it in that case. */ + if (to_read >= stream->__bufsize && + stream->__room_funcs.__input == default_func && + stream->__offset == stream->__target) + { + /* Read directly into the user's buffer. */ + if (stream->__io_funcs.__read != NULL) + while (to_read > 0) + { + register int count; + count = (*stream->__io_funcs.__read)(stream->__cookie, + ptr, to_read); + if (count > 0) + { + to_read -= count; + stream->__offset += count; + stream->__target += count; + ptr += count; + } + else if (count == 0) + { + stream->__eof = 1; + break; + } + else + { + stream->__error = 1; + break; + } + } + else + stream->__eof = 1; + } + else + { + int c = __fillbf(stream); + if (c == EOF) + return (bytes - to_read) / size; + *ptr++ = (char) c; + --to_read; + if (to_read > 0) + goto read_from_buffer; + } + + return (bytes - to_read) / size; +} diff --git a/stdio/freopen.c b/stdio/freopen.c new file mode 100644 index 0000000000..bedddb1a63 --- /dev/null +++ b/stdio/freopen.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Defined in fopen.c. */ +extern int __getmode __P ((const char *, __io_mode *)); + +/* Defined in sysd-stdio.c. */ +extern int __stdio_reopen __P ((const char *filename, __io_mode mode, + PTR *cookieptr, __io_close_fn closefn)); + +/* Replace STREAM, opening it on FILENAME. */ +FILE * +DEFUN(freopen, (filename, mode, stream), + CONST char *filename AND CONST char *mode AND register FILE *stream) +{ + __io_mode m; + PTR cookie; + + if (!__getmode (mode, &m)) + { + (void) fclose (stream); + errno = EINVAL; + return NULL; + } + + if (stream->__mode.__write) + /* Flush the stream. */ + (void) fflush (stream); + + /* Open the file, attempting to preserve the old cookie value. */ + cookie = stream->__cookie; + if (__stdio_reopen (filename, m, &cookie, + stream->__seen ? + stream->__io_funcs.__close : + __stdio_close)) + { + int save = errno; + (void) fclose (stream); + errno = save; + return NULL; + } + + /* Close the stream, first disabling its cookie close function because + __stdio_reopen has already dealt with closing the old cookie. */ + stream->__seen = 1; /* It might have no functions yet. */ + stream->__io_funcs.__close = NULL; + (void) fclose (stream); + + stream->__magic = _IOMAGIC; + stream->__cookie = cookie; + stream->__mode = m; + + return stream; +} diff --git a/stdio/fscanf.c b/stdio/fscanf.c new file mode 100644 index 0000000000..cbe0103368 --- /dev/null +++ b/stdio/fscanf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(fscanf, (stream, format), + FILE *stream AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = __vfscanf(stream, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/fseek.c b/stdio/fseek.c new file mode 100644 index 0000000000..a5abfe4866 --- /dev/null +++ b/stdio/fseek.c @@ -0,0 +1,177 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Move the file position of STREAM to OFFSET + bytes from the beginning of the file if WHENCE + is SEEK_SET, the end of the file is it is SEEK_END, + or the current position if it is SEEK_CUR. */ +int +DEFUN(fseek, (stream, offset, whence), + register FILE *stream AND long int offset AND int whence) +{ + long int o; + + if (!__validfp (stream)) + { + errno = EINVAL; + return EOF; + } + + /* Write out any pending data. */ + if (stream->__mode.__write && __flshfp (stream, EOF) == EOF) + return EOF; + + /* Make sure we know the current offset info. */ + if (__stdio_check_offset (stream) == EOF) + return EOF; + + /* We are moving the file position, so we are no longer at EOF. */ + stream->__eof = 0; + + if (stream->__pushed_back) + { + /* Discard the character pushed back by ungetc. */ + stream->__bufp = stream->__pushback_bufp; + stream->__pushed_back = 0; + } + + /* Check the WHENCE argument for validity, and process OFFSET + into an absolute position in O. By the end of this switch, + either we have returned, or O contains an absolute position. */ + o = offset; + switch (whence) + { + default: + errno = EINVAL; + return EOF; + + case SEEK_END: + /* We don't know where the end of the file is, + so seek to the position in the file the user asked + for, and then look where that is. */ + if (stream->__io_funcs.__seek == NULL) + { + errno = ESPIPE; + return EOF; + } + else + { + fpos_t pos = (fpos_t) o; + if ((*stream->__io_funcs.__seek) + (stream->__cookie, &pos, SEEK_END) < 0) + { + if (errno == ESPIPE) + stream->__io_funcs.__seek = NULL; + return EOF; + } + stream->__offset = pos; + /* Make O be absolute, rather than + relative to the end of the file. */ + o = pos; + } + + /* Fall through to try an absolute seek. */ + + case SEEK_SET: + /* Make O be relative to the buffer. */ + o -= stream->__target; + /* Make O be relative to the current position in the buffer. */ + o -= stream->__bufp - stream->__buffer; + + /* Fall through to see if we can do it by + moving the pointer around in the buffer. */ + + case SEEK_CUR: + /* If the offset is small enough, we can just + move the pointer around in the buffer. */ + +#if 0 /* Why did I think this would ever work??? */ + if (stream->__put_limit > stream->__buffer) + { + /* We are writing. */ + if (stream->__bufp + o >= stream->__buffer && + stream->__put_limit > stream->__bufp + o && + stream->__get_limit > stream->__bufp + o) + { + /* We have read all the data we will change soon. + We can just move the pointer around. */ + stream->__bufp += o; + return 0; + } + else + { + /* Flush the buffer. */ + if (__flshfp(stream, EOF) == EOF) + return EOF; + } + } else +#endif + if (o < 0 ? + (-o <= stream->__bufp - stream->__buffer) : + (o <= stream->__get_limit - stream->__bufp)) + { + stream->__bufp += o; + return 0; + } + + /* Turn it into an absolute seek. */ + o += stream->__bufp - stream->__buffer; + o += stream->__target; + break; + } + + if (o < 0) + { + /* Negative file position is meaningless. */ + errno = EINVAL; + return -1; + } + + /* O is now an absolute position, the new target. */ + stream->__target = o; + + /* Set bufp and both end pointers to the beginning of the buffer. + The next i/o will force a call to the input/output room function. */ + stream->__bufp + = stream->__get_limit = stream->__put_limit = stream->__buffer; + + /* Make sure __flshfp doesn't think the put_limit is at the beginning + of the buffer because of line-buffering magic. */ + stream->__linebuf_active = 0; + + /* If there is no seek function, seeks always fail. */ + if (stream->__io_funcs.__seek == NULL) + { + /* This is preemptive, since we don't actually do the seeking. + But it makes more sense for fseek to to fail with ESPIPE + than for the next reading or writing operation to fail + that way. */ + errno = ESPIPE; + return EOF; + } + + /* Don't actually seek. The next reading or writing operation + will force a call to the input or output room function, + which will move to the target file position before reading or writing. */ + return 0; +} diff --git a/stdio/fsetpos.c b/stdio/fsetpos.c new file mode 100644 index 0000000000..7c8fcb78bb --- /dev/null +++ b/stdio/fsetpos.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +#undef fsetpos + + +/* Set the file position of STREAM to *POS. */ +int +DEFUN(fsetpos, (stream, pos), FILE *stream AND CONST fpos_t *pos) +{ + if (pos == NULL) + { + errno = EINVAL; + return EOF; + } + + return fseek(stream, *pos, SEEK_SET); +} diff --git a/stdio/ftell.c b/stdio/ftell.c new file mode 100644 index 0000000000..d27eaf7598 --- /dev/null +++ b/stdio/ftell.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +/* Return the offset in bytes from the beginning + of the file of the file position of STREAM. */ +long int +DEFUN(ftell, (stream), FILE *stream) +{ + long int pos; + + if (!__validfp (stream)) + { + errno = EINVAL; + return -1L; + } + + if (__stdio_check_offset (stream) == EOF) + return -1L; + + /* Start with the file position associated with the beginning + of our buffer. */ + pos = stream->__target; + + if (stream->__pushed_back) + /* ungetc was just called, so our real buffer pointer is squirreled + away in STREAM->__pushback_bufp, not in STREAM->__bufp as normal. + Calling ungetc is supposed to decrement the file position. ANSI + says the file position is unspecified if you ungetc when the + position is zero; -1 seems as good as anything to me. */ + pos += stream->__pushback_bufp - stream->__buffer - 1; + else + pos += stream->__bufp - stream->__buffer; + + return pos; +} diff --git a/stdio/fwrite.c b/stdio/fwrite.c new file mode 100644 index 0000000000..4d012f1779 --- /dev/null +++ b/stdio/fwrite.c @@ -0,0 +1,208 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + + +/* Write NMEMB chunks of SIZE bytes each from PTR onto STREAM. */ +size_t +DEFUN(fwrite, (ptr, size, nmemb, stream), + CONST PTR ptr AND size_t size AND + size_t nmemb AND register FILE *stream) +{ + register CONST unsigned char *p = (CONST unsigned char *) ptr; + register size_t to_write = size * nmemb; + register size_t written = 0; + int newlinep; + size_t buffer_space; + int default_func; + + if (!__validfp (stream) || !stream->__mode.__write) + { + errno = EINVAL; + return 0; + } + + if (ferror (stream)) + return 0; + if (p == NULL || to_write == 0) + return 0; + + if (!stream->__seen || stream->__put_limit == stream->__buffer) + { + /* This stream has never been seen before. + Calling __flshfp will give it a buffer + and I/O functions if it needs them. */ + if (__flshfp (stream, *p++) == EOF) + return 0; + if (--to_write == 0) + return 1; + else + ++written; + } + + default_func + = stream->__room_funcs.__output == __default_room_functions.__output; + + { + int save = errno; + + if (__stdio_check_offset (stream) == EOF && errno != ESPIPE) + { + stream->__error = 1; + goto done; + } + + errno = save; + } + + if (stream->__buffer == NULL && default_func && + stream->__offset == stream->__target) + write_through: + /* This is an unbuffered stream using the standard output + buffer-flushing function, so we just do a straight write. */ + { + int count = (stream->__io_funcs.__write == NULL ? to_write : + (*stream->__io_funcs.__write) (stream->__cookie, + (CONST char *) p, + to_write)); + if (count > 0) + { + written += count; + if (stream->__offset != -1) + { + stream->__offset += count; + stream->__target = stream->__offset; + } + to_write -= count; + p += count; + } + else + stream->__error = 1; + goto done; + } + + /* We ignore the end pointer here since we want to find out how much space + is really in the buffer, even for a line-buffered stream. */ + buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer); + + newlinep = (stream->__linebuf && + memchr ((CONST PTR) p, '\n', to_write) != NULL); + + if (newlinep && stream->__bufp == stream->__buffer && + stream->__offset == stream->__target) + /* The buffer's empty, and we want to write our data + out soon anyway, so just write it straight out. */ + goto write_through; + + if (stream->__bufsize == 0 && !default_func) + { + /* No buffer, and a special function. + We can't do much better than putc. */ + while (to_write-- > 0) + { + if (__flshfp (stream, *p++) == EOF) + break; + else + ++written; + } + } + else if (!default_func || buffer_space >= to_write) + fill_buffer: + /* There is enough room in the buffer for everything we + want to write or the user has specified his own output + buffer-flushing/expanding function. */ + while (to_write > 0) + { + register size_t n = to_write; + + if (n > buffer_space) + n = buffer_space; + + buffer_space -= n; + + written += n; + to_write -= n; + + if (n < 20) + while (n-- > 0) + *stream->__bufp++ = *p++; + else + { + memcpy ((PTR) stream->__bufp, (PTR) p, n); + stream->__bufp += n; + p += n; + } + + if (buffer_space == 0 || (to_write == 0 && newlinep)) + { + /* We've filled the buffer, so flush it. */ + if (fflush (stream) == EOF) + break; + + /* Reset our record of the space available in the buffer, + since we have just flushed it. */ + check_space: + buffer_space = (stream->__bufsize - + (stream->__bufp - stream->__buffer)); + if (buffer_space == 0) + { + /* With a custom output-room function, flushing might + not create any buffer space. Try writing a single + character to create the space. */ + if (__flshfp (stream, *p++) == EOF) + goto done; + ++written; + --to_write; + goto check_space; + } + } + } + else + { + /* It won't all fit in the buffer. */ + + if (stream->__bufp != stream->__buffer) + { + /* There are characters in the buffer. Flush them. */ + if (__flshfp (stream, EOF) == EOF) + goto done; + } + + /* The buffer has been flushed. + Now either fill it or write directly. */ + + buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer); + + if (stream->__offset == stream->__target && + (buffer_space < to_write || newlinep)) + /* What we have to write is bigger than the buffer, + or it contains a newline and we're line-buffered, + so write it out. */ + goto write_through; + else + /* It will fit in the buffer. */ + goto fill_buffer; + } + + done:; + return (size_t) written / size; +} diff --git a/stdio/gen-mpn-copy b/stdio/gen-mpn-copy new file mode 100644 index 0000000000..b403f27a55 --- /dev/null +++ b/stdio/gen-mpn-copy @@ -0,0 +1,31 @@ +#!/bin/sh + +translations=' +pentium i386/i586 +sparc8 sparc/sparc8 +sparc9 sparc/sparc9 +mc68000 m68k/m68000 +mc68020 m68k/m68020 +mc88100 m88k/m88100 +mc88110 m88k/m88110 +r3000 mips +r4000 mips/mips64 +hppa1_0 hppa/hppa1.0 +hppa1_1 hppa/hppa1.1 +' + +set $translations +while [ $# -ge 2 ]; do + gmp=$1 glibc=$2 + shift; shift + echo 'mpn-found-1 := $(filter $(gmp-srcdir)/mpn/'$gmp'/%,$(mpn-found)) +mpn-copy-1 := $(patsubst $(gmp-srcdir)/mpn/'$gmp'/%,$(sysdep_dir)/'$glibc\ +'/%,$(mpn-found-1)) +mpn-found := $(filter-out $(mpn-found-1),$(mpn-found)) +mpn-copy-sysdep := $(mpn-copy-sysdep) $(mpn-copy-1) +$(mpn-copy-1): $(sysdep_dir)/'$glibc'/%: \ + $(ignore gmp2glibc.sed) $(gmp-srcdir)/mpn/'$gmp'/% + $(gmp2glibc)' +done + +exit 0 diff --git a/stdio/getc.c b/stdio/getc.c new file mode 100644 index 0000000000..00aee33d31 --- /dev/null +++ b/stdio/getc.c @@ -0,0 +1,5 @@ +#include <ansidecl.h> +#include <stdio.h> +#undef getc +#define fgetc getc +#include <fgetc.c> diff --git a/stdio/getchar.c b/stdio/getchar.c new file mode 100644 index 0000000000..427de7738f --- /dev/null +++ b/stdio/getchar.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +#undef getchar + + +/* Read a character from stdin. */ +int +DEFUN_VOID(getchar) +{ + return __getc(stdin); +} diff --git a/stdio/getdelim.c b/stdio/getdelim.c new file mode 100644 index 0000000000..8047c1fe0c --- /dev/null +++ b/stdio/getdelim.c @@ -0,0 +1,173 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'd as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ + +ssize_t +DEFUN(__getdelim, (lineptr, n, terminator, stream), + char **lineptr AND size_t *n AND int terminator AND FILE *stream) +{ + char *line, *p; + size_t size, copy; + + if (!__validfp (stream) || lineptr == NULL || n == NULL) + { + errno = EINVAL; + return -1; + } + + if (ferror (stream)) + return -1; + + /* Make sure we have a line buffer to start with. */ + if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */ + { +#ifndef MAX_CANON +#define MAX_CANON 256 +#endif + line = realloc (*lineptr, MAX_CANON); + if (line == NULL) + return -1; + *lineptr = line; + *n = MAX_CANON; + } + + line = *lineptr; + size = *n; + + copy = size; + p = line; + + if (stream->__buffer == NULL && stream->__userbuf) + { + /* Unbuffered stream. Not much optimization to do. */ + + while (1) + { + size_t len; + + while (--copy > 0) + { + register int c = getc (stream); + if (c == EOF) + goto lose; + else if ((*p++ = c) == terminator) + goto win; + } + + /* Need to enlarge the line buffer. */ + len = p - line; + size *= 2; + line = realloc (line, size); + if (line == NULL) + goto lose; + *lineptr = line; + *n = size; + p = line + len; + copy = size - len; + } + } + else + { + /* Leave space for the terminating null. */ + --copy; + + if (!stream->__seen || stream->__buffer == NULL || stream->__pushed_back) + { + /* Do one with getc to allocate a buffer. */ + int c = getc (stream); + if (c == EOF) + goto lose; + *p++ = c; + if (c == terminator) + goto win; + --copy; + } + + while (1) + { + size_t i; + char *found; + + i = stream->__get_limit - stream->__bufp; + if (i == 0) + { + /* Refill the buffer. */ + int c = __fillbf (stream); + if (c == EOF) + goto lose; + *p++ = c; + if (c == terminator) + goto win; + --copy; + i = stream->__get_limit - stream->__bufp; + } + + if (i > copy) + i = copy; + + found = (char *) __memccpy ((PTR) p, stream->__bufp, terminator, i); + if (found != NULL) + { + stream->__bufp += found - p; + p = found; + goto win; + } + + stream->__bufp += i; + p += i; + copy -= i; + if (copy == 0) + { + /* Need to enlarge the line buffer. */ + size_t len = p - line; + size *= 2; + line = realloc (line, size); + if (line == NULL) + goto lose; + *lineptr = line; + *n = size; + p = line + len; + copy = size - len; + /* Leave space for the terminating null. */ + --copy; + } + } + } + + lose: + if (p == *lineptr) + return -1; + /* Return a partial line since we got an error in the middle. */ + win: + *p = '\0'; + return p - *lineptr; +} + +weak_alias (__getdelim, getdelim) diff --git a/stdio/getline.c b/stdio/getline.c new file mode 100644 index 0000000000..1a2f975c75 --- /dev/null +++ b/stdio/getline.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> + +#undef __getline + +/* Like getdelim, but always looks for a newline. */ +ssize_t +DEFUN(__getline, (lineptr, n, stream), + char **lineptr AND size_t *n AND FILE *stream) +{ + return __getdelim (lineptr, n, '\n', stream); +} + +weak_alias (__getline, getline) diff --git a/stdio/gets.c b/stdio/gets.c new file mode 100644 index 0000000000..2267792fb0 --- /dev/null +++ b/stdio/gets.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +link_warning ("the `gets' function is unreliable and should not be used.") + +/* Read a newline-terminated string from stdin into S, + removing the trailing newline. Return S or NULL. */ +char * +DEFUN(gets, (s), char *s) +{ + register char *p = s; + register int c; + FILE *stream = stdin; + + if (!__validfp(stream) || p == NULL) + { + errno = EINVAL; + return NULL; + } + + if (feof(stream) || ferror(stream)) + return NULL; + + while ((c = getchar()) != EOF) + if (c == '\n') + break; + else + *p++ = c; + + *p = '\0'; + + /* Return null if we had an error, or if we got EOF + before writing any characters. */ + + if (ferror (stream) || (feof (stream) && p == s)) + return NULL; + + return s; +} diff --git a/stdio/getw.c b/stdio/getw.c new file mode 100644 index 0000000000..45d4d8875d --- /dev/null +++ b/stdio/getw.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + + +/* Read a word (int) from STREAM. */ +int +DEFUN(getw, (stream), FILE *stream) +{ + int w; + + /* Is there a better way? */ + if (fread((PTR) &w, sizeof(w), 1, stream) != 1) + return(EOF); + return(w); +} diff --git a/stdio/glue.c b/stdio/glue.c new file mode 100644 index 0000000000..6ef52a7ada --- /dev/null +++ b/stdio/glue.c @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file provides glue between Unix stdio and GNU stdio. + It supports use of Unix stdio `getc' and `putc' (and, by extension, + `getchar' and `putchar') macros on GNU stdio streams (they are slow, but + they work). It also supports all stdio operations (including Unix + `getc' and `putc') on Unix's stdin, stdout, and stderr (the elements of + `_iob'). + + The reasoning behind this is to allow programs (and especially + libraries) compiled with Unix header files to work with the GNU C + library. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <errno.h> + +typedef union + { + struct + { + int magic; + FILE **streamp; /* Overlaps GNU stdio `bufp' member. */ + /* These two overlap the GNU stdio `get_limit' and `put_limit' + members. They must be <= `streamp'/`bufp' for GNU getc and putc + to do the right thing. */ + FILE **streamp2, **streamp3; + } glue; + struct _iobuf + { + int _cnt; + unsigned char *_ptr; + unsigned char *_base; + int _bufsiz; + short int _flag; + char _file; + } unix_iobuf; + FILE gnu_stream; + } unix_FILE; + +/* These are the Unix stdio's stdin, stdout, and stderr. + In Unix stdin is (&_iob[0]), stdout is (&_iob[1]), and stderr is + (&_iob[2]). The magic number marks these as glued streams. The + __validfp macro in stdio.h is used by every stdio function. It checks + for glued streams, and replaces them with the GNU stdio stream. */ +unix_FILE _iob[] = + { +#define S(name) { { _GLUEMAGIC, &name, &name, &name } } + S (stdin), + S (stdout), + S (stderr), +#undef S + }; + +/* Called by the Unix stdio `getc' macro. + The macro is assumed to look something like: + (--file->_cnt < 0 ? _filbuf (file) ...) + In a Unix stdio FILE `_cnt' is the first element. + In a GNU stdio or glued FILE, the first element is the magic number. */ +int +DEFUN(_filbuf, (file), unix_FILE *file) +{ + switch (++file->glue.magic) /* Compensate for Unix getc's decrement. */ + { + case _GLUEMAGIC: + /* This is a glued stream. */ + return getc (*file->glue.streamp); + + case _IOMAGIC: + /* This is a normal GNU stdio stream. */ + return getc ((FILE *) file); + + default: + /* Bogus stream. */ + errno = EINVAL; + return EOF; + } +} + +/* Called by the Unix stdio `putc' macro. Much like getc, above. */ +int +DEFUN(_flsbuf, (c, file), + int c AND unix_FILE *file) +{ + /* Compensate for putc's decrement. */ + switch (++file->glue.magic) + { + case _GLUEMAGIC: + return putc (c, *file->glue.streamp); + + case _IOMAGIC: + return putc (c, (FILE *) file); + + default: + errno = EINVAL; + return EOF; + } +} diff --git a/stdio/gmp-impl.h b/stdio/gmp-impl.h new file mode 100644 index 0000000000..ccffe7bb1e --- /dev/null +++ b/stdio/gmp-impl.h @@ -0,0 +1,283 @@ +/* Include file for internal GNU MP types and definitions. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if ! defined (alloca) +#if defined (__GNUC__) || defined (__sparc__) || defined (sparc) +#define alloca __builtin_alloca +#endif +#endif + +#ifndef NULL +#define NULL 0L +#endif + +#if ! defined (__GNUC__) +#define inline /* Empty */ +void *alloca(); +#endif + +#define ABS(x) (x >= 0 ? x : -x) +#define MIN(l,o) ((l) < (o) ? (l) : (o)) +#define MAX(h,i) ((h) > (i) ? (h) : (i)) + +#include "gmp-mparam.h" +/* #include "longlong.h" */ + +#ifdef __STDC__ +void *malloc (size_t); +void *realloc (void *, size_t); +void free (void *); + +extern void * (*_mp_allocate_func) (size_t); +extern void * (*_mp_reallocate_func) (void *, size_t, size_t); +extern void (*_mp_free_func) (void *, size_t); + +void *_mp_default_allocate (size_t); +void *_mp_default_reallocate (void *, size_t, size_t); +void _mp_default_free (void *, size_t); + +#else + +#define const /* Empty */ +#define signed /* Empty */ + +void *malloc (); +void *realloc (); +void free (); + +extern void * (*_mp_allocate_func) (); +extern void * (*_mp_reallocate_func) (); +extern void (*_mp_free_func) (); + +void *_mp_default_allocate (); +void *_mp_default_reallocate (); +void _mp_default_free (); +#endif + +/* Copy NLIMBS *limbs* from SRC to DST. */ +#define MPN_COPY_INCR(DST, SRC, NLIMBS) \ + do { \ + mp_size_t __i; \ + for (__i = 0; __i < (NLIMBS); __i++) \ + (DST)[__i] = (SRC)[__i]; \ + } while (0) +#define MPN_COPY_DECR(DST, SRC, NLIMBS) \ + do { \ + mp_size_t __i; \ + for (__i = (NLIMBS) - 1; __i >= 0; __i--) \ + (DST)[__i] = (SRC)[__i]; \ + } while (0) +#define MPN_COPY MPN_COPY_INCR + +/* Zero NLIMBS *limbs* AT DST. */ +#define MPN_ZERO(DST, NLIMBS) \ + do { \ + mp_size_t __i; \ + for (__i = 0; __i < (NLIMBS); __i++) \ + (DST)[__i] = 0; \ + } while (0) + +#define MPN_NORMALIZE(DST, NLIMBS) \ + do { \ + while (NLIMBS > 0) \ + { \ + if ((DST)[(NLIMBS) - 1] != 0) \ + break; \ + NLIMBS--; \ + } \ + } while (0) +#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \ + do { \ + while (1) \ + { \ + if ((DST)[(NLIMBS) - 1] != 0) \ + break; \ + NLIMBS--; \ + } \ + } while (0) + +/* Swap (mp_ptr, mp_size_t) (U, UL) with (V, VL) */ +#define MPN_SWAP(u, l, v, m) \ + do { \ + { mp_ptr _; _ = (u), (u) = (v), (v) = _;} \ + { mp_size_t _; _ = (l), (l) = (m), (m) = _;} \ + } while (0) + +/* Return true iff the limb X has less bits than the limb Y. */ +#define MPN_LESS_BITS_LIMB(x,y) ((x) < (y) && (x) < ((x) ^ (y))) + +/* Return true iff (mp_ptr, mp_size_t) (U, UL) has less bits than (V, VL). */ +#define MPN_LESS_BITS(u, l, v, m) \ + ((l) < (m) \ + || ((l) == (m) && (l) != 0 && MPN_LESS_BITS_LIMB ((u)[(l - 1)], (v)[(l) - 1]))) + +/* Return true iff (mp_ptr, mp_size_t) (U, UL) has more bits than (V, VL). */ +#define MPN_MORE_BITS(u, l, v, m) MPN_LESS_BITS (v, m, u, l) + +/* Perform twos complement on (mp_ptr, mp_size_t) (U, UL), + putting result at (v, VL). Precondition: U[0] != 0. */ +#define MPN_COMPL_INCR(u, v, l) \ + do { \ + mp_size_t _ = 0; \ + (u)[0] = -(v)[_]; \ + while (_++ < (l)) \ + (u)[_] = ~(v)[_]; \ + } while (0) +#define MPN_COMPL MPN_COMPL_INCR + +/* Initialize the MP_INT X with space for NLIMBS limbs. + X should be a temporary variable, and it will be automatically + cleared out when the running function returns. + We use __x here to make it possible to accept both mpz_ptr and mpz_t + arguments. */ +#define MPZ_TMP_INIT(X, NLIMBS) \ + do { \ + mpz_ptr __x = (X); \ + __x->alloc = (NLIMBS); \ + __x->d = (mp_ptr) alloca ((NLIMBS) * BYTES_PER_MP_LIMB); \ + } while (0) + +#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ + do { \ + if ((size) < KARATSUBA_THRESHOLD) \ + ____mpn_mul_n_basecase (prodp, up, vp, size); \ + else \ + ____mpn_mul_n (prodp, up, vp, size, tspace); \ + } while (0); +#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \ + do { \ + if ((size) < KARATSUBA_THRESHOLD) \ + ____mpn_sqr_n_basecase (prodp, up, size); \ + else \ + ____mpn_sqr_n (prodp, up, size, tspace); \ + } while (0); + +/* Structure for conversion between internal binary format and + strings in base 2..36. */ +struct bases +{ + /* Number of digits in the conversion base that always fits in + an mp_limb. For example, for base 10 this is 10, since + 2**32 = 4294967296 has ten digits. */ + int chars_per_limb; + + /* log(2)/log(conversion_base) */ + float chars_per_bit_exactly; + + /* big_base is conversion_base**chars_per_limb, i.e. the biggest + number that fits a word, built by factors of conversion_base. + Exception: For 2, 4, 8, etc, big_base is log2(base), i.e. the + number of bits used to represent each digit in the base. */ + mp_limb big_base; + + /* big_base_inverted is a BITS_PER_MP_LIMB bit approximation to + 1/big_base, represented as a fixed-point number. Instead of + dividing by big_base an application can choose to multiply + by big_base_inverted. */ + mp_limb big_base_inverted; +}; + +extern const struct bases __mp_bases[]; +extern mp_size_t __gmp_default_fp_limb_precision; + +/* Divide the two-limb number in (NH,,NL) by D, with DI being a 32 bit + approximation to (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB). + Put the quotient in Q and the remainder in R. */ +#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ + do { \ + mp_limb _q, _ql, _r; \ + mp_limb _xh, _xl; \ + umul_ppmm (_q, _ql, (nh), (di)); \ + _q += (nh); /* DI is 2**BITS_PER_MP_LIMB too small */\ + umul_ppmm (_xh, _xl, _q, (d)); \ + sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \ + if (_xh != 0) \ + { \ + sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ + _q += 1; \ + if (_xh != 0) \ + { \ + sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ + _q += 1; \ + } \ + } \ + if (_r >= (d)) \ + { \ + _r -= (d); \ + _q += 1; \ + } \ + (r) = _r; \ + (q) = _q; \ + } while (0) +#define udiv_qrnnd_preinv2gen(q, r, nh, nl, d, di, dnorm, lgup) \ + do { \ + mp_limb n2, n10, n1, nadj, q1; \ + mp_limb _xh, _xl; \ + n2 = ((nh) << (BITS_PER_MP_LIMB - (lgup))) + ((nl) >> 1 >> (l - 1));\ + n10 = (nl) << (BITS_PER_MP_LIMB - (lgup)); \ + n1 = ((mp_limb_signed) n10 >> (BITS_PER_MP_LIMB - 1)); \ + nadj = n10 + (n1 & (dnorm)); \ + umul_ppmm (_xh, _xl, di, n2 - n1); \ + add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \ + q1 = ~(n2 + _xh); \ + umul_ppmm (_xh, _xl, q1, d); \ + add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \ + _xh -= (d); \ + (r) = _xl + ((d) & _xh); \ + (q) = _xh - q1; \ + } while (0) +#define udiv_qrnnd_preinv2norm(q, r, nh, nl, d, di) \ + do { \ + mp_limb n2, n10, n1, nadj, q1; \ + mp_limb _xh, _xl; \ + n2 = (nh); \ + n10 = (nl); \ + n1 = ((mp_limb_signed) n10 >> (BITS_PER_MP_LIMB - 1)); \ + nadj = n10 + (n1 & (d)); \ + umul_ppmm (_xh, _xl, di, n2 - n1); \ + add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \ + q1 = ~(n2 + _xh); \ + umul_ppmm (_xh, _xl, q1, d); \ + add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \ + _xh -= (d); \ + (r) = _xl + ((d) & _xh); \ + (q) = _xh - q1; \ + } while (0) + +#if defined (__GNUC__) +/* Define stuff for longlong.h asm macros. */ +#if __GNUC_NEW_ATTR_MODE_SYNTAX +typedef unsigned int UQItype __attribute__ ((mode ("QI"))); +typedef int SItype __attribute__ ((mode ("SI"))); +typedef unsigned int USItype __attribute__ ((mode ("SI"))); +typedef int DItype __attribute__ ((mode ("DI"))); +typedef unsigned int UDItype __attribute__ ((mode ("DI"))); +#else +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#endif +#endif + +typedef mp_limb UWtype; +typedef unsigned int UHWtype; +#define W_TYPE_SIZE BITS_PER_MP_LIMB diff --git a/stdio/gmp.h b/stdio/gmp.h new file mode 100644 index 0000000000..95c2f1beba --- /dev/null +++ b/stdio/gmp.h @@ -0,0 +1,525 @@ +/* gmp.h -- Definitions for GNU multiple precision functions. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef __GMP_H__ + +#ifndef __GNU_MP__ +#define __need_size_t +#include <stddef.h> + +#ifdef __STDC__ +#define __gmp_const const +#else +#define __gmp_const +#endif + +#ifdef __GNUC__ +#define __gmp_inline inline +#else +#define __gmp_inline +#endif + +#ifdef _SHORT_LIMB +typedef unsigned int mp_limb; +typedef int mp_limb_signed; +#else +typedef unsigned long int mp_limb; +typedef long int mp_limb_signed; +#endif + +typedef mp_limb * mp_ptr; +typedef __gmp_const mp_limb * mp_srcptr; +typedef int mp_size_t; +typedef long int mp_exp_t; + +#ifndef __MP_SMALL__ +typedef struct +{ + long int alloc; /* Number of *limbs* allocated and pointed + to by the D field. */ + long int size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_limb *d; /* Pointer to the limbs. */ +} __mpz_struct; +#else +typedef struct +{ + short int alloc; /* Number of *limbs* allocated and pointed + to by the D field. */ + short int size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_limb *d; /* Pointer to the limbs. */ +} __mpz_struct; +#endif +#endif /* __GNU_MP__ */ + +/* User-visible types. */ +typedef __mpz_struct MP_INT; +typedef __mpz_struct mpz_t[1]; + +/* Structure for rational numbers. Zero is represented as 0/any, i.e. + the denominator is ignored. Negative numbers have the sign in + the numerator. */ +typedef struct +{ + __mpz_struct num; + __mpz_struct den; +#if 0 + long int num_alloc; /* Number of limbs allocated + for the numerator. */ + long int num_size; /* The absolute value of this field is the + length of the numerator; the sign is the + sign of the entire rational number. */ + mp_ptr num; /* Pointer to the numerator limbs. */ + long int den_alloc; /* Number of limbs allocated + for the denominator. */ + long int den_size; /* Length of the denominator. (This field + should always be positive.) */ + mp_ptr den; /* Pointer to the denominator limbs. */ +#endif +} __mpq_struct; + +typedef __mpq_struct MP_RAT; +typedef __mpq_struct mpq_t[1]; + +typedef struct +{ + mp_size_t alloc; /* Number of *limbs* allocated and pointed + to by the D field. */ + mp_size_t prec; /* Max precision, in number of `mp_limb's. + Set by mpf_init and modified by + mpf_set_prec. */ + mp_size_t size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_exp_t exp; /* Exponent, in the base of `mp_limb'. */ + mp_limb *d; /* Pointer to the limbs. */ +} __mpf_struct; + +/* typedef __mpf_struct MP_FLOAT; */ +typedef __mpf_struct mpf_t[1]; + +/* Types for function declarations in gmp files. */ +/* ??? Should not pollute user name space ??? */ +typedef __gmp_const __mpz_struct *mpz_srcptr; +typedef __mpz_struct *mpz_ptr; +typedef __gmp_const __mpf_struct *mpf_srcptr; +typedef __mpf_struct *mpf_ptr; +typedef __gmp_const __mpq_struct *mpq_srcptr; +typedef __mpq_struct *mpq_ptr; + +#ifdef __STDC__ +#define _PROTO(x) x +#else +#define _PROTO(x) () +#endif + +void mp_set_memory_functions _PROTO((void *(*) (size_t), + void *(*) (void *, size_t, size_t), + void (*) (void *, size_t))); + +/**************** Integer (i.e. Z) routines. ****************/ + +void *_mpz_realloc _PROTO ((mpz_ptr, mp_size_t)); + +void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_add _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_and _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_clear _PROTO ((mpz_ptr)); +void mpz_clrbit _PROTO ((mpz_ptr, unsigned long int)); +int mpz_cmp _PROTO ((mpz_srcptr, mpz_srcptr)); +int mpz_cmp_si _PROTO ((mpz_srcptr, signed long int)); +int mpz_cmp_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_com _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_div_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fac_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_gcd _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +/* signed */ long int mpz_get_si _PROTO ((mpz_srcptr)); +char *mpz_get_str _PROTO ((char *, int, mpz_srcptr)); +unsigned long int mpz_get_ui _PROTO ((mpz_srcptr)); +mp_limb mpz_getlimbn _PROTO ((mpz_srcptr, mp_size_t)); +mp_size_t mpz_hamdist _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_init _PROTO ((mpz_ptr)); +#ifdef FILE +void mpz_inp_raw _PROTO ((mpz_ptr, FILE *)); +int mpz_inp_str _PROTO ((mpz_ptr, FILE *, int)); +#endif +void mpz_ior _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_init_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_init_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_init_set_str _PROTO ((mpz_ptr, const char *, int)); +void mpz_init_set_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_lcm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mod_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_mul _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr)); +#ifdef FILE +void mpz_out_raw _PROTO ((FILE *, mpz_srcptr)); +void mpz_out_str _PROTO ((FILE *, int, mpz_srcptr)); +#endif +int mpz_perfect_square_p _PROTO ((mpz_srcptr)); +mp_size_t mpz_popcount _PROTO ((mpz_srcptr)); +void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr)); +void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr)); +int mpz_probab_prime_p _PROTO ((mpz_srcptr, int)); +void mpz_random _PROTO ((mpz_ptr, mp_size_t)); +void mpz_random2 _PROTO ((mpz_ptr, mp_size_t)); +void mpz_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_set_str _PROTO ((mpz_ptr, const char *, int)); +void mpz_set_ui _PROTO ((mpz_ptr, unsigned long int)); +size_t mpz_size _PROTO ((mpz_srcptr)); +size_t mpz_sizeinbase _PROTO ((mpz_srcptr, int)); +void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr)); +void mpz_sub _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_ui_pow_ui _PROTO ((mpz_ptr, unsigned long int, unsigned long int)); + +void mpz_fdiv_q _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_fdiv_q_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_qr _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_fdiv_qr_ui _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_r _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_fdiv_r_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_ui _PROTO((mpz_srcptr, unsigned long int)); +void mpz_tdiv_q _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_q_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_qr _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_qr_ui _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_r _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_r_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int)); + +/**************** Rational (i.e. Q) routines. ****************/ + +void mpq_init _PROTO ((mpq_ptr)); +void mpq_clear _PROTO ((mpq_ptr)); +void mpq_set _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_ui _PROTO ((mpq_ptr, unsigned long int, unsigned long int)); +void mpq_set_si _PROTO ((mpq_ptr, signed long int, unsigned long int)); +void mpq_add _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_sub _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_mul _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_div _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_neg _PROTO ((mpq_ptr, mpq_srcptr)); +int mpq_cmp _PROTO ((mpq_srcptr, mpq_srcptr)); +void mpq_inv _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_num _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_set_den _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_get_num _PROTO ((mpz_ptr, mpq_srcptr)); +void mpq_get_den _PROTO ((mpz_ptr, mpq_srcptr)); + +/**************** Float (i.e. F) routines. ****************/ + +void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_add _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_add_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_clear _PROTO ((mpf_ptr)); +int mpf_cmp _PROTO ((mpf_srcptr, mpf_srcptr)); +int mpf_cmp_si _PROTO ((mpf_srcptr, long int)); +int mpf_cmp_ui _PROTO ((mpf_srcptr, unsigned long int)); +void mpf_div _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_div_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_dump _PROTO ((mpf_srcptr)); +char *mpf_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpf_srcptr)); +void mpf_init _PROTO ((mpf_ptr)); +void mpf_init2 _PROTO ((mpf_ptr, mp_size_t)); +#ifdef FILE +void mpf_inp_str _PROTO ((mpf_ptr, FILE *, int)); +#endif +void mpf_init_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_init_set_d _PROTO ((mpf_ptr, double)); +void mpf_init_set_si _PROTO ((mpf_ptr, long int)); +int mpf_init_set_str _PROTO ((mpf_ptr, char *, int)); +void mpf_init_set_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_mul _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_mul_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr)); +#ifdef FILE +void mpf_out_str _PROTO ((mpf_ptr, int, size_t, FILE *)); +#endif +void mpf_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_set_d _PROTO ((mpf_ptr, double)); +mp_size_t mpf_set_default_prec _PROTO ((mp_size_t)); +void mpf_set_si _PROTO ((mpf_ptr, long int)); +int mpf_set_str _PROTO ((mpf_ptr, const char *, int)); +void mpf_set_ui _PROTO ((mpf_ptr, unsigned long int)); +size_t mpf_size _PROTO ((mpf_srcptr)); +void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_sqrt_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_sub _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_sub_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_ui_div _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); + +/************ Low level positive-integer (i.e. N) routines. ************/ + +/* This is ugly, but we need to make usr calls reach the prefixed function. */ +#define mpn_add_n __mpn_add_n +#define mpn_sub_n __mpn_sub_n +#define mpn_mul_1 __mpn_mul_1 +#define mpn_addmul_1 __mpn_addmul_1 +#define mpn_submul_1 __mpn_submul_1 +#define mpn_lshift __mpn_lshift +#define mpn_rshift __mpn_rshift +#define mpn_sub __mpn_sub +#define mpn_add __mpn_add +#define mpn_normal_size __mpn_normal_size +#define mpn_cmp __mpn_cmp +#define mpn_add_1 __mpn_add_1 +#define mpn_sub_1 __mpn_sub_1 +#define mpn_mul_n __mpn_mul_n +#define mpn_mul __mpn_mul +#define mpn_divmod __mpn_divmod +#define mpn_divmod_1 __mpn_divmod_1 +#define mpn_mod_1 __mpn_mod_1 +#define mpn_sqrt __mpn_sqrt +#define mpn_next_bit_set __mpn_next_bit_set +#define mpn_popcount __mpn_popcount +#define mpn_hamdist __mpn_hamdist +#define mpn_random2 __mpn_random2 +#define mpn_set_str __mpn_set_str +#define mpn_get_str __mpn_get_str +#define mpn_gcd_1 __mpn_gcd_1 + +mp_limb __mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb __mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb __mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)); +void __mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb __mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb)); +mp_limb __mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb)); +mp_limb __mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb)); +mp_limb __mpn_divmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t)); +mp_limb __mpn_divmod_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb)); +mp_limb __mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb)); +mp_limb __mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +mp_limb __mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +mp_size_t __mpn_sqrt _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t)); +int __mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +mp_size_t __mpn_next_bit_set _PROTO ((mp_srcptr, mp_size_t)); +mp_size_t __mpn_popcount _PROTO ((mp_srcptr, mp_size_t)); +mp_size_t __mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +void __mpn_random2 _PROTO ((mp_ptr, mp_size_t)); +mp_size_t __mpn_set_str _PROTO ((mp_ptr, const unsigned char *, size_t, int)); +size_t __mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t)); +mp_limb __mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb)); + + +static __gmp_inline mp_limb +#if __STDC__ +__mpn_add_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb s2_limb) +#else +__mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb s2_limb; +#endif +{ + register mp_limb x; + + x = *s1_ptr++; + s2_limb = x + s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb < x) + { + while (--s1_size != 0) + { + x = *s1_ptr++ + 1; + *res_ptr++ = x; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +static __gmp_inline mp_limb +#if __STDC__ +__mpn_add (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +__mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb cy_limb = 0; + + if (s2_size != 0) + cy_limb = __mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = __mpn_add_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} + +static __gmp_inline mp_limb +#if __STDC__ +__mpn_sub_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb s2_limb) +#else +__mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb s2_limb; +#endif +{ + register mp_limb x; + + x = *s1_ptr++; + s2_limb = x - s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb > x) + { + while (--s1_size != 0) + { + x = *s1_ptr++; + *res_ptr++ = x - 1; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +static __gmp_inline mp_limb +#if __STDC__ +__mpn_sub (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +__mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb cy_limb = 0; + + if (s2_size != 0) + cy_limb = __mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = __mpn_sub_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} + +static __gmp_inline mp_size_t +#if __STDC__ +__mpn_normal_size (mp_srcptr ptr, mp_size_t size) +#else +__mpn_normal_size (ptr, size) + mp_srcptr ptr; + mp_size_t size; +#endif +{ + while (size) + { + size--; + if (ptr[size] != 0) + return size + 1; + } + return 0; +} + +/* Compatibility with GMP 1. */ + +#define mpz_mdiv mpz_fdiv_q +#define mpz_mdivmod mpz_fdiv_qr +#define mpz_mmod mpz_fdiv_r +#define mpz_mdiv_ui mpz_fdiv_q_ui +#define mpz_mdivmod_ui(q,r,n,d) \ + ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d)) +#define mpz_mmod_ui(r,n,d) \ + ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d)) +/* ??? Before release... +#define mpz_div_2exp mpz_fdiv_q_2exp +#define mpz_mod_2exp mpz_fdiv_r_2exp +*/ + +/* Useful synonyms, but not quite compatible with GMP 1. */ +#define mpz_div mpz_fdiv_q +#define mpz_divmod mpz_fdiv_qr +#define mpz_mod mpz_fdiv_r +#define mpz_div_ui mpz_fdiv_q_ui +#define mpz_divmod_ui mpz_fdiv_qr_ui +#define mpz_mod_ui mpz_fdiv_r_ui + + +#define __GNU_MP__ 2 +#define __GNU_MP_VERSION 2 +#define __GNU_MP_VERSION_MINOR -900 /* ??? */ +#define __GMP_H__ +#endif /* __GMP_H__ */ diff --git a/stdio/internals.c b/stdio/internals.c new file mode 100644 index 0000000000..b01c5bd531 --- /dev/null +++ b/stdio/internals.c @@ -0,0 +1,667 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Make sure that FP has its functions set. */ +void +DEFUN(__stdio_check_funcs, (fp), register FILE *fp) +{ + if (!fp->__seen) + { + /* Initialize the stream's info, including buffering info. + This may give a buffer, change I/O functions, etc. + If no buffer is set (and the stream is not made explicitly + unbuffered), we allocate a buffer below, using the bufsize + set by this function. */ + extern void EXFUN(__stdio_init_stream, (FILE *)); + fp->__room_funcs = __default_room_functions; + fp->__io_funcs = __default_io_functions; + __stdio_init_stream (fp); + fp->__seen = 1; + } +} + + +/* Minimum size of a buffer we will allocate by default. + If this much memory is not available, + the stream in question will be made unbuffered instead. */ +#define MIN_BUFSIZE 128 + +/* Figure out what kind of buffering (none, line, or full) + and what buffer size to give FP. */ +static void +DEFUN(init_stream, (fp), register FILE *fp) +{ + __stdio_check_funcs (fp); + + if (fp->__buffer == NULL && !fp->__userbuf) + { + int save; + + if (fp->__bufsize == 0) + fp->__bufsize = BUFSIZ; + + /* Try to get however many bytes of buffering __stdio_pickbuf + specified, but if that much memory isn't available, + try half as much each time until it succeeds or the buffer + size becomes too small to be useful. */ + save = errno; + while (fp->__bufsize >= MIN_BUFSIZE) + { + fp->__buffer = (char *) malloc(fp->__bufsize); + if (fp->__buffer == NULL) + fp->__bufsize /= 2; + else + break; + } + errno = save; + + if (fp->__buffer == NULL) + { + /* We can't get space for the buffer, so make it unbuffered. */ + fp->__userbuf = 1; + fp->__bufsize = 0; + } + } + + if (fp->__bufp == NULL) + { + /* Set the buffer pointer to the beginning of the buffer. */ + fp->__bufp = fp->__buffer; + fp->__put_limit = fp->__get_limit = fp->__buffer; + } +} + + +/* Determine the current file position of STREAM if it is unknown. */ +int +DEFUN(__stdio_check_offset, (stream), FILE *stream) +{ + init_stream (stream); + + if (stream->__offset == (fpos_t) -1) + { + /* This stream's offset is unknown or unknowable. */ + if (stream->__io_funcs.__seek == NULL) + { + /* Unknowable. */ + errno = ESPIPE; + return EOF; + } + else + { + /* Unknown. Find it out. */ + fpos_t pos = (fpos_t) 0; + if ((*stream->__io_funcs.__seek)(stream->__cookie, + &pos, SEEK_CUR) < 0) + { + if (errno == ESPIPE) + /* Object is incapable of seeking. */ + stream->__io_funcs.__seek = NULL; + return EOF; + } + stream->__offset = pos; + } + } + + if (stream->__target == (fpos_t) -1) + /* This stream was opened on an existing object with + an unknown file position. The position is now known. + Make this the target position. */ + stream->__target = stream->__offset; + + return 0; +} + + +/* Move FP's file position to its target file position, + seeking as necessary and updating its `offset' field. + Sets ferror(FP) (and possibly errno) for errors. */ +static void +DEFUN(seek_to_target, (fp), FILE *fp) +{ + int save = errno; + if (__stdio_check_offset (fp) == EOF) + { + if (errno == ESPIPE) + errno = save; + else + fp->__error = 1; + } + else if (fp->__target != fp->__offset) + { + /* We are not at the target file position. + Seek to that position. */ + if (fp->__io_funcs.__seek == NULL) + { + /* We can't seek! */ + errno = ESPIPE; + fp->__error = 1; + } + else + { + fpos_t pos = fp->__target; + if ((*fp->__io_funcs.__seek)(fp->__cookie, &pos, SEEK_SET) < 0) + /* Seek failed! */ + fp->__error = 1; + else + { + fp->__offset = pos; + if (pos != fp->__target) + /* Seek didn't go to the right place! */ + fp->__error = 1; + } + } + } +} + +/* Flush the buffer for FP. + If C is not EOF, it is also to be written. + If the stream is line buffered and C is a newline, it is written + to the output, otherwise it is put in the buffer after it has been + flushed to avoid a system call for a single character. + This is the default `output room' function. */ +static void +DEFUN(flushbuf, (fp, c), + register FILE *fp AND int c) +{ + int flush_only = c == EOF; + size_t buffer_written; + size_t to_write; + + /* Set if target and get_limit have already been twiddled appropriately. */ + int twiddled = 0; + + if (fp->__put_limit == fp->__buffer) + { + /* The stream needs to be primed for writing. */ + + size_t buffer_offset = 0; + + /* If the user has read some of the buffer, the target position + is incremented for each character he has read. */ + fp->__target += fp->__bufp - fp->__buffer; + + if (fp->__mode.__read && fp->__room_funcs.__input != NULL && + !fp->__mode.__append) + { + int save = errno; + CONST int aligned = (fp->__buffer == NULL || + __stdio_check_offset(fp) == EOF || + fp->__target % fp->__bufsize == 0); + errno = save; + + if (!aligned) + { + /* Move to a block (buffer size) boundary and read in a block. + Then the output will be written as a whole block, too. */ + CONST size_t o = fp->__target % fp->__bufsize; + fp->__target -= o; + if ((*fp->__room_funcs.__input)(fp) == EOF && ferror(fp)) + return; + else + __clearerr(fp); + + if (fp->__get_limit - fp->__buffer < o) + /* Oops. We didn't read enough (probably because we got EOF). + Forget we even mentioned it. */ + fp->__target += o; + else + /* Start bufp as far into the buffer as we were into + this block before we read it. */ + buffer_offset = o; + } + + /* The target position is now set to where the beginning of the + buffer maps to; and the get_limit was set by the input-room + function. */ + twiddled = 1; + } + + if (fp->__buffer != NULL) + { + /* Set up to write output into the buffer. */ + fp->__put_limit = fp->__buffer + fp->__bufsize; + fp->__bufp = fp->__buffer + buffer_offset; + + if (!flush_only) + { + /* Put C in the buffer to be written out. + We only need to actually write it out now if + it is a newline on a line-buffered stream. */ + *fp->__bufp++ = (unsigned char) c; + if (!fp->__linebuf || (unsigned char) c != '\n') + { + /* There is no need to flush C from the buffer right now. + Record that nothing was written from the buffer, + and go do clean-up at end. */ + buffer_written = 0; + goto end; + } + else + /* We put C in the buffer, so don't write it again later. */ + flush_only = 1; + } + } + + if (fp->__bufp - fp->__buffer <= buffer_offset) + { + /* There is nothing new in the buffer, only data that + was read back aligned from the file. */ + buffer_written = 0; + goto end; + } + } + + /* If there is read data in the buffer past what was written, + write all of that as well. Otherwise, just write what has been + written into the buffer. */ + buffer_written = fp->__bufp - fp->__buffer; + to_write = (buffer_written == 0 ? 0 : + fp->__get_limit > fp->__bufp ? + fp->__get_limit - fp->__buffer : + buffer_written); + + if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only)) + { + /* There is no writing function or we're coming from an fflush + call with nothing in the buffer, so just say the buffer's + been flushed, increment the file offset, and return. */ + fp->__bufp = fp->__buffer; + fp->__offset += to_write; + goto end; + } + + if (to_write > 0) + { + int wrote; + + /* Go to the target file position. Don't bother if appending; + the write will just ignore the file position anyway. */ + if (!fp->__mode.__append) + seek_to_target (fp); + + if (!ferror(fp)) + { + /* Write out the buffered data. */ + wrote = (*fp->__io_funcs.__write)(fp->__cookie, fp->__buffer, + to_write); + if (wrote > 0) + { + if (fp->__mode.__append) + /* The write has written the data to the end of the file + and updated the file position to after the data. Don't + bother to find the current position; we can get it + later if we need it. */ + fp->__offset = fp->__target = -1; + else + /* Record that we've moved forward in the file. */ + fp->__offset += wrote; + } + if (wrote < (int) to_write) + /* The writing function should always write + the whole buffer unless there is an error. */ + fp->__error = 1; + } + } + + /* Reset the buffer pointer to the beginning of the buffer. */ + fp->__bufp = fp->__buffer; + + /* If we're not just flushing, write the last character, C. */ + if (!flush_only && !ferror(fp)) + { + if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n')) + { + /* Either we're unbuffered, or we're line-buffered and + C is a newline, so really write it out immediately. */ + char cc = (unsigned char) c; + if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1) + fp->__error = 1; + else + { + /* Record that we've moved forward in the file. */ + ++fp->__offset; + ++fp->__target; + } + } + else + /* Just put C in the buffer. */ + *fp->__bufp++ = (unsigned char) c; + } + + end: + + if (!twiddled) + { + /* The new target position moves up as + much as the user wrote into the buffer. */ + fp->__target += buffer_written; + + /* Set the reading limit to the beginning of the buffer, + so the next `getc' will call __fillbf. */ + fp->__get_limit = fp->__buffer; + } + + if (feof(fp) || ferror(fp)) + fp->__bufp = fp->__put_limit; +} + + +/* Fill the buffer for FP and return the first character read (or EOF). + This is the default `input_room' function. */ +static int +DEFUN(fillbuf, (fp), register FILE *fp) +{ + /* How far into the buffer we read we want to start bufp. */ + size_t buffer_offset = 0; + register char *buffer; + register size_t to_read, nread = 0; + /* This must be unsigned to avoid sign extension in return. */ + unsigned char c; + + if (fp->__io_funcs.__read == NULL) + { + /* There is no read function, so always return EOF. */ + fp->__eof = 1; + goto end; + } + + if (fp->__buffer == NULL) + { + /* We're unbuffered, so we want to read only one character. */ + buffer = (char *) &c; + to_read = 1; + } + else + { + /* We're buffered, so try to fill the buffer. */ + buffer = fp->__buffer; + to_read = fp->__bufsize; + } + + /* We're reading, so we're not at the end-of-file. */ + fp->__eof = 0; + + /* Go to the target file position. */ + { + int save = errno; + if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset) + { + /* Move to a block (buffer size) boundary. */ + if (fp->__bufsize != 0) + { + buffer_offset = fp->__target % fp->__bufsize; + fp->__target -= buffer_offset; + } + seek_to_target (fp); + } + errno = save; + } + + while (!ferror(fp) && !feof(fp) && nread <= buffer_offset) + { + /* Try to fill the buffer. */ + int count = (*fp->__io_funcs.__read)(fp->__cookie, buffer, to_read); + if (count == 0) + fp->__eof = 1; + else if (count < 0) + fp->__error = 1; + else + { + buffer += count; + nread += count; + to_read -= count; + /* Record that we've moved forward in the file. */ + fp->__offset += count; + } + } + + if (fp->__buffer == NULL) + /* There is no buffer, so return the character we read + without all the buffer pointer diddling. */ + return (feof(fp) || ferror(fp)) ? EOF : c; + + /* Reset the buffer pointer to the beginning of the buffer + (plus whatever offset we may have set above). */ + fp->__bufp = fp->__buffer + buffer_offset; + + end:; + + if (feof(fp) || ferror(fp)) + { + /* Set both end pointers to the beginning of the buffer so + the next i/o call will force a call to __fillbf/__flshfp. */ + fp->__put_limit = fp->__get_limit = fp->__buffer; + return EOF; + } + + /* Set the end pointer to one past the last character we read. */ + fp->__get_limit = fp->__buffer + nread; + + /* Make it so the next `putc' will call __flshfp. */ + fp->__put_limit = fp->__buffer; + + /* Return the first character in the buffer. */ + return *((unsigned char *) (fp->__bufp++)); +} + + +/* Default I/O and room functions. */ + +extern __io_read_fn __stdio_read; +extern __io_write_fn __stdio_write; +extern __io_seek_fn __stdio_seek; +extern __io_close_fn __stdio_close; +extern __io_fileno_fn __stdio_fileno; +CONST __io_functions __default_io_functions = + { + __stdio_read, __stdio_write, __stdio_seek, __stdio_close, __stdio_fileno + }; + +CONST __room_functions __default_room_functions = + { + fillbuf, flushbuf + }; + + +/* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero. + This is the function used by putc and fflush. */ +int +DEFUN(__flshfp, (fp, c), + register FILE *fp AND int c) +{ + int flush_only = c == EOF; + + if (!__validfp(fp) || !fp->__mode.__write) + { + errno = EINVAL; + return EOF; + } + + if (ferror(fp)) + return EOF; + + if (fp->__pushed_back) + { + /* Discard the char pushed back by ungetc. */ + fp->__bufp = fp->__pushback_bufp; + fp->__pushed_back = 0; + } + + /* Make sure the stream is initialized (has functions and buffering). */ + init_stream(fp); + + /* Do this early, so a `putc' on such a stream will never return success. */ + if (fp->__room_funcs.__output == NULL) + { + /* A NULL `output room' function means + to always return an output error. */ + fp->__error = 1; + return EOF; + } + + if (!flush_only && + /* Will C fit into the buffer? + See below about linebuf_active. */ + fp->__bufp < (fp->__linebuf_active ? fp->__buffer + fp->__bufsize : + fp->__put_limit)) + { + /* The character will fit in the buffer, so put it there. */ + *fp->__bufp++ = (unsigned char) c; + if (fp->__linebuf && (unsigned char) c == '\n') + flush_only = 1; + else + return (unsigned char) c; + } + + if (fp->__linebuf_active) + /* This is an active line-buffered stream, so its put-limit is set + to the beginning of the buffer in order to force a __flshfp call + on each putc (see below). We undo this hack here (by setting + the limit to the end of the buffer) to simplify the interface + with the output-room function. */ + fp->__put_limit = fp->__buffer + fp->__bufsize; + + /* Make room in the buffer. */ + (*fp->__room_funcs.__output) (fp, flush_only ? EOF : (unsigned char) c); + + if (fp->__linebuf) + { + /* This is a line-buffered stream, and it is now ready to do + some output. We call this an "active line-buffered stream". + We set the put_limit to the beginning of the buffer, + so the next `putc' call will force a call to this function. + Setting the linebuf_active flag tells the code above + (on the next call) to undo this hackery. */ + fp->__put_limit = fp->__buffer; + fp->__linebuf_active = 1; + } + + if (ferror (fp)) + return EOF; + if (flush_only) + return 0; + return (unsigned char) c; +} + + +/* Fill the buffer for FP and return the first character read. + This is the function used by getc. */ +int +DEFUN(__fillbf, (fp), register FILE *fp) +{ + register int c; + fpos_t new_target; + + if (!__validfp(fp) || !fp->__mode.__read) + { + errno = EINVAL; + return EOF; + } + + if (fp->__pushed_back) + { + /* Return the char pushed back by ungetc. */ + fp->__bufp = fp->__pushback_bufp; + fp->__pushed_back = 0; + return fp->__pushback; + } + + /* Make sure the stream is initialized (has functions and buffering). */ + init_stream(fp); + + /* If we're trying to read the first character of a new + line of input from an unbuffered or line buffered stream, + we must flush all line-buffered output streams. */ + if (fp->__buffer == NULL || fp->__linebuf) + { + register FILE *f; + for (f = __stdio_head; f != NULL; f = f->__next) + if (__validfp (f) && f->__linebuf && f->__mode.__write) + (void) __flshfp (f, EOF); + } + + /* Note we must do this after flushing all line-buffered + streams, or else __flshfp would undo it! */ + if (fp->__linebuf_active) + { + /* This is an active line-buffered stream, meaning it is in the midst + of writing, but has a bogus put_limit. Restore it to normality. */ + fp->__put_limit = fp->__buffer + fp->__bufsize; + fp->__linebuf_active = 0; + } + + /* We want the beginning of the buffer to now + map to just past the last data we read. */ + new_target = fp->__target + (fp->__get_limit - fp->__buffer); + + if (fp->__put_limit > fp->__buffer) + { + /* There is written data in the buffer. + Flush it out. */ + if (fp->__room_funcs.__output == NULL) + fp->__error = 1; + else + (*fp->__room_funcs.__output) (fp, EOF); + } + + fp->__target = new_target; + + if (ferror(fp)) + c = EOF; + else if (fp->__room_funcs.__input != NULL) + { + c = (*fp->__room_funcs.__input)(fp); + if (fp->__buffer == NULL) + /* This is an unbuffered stream, so the target sync above + won't do anything the next time around. Instead, note that + we have read one character. The (nonexistent) buffer now + maps to the position just past that character. */ + ++fp->__target; + } + else + { + /* A NULL `input_room' function means always return EOF. */ + fp->__eof = 1; + c = EOF; + } + + return c; +} + + +/* Nuke a stream, but don't kill its link in the chain. */ +void +DEFUN(__invalidate, (stream), register FILE *stream) +{ + /* Save its link. */ + register FILE *next = stream->__next; + + /* Pulverize the fucker. */ + memset((PTR) stream, 0, sizeof(FILE)); + + /* Restore the deceased's link. */ + stream->__next = next; +} diff --git a/stdio/longlong.h b/stdio/longlong.h new file mode 100644 index 0000000000..97c469d8c0 --- /dev/null +++ b/stdio/longlong.h @@ -0,0 +1,1295 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + +Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with this file; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* You have to define the following before including this file: + + UWtype -- An unsigned type, default type for operations (typically a "word") + UHWtype -- An unsigned type, at least half the size of UWtype. + UDWtype -- An unsigned type, at least twice as large a UWtype + W_TYPE_SIZE -- size in bits of UWtype + + SItype, USItype -- Signed and unsigned 32 bit types. + DItype, UDItype -- Signed and unsigned 64 bit types. + + On a 32 bit machine UWtype should typically be USItype; + on a 64 bit machine, UWtype should typically be UDItype. +*/ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two + UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a + UDWtype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a UDWtype, composed by the UWtype integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The quotient + is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from the + msb to the first non-zero bit in the UWtype X. This is the number of + steps X needs to be shifted left to set the msb. Undefined for X == 0, + unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. + + 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts + from the least significant end. + + 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two UWtype integers, composed by + HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 + respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow + (i.e. carry out) is not stored anywhere, and is lost. + + 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, + composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and + LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE + and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if (defined (__a29k__) || defined (___AM29K__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %1,%4,%5 + addc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %1,%4,%5 + subc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("multiplu %0,%1,%2" \ + : "=r" ((USItype)(xl)) \ + : "r" (__m0), \ + "r" (__m1)); \ + __asm__ ("multmu %0,%1,%2" \ + : "=r" ((USItype)(xh)) \ + : "r" (__m0), \ + "r" (__m1)); \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("dividu %0,%3,%4" \ + : "=r" ((USItype)(q)), \ + "=q" ((USItype)(r)) \ + : "1" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "r" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))) +#endif /* __a29k__ */ + +#if defined (__alpha__) && W_TYPE_SIZE == 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("umulh %r1,%2,%0" \ + : "=r" ((UDItype) ph) \ + : "%rJ" (__m0), \ + "rI" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 46 +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { UDItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern UDItype __udiv_qrnnd (); +#define UDIV_TIME 220 +#endif + +#if defined (__arm__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1,%4,%5 + adc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1,%4,%5 + sbc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("; Inlined umul_ppmm + mov r0,%2 lsr 16 + mov r2,%3 lsr 16 + bic r1,%2,r0 lsl 16 + bic r2,%3,r2 lsl 16 + mul %1,r1,r2 + mul r2,r0,r2 + mul r1,%0,r1 + mul %0,r0,%0 + adds r1,r2,r1 + addcs %0,%0,0x10000 + adds %1,%1,r1 lsl 16 + adc %0,%0,r1 lsr 16" \ + : "=&r" ((USItype)(xh)), \ + "=r" ((USItype)(xl)) \ + : "r" ((USItype)(a)), \ + "r" ((USItype)(b)) \ + : "r0", "r1", "r2") +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined (__clipper__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("mulwux %2,%0" \ + : "=r" (__xx.__ll) \ + : "%0" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define smul_ppmm(w1, w0, u, v) \ + ({union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("mulwx %2,%0" \ + : "=r" (__xx.__ll) \ + : "%0" ((SItype)(u)), \ + "r" ((SItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("mulwux %2,%0" \ + : "=r" (__w) \ + : "%0" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + __w; }) +#endif /* __clipper__ */ + +#if defined (__gmicro__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.w %5,%1 + addx %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.w %5,%1 + subx %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + __asm__ ("mulx %3,%0,%1" \ + : "=g" ((USItype)(ph)), \ + "=r" ((USItype)(pl)) \ + : "%0" ((USItype)(m0)), \ + "g" ((USItype)(m1))) +#define udiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("divx %4,%0,%1" \ + : "=g" ((USItype)(q)), \ + "=r" ((USItype)(r)) \ + : "1" ((USItype)(nh)), \ + "0" ((USItype)(nl)), \ + "g" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("bsch/1 %1,%0" \ + : "=g" (count) \ + : "g" ((USItype)(x)), \ + "0" ((USItype)0)) +#endif + +#if defined (__hppa) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1 + addc %2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rM" ((USItype)(ah)), \ + "rM" ((USItype)(bh)), \ + "%rM" ((USItype)(al)), \ + "rM" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1 + subb %2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rM" ((USItype)(ah)), \ + "rM" ((USItype)(bh)), \ + "rM" ((USItype)(al)), \ + "rM" ((USItype)(bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__xx.__ll) \ + : "x" ((USItype)(u)), \ + "x" ((USItype)(v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define UMUL_TIME 8 +#define UDIV_TIME 60 +#else +#define UMUL_TIME 40 +#define UDIV_TIME 80 +#endif +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { USItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern USItype __udiv_qrnnd (); +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0 + extru,= %1,15,16,%%r0 ; Bits 31..16 zero? + extru,tr %1,15,16,%1 ; No. Shift down, skip add. + ldo 16(%0),%0 ; Yes. Perform add. + extru,= %1,23,8,%%r0 ; Bits 15..8 zero? + extru,tr %1,23,8,%1 ; No. Shift down, skip add. + ldo 8(%0),%0 ; Yes. Perform add. + extru,= %1,27,4,%%r0 ; Bits 7..4 zero? + extru,tr %1,27,4,%1 ; No. Shift down, skip add. + ldo 4(%0),%0 ; Yes. Perform add. + extru,= %1,29,2,%%r0 ; Bits 3..2 zero? + extru,tr %1,29,2,%1 ; No. Shift down, skip add. + ldo 2(%0),%0 ; Yes. Perform add. + extru %1,30,1,%1 ; Extract bit 1. + sub %0,%1,%0 ; Subtract it. + " : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "r" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (m0), \ + "r" (m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("dr %0,%2" \ + : "=r" (__xx.__ll) \ + : "0" (__xx.__ll), "r" (d)); \ + (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ + } while (0) +#endif + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl %5,%1 + adcl %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%1 + sbbl %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "rm" ((USItype)(v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divl %4" \ + : "=a" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "rm" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define count_trailing_zeros(count, x) \ + __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if defined (__i960__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype)(u)), \ + "dI" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype)(u)), \ + "dI" ((USItype)(v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__mc68000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1 + addx%.l %3,%0" \ + : "=d" ((USItype)(sh)), \ + "=&d" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "d" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1 + subx%.l %3,%0" \ + : "=d" ((USItype)(sh)), \ + "=&d" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "d" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "dmi" ((USItype)(v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "dmi" ((USItype)(d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "dmi" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype)(count)) \ + : "od" ((USItype)(x)), "n" (0)) +#else /* not mc68020 */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm + move%.l %2,%/d0 + move%.l %3,%/d1 + move%.l %/d0,%/d2 + swap %/d0 + move%.l %/d1,%/d3 + swap %/d1 + move%.w %/d2,%/d4 + mulu %/d3,%/d4 + mulu %/d1,%/d2 + mulu %/d0,%/d3 + mulu %/d0,%/d1 + move%.l %/d4,%/d0 + eor%.w %/d0,%/d0 + swap %/d0 + add%.l %/d0,%/d2 + add%.l %/d3,%/d2 + jcc 1f + add%.l #65536,%/d1 +1: swap %/d2 + moveq #0,%/d0 + move%.w %/d2,%/d0 + move%.w %/d4,%/d2 + move%.l %/d2,%1 + add%.l %/d1,%/d0 + move%.l %/d0,%0" \ + : "=g" ((USItype)(xh)), \ + "=g" ((USItype)(xl)) \ + : "g" ((USItype)(a)), \ + "g" ((USItype)(b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#endif /* not mc68020 */ +#endif /* mc68000 */ + +#if defined (__m88000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5 + addu.ci %0,%r2,%r3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rJ" ((USItype)(ah)), \ + "rJ" ((USItype)(bh)), \ + "%rJ" ((USItype)(al)), \ + "rJ" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5 + subu.ci %0,%r2,%r3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rJ" ((USItype)(ah)), \ + "rJ" ((USItype)(bh)), \ + "rJ" ((USItype)(al)), \ + "rJ" ((USItype)(bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype)(x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype)(d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mips__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3 + mflo %0 + mfhi %1" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "d" ((USItype)(u)), \ + "d" ((USItype)(v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 +#endif /* __mips__ */ + +#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("dmultu %2,%3 + mflo %0 + mfhi %1" \ + : "=d" ((UDItype)(w0)), \ + "=d" ((UDItype)(w1)) \ + : "d" ((UDItype)(u)), \ + "d" ((UDItype)(v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 +#endif /* __mips__ */ + +#if defined (__ns32000__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype)(u)), \ + "g" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype)(u)), \ + "g" ((USItype)(v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype)(d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#define count_trailing_zeros(count,x) \ + do { + __asm__ ("ffsd %2,%0" \ + : "=r" ((USItype) (count)) \ + : "0" ((USItype) 0), \ + "r" ((USItype) (x))); \ + } while (0) +#endif /* __ns32000__ */ + +#if (defined (__powerpc__) || defined (___IBMR2__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))) +#if defined (__powerpc__) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" \ + : "=r" ((USItype) ph) \ + : "%r" (__m0), \ + "r" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" \ + : "=r" ((SItype) ph) \ + : "%r" (__m0), \ + "r" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#else +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mul %0,%2,%3" \ + : "=r" ((USItype)(xh)), \ + "=q" ((USItype)(xl)) \ + : "r" (__m0), \ + "r" (__m1)); \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" \ + : "=r" ((SItype)(xh)), \ + "=q" ((SItype)(xl)) \ + : "r" (m0), \ + "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" \ + : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ + : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) +#define UDIV_TIME 100 +#endif +#endif /* Power architecture variants. */ + +#if defined (__pyr__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addw %5,%1 + addwc %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subw %5,%1 + subwb %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +/* This insn doesn't work on ancient pyramids. */ +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __xx.__i.__l = u; \ + __asm__ ("uemul %3,%0" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "1" (__xx.__i.__l), \ + "g" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#endif /* __pyr__ */ + +#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5 + ae %0,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "r" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5 + se %0,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "r" ((USItype)(bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2 + mts r10,%2 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + cas %0,r2,r0 + mfs r10,%1" \ + : "=r" ((USItype)(ph)), \ + "=r" ((USItype)(pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined (__sparc__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1 + addx %r2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rJ" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%rJ" ((USItype)(al)), \ + "rI" ((USItype)(bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1 + subx %r2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rJ" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "rJ" ((USItype)(al)), \ + "rI" ((USItype)(bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +/* Don't match immediate range because, 1) it is not often useful, + 2) the 'I' flag thinks of the range as a 13 bit signed interval, + while we want to match a 13 bit interval, sign extended to 32 bits, + but INTERPRETED AS UNSIGNED. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))) +#define UMUL_TIME 5 +/* We might want to leave this undefined for `SuperSPARC (tm)' since + its implementation is crippled and often traps. */ +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype)(q)), \ + "=&r" ((USItype)(r)) \ + : "r" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "r" ((USItype)(d))) +#define UDIV_TIME 25 +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))) +#define UMUL_TIME 5 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd + wr %%g0,%2,%%y ! Not a delayed write for sparclite + tst %%g0 + divscc %3,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%0 + rd %%y,%1 + bl,a 1f + add %1,%4,%1 +1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype)(q)), \ + "=r" ((USItype)(r)) \ + : "r" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "rI" ((USItype)(d)) \ + : "%g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + __asm__ ("scan %1,0,%0" \ + : "=r" ((USItype)(x)) \ + : "r" ((USItype)(count))) +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm + wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr + sra %3,31,%%g2 ! Don't move this insn + and %2,%%g2,%%g2 ! Don't move this insn + andcc %%g0,0,%%g1 ! Don't move this insn + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,0,%%g1 + add %%g1,%%g2,%0 + rd %%y,%1" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "%rI" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "%g1", "%g2" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { USItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern USItype __udiv_qrnnd (); +#define UDIV_TIME 140 +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* __sparc__ */ + +#if defined (__vax__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1 + adwc %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1 + sbwc %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=g" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__n1n0.ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#if defined (__z8000__) && W_TYPE_SIZE == 16 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "%0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "%1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + unsigned int __m0 = (m0), __m1 = (m1); \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "rQR" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((signed int) __m0 >> 15) & __m1) \ + + (((signed int) __m1 >> 15) & __m0)); \ + } while (0) +#define umul_ppmm_off(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (m0), \ + "rQR" (m1)); \ + (xh) = __xx.__i.__h + ((((signed int) m0 >> 15) & m1) \ + + (((signed int) m1 >> 15) & m0)); \ + (xl) = __xx.__i.__l; \ + } while (0) +#endif /* __z8000__ */ + +#endif /* __GNUC__ */ + + +#if !defined (umul_ppmm) && defined (__umulsidi3) +#define umul_ppmm(ph, pl, m0, m1) \ + { \ + UDWtype __ll = __umulsidi3 (m0, m1); \ + ph = (UWtype) (__ll >> W_TYPE_SIZE); \ + pl = (UWtype) __ll; \ + } +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({UWtype __hi, __lo; \ + umul_ppmm (__hi, __lo, u, v); \ + ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) +#endif + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\ + } while (0) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + UWtype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +extern +#ifdef __STDC__ +const +#endif +unsigned char __clz_tab[]; +#define count_leading_zeros(count, x) \ + do { \ + UWtype __xr = (x); \ + UWtype __a; \ + \ + if (W_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((UWtype) 1 << 2*__BITS4) \ + ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \ + : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\ + } \ + else \ + { \ + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +/* This version gives a well-defined value for zero. */ +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if !defined (count_trailing_zeros) +/* Define count_trailing_zeros using count_leading_zeros. The latter might be + defined in asm, but if it is not, the C version above is good enough. */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + UWtype __ctz_c; \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = W_TYPE_SIZE - 1 - __ctz_c; \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif diff --git a/stdio/memstream.c b/stdio/memstream.c new file mode 100644 index 0000000000..704eca53b3 --- /dev/null +++ b/stdio/memstream.c @@ -0,0 +1,177 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct memstream_info + { + char **buffer; + size_t *bufsize; + }; + +/* Enlarge STREAM's buffer. */ +static void +DEFUN(enlarge_buffer, (stream, c), + register FILE *stream AND int c) +{ + struct memstream_info *info = (struct memstream_info *) stream->__cookie; + size_t need; + + if (stream->__put_limit != stream->__buffer) + /* Record how much has actually been written into the buffer. */ + *info->bufsize = stream->__bufp - stream->__buffer; + + if (stream->__target != -1 + && stream->__target > *info->bufsize) + /* Our target (where the buffer maps to) is always zero except when + the user just did a SEEK_END fseek. If he sought within the + buffer, we need do nothing and will zero the target below. If he + sought past the end of the object, grow and zero-fill the buffer + up to the target address. */ + need = stream->__target; + else + need = *info->bufsize; + + /* We always need an extra character in the buffer. Either we are + writing C, or we are flushing and need to write a NUL terminator. */ + ++need; + + if (stream->__bufsize < need) + { + /* Enlarge the buffer. */ + char *newbuf; + size_t newsize; + if (stream->__bufsize * 2 < need) + newsize = need; + else + newsize = stream->__bufsize * 2; + newbuf = (char *) realloc ((PTR) stream->__buffer, newsize); + if (newbuf == NULL) + { + stream->__error = 1; + return; + } + *info->buffer = stream->__buffer = newbuf; + stream->__bufsize = newsize; + } + + stream->__target = stream->__offset = 0; + stream->__get_limit = stream->__bufp = stream->__buffer + *info->bufsize; + stream->__put_limit = stream->__buffer + stream->__bufsize; + + need -= stream->__bufp - stream->__buffer + 1; + if (need > 0) + { + /* We are extending the buffer after an fseek; zero-fill new space. */ + bzero (stream->__bufp, need); + stream->__bufp += need; + } + + if (c != EOF) + *stream->__bufp++ = (unsigned char) c; + else + *stream->__bufp = '\0'; +} + +/* Seek function for memstreams. + There is no external state to munge. */ + +static int +DEFUN(seek, (cookie, pos, whence), + PTR cookie AND fpos_t *pos AND int whence) +{ + switch (whence) + { + case SEEK_SET: + case SEEK_CUR: + return 0; + + case SEEK_END: + /* Return the position relative to the end of the object. + fseek has just flushed us, so the info is consistent. */ + *pos += *((struct memstream_info *) cookie)->bufsize; + return 0; + + default: + __libc_fatal ("memstream::seek called with bogus WHENCE\n"); + return -1; + } +} + +static int +DEFUN(free_info, (cookie), PTR cookie) +{ +#if 0 + struct memstream_info *info = (struct memstream_info *) cookie; + char *buf; + + buf = (char *) realloc ((PTR) *info->buffer, *info->bufsize); + if (buf != NULL) + *info->buffer = buf; +#endif + + free (cookie); + + return 0; +} + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +FILE * +DEFUN(open_memstream, (bufloc, sizeloc), + char **bufloc AND size_t *sizeloc) +{ + FILE *stream; + struct memstream_info *info; + + if (bufloc == NULL || sizeloc == NULL) + { + errno = EINVAL; + return NULL; + } + + stream = fmemopen ((char *) NULL, BUFSIZ, "w+"); + if (stream == NULL) + return NULL; + + info = (struct memstream_info *) malloc (sizeof (struct memstream_info)); + if (info == NULL) + { + int save = errno; + (void) fclose (stream); + errno = save; + return NULL; + } + + stream->__room_funcs.__output = enlarge_buffer; + stream->__io_funcs.__seek = seek; + stream->__io_funcs.__close = free_info; + stream->__cookie = (PTR) info; + stream->__userbuf = 1; + + info->buffer = bufloc; + info->bufsize = sizeloc; + + *bufloc = stream->__buffer; + + return stream; +} diff --git a/stdio/mp_clz_tab.c b/stdio/mp_clz_tab.c new file mode 100644 index 0000000000..ed1b7eebe8 --- /dev/null +++ b/stdio/mp_clz_tab.c @@ -0,0 +1,39 @@ +/* __clz_tab -- support for longlong.h + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if 0 +#include "gmp.h" +#include "gmp-impl.h" +#endif + +#if 0 +const +#endif + unsigned char __clz_tab[] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +}; diff --git a/stdio/newstream.c b/stdio/newstream.c new file mode 100644 index 0000000000..08feb8da6e --- /dev/null +++ b/stdio/newstream.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + + +/* Return a new, zeroed, stream. + You must set its cookie and io_mode. + The first operation will give it a buffer unless you do. + It will also give it the default functions unless you set the `seen' flag. + Returns NULL if a stream can't be created. */ +FILE * +DEFUN_VOID(__newstream) +{ + register FILE *stream; + + stream = __stdio_head; + while (__validfp (stream)) + stream = stream->__next; + if (stream == NULL) + { + /* None to reuse. */ + stream = (FILE *) malloc (sizeof (FILE)); + if (stream == NULL) + return NULL; + stream->__next = __stdio_head; + __stdio_head = stream; + } + + __invalidate (stream); + stream->__magic = _IOMAGIC; + stream->__offset = (fpos_t) -1; + stream->__target = (fpos_t) -1; + + return stream; +} diff --git a/stdio/obstream.c b/stdio/obstream.c new file mode 100644 index 0000000000..32f7220b59 --- /dev/null +++ b/stdio/obstream.c @@ -0,0 +1,187 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <obstack.h> +#include <stdarg.h> +#include <string.h> + +/* Output-room function for obstack streams. */ + +static void +DEFUN(grow, (stream, c), FILE *stream AND int c) +{ + struct obstack *const obstack = (struct obstack *) stream->__cookie; + + /* Move the end of the object back to include only the portion + of the buffer which the user has already written into. */ + obstack_blank_fast (obstack, - (stream->__put_limit - stream->__bufp)); + + if (stream->__target > obstack_object_size (obstack)) + { + /* Our target (where the buffer maps to) is always zero except when + the user just did a SEEK_END fseek. If he sought within the + buffer, we need do nothing and will zero the target below. If he + sought past the end of the object, grow and zero-fill the object + up to the target address. */ + + obstack_blank (obstack, + stream->__target - obstack_object_size (obstack)); + /* fseek has just flushed us, so the put limit points + to the end of the written data. */ + bzero (stream->__put_limit, + stream->__target - stream->__bufsize); + } + + if (c != EOF) + obstack_1grow (obstack, (unsigned char) c); + + /* The stream buffer always maps exactly to the object on the top + of the obstack. The start of the buffer is the start of the object. + The put limit points just past the end of the object. On fflush, the + obstack is sync'd so the end of the object points just past the last + character written to the stream. */ + + stream->__target = stream->__offset = 0; + stream->__buffer = obstack_base (obstack); + stream->__bufsize = obstack_room (obstack); + stream->__bufp = obstack_next_free (obstack); + stream->__get_limit = stream->__bufp; + + if (c == EOF) + /* This is fflush. Make the stream buffer, the object, + and the characters actually written all match. */ + stream->__put_limit = stream->__get_limit; + else + { + /* Extend the buffer (and the object) to include + the rest of the obstack chunk (which is unitialized). + Data past bufp is undefined. */ + stream->__put_limit = stream->__buffer + stream->__bufsize; + obstack_blank_fast (obstack, stream->__put_limit - stream->__bufp); + } +} + +/* Seek function for obstack streams. + There is no external state to munge. */ + +static int +DEFUN(seek, (cookie, pos, whence), + PTR cookie AND fpos_t *pos AND int whence) +{ + switch (whence) + { + case SEEK_SET: + case SEEK_CUR: + return 0; + + case SEEK_END: + /* Return the position relative to the end of the object. + fseek has just flushed us, so the obstack is consistent. */ + *pos += obstack_object_size ((struct obstack *) cookie); + return 0; + + default: + __libc_fatal ("obstream::seek called with bogus WHENCE\n"); + return -1; + } +} + +/* Input room function for obstack streams. + Only what has been written to the stream can be read back. */ + +static int +DEFUN(input, (stream), FILE *stream) +{ + /* Re-sync with the obstack, growing the object if necessary. */ + grow (stream, EOF); + + if (stream->__bufp < stream->__get_limit) + return (unsigned char) *stream->__bufp++; + + stream->__eof = 1; + return EOF; +} + +/* Initialize STREAM to talk to OBSTACK. */ + +static void +DEFUN(init_obstream, (stream, obstack), + FILE *stream AND struct obstack *obstack) +{ + stream->__mode.__write = 1; + stream->__mode.__read = 1; + + /* Input can read only what has been written. */ + stream->__room_funcs.__input = input; + + /* Do nothing for close. */ + stream->__io_funcs.__close = NULL; + + /* When the buffer is full, grow the obstack. */ + stream->__room_funcs.__output = grow; + + /* Seek within the object, and extend it. */ + stream->__io_funcs.__seek = seek; + stream->__target = stream->__offset = 0; + + stream->__seen = 1; + + /* Don't deallocate that buffer! */ + stream->__userbuf = 1; + + /* We don't have to initialize the buffer. + The first read attempt will call grow, which will do all the work. */ +} + +FILE * +open_obstack_stream (obstack) + struct obstack *obstack; +{ + register FILE *stream; + + stream = __newstream (); + if (stream == NULL) + return NULL; + + init_obstream (stream, obstack); + return stream; +} + +int +DEFUN(obstack_vprintf, (obstack, format, args), + struct obstack *obstack AND const char *format AND va_list args) +{ + FILE f; + bzero (&f, sizeof (f)); + init_obstream (&f, obstack); + return vfprintf (&f, format, args); +} + +int +DEFUN(obstack_printf, (obstack, format), + struct obstack *obstack AND const char *format DOTS) +{ + int result; + va_list ap; + va_start (ap, format); + result = obstack_vprintf (obstack, format, ap); + va_end (ap); + return result; +} diff --git a/stdio/perror.c b/stdio/perror.c new file mode 100644 index 0000000000..718a6f2256 --- /dev/null +++ b/stdio/perror.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <errno.h> + +extern char *_strerror_internal __P ((int, char buf[1024])); + +/* Print a line on stderr consisting of the text in S, a colon, a space, + a message describing the meaning of the contents of `errno' and a newline. + If S is NULL or "", the colon and space are omitted. */ +void +DEFUN(perror, (s), register CONST char *s) +{ + char buf[1024]; + int errnum = errno; + CONST char *colon; + + if (s == NULL || *s == '\0') + s = colon = ""; + else + colon = ": "; + + (void) fprintf (stderr, "%s%s%s\n", + s, colon, _strerror_internal (errnum, buf)); +} diff --git a/stdio/printf-prs.c b/stdio/printf-prs.c new file mode 100644 index 0000000000..2f55dd3157 --- /dev/null +++ b/stdio/printf-prs.c @@ -0,0 +1,211 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <printf.h> +#include <limits.h> +#include <string.h> +#include <ctype.h> + +#ifdef __GNUC__ +#define HAVE_LONGLONG +#endif + +extern printf_arginfo_function *__printf_arginfo_table[]; + +size_t +DEFUN(parse_printf_format, (fmt, n, argtypes), + CONST char *fmt AND size_t n AND int *argtypes) +{ + register CONST char *f; + size_t need = 0; + + for (f = strchr (fmt, '%'); f != NULL; f = strchr (f, '%')) + { + struct printf_info info; + printf_arginfo_function *arginfo; + + ++f; + + info.space = info.showsign = info.left = info.alt = info.group = 0; + info.pad = ' '; + while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0' || + *f == '\'') + switch (*f++) + { + case ' ': + info.space = 1; + break; + case '+': + info.showsign = 1; + break; + case '-': + info.left = 1; + break; + case '#': + info.alt = 1; + break; + case '\'': + info.group = 1; + break; + case '0': + info.pad = '0'; + break; + } + if (info.left) + info.pad = ' '; + + /* Get the field width. */ + if (*f == '*') + { + if (++need < n) + *argtypes++ = PA_INT; + info.width = INT_MIN; + ++f; + } + else + { + info.width = 0; + while (isdigit(*f)) + { + info.width *= 10; + info.width += *f++ - '0'; + } + } + + /* Get the precision. */ + /* -1 means none given; 0 means explicit 0. */ + info.prec = -1; + if (*f == '.') + { + ++f; + if (*f == '*') + { + /* The precision is given in an argument. */ + if (++need < n) + *argtypes++ = PA_INT; + info.prec = INT_MIN; + ++f; + } + else if (isdigit(*f)) + { + info.prec = 0; + while (*f != '\0' && isdigit(*f)) + { + info.prec *= 10; + info.prec += *f++ - '0'; + } + } + } + + /* Check for type modifiers. */ + info.is_short = info.is_long = info.is_long_double = 0; + while (*f == 'h' || *f == 'l' || *f == 'L') + switch (*f++) + { + case 'h': + /* int's are short int's. */ + info.is_short = 1; + break; + case 'l': +#ifdef HAVE_LONGLONG + if (info.is_long) + /* A double `l' is equivalent to an `L'. */ + info.is_long_double = 1; + else +#endif + /* int's are long int's. */ + info.is_long = 1; + break; + case 'L': + /* double's are long double's, and int's are long long int's. */ + info.is_long_double = 1; + break; + } + + if (*f == '\0') + return need; + + info.spec = *f++; + + arginfo = __printf_arginfo_table[info.spec]; + if (arginfo != NULL) + { + size_t nargs + = (*arginfo) (&info, need > n ? 0 : n - need, argtypes); + need += nargs; + argtypes += nargs; + } + else + { + int type; + switch (info.spec) + { + case 'i': + case 'd': + case 'u': + case 'o': + case 'X': + case 'x': + type = PA_INT; + break; + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + type = PA_DOUBLE; + break; + + case 'c': + type = PA_CHAR; + break; + + case 's': + type = PA_STRING; + break; + + case 'p': + type = PA_POINTER; + break; + + case 'n': + type = PA_INT | PA_FLAG_PTR; + break; + + default: + /* No arg for an unknown spec. */ + continue; + } + + if (info.is_long_double) + type |= PA_FLAG_LONG_DOUBLE; + if (info.is_long) + type |= PA_FLAG_LONG; + if (info.is_short) + type |= PA_FLAG_SHORT; + + if (++need < n) + *argtypes++ = type; + } + } + + return need; +} diff --git a/stdio/printf.c b/stdio/printf.c new file mode 100644 index 0000000000..9cdae768ae --- /dev/null +++ b/stdio/printf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output to stdout from the format string FORMAT. */ +/* VARARGS1 */ +int +DEFUN(printf, (format), CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vprintf(format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/printf.h b/stdio/printf.h new file mode 100644 index 0000000000..c369222281 --- /dev/null +++ b/stdio/printf.h @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _PRINTF_H + +#define _PRINTF_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_FILE +#include <stdio.h> +#define __need_size_t +#include <stddef.h> + +#include <stdarg.h> /* Need va_list. */ + + +struct printf_info +{ + int prec; /* Precision. */ + int width; /* Width. */ + unsigned char spec; /* Format letter. */ + unsigned int is_long_double:1;/* L flag. */ + unsigned int is_short:1; /* h flag. */ + unsigned int is_long:1; /* l flag. */ + unsigned int alt:1; /* # flag. */ + unsigned int space:1; /* Space flag. */ + unsigned int left:1; /* - flag. */ + unsigned int showsign:1; /* + flag. */ + unsigned int group:1; /* ' flag. */ + char pad; /* Padding character. */ +}; + + +/* Type of a printf specifier-handler function. + STREAM is the FILE on which to write output. + INFO gives information about the format specification. + Arguments can be read from ARGS. + The function should return the number of characters written, + or -1 for errors. */ + +typedef int printf_function __P ((FILE * __stream, + __const struct printf_info * __info, + va_list * __args)); +typedef int printf_arginfo_function __P ((__const struct printf_info * __info, + size_t __n, + int *__argtypes)); + +/* Register FUNC to be called to format SPEC specifiers. + ARGINFO, if not NULL, is a function used by `parse_printf_format' + to determine how many arguments a SPEC conversion requires, + and what their types are. */ +extern int register_printf_function __P ((int __spec, printf_function __func, + printf_arginfo_function __arginfo)); + +/* Parse FMT, and fill in N elements of ARGTYPES with the + types needed for the conversions FMT specifies. Returns + the number of arguments required by FMT. + + The ARGINFO function registered with a user-defined format is passed a + `struct printf_info' describing the format spec being parsed. A width + or precision of INT_MIN means a `*' was used to indicate that the + width/precision will come from an arg. The function should fill in the + array it is passed with the types of the arguments it wants, and return + the number of arguments it wants. */ + +extern size_t parse_printf_format __P ((__const char *__fmt, + size_t __n, + int *__argtypes)); + +/* Codes returned by `parse_printf_format' for basic types. + + These values cover all the standard format specifications. + Users can add new values after PA_LAST for their own types. */ + +enum +{ /* C type: */ + PA_INT, /* int */ + PA_CHAR, /* int, cast to char */ + PA_STRING, /* const char *, a '\0'-terminated string */ + PA_POINTER, /* void * */ + PA_FLOAT, /* float */ + PA_DOUBLE, /* double */ + PA_LAST +}; + +/* Flag bits that can be set in a type returned by `parse_printf_format'. */ +#define PA_FLAG_MASK 0xff00 +#define PA_FLAG_LONG_LONG (1 << 8) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG +#define PA_FLAG_LONG (1 << 9) +#define PA_FLAG_SHORT (1 << 10) +#define PA_FLAG_PTR (1 << 11) + + +__END_DECLS + +#endif /* printf.h */ diff --git a/stdio/printf_fp.c b/stdio/printf_fp.c new file mode 100644 index 0000000000..ddf025721b --- /dev/null +++ b/stdio/printf_fp.c @@ -0,0 +1,991 @@ +/* Floating point output for `printf'. +Copyright (C) 1995 Free Software Foundation, Inc. +Written by Ulrich Drepper. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef USE_IN_LIBIO +# include <libioP.h> +#else +# include <stdio.h> +#endif +#include <alloca.h> +#include <ansidecl.h> +#include <ctype.h> +#include <float.h> +#include <gmp-mparam.h> +#include <gmp.h> +#include <gmp-impl.h> +#include <longlong.h> +#include <localeinfo.h> +#include <math.h> +#include <printf.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +/* #define NDEBUG 1 */ +#include <assert.h> + +/* This defines make it possible to use the same code for GNU C library and + the GNU I/O library. */ +#ifdef USE_IN_LIBIO +# define PUT(f, s, n) _IO_sputn (f, s, n) +# define PAD(f, c, n) _IO_padn (f, c, n) +/* We use this file GNU C library and GNU I/O library. So make + names equal. */ +# undef putc +# define putc(c, f) _IO_putc (c, f) +# define size_t _IO_size_t +# define FILE _IO_FILE +#else /* ! USE_IN_LIBIO */ +# define PUT(f, s, n) fwrite (s, 1, n, f) +# define PAD(f, c, n) __printf_pad (f, c, n) +ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c. */ +#endif /* USE_IN_LIBIO */ + +/* Macros for doing the actual output. */ + +#define outchar(ch) \ + do \ + { \ + register CONST int outc = (ch); \ + if (putc (outc, fp) == EOF) \ + return -1; \ + ++done; \ + } while (0) + +#define PRINT(ptr, len) \ + do \ + { \ + register size_t outlen = (len); \ + if (len > 20) \ + { \ + if (PUT (fp, ptr, outlen) != outlen) \ + return -1; \ + ptr += outlen; \ + done += outlen; \ + } \ + else \ + { \ + while (outlen-- > 0) \ + outchar (*ptr++); \ + } \ + } while (0) + +#define PADN(ch, len) \ + do \ + { \ + if (PAD (fp, ch, len) != len) \ + return -1; \ + done += len; \ + } \ + while (0) + +/* We use the GNU MP library to handle large numbers. + + An MP variable occupies a varying number of entries in its array. We keep + track of this number for efficiency reasons. Otherwise we would always + have to process the whole array. */ +#define MPN_VAR(name) mp_limb *name; mp_size_t name##size + +#define MPN_ASSIGN(dst,src) \ + memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb)) +#define MPN_GE(u,v) \ + (u##size > v##size || (u##size == v##size && __mpn_cmp (u, v, u##size) >= 0)) + +extern int __isinfl (long double), __isnanl (long double); + +extern mp_size_t __mpn_extract_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + double value); +extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + long double value); + +#include "fpioconst.h" + + +static unsigned int guess_grouping (unsigned int intdig_max, + const char *grouping, wchar_t sepchar); +static char *group_number (char *buf, char *bufend, unsigned int intdig_no, + const char *grouping, wchar_t thousands_sep); + + +int +__printf_fp (fp, info, args) + FILE *fp; + const struct printf_info *info; + va_list *args; +{ + /* The floating-point value to output. */ + union + { + double dbl; + LONG_DOUBLE ldbl; + } + fpnum; + + /* Locale-dependent representation of decimal point. */ + wchar_t decimal; + + /* Locale-dependent thousands separator and grouping specification. */ + wchar_t thousands_sep; + const char *grouping; + + /* "NaN" or "Inf" for the special cases. */ + CONST char *special = NULL; + + /* We need just a few limbs for the input before shifting to the right + position. */ + mp_limb fp_input[(LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB]; + /* We need to shift the contents of fp_input by this amount of bits. */ + int to_shift; + + /* The significant of the floting-point value in question */ + MPN_VAR(frac); + /* and the exponent. */ + int exponent; + /* Sign of the exponent. */ + int expsign = 0; + /* Sign of float number. */ + int is_neg = 0; + + /* Scaling factor. */ + MPN_VAR(scale); + + /* Temporary bignum value. */ + MPN_VAR(tmp); + + /* Digit which is result of last hack_digit() call. */ + int digit; + + /* The type of output format that will be used: 'e'/'E' or 'f'. */ + int type; + + /* Counter for number of written characters. */ + int done = 0; + + /* General helper (carry limb). */ + mp_limb cy; + + char hack_digit (void) + { + mp_limb hi; + + if (expsign != 0 && type == 'f' && exponent-- > 0) + hi = 0; + else if (scalesize == 0) + { + hi = frac[fracsize - 1]; + cy = __mpn_mul_1 (frac, frac, fracsize - 1, 10); + frac[fracsize - 1] = cy; + } + else + { + if (fracsize < scalesize) + hi = 0; + else + { + hi = __mpn_divmod (tmp, frac, fracsize, scale, scalesize); + tmp[fracsize - scalesize] = hi; + hi = tmp[0]; + + fracsize = __mpn_normal_size (frac, scalesize); + if (fracsize == 0) + { + /* We're not prepared for an mpn variable with zero + limbs. */ + fracsize = 1; + return '0' + hi; + } + } + + cy = __mpn_mul_1 (frac, frac, fracsize, 10); + if (cy != 0) + frac[fracsize++] = cy; + } + + return '0' + hi; + } + + + /* Figure out the decimal point character. */ + if (mbtowc (&decimal, _numeric_info->decimal_point, + strlen (_numeric_info->decimal_point)) <= 0) + decimal = (wchar_t) *_numeric_info->decimal_point; + + + if (info->group) + { + grouping = _numeric_info->grouping; /* Cache the grouping info array. */ + if (*grouping <= 0 || *grouping == CHAR_MAX) + grouping = NULL; + else + { + /* Figure out the thousands seperator character. */ + if (mbtowc (&thousands_sep, _numeric_info->thousands_sep, + strlen (_numeric_info->thousands_sep)) <= 0) + thousands_sep = (wchar_t) *_numeric_info->thousands_sep; + if (thousands_sep == L'\0') + grouping = NULL; + } + } + else + grouping = NULL; + + /* Fetch the argument value. */ + if (info->is_long_double && sizeof (long double) > sizeof (double)) + { + fpnum.ldbl = va_arg (*args, LONG_DOUBLE); + + /* Check for special values: not a number or infinity. */ + if (__isnanl (fpnum.ldbl)) + { + special = "NaN"; + is_neg = 0; + } + else if (__isinfl (fpnum.ldbl)) + { + special = "Inf"; + is_neg = fpnum.ldbl < 0; + } + else + { + fracsize = __mpn_extract_long_double (fp_input, + (sizeof (fp_input) / + sizeof (fp_input[0])), + &exponent, &is_neg, + fpnum.ldbl); + to_shift = 1 + fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG; + } + } + else + { + fpnum.dbl = va_arg (*args, double); + + /* Check for special values: not a number or infinity. */ + if (__isnan (fpnum.dbl)) + { + special = "NaN"; + is_neg = 0; + } + else if (__isinf (fpnum.dbl)) + { + special = "Inf"; + is_neg = fpnum.dbl < 0; + } + else + { + fracsize = __mpn_extract_double (fp_input, + (sizeof (fp_input) + / sizeof (fp_input[0])), + &exponent, &is_neg, fpnum.dbl); + to_shift = 1 + fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG; + } + } + + if (special) + { + int width = info->prec > info->width ? info->prec : info->width; + + if (is_neg || info->showsign || info->space) + --width; + width -= 3; + + if (!info->left && width > 0) + PADN (' ', width); + + if (is_neg) + outchar ('-'); + else if (info->showsign) + outchar ('+'); + else if (info->space) + outchar (' '); + + PRINT (special, 3); + + if (info->left && width > 0) + PADN (' ', width); + + return done; + } + + + /* We need three multiprecision variables. Now that we have the exponent + of the number we can allocate the needed memory. It would be more + efficient to use variables of the fixed maximum size but because this + would be really big it could lead to memory problems. */ + { + mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1) + / BITS_PER_MP_LIMB + 3) * sizeof (mp_limb); + frac = (mp_limb *) alloca (bignum_size); + tmp = (mp_limb *) alloca (bignum_size); + scale = (mp_limb *) alloca (bignum_size); + } + + /* We now have to distinguish between numbers with positive and negative + exponents because the method used for the one is not applicable/efficient + for the other. */ + scalesize = 0; + if (exponent > 2) + { + /* |FP| >= 1.0. */ + int scaleexpo = 0; + int explog = LDBL_MAX_10_EXP_LOG; + int exp10 = 0; + const struct mp_power *tens = &_fpioconst_pow10[explog + 1]; + int cnt_h, cnt_l, i; + + if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0) + { + MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB, + fp_input, fracsize); + fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB; + } + else + { + cy = __mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB, + fp_input, fracsize, + (exponent + to_shift) % BITS_PER_MP_LIMB); + fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB; + if (cy) + frac[fracsize++] = cy; + } + MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB); + + assert (tens > &_fpioconst_pow10[0]); + do + { + --tens; + + /* The number of the product of two binary numbers with n and m + bits respectively has m+n or m+n-1 bits. */ + if (exponent >= scaleexpo + tens->p_expo - 1) + { + if (scalesize == 0) + MPN_ASSIGN (tmp, tens->array); + else + { + cy = __mpn_mul (tmp, scale, scalesize, + tens->array + 2, tens->arraysize - 2); + tmpsize = scalesize + tens->arraysize - 2; + if (cy == 0) + --tmpsize; + } + + if (MPN_GE (frac, tmp)) + { + int cnt; + MPN_ASSIGN (scale, tmp); + count_leading_zeros (cnt, scale[scalesize - 1]); + scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1; + exp10 |= 1 << explog; + } + } + --explog; + } + while (tens > &_fpioconst_pow10[0]); + exponent = exp10; + + /* Optimize number representations. We want to represent the numbers + with the lowest number of bytes possible without losing any + bytes. Also the highest bit in the scaling factor has to be set + (this is a requirement of the MPN division routines). */ + if (scalesize > 0) + { + /* Determine minimum number of zero bits at the end of + both numbers. */ + for (i = 0; scale[i] == 0 && frac[i] == 0; i++) + ; + + /* Determine number of bits the scaling factor is misplaced. */ + count_leading_zeros (cnt_h, scale[scalesize - 1]); + + if (cnt_h == 0) + { + /* The highest bit of the scaling factor is already set. So + we only have to remove the trailing empty limbs. */ + if (i > 0) + { + MPN_COPY_INCR (scale, scale + i, scalesize - i); + scalesize -= i; + MPN_COPY_INCR (frac, frac + i, fracsize - i); + fracsize -= i; + } + } + else + { + if (scale[i] != 0) + { + count_trailing_zeros (cnt_l, scale[i]); + if (frac[i] != 0) + { + int cnt_l2; + count_trailing_zeros (cnt_l2, frac[i]); + if (cnt_l2 < cnt_l) + cnt_l = cnt_l2; + } + } + else + count_trailing_zeros (cnt_l, frac[i]); + + /* Now shift the numbers to their optimal position. */ + if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l) + { + /* We cannot save any memory. So just roll both numbers + so that the scaling factor has its highest bit set. */ + + (void) __mpn_lshift (scale, scale, scalesize, cnt_h); + cy = __mpn_lshift (frac, frac, fracsize, cnt_h); + if (cy != 0) + frac[fracsize++] = cy; + } + else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l) + { + /* We can save memory by removing the trailing zero limbs + and by packing the non-zero limbs which gain another + free one. */ + + (void) __mpn_rshift (scale, scale + i, scalesize - i, + BITS_PER_MP_LIMB - cnt_h); + scalesize -= i + 1; + (void) __mpn_rshift (frac, frac + i, fracsize - i, + BITS_PER_MP_LIMB - cnt_h); + fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i; + } + else + { + /* We can only save the memory of the limbs which are zero. + The non-zero parts occupy the same number of limbs. */ + + (void) __mpn_rshift (scale, scale + (i - 1), + scalesize - (i - 1), + BITS_PER_MP_LIMB - cnt_h); + scalesize -= i; + (void) __mpn_rshift (frac, frac + (i - 1), + fracsize - (i - 1), + BITS_PER_MP_LIMB - cnt_h); + fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1; + } + } + } + } + else if (exponent < 0) + { + /* |FP| < 1.0. */ + int exp10 = 0; + int explog = LDBL_MAX_10_EXP_LOG; + const struct mp_power *tens = &_fpioconst_pow10[explog + 1]; + mp_size_t used_limbs = fracsize - 1; + + /* Now shift the input value to its right place. */ + cy = __mpn_lshift (frac, fp_input, fracsize, to_shift); + frac[fracsize++] = cy; + assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0)); + + expsign = 1; + exponent = -exponent; + + assert (tens != &_fpioconst_pow10[0]); + do + { + --tens; + + if (exponent >= tens->m_expo) + { + int i, incr, cnt_h, cnt_l; + mp_limb topval[2]; + + /* The __mpn_mul function expects the first argument to be + bigger than the second. */ + if (fracsize < tens->arraysize - 2) + cy = __mpn_mul (tmp, &tens->array[2], tens->arraysize - 2, + frac, fracsize); + else + cy = __mpn_mul (tmp, frac, fracsize, + &tens->array[2], tens->arraysize - 2); + tmpsize = fracsize + tens->arraysize - 2; + if (cy == 0) + --tmpsize; + + count_leading_zeros (cnt_h, tmp[tmpsize - 1]); + incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB + + BITS_PER_MP_LIMB - 1 - cnt_h; + + assert (incr <= tens->p_expo); + + /* If we increased the exponent by exactly 3 we have to test + for overflow. This is done by comparing with 10 shifted + to the right position. */ + if (incr == exponent + 3) + if (cnt_h <= BITS_PER_MP_LIMB - 4) + { + topval[0] = 0; + topval[1] = 10 << (BITS_PER_MP_LIMB - 4 - cnt_h); + } + else + { + topval[0] = 10 << (BITS_PER_MP_LIMB - 4); + topval[1] = 0; + (void) __mpn_lshift (topval, topval, 2, + BITS_PER_MP_LIMB - cnt_h); + } + + /* We have to be careful when multiplying the last factor. + If the result is greater than 1.0 be have to test it + against 10.0. If it is greater or equal to 10.0 the + multiplication was not valid. This is because we cannot + determine the number of bits in the result in advance. */ + if (incr < exponent + 3 + || (incr == exponent + 3 && + (tmp[tmpsize - 1] < topval[1] + || (tmp[tmpsize - 1] == topval[1] + && tmp[tmpsize - 2] < topval[0])))) + { + /* The factor is right. Adapt binary and decimal + exponents. */ + exponent -= incr; + exp10 |= 1 << explog; + + /* If this factor yields a number greater or equal to + 1.0, we must not shift the non-fractional digits down. */ + if (exponent < 0) + cnt_h += -exponent; + + /* Now we optimize the number representation. */ + for (i = 0; tmp[i] == 0; ++i); + if (cnt_h == BITS_PER_MP_LIMB - 1) + { + MPN_COPY (frac, tmp + i, tmpsize - i); + fracsize = tmpsize - i; + } + else + { + count_trailing_zeros (cnt_l, tmp[i]); + + /* Now shift the numbers to their optimal position. */ + if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l) + { + /* We cannot save any memory. Just roll the + number so that the leading digit is in a + seperate limb. */ + + cy = __mpn_lshift (frac, tmp, tmpsize, cnt_h + 1); + fracsize = tmpsize + 1; + frac[fracsize - 1] = cy; + } + else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l) + { + (void) __mpn_rshift (frac, tmp + i, tmpsize - i, + BITS_PER_MP_LIMB - 1 - cnt_h); + fracsize = tmpsize - i; + } + else + { + /* We can only save the memory of the limbs which + are zero. The non-zero parts occupy the same + number of limbs. */ + + (void) __mpn_rshift (frac, tmp + (i - 1), + tmpsize - (i - 1), + BITS_PER_MP_LIMB - 1 - cnt_h); + fracsize = tmpsize - (i - 1); + } + } + used_limbs = fracsize - 1; + } + } + --explog; + } + while (tens != &_fpioconst_pow10[1] && exponent > 0); + /* All factors but 10^-1 are tested now. */ + if (exponent > 0) + { + cy = __mpn_mul_1 (tmp, frac, fracsize, 10); + tmpsize = fracsize; + assert (cy == 0 || tmp[tmpsize - 1] < 20); + + (void) __mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent)); + fracsize = tmpsize; + exp10 |= 1; + assert (frac[fracsize - 1] < 10); + } + exponent = exp10; + } + else + { + /* This is a special case. We don't need a factor because the + numbers are in the range of 0.0 <= fp < 8.0. We simply + shift it to the right place and divide it by 1.0 to get the + leading digit. (Of course this division is not really made.) */ + assert (0 <= exponent && exponent < 3 && + exponent + to_shift < BITS_PER_MP_LIMB); + + /* Now shift the input value to its right place. */ + cy = __mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift)); + frac[fracsize++] = cy; + exponent = 0; + } + + { + int width = info->width; + char *buffer, *startp, *cp; + int chars_needed; + int expscale; + int intdig_max, intdig_no = 0; + int fracdig_min, fracdig_max, fracdig_no = 0; + int dig_max; + int significant; + + if (tolower (info->spec) == 'e') + { + type = info->spec; + intdig_max = 1; + fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec; + chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4; + /* d . ddd e +- ddd */ + dig_max = INT_MAX; /* Unlimited. */ + significant = 1; /* Does not matter here. */ + } + else if (info->spec == 'f') + { + type = 'f'; + fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec; + if (expsign == 0) + { + intdig_max = exponent + 1; + /* This can be really big! */ /* XXX Maybe malloc if too big? */ + chars_needed = exponent + 1 + 1 + fracdig_max; + } + else + { + intdig_max = 1; + chars_needed = 1 + 1 + fracdig_max; + } + dig_max = INT_MAX; /* Unlimited. */ + significant = 1; /* Does not matter here. */ + } + else + { + dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec); + if ((expsign == 0 && exponent >= dig_max) + || (expsign != 0 && exponent > 4)) + { + type = isupper (info->spec) ? 'E' : 'e'; + fracdig_max = dig_max - 1; + intdig_max = 1; + chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4; + } + else + { + type = 'f'; + intdig_max = expsign == 0 ? exponent + 1 : 0; + fracdig_max = dig_max - intdig_max; + /* We need space for the significant digits and perhaps for + leading zeros when < 1.0. Pessimistic guess: dig_max. */ + chars_needed = dig_max + dig_max + 1; + } + fracdig_min = info->alt ? fracdig_max : 0; + significant = 0; /* We count significant digits. */ + } + + if (grouping) + /* Guess the number of groups we will make, and thus how + many spaces we need for separator characters. */ + chars_needed += guess_grouping (intdig_max, grouping, thousands_sep); + + /* Allocate buffer for output. We need two more because while rounding + it is possible that we need two more characters in front of all the + other output. */ + buffer = alloca (2 + chars_needed); + cp = startp = buffer + 2; /* Let room for rounding. */ + + /* Do the real work: put digits in allocated buffer. */ + if (expsign == 0 || type != 'f') + { + assert (expsign == 0 || intdig_max == 1); + while (intdig_no < intdig_max) + { + ++intdig_no; + *cp++ = hack_digit (); + } + significant = 1; + if (info->alt + || fracdig_min > 0 + || (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0))) + *cp++ = decimal; + } + else + { + /* |fp| < 1.0 and the selected type is 'f', so put "0." + in the buffer. */ + *cp++ = '0'; + --exponent; + *cp++ = decimal; + } + + /* Generate the needed number of fractional digits. */ + while (fracdig_no < fracdig_min + || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0))) + { + ++fracdig_no; + *cp = hack_digit (); + if (*cp != '0') + significant = 1; + else if (significant == 0) + { + ++fracdig_max; + if (fracdig_min > 0) + ++fracdig_min; + } + ++cp; + } + + /* Do rounding. */ + digit = hack_digit (); + if (digit > '4') + { + char *tp = cp; + + if (digit == '5') + /* This is the critical case. */ + if (fracsize == 1 && frac[0] == 0) + /* Rest of the number is zero -> round to even. + (IEEE 754-1985 4.1 says this is the default rounding.) */ + if ((*(cp - 1) & 1) == 0) + goto do_expo; + + if (fracdig_no > 0) + { + /* Process fractional digits. Terminate if not rounded or + radix character is reached. */ + while (*--tp != decimal && *tp == '9') + *tp = '0'; + if (*tp != decimal) + /* Round up. */ + (*tp)++; + } + + if (fracdig_no == 0 || *tp == decimal) + { + /* Round the integer digits. */ + if (*(tp - 1) == decimal) + --tp; + + while (--tp >= startp && *tp == '9') + *tp = '0'; + + if (tp >= startp) + /* Round up. */ + (*tp)++; + else + /* It is more citical. All digits were 9's. */ + { + if (type != 'f') + { + *startp = '1'; + exponent += expsign == 0 ? 1 : -1; + } + else if (intdig_no == dig_max) + { + /* This is the case where for type %g the number fits + really in the range for %f output but after rounding + the number of digits is too big. */ + *--startp = decimal; + *--startp = '1'; + + if (info->alt || fracdig_no > 0) + { + /* Overwrite the old radix character. */ + startp[intdig_no + 2] = '0'; + ++fracdig_no; + } + + fracdig_no += intdig_no; + intdig_no = 1; + fracdig_max = intdig_max - intdig_no; + ++exponent; + /* Now we must print the exponent. */ + type = isupper (info->spec) ? 'E' : 'e'; + } + else + { + /* We can simply add another another digit before the + radix. */ + *--startp = '1'; + ++intdig_no; + } + + /* While rounding the number of digits can change. + If the number now exceeds the limits remove some + fractional digits. */ + if (intdig_no + fracdig_no > dig_max) + { + cp -= intdig_no + fracdig_no - dig_max; + fracdig_no -= intdig_no + fracdig_no - dig_max; + } + } + } + } + + do_expo: + /* Now remove unnecessary '0' at the end of the string. */ + while (fracdig_no > fracdig_min && *(cp - 1) == '0') + { + --cp; + --fracdig_no; + } + /* If we eliminate all fractional digits we perhaps also can remove + the radix character. */ + if (fracdig_no == 0 && !info->alt && *(cp - 1) == decimal) + --cp; + + if (grouping) + /* Add in separator characters, overwriting the same buffer. */ + cp = group_number (startp, cp, intdig_no, grouping, thousands_sep); + + /* Write the exponent if it is needed. */ + if (type != 'f') + { + *cp++ = type; + *cp++ = expsign ? '-' : '+'; + + /* Find the magnitude of the exponent. */ + expscale = 10; + while (expscale <= exponent) + expscale *= 10; + + if (exponent < 10) + /* Exponent always has at least two digits. */ + *cp++ = '0'; + else + do + { + expscale /= 10; + *cp++ = '0' + (exponent / expscale); + exponent %= expscale; + } + while (expscale > 10); + *cp++ = '0' + exponent; + } + + /* Compute number of characters which must be filled with the padding + character. */ + if (is_neg || info->showsign || info->space) + --width; + width -= cp - startp; + + if (!info->left && info->pad != '0' && width > 0) + PADN (info->pad, width); + + if (is_neg) + outchar ('-'); + else if (info->showsign) + outchar ('+'); + else if (info->space) + outchar (' '); + + if (!info->left && info->pad == '0' && width > 0) + PADN ('0', width); + + PRINT (startp, cp - startp); + + if (info->left && width > 0) + PADN (info->pad, width); + } + return done; +} + +/* Return the number of extra grouping characters that will be inserted + into a number with INTDIG_MAX integer digits. */ + +static unsigned int +guess_grouping (unsigned int intdig_max, const char *grouping, wchar_t sepchar) +{ + unsigned int groups; + + /* We treat all negative values like CHAR_MAX. */ + + if (*grouping == CHAR_MAX || *grouping <= 0) + /* No grouping should be done. */ + return 0; + + groups = 0; + while (intdig_max > *grouping) + { + ++groups; + intdig_max -= *grouping++; + + if (*grouping == CHAR_MAX || *grouping < 0) + /* No more grouping should be done. */ + break; + else if (*grouping == 0) + { + /* Same grouping repeats. */ + groups += intdig_max / grouping[-1]; + break; + } + } + + return groups; +} + +/* Group the INTDIG_NO integer digits of the number in [BUF,BUFEND). + There is guaranteed enough space past BUFEND to extend it. + Return the new end of buffer. */ + +static char * +group_number (char *buf, char *bufend, unsigned int intdig_no, + const char *grouping, wchar_t thousands_sep) +{ + unsigned int groups = guess_grouping (intdig_no, grouping, thousands_sep); + char *p; + + if (groups == 0) + return bufend; + + /* Move the fractional part down. */ + memmove (buf + intdig_no + groups, buf + intdig_no, + bufend - (buf + intdig_no)); + + p = buf + intdig_no + groups - 1; + do + { + unsigned int len = *grouping++; + do + *p-- = buf[--intdig_no]; + while (--len > 0); + *p-- = thousands_sep; + + if (*grouping == CHAR_MAX || *grouping < 0) + /* No more grouping should be done. */ + break; + else if (*grouping == 0) + /* Same grouping repeats. */ + --grouping; + } while (intdig_no > *grouping); + + /* Copy the remaining ungrouped digits. */ + do + *p-- = buf[--intdig_no]; + while (p > buf); + + return bufend + groups; +} diff --git a/stdio/psignal.c b/stdio/psignal.c new file mode 100644 index 0000000000..8997a2ecdf --- /dev/null +++ b/stdio/psignal.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <signal.h> + + +#ifndef HAVE_GNU_LD +#define _sys_siglist sys_siglist +#endif + +/* Defined in sys_siglist.c. */ +extern CONST char *CONST _sys_siglist[]; + + +/* Print out on stderr a line consisting of the test in S, a colon, a space, + a message describing the meaning of the signal number SIG and a newline. + If S is NULL or "", the colon and space are omitted. */ +void +DEFUN(psignal, (sig, s), int sig AND register CONST char *s) +{ + CONST char *colon; + + if (s == NULL || s == '\0') + s = colon = ""; + else + colon = ": "; + + if (sig >= 0 && sig < NSIG) + (void) fprintf(stderr, "%s%s%s\n", s, colon, _sys_siglist[sig]); + else + (void) fprintf(stderr, "%s%sUnknown signal %d\n", s, colon, sig); +} diff --git a/stdio/putc.c b/stdio/putc.c new file mode 100644 index 0000000000..51aae378ae --- /dev/null +++ b/stdio/putc.c @@ -0,0 +1,5 @@ +#include <ansidecl.h> +#include <stdio.h> +#undef putc +#define fputc putc +#include <fputc.c> diff --git a/stdio/putchar.c b/stdio/putchar.c new file mode 100644 index 0000000000..90c037600a --- /dev/null +++ b/stdio/putchar.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +#undef putchar + + +/* Write the character C on stdout. */ +int +DEFUN(putchar, (c), int c) +{ + return __putc(c, stdout); +} diff --git a/stdio/puts.c b/stdio/puts.c new file mode 100644 index 0000000000..269c607da7 --- /dev/null +++ b/stdio/puts.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#undef puts + + +/* Write the string in S and a newline to stdout. */ +int +DEFUN(puts, (s), CONST char *s) +{ + return(fputs(s, stdout) || putchar('\n') == EOF ? EOF : 0); +} diff --git a/stdio/putw.c b/stdio/putw.c new file mode 100644 index 0000000000..1b70baeeaf --- /dev/null +++ b/stdio/putw.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + + +/* Write the word (int) W to STREAM. */ +int +DEFUN(putw, (w, stream), int w AND FILE *stream) +{ + /* Is there a better way? */ + if (fwrite((CONST PTR) &w, sizeof(w), 1, stream) < 1) + return(EOF); + return(0); +} diff --git a/stdio/reg-printf.c b/stdio/reg-printf.c new file mode 100644 index 0000000000..95d7a1f3c9 --- /dev/null +++ b/stdio/reg-printf.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <printf.h> + +/* Array of functions indexed by format character. */ +static printf_function *printf_funcs[UCHAR_MAX + 1]; +printf_arginfo_function *__printf_arginfo_table[UCHAR_MAX + 1]; + +printf_function **__printf_function_table; + +/* Register FUNC to be called to format SPEC specifiers. */ +int +DEFUN(register_printf_function, (spec, converter, arginfo), + int spec AND printf_function converter AND + printf_arginfo_function arginfo) +{ + if (spec < 0 || spec > (int) UCHAR_MAX) + { + errno = EINVAL; + return -1; + } + + __printf_function_table = printf_funcs; + __printf_arginfo_table[spec] = arginfo; + printf_funcs[spec] = converter; + + return 0; +} diff --git a/stdio/rewind.c b/stdio/rewind.c new file mode 100644 index 0000000000..038b0164d8 --- /dev/null +++ b/stdio/rewind.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +#undef rewind + + +/* Rewind STREAM to the beginning of the + file and clear its error and EOF flags. */ +void +DEFUN(rewind, (stream), FILE *stream) +{ + clearerr(stream); + (void) fseek(stream, 0L, SEEK_SET); + clearerr(stream); +} diff --git a/stdio/scanf.c b/stdio/scanf.c new file mode 100644 index 0000000000..aa7021526f --- /dev/null +++ b/stdio/scanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +DEFUN(scanf, (format), CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vscanf(format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/setbuf.c b/stdio/setbuf.c new file mode 100644 index 0000000000..99cfa9dd24 --- /dev/null +++ b/stdio/setbuf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> + + +/* If BUF is NULL, make STREAM unbuffered. + If not, make BUF, which is BUFSIZ bytes long, be its buffer. */ +void +DEFUN(setbuf, (stream, buf), FILE *stream AND char *buf) +{ + (void) setvbuf(stream, buf, buf != NULL ? _IOFBF : _IONBF, BUFSIZ); +} diff --git a/stdio/setbuffer.c b/stdio/setbuffer.c new file mode 100644 index 0000000000..7677c1e358 --- /dev/null +++ b/stdio/setbuffer.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> + + +/* If BUF is NULL, make stream unbuffered. + If not, make BUF, which is N bytes long, be its buffer. */ +void +DEFUN(setbuffer, (stream, buf, n), FILE *stream AND char *buf AND size_t n) +{ + (void) setvbuf(stream, buf, buf != NULL ? _IOFBF : _IONBF, n); +} diff --git a/stdio/setlinebuf.c b/stdio/setlinebuf.c new file mode 100644 index 0000000000..578cdfa54f --- /dev/null +++ b/stdio/setlinebuf.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + + +/* Make STREAM line buffered. */ +void +DEFUN(setlinebuf, (stream), FILE *stream) +{ + if (stream->__buffer != NULL || !stream->__userbuf) + stream->__linebuf = 1; +} diff --git a/stdio/setvbuf.c b/stdio/setvbuf.c new file mode 100644 index 0000000000..8c33386610 --- /dev/null +++ b/stdio/setvbuf.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + + +/* Make STREAM use the buffering method given in MODE. + If MODE indicates full or line buffering, use BUF, + a buffer of SIZE bytes; if BUF is NULL, malloc a buffer. */ +int +DEFUN(setvbuf, (stream, buf, mode, size), + FILE *stream AND char *buf AND int mode AND size_t size) +{ + if (!__validfp(stream)) + { + errno = EINVAL; + return EOF; + } + + /* The ANSI standard says setvbuf can only be called before any I/O is done, + but we allow it to replace an old buffer, flushing it first. */ + if (stream->__buffer != NULL) + { + (void) fflush(stream); + /* Free the old buffer if it was malloc'd. */ + if (!stream->__userbuf) + free(stream->__buffer); + } + + stream->__get_limit = stream->__put_limit = NULL; + stream->__bufp = stream->__buffer = NULL; + stream->__userbuf = stream->__linebuf = stream->__linebuf_active = 0; + + switch (mode) + { + default: + errno = EINVAL; + return EOF; + case _IONBF: /* Unbuffered. */ + stream->__buffer = NULL; + stream->__bufsize = 0; + stream->__userbuf = 1; + break; + case _IOLBF: /* Line buffered. */ + stream->__linebuf = 1; + case _IOFBF: /* Fully buffered. */ + if (size == 0) + { + errno = EINVAL; + return EOF; + } + stream->__bufsize = size; + if (buf != NULL) + stream->__userbuf = 1; + else if ((buf = (char *) malloc(size)) == NULL) + return EOF; + stream->__buffer = buf; + break; + } + + stream->__bufp = stream->__buffer; + stream->__get_limit = stream->__buffer; + /* The next output operation will prime the stream for writing. */ + stream->__put_limit = stream->__buffer; + + return 0; +} diff --git a/stdio/snprintf.c b/stdio/snprintf.c new file mode 100644 index 0000000000..9f3e0c4868 --- /dev/null +++ b/stdio/snprintf.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output into S, according to the format + string FORMAT, writing no more than MAXLEN characters. */ +/* VARARGS3 */ +int +DEFUN(snprintf, (s, maxlen, format), + char *s AND size_t maxlen AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vsnprintf(s, maxlen, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/sprintf.c b/stdio/sprintf.c new file mode 100644 index 0000000000..ce3a970074 --- /dev/null +++ b/stdio/sprintf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(sprintf, (s, format), char *s AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = vsprintf(s, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/sscanf.c b/stdio/sscanf.c new file mode 100644 index 0000000000..33bc203577 --- /dev/null +++ b/stdio/sscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +DEFUN(sscanf, (s, format), CONST char *s AND CONST char *format DOTS) +{ + va_list arg; + int done; + + va_start(arg, format); + done = __vsscanf(s, format, arg); + va_end(arg); + + return done; +} diff --git a/stdio/stdio.h b/stdio/stdio.h new file mode 100644 index 0000000000..2994432328 --- /dev/null +++ b/stdio/stdio.h @@ -0,0 +1,681 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.9 INPUT/OUTPUT <stdio.h> + */ + +#ifndef _STDIO_H + +#if !defined(__need_FILE) +#define _STDIO_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + +#define __need___va_list +#include <stdarg.h> +#ifndef __GNUC_VA_LIST +#define __gnuc_va_list __ptr_t +#endif + +#include <gnu/types.h> +#endif /* Don't need FILE. */ +#undef __need_FILE + + +#ifndef __FILE_defined + +/* The opaque type of streams. */ +typedef struct __stdio_file FILE; + +#define __FILE_defined 1 +#endif /* FILE not defined. */ + + +#ifdef _STDIO_H + +/* The type of the second argument to `fgetpos' and `fsetpos'. */ +typedef __off_t fpos_t; + +/* The mode of I/O, as given in the MODE argument to fopen, etc. */ +typedef struct +{ + unsigned int __read:1; /* Open for reading. */ + unsigned int __write:1; /* Open for writing. */ + unsigned int __append:1; /* Open for appending. */ + unsigned int __binary:1; /* Opened binary. */ + unsigned int __create:1; /* Create the file. */ + unsigned int __exclusive:1; /* Error if it already exists. */ + unsigned int __truncate:1; /* Truncate the file on opening. */ +} __io_mode; + + +/* Functions to do I/O and file management for a stream. */ + +/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. + Return number of bytes read. */ +typedef __ssize_t __io_read_fn __P ((__ptr_t __cookie, char *__buf, + size_t __nbytes)); + +/* Write N bytes pointed to by BUF to COOKIE. Write all N bytes + unless there is an error. Return number of bytes written, or -1 if + there is an error without writing anything. If the file has been + opened for append (__mode.__append set), then set the file pointer + to the end of the file and then do the write; if not, just write at + the current file pointer. */ +typedef __ssize_t __io_write_fn __P ((__ptr_t __cookie, __const char *__buf, + size_t __n)); + +/* Move COOKIE's file position to *POS bytes from the + beginning of the file (if W is SEEK_SET), + the current position (if W is SEEK_CUR), + or the end of the file (if W is SEEK_END). + Set *POS to the new file position. + Returns zero if successful, nonzero if not. */ +typedef int __io_seek_fn __P ((__ptr_t __cookie, fpos_t *__pos, int __w)); + +/* Close COOKIE. */ +typedef int __io_close_fn __P ((__ptr_t __cookie)); + +/* Return the file descriptor associated with COOKIE, + or -1 on error. There need not be any associated file descriptor. */ +typedef int __io_fileno_fn __P ((__ptr_t __cookie)); + +#ifdef __USE_GNU +/* User-visible names for the above. */ +typedef __io_read_fn cookie_read_function_t; +typedef __io_write_fn cookie_write_function_t; +typedef __io_seek_fn cookie_seek_function_t; +typedef __io_close_fn cookie_close_function_t; +typedef __io_fileno_fn cookie_fileno_function_t; +#endif + +/* Low level interface, independent of FILE representation. */ +#if defined (__USE_GNU) && !defined (_LIBC) +/* Define the user-visible type, with user-friendly member names. */ +typedef struct +{ + __io_read_fn *read; /* Read bytes. */ + __io_write_fn *write; /* Write bytes. */ + __io_seek_fn *seek; /* Seek/tell file position. */ + __io_close_fn *close; /* Close file. */ + __io_fileno_fn *fileno; /* Return file descriptor. */ +} cookie_io_functions_t; +/* This name is still used in the prototypes in this file. */ +typedef cookie_io_functions_t __io_functions; +#else +/* Stick to ANSI-safe names. */ +typedef struct +{ + __io_read_fn *__read; /* Read bytes. */ + __io_write_fn *__write; /* Write bytes. */ + __io_seek_fn *__seek; /* Seek/tell file position. */ + __io_close_fn *__close; /* Close file. */ + __io_fileno_fn *__fileno; /* Return file descriptor. */ +} __io_functions; +#endif + +/* Higher level interface, dependent on FILE representation. */ +typedef struct +{ + /* Make room in the input buffer. */ + int (*__input) __P ((FILE *__stream)); + /* Make room in the output buffer. */ + void (*__output) __P ((FILE *__stream, int __c)); +} __room_functions; + +extern __const __io_functions __default_io_functions; +extern __const __room_functions __default_room_functions; + + +/* Default close function. */ +extern __io_close_fn __stdio_close; +/* Open FILE with mode M, store cookie in *COOKIEPTR. */ +extern int __stdio_open __P ((__const char *__file, __io_mode __m, + __ptr_t *__cookieptr)); +/* Put out an error message for when stdio needs to die. */ +extern void __stdio_errmsg __P ((__const char *__msg, size_t __len)); +/* Generate a unique file name (and possibly open it with mode "w+b"). */ +extern char *__stdio_gen_tempname __P ((__const char *__dir, + __const char *__pfx, + int __dir_search, + size_t *__lenptr, + FILE **__streamptr)); + + +/* Print out MESSAGE on the error output and abort. */ +extern void __libc_fatal __P ((__const char *__message)) + __attribute__ ((__noreturn__)); + + +/* The FILE structure. */ +struct __stdio_file +{ + /* Magic number for validation. Must be negative in open streams + for the glue to Unix stdio getc/putc to work. + NOTE: stdio/glue.c has special knowledge of these first four members. */ + int __magic; +#define _IOMAGIC 0xfedabeeb /* Magic number to fill `__magic'. */ +#define _GLUEMAGIC 0xfeedbabe /* Magic for glued Unix streams. */ + + char *__bufp; /* Pointer into the buffer. */ + char *__get_limit; /* Reading limit. */ + char *__put_limit; /* Writing limit. */ + + char *__buffer; /* Base of buffer. */ + size_t __bufsize; /* Size of the buffer. */ + __ptr_t __cookie; /* Magic cookie. */ + __io_mode __mode; /* File access mode. */ + __io_functions __io_funcs; /* I/O functions. */ + __room_functions __room_funcs;/* I/O buffer room functions. */ + fpos_t __offset; /* Current file position. */ + fpos_t __target; /* Target file position. */ + FILE *__next; /* Next FILE in the linked list. */ + char *__pushback_bufp; /* Old bufp if char pushed back. */ + unsigned char __pushback; /* Pushed-back character. */ + unsigned int __pushed_back:1; /* A char has been pushed back. */ + unsigned int __eof:1; /* End of file encountered. */ + unsigned int __error:1; /* Error encountered. */ + unsigned int __userbuf:1; /* Buffer from user (should not be freed). */ + unsigned int __linebuf:1; /* Flush on newline. */ + unsigned int __linebuf_active:1; /* put_limit is not really in use. */ + unsigned int __seen:1; /* This stream has been seen. */ + unsigned int __ispipe:1; /* Nonzero if opened by popen. */ +}; + + +/* All macros used internally by other macros here and by stdio functions begin + with `__'. All of these may evaluate their arguments more than once. */ + + +/* Nonzero if STREAM is a valid stream. + STREAM must be a modifiable lvalue (wow, I got to use that term). + See stdio/glue.c for what the confusing bit is about. */ +#define __validfp(stream) \ + (stream != NULL && \ + ((stream->__magic == _GLUEMAGIC && \ + (stream = *(((struct { int __magic; FILE **__p; } *) stream)->__p))), \ + (stream->__magic == _IOMAGIC))) + +/* Clear the error and EOF indicators of STREAM. */ +#define __clearerr(stream) ((stream)->__error = (stream)->__eof = 0) + +/* Nuke STREAM, making it unusable but available for reuse. */ +extern void __invalidate __P ((FILE *__stream)); + +/* Make sure STREAM->__offset and STREAM->__target are initialized. + Returns 0 if successful, or EOF on + error (but doesn't set STREAM->__error). */ +extern int __stdio_check_offset __P ((FILE *__stream)); + + +/* The possibilities for the third argument to `setvbuf'. */ +#define _IOFBF 0x1 /* Full buffering. */ +#define _IOLBF 0x2 /* Line buffering. */ +#define _IONBF 0x4 /* No buffering. */ + + +/* Default buffer size. */ +#define BUFSIZ 1024 + + +/* End of file character. + Some things throughout the library rely on this being -1. */ +#define EOF (-1) + + +/* The possibilities for the third argument to `fseek'. + These values should not be changed. */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ + + +#ifdef __USE_SVID +/* Default path prefix for `tempnam' and `tmpnam'. */ +#define P_tmpdir "/usr/tmp" +#endif + + +/* Get the values: + L_tmpnam How long an array of chars must be to be passed to `tmpnam'. + TMP_MAX The minimum number of unique filenames generated by tmpnam + (and tempnam when it uses tmpnam's name space), + or tempnam (the two are separate). + L_ctermid How long an array to pass to `ctermid'. + L_cuserid How long an array to pass to `cuserid'. + FOPEN_MAX Mininum number of files that can be open at once. + FILENAME_MAX Maximum length of a filename. */ +#include <stdio_lim.h> + + +/* All the known streams are in a linked list + linked by the `next' field of the FILE structure. */ +extern FILE *__stdio_head; /* Head of the list. */ + +/* Standard streams. */ +extern FILE *stdin, *stdout, *stderr; +#ifdef __STRICT_ANSI__ +/* ANSI says these are macros; satisfy pedants. */ +#define stdin stdin +#define stdout stdout +#define stderr stderr +#endif + + +/* Remove file FILENAME. */ +extern int remove __P ((__const char *__filename)); +/* Rename file OLD to NEW. */ +extern int rename __P ((__const char *__old, __const char *__new)); + + +/* Create a temporary file and open it read/write. */ +extern FILE *tmpfile __P ((void)); +/* Generate a temporary filename. */ +extern char *tmpnam __P ((char *__s)); + + +#ifdef __USE_SVID +/* Generate a unique temporary filename using up to five characters of PFX + if it is not NULL. The directory to put this file in is searched for + as follows: First the environment variable "TMPDIR" is checked. + If it contains the name of a writable directory, that directory is used. + If not and if DIR is not NULL, that value is checked. If that fails, + P_tmpdir is tried and finally "/tmp". The storage for the filename + is allocated by `malloc'. */ +extern char *tempnam __P ((__const char *__dir, __const char *__pfx)); +#endif + + +/* This performs actual output when necessary, flushing + STREAM's buffer and optionally writing another character. */ +extern int __flshfp __P ((FILE *__stream, int __c)); + + +/* Close STREAM, or all streams if STREAM is NULL. */ +extern int fclose __P ((FILE *__stream)); +/* Flush STREAM, or all streams if STREAM is NULL. */ +extern int fflush __P ((FILE *__stream)); + + +/* Open a file and create a new stream for it. */ +extern FILE *fopen __P ((__const char *__filename, __const char *__modes)); +/* Open a file, replacing an existing stream with it. */ +extern FILE *freopen __P ((__const char *__filename, + __const char *__modes, FILE *__stream)); + +/* Return a new, zeroed, stream. + You must set its cookie and io_mode. + The first operation will give it a buffer unless you do. + It will also give it the default functions unless you set the `seen' flag. + The offset is set to -1, meaning it will be determined by doing a + stationary seek. You can set it to avoid the initial tell call. + The target is set to -1, meaning it will be set to the offset + before the target is needed. + Returns NULL if a stream can't be created. */ +extern FILE *__newstream __P ((void)); + +#ifdef __USE_POSIX +/* Create a new stream that refers to an existing system file descriptor. */ +extern FILE *fdopen __P ((int __fd, __const char *__modes)); +#endif + +#ifdef __USE_GNU +/* Create a new stream that refers to the given magic cookie, + and uses the given functions for input and output. */ +extern FILE *fopencookie __P ((__ptr_t __magic_cookie, __const char *__modes, + __io_functions __io_funcs)); + +/* Create a new stream that refers to a memory buffer. */ +extern FILE *fmemopen __P ((__ptr_t __s, size_t __len, __const char *__modes)); + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +extern FILE *open_memstream __P ((char **__bufloc, size_t *__sizeloc)); +#endif + + +/* If BUF is NULL, make STREAM unbuffered. + Else make it use buffer BUF, of size BUFSIZ. */ +extern void setbuf __P ((FILE *__stream, char *__buf)); +/* Make STREAM use buffering mode MODE. + If BUF is not NULL, use N bytes of it for buffering; + else allocate an internal buffer N bytes long. */ +extern int setvbuf __P ((FILE *__stream, char *__buf, + int __modes, size_t __n)); + +#ifdef __USE_BSD +/* If BUF is NULL, make STREAM unbuffered. + Else make it use SIZE bytes of BUF for buffering. */ +extern void setbuffer __P ((FILE *__stream, char *__buf, size_t __size)); + +/* Make STREAM line-buffered. */ +extern void setlinebuf __P ((FILE *__stream)); +#endif + + +/* Write formatted output to STREAM. */ +extern int fprintf __P ((FILE *__stream, __const char *__format, ...)); +/* Write formatted output to stdout. */ +extern int printf __P ((__const char *__format, ...)); +/* Write formatted output to S. */ +extern int sprintf __P ((char *__s, __const char *__format, ...)); + +/* Write formatted output to S from argument list ARG. */ +extern int vfprintf __P ((FILE *__s, __const char *__format, + __gnuc_va_list __arg)); +/* Write formatted output to stdout from argument list ARG. */ +extern int vprintf __P ((__const char *__format, __gnuc_va_list __arg)); +/* Write formatted output to S from argument list ARG. */ +extern int vsprintf __P ((char *__s, __const char *__format, + __gnuc_va_list __arg)); + +#ifdef __OPTIMIZE__ +extern __inline int +vprintf (const char *__fmt, __gnuc_va_list __arg) +{ + return vfprintf (stdout, __fmt, __arg); +} +#endif /* Optimizing. */ + +#ifdef __USE_GNU +/* Maximum chars of output to write in MAXLEN. */ +extern int snprintf __P ((char *__s, size_t __maxlen, + __const char *__format, ...)); + +extern int vsnprintf __P ((char *__s, size_t __maxlen, + __const char *__format, __gnuc_va_list __arg)); + +/* Write formatted output to a string dynamically allocated with `malloc'. + Store the address of the string in *PTR. */ +extern int vasprintf __P ((char **__ptr, __const char *__f, + __gnuc_va_list __arg)); +extern int asprintf __P ((char **__ptr, __const char *__fmt, ...)); + +/* Write formatted output to a file descriptor. */ +extern int vdprintf __P ((int __fd, __const char *__fmt, + __gnuc_va_list __arg)); +extern int dprintf __P ((int __fd, __const char *__fmt, ...)); +#endif + + +/* Read formatted input from STREAM. */ +extern int fscanf __P ((FILE *__stream, __const char *__format, ...)); +/* Read formatted input from stdin. */ +extern int scanf __P ((__const char *__format, ...)); +/* Read formatted input from S. */ +extern int sscanf __P ((__const char *__s, __const char *__format, ...)); + +#ifdef __USE_GNU +/* Read formatted input from S into argument list ARG. */ +extern int __vfscanf __P ((FILE *__s, __const char *__format, + __gnuc_va_list __arg)); +extern int vfscanf __P ((FILE *__s, __const char *__format, + __gnuc_va_list __arg)); + +/* Read formatted input from stdin into argument list ARG. */ +extern int vscanf __P ((__const char *__format, __gnuc_va_list __arg)); + +/* Read formatted input from S into argument list ARG. */ +extern int __vsscanf __P ((__const char *__s, __const char *__format, + __gnuc_va_list __arg)); +extern int vsscanf __P ((__const char *__s, __const char *__format, + __gnuc_va_list __arg)); + + +#ifdef __OPTIMIZE__ +extern __inline int +vfscanf (FILE *__s, const char *__fmt, __gnuc_va_list __arg) +{ + return __vfscanf (__s, __fmt, __arg); +} +extern __inline int +vscanf (const char *__fmt, __gnuc_va_list __arg) +{ + return __vfscanf (stdin, __fmt, __arg); +} +extern __inline int +vsscanf (const char *__s, const char *__fmt, __gnuc_va_list __arg) +{ + return __vsscanf (__s, __fmt, __arg); +} +#endif /* Optimizing. */ +#endif /* Use GNU. */ + + +/* This does actual reading when necessary, filling STREAM's + buffer and returning the first character in it. */ +extern int __fillbf __P ((FILE *__stream)); + + +/* Read a character from STREAM. */ +extern int fgetc __P ((FILE *__stream)); +extern int getc __P ((FILE *__stream)); + +/* Read a character from stdin. */ +extern int getchar __P ((void)); + +/* The C standard explicitly says this can + re-evaluate its argument, so it does. */ +#define __getc(stream) \ + ((stream)->__bufp < (stream)->__get_limit ? \ + (int) ((unsigned char) *(stream)->__bufp++) : __fillbf(stream)) + +/* The C standard explicitly says this is a macro, + so we always do the optimization for it. */ +#define getc(stream) __getc(stream) + +#ifdef __OPTIMIZE__ +extern __inline int +getchar (void) +{ + return __getc (stdin); +} +#endif /* Optimizing. */ + + +/* Write a character to STREAM. */ +extern int fputc __P ((int __c, FILE *__stream)); +extern int putc __P ((int __c, FILE *__stream)); + +/* Write a character to stdout. */ +extern int putchar __P ((int __c)); + + +/* The C standard explicitly says this can + re-evaluate its arguments, so it does. */ +#define __putc(c, stream) \ + ((stream)->__bufp < (stream)->__put_limit ? \ + (int) (unsigned char) (*(stream)->__bufp++ = (unsigned char) (c)) : \ + __flshfp ((stream), (unsigned char) (c))) + +/* The C standard explicitly says this can be a macro, + so we always do the optimization for it. */ +#define putc(c, stream) __putc ((c), (stream)) + +#ifdef __OPTIMIZE__ +extern __inline int +putchar (int __c) +{ + return __putc (__c, stdout); +} +#endif + + +#if defined(__USE_SVID) || defined(__USE_MISC) +/* Get a word (int) from STREAM. */ +extern int getw __P ((FILE *__stream)); + +/* Write a word (int) to STREAM. */ +extern int putw __P ((int __w, FILE *__stream)); +#endif + + +/* Get a newline-terminated string of finite length from STREAM. */ +extern char *fgets __P ((char *__s, int __n, FILE *__stream)); + +/* Get a newline-terminated string from stdin, removing the newline. + DO NOT USE THIS FUNCTION!! There is no limit on how much it will read. */ +extern char *gets __P ((char *__s)); + + +#ifdef __USE_GNU +#include <sys/types.h> + +/* Read up to (and including) a DELIMITER from STREAM into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'd as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ +ssize_t __getdelim __P ((char **__lineptr, size_t *__n, + int __delimiter, FILE *__stream)); +ssize_t getdelim __P ((char **__lineptr, size_t *__n, + int __delimiter, FILE *__stream)); + +/* Like `getdelim', but reads up to a newline. */ +ssize_t __getline __P ((char **__lineptr, size_t *__n, FILE *__stream)); +ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream)); + +#ifdef __OPTIMIZE__ +extern __inline ssize_t +__getline (char **__lineptr, size_t *__n, FILE *__stream) +{ + return __getdelim (__lineptr, __n, '\n', __stream); +} + +extern __inline ssize_t +getdelim (char **__lineptr, size_t *__n, int __delimiter, FILE *__stream) +{ + return __getdelim (__lineptr, __n, __delimiter, __stream); +} +extern __inline ssize_t +getline (char **__lineptr, size_t *__n, FILE *__stream) +{ + return __getline (__lineptr, __n, __stream); +} +#endif /* Optimizing. */ +#endif + + +/* Write a string to STREAM. */ +extern int fputs __P ((__const char *__s, FILE *__stream)); +/* Write a string, followed by a newline, to stdout. */ +extern int puts __P ((__const char *__s)); + + +/* Push a character back onto the input buffer of STREAM. */ +extern int ungetc __P ((int __c, FILE *__stream)); + + +/* Read chunks of generic data from STREAM. */ +extern size_t fread __P ((__ptr_t __ptr, size_t __size, + size_t __n, FILE *__stream)); +/* Write chunks of generic data to STREAM. */ +extern size_t fwrite __P ((__const __ptr_t __ptr, size_t __size, + size_t __n, FILE *__s)); + + +/* Seek to a certain position on STREAM. */ +extern int fseek __P ((FILE *__stream, long int __off, int __whence)); +/* Return the current position of STREAM. */ +extern long int ftell __P ((FILE *__stream)); +/* Rewind to the beginning of STREAM. */ +extern void rewind __P ((FILE *__stream)); + +/* Get STREAM's position. */ +extern int fgetpos __P ((FILE *__stream, fpos_t *__pos)); +/* Set STREAM's position. */ +extern int fsetpos __P ((FILE *__stream, __const fpos_t *__pos)); + + +/* Clear the error and EOF indicators for STREAM. */ +extern void clearerr __P ((FILE *__stream)); +/* Return the EOF indicator for STREAM. */ +extern int feof __P ((FILE *__stream)); +/* Return the error indicator for STREAM. */ +extern int ferror __P ((FILE *__stream)); + +#ifdef __OPTIMIZE__ +#define feof(stream) ((stream)->__eof != 0) +#define ferror(stream) ((stream)->__error != 0) +#endif /* Optimizing. */ + + +/* Print a message describing the meaning of the value of errno. */ +extern void perror __P ((__const char *__s)); + +#ifdef __USE_BSD +extern int sys_nerr; +extern char *sys_errlist[]; +#endif +#ifdef __USE_GNU +extern int _sys_nerr; +extern char *_sys_errlist[]; +#endif + + +#ifdef __USE_POSIX +/* Return the system file descriptor for STREAM. */ +extern int fileno __P ((FILE *__stream)); +#endif /* Use POSIX. */ + + +#if (defined (__USE_POSIX2) || defined(__USE_SVID) || defined(__USE_BSD) || \ + defined(__USE_MISC)) +/* Create a new stream connected to a pipe running the given command. */ +extern FILE *popen __P ((__const char *__command, __const char *__modes)); + +/* Close a stream opened by popen and return the status of its child. */ +extern int pclose __P ((FILE *__stream)); +#endif + + +#ifdef __USE_POSIX +/* Return the name of the controlling terminal. */ +extern char *ctermid __P ((char *__s)); +/* Return the name of the current user. */ +extern char *cuserid __P ((char *__s)); +#endif + + +#ifdef __USE_GNU +struct obstack; /* See <obstack.h>. */ + +/* Open a stream that writes to OBSTACK. */ +extern FILE *open_obstack_stream __P ((struct obstack *__obstack)); + +/* Write formatted output to an obstack. */ +extern int obstack_printf __P ((struct obstack *__obstack, + __const char *__format, ...)); +extern int obstack_vprintf __P ((struct obstack *__obstack, + __const char *__format, + __gnuc_va_list __args)); +#endif + + +__END_DECLS + +#endif /* <stdio.h> included. */ + +#endif /* stdio.h */ diff --git a/stdio/tempnam.c b/stdio/tempnam.c new file mode 100644 index 0000000000..14988a8656 --- /dev/null +++ b/stdio/tempnam.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Generate a unique temporary filename using up to five characters of PFX + if it is not NULL. The directory to put this file in is searched for + as follows: First the environment variable "TMPDIR" is checked. + If it contains the name of a writable directory, that directory is used. + If not and if DIR is not NULL, that value is checked. If that fails, + P_tmpdir is tried and finally "/tmp". The storage for the filename + is allocated by `malloc'. */ +char * +DEFUN(tempnam, (dir, pfx), CONST char *dir AND CONST char *pfx) +{ + size_t len; + register char *s; + register char *t = __stdio_gen_tempname(dir, pfx, 1, &len, (FILE **) NULL); + + if (t == NULL) + return NULL; + + s = (char *) malloc(len); + if (s == NULL) + return NULL; + + (void) memcpy(s, t, len); + return s; +} diff --git a/stdio/temptest.c b/stdio/temptest.c new file mode 100644 index 0000000000..374719896a --- /dev/null +++ b/stdio/temptest.c @@ -0,0 +1,31 @@ +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + +char *files[500]; + +int +main () +{ + char *fn; + FILE *fp; + int i; + + for (i = 0; i < 500; i++) { + fn = __stdio_gen_tempname((CONST char *) NULL, + "file", 0, (size_t *) NULL, (FILE **) NULL); + if (fn == NULL) { + printf ("__stdio_gen_tempname failed\n"); + exit (1); + } + files[i] = strdup (fn); + printf ("file: %s\n", fn); + fp = fopen (fn, "w"); + fclose (fp); + } + + for (i = 0; i < 500; i++) + remove (files[i]); + + exit (0); +} diff --git a/stdio/test-fseek.c b/stdio/test-fseek.c new file mode 100644 index 0000000000..398cac796f --- /dev/null +++ b/stdio/test-fseek.c @@ -0,0 +1,67 @@ +#include <ansidecl.h> +#include <stdio.h> + +#define TESTFILE "test.dat" + +int +main __P((void)) +{ + FILE *fp; + int i, j; + + puts ("\nFile seek test"); + fp = fopen (TESTFILE, "w"); + if (fp == NULL) + { + perror (TESTFILE); + return 1; + } + + for (i = 0; i < 256; i++) + putc (i, fp); + if (freopen (TESTFILE, "r", fp) != fp) + { + perror ("Cannot open file for reading"); + return 1; + } + + for (i = 1; i <= 255; i++) + { + printf ("%3d\n", i); + fseek (fp, (long) -i, SEEK_END); + if ((j = getc (fp)) != 256 - i) + { + printf ("SEEK_END failed %d\n", j); + break; + } + if (fseek (fp, (long) i, SEEK_SET)) + { + puts ("Cannot SEEK_SET"); + break; + } + if ((j = getc (fp)) != i) + { + printf ("SEEK_SET failed %d\n", j); + break; + } + if (fseek (fp, (long) i, SEEK_SET)) + { + puts ("Cannot SEEK_SET"); + break; + } + if (fseek (fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR)) + { + puts ("Cannot SEEK_CUR"); + break; + } + if ((j = getc (fp)) != (i >= 128 ? i - 128 : i + 128)) + { + printf ("SEEK_CUR failed %d\n", j); + break; + } + } + fclose (fp); + + puts ((i > 255) ? "Test succeeded." : "Test FAILED!"); + return (i > 255) ? 0 : 1; +} diff --git a/stdio/test-fwrite.c b/stdio/test-fwrite.c new file mode 100644 index 0000000000..cc6cdf038e --- /dev/null +++ b/stdio/test-fwrite.c @@ -0,0 +1,68 @@ +#include <stdio.h> +#include <string.h> + +int +main () +{ + FILE *f = tmpfile (); + char obuf[99999], ibuf[sizeof obuf]; + char *line; + size_t linesz; + + if (! f) + { + perror ("tmpfile"); + return 1; + } + + if (fputs ("line\n", f) == EOF) + { + perror ("fputs"); + return 1; + } + + memset (obuf, 'z', sizeof obuf); + memset (ibuf, 'y', sizeof ibuf); + + if (fwrite (obuf, sizeof obuf, 1, f) != 1) + { + perror ("fwrite"); + return 1; + } + + rewind (f); + + line = NULL; + linesz = 0; + if (getline (&line, &linesz, f) != 5) + { + perror ("getline"); + return 1; + } + if (strcmp (line, "line\n")) + { + puts ("Lines differ. Test FAILED!"); + return 1; + } + + if (fread (ibuf, sizeof ibuf, 1, f) != 1) + { + perror ("fread"); + return 1; + } + + if (memcmp (ibuf, obuf, sizeof ibuf)) + { + puts ("Buffers differ. Test FAILED!"); + return 1; + } + + asprintf (&line, "\ +GDB is free software and you are welcome to distribute copies of it\n\ + under certain conditions; type \"show copying\" to see the conditions.\n\ +There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\ +"); + + puts ("Test succeeded."); + return 0; +} diff --git a/stdio/test-popen.c b/stdio/test-popen.c new file mode 100644 index 0000000000..df6138b76f --- /dev/null +++ b/stdio/test-popen.c @@ -0,0 +1,67 @@ +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> + +void +DEFUN(write_data, (stream), FILE *stream) +{ + int i; + for (i=0; i<100; i++) + fprintf (stream, "%d\n", i); + if (ferror (stream)) { + fprintf (stderr, "Output to stream failed.\n"); + exit (1); + } +} + +void +DEFUN(read_data, (stream), FILE *stream) +{ + int i, j; + + for (i=0; i<100; i++) + { + if (fscanf (stream, "%d\n", &j) != 1 || j != i) + { + if (ferror (stream)) + perror ("fscanf"); + puts ("Test FAILED!"); + exit (1); + } + } +} + +int +DEFUN_VOID(main) +{ + FILE *output, *input; + int wstatus, rstatus; + + output = popen ("/bin/cat >tstpopen.tmp", "w"); + if (output == NULL) + { + perror ("popen"); + puts ("Test FAILED!"); + exit (1); + } + write_data (output); + wstatus = pclose (output); + printf ("writing pclose returned %d\n", wstatus); + input = popen ("/bin/cat tstpopen.tmp", "r"); + if (input == NULL) + { + perror ("tstpopen.tmp"); + puts ("Test FAILED!"); + exit (1); + } + read_data (input); + rstatus = pclose (input); + printf ("reading pclose returned %d\n", rstatus); + + puts (wstatus | rstatus ? "Test FAILED!" : "Test succeeded."); + exit (wstatus | rstatus); +} + + + + diff --git a/stdio/test_rdwr.c b/stdio/test_rdwr.c new file mode 100644 index 0000000000..8e0c1dfade --- /dev/null +++ b/stdio/test_rdwr.c @@ -0,0 +1,129 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + static CONST char hello[] = "Hello, world.\n"; + static CONST char replace[] = "Hewwo, world.\n"; + static CONST size_t replace_from = 2, replace_to = 4; + char filename[FILENAME_MAX]; + char *name = strrchr(*argv, '/'); + char buf[BUFSIZ]; + FILE *f; + int lose = 0; + + if (name != NULL) + ++name; + else + name = *argv; + + (void) sprintf(filename, "/tmp/%s.test", name); + + f = fopen(filename, "w+"); + if (f == NULL) + { + perror(filename); + exit(1); + } + + (void) fputs(hello, f); + rewind(f); + (void) fgets(buf, sizeof(buf), f); + rewind(f); + (void) fputs(buf, f); + rewind(f); + { + register size_t i; + for (i = 0; i < replace_from; ++i) + { + int c = getc(f); + if (c == EOF) + { + printf("EOF at %u.\n", i); + lose = 1; + break; + } + else if (c != hello[i]) + { + printf("Got '%c' instead of '%c' at %u.\n", + (unsigned char) c, hello[i], i); + lose = 1; + break; + } + } + } + + { + long int where = ftell(f); + if (where == replace_from) + { + register size_t i; + for (i = replace_from; i < replace_to; ++i) + if (putc(replace[i], f) == EOF) + { + printf("putc('%c') got %s at %u.\n", + replace[i], strerror(errno), i); + lose = 1; + break; + } + } + else if (where == -1L) + { + printf("ftell got %s (should be at %u).\n", + strerror(errno), replace_from); + lose = 1; + } + else + { + printf("ftell returns %u; should be %u.\n", where, replace_from); + lose = 1; + } + } + + if (!lose) + { + rewind(f); + if (fgets(buf, sizeof(buf), f) == NULL) + { + printf("fgets got %s.\n", strerror(errno)); + lose = 1; + } + else if (strcmp(buf, replace)) + { + printf("Read \"%s\" instead of \"%s\".\n", buf, replace); + lose = 1; + } + } + + if (lose) + printf("Test FAILED! Losing file is \"%s\".\n", filename); + else + { + (void) remove(filename); + puts("Test succeeded."); + } + + exit(lose ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/stdio/tmpfile.c b/stdio/tmpfile.c new file mode 100644 index 0000000000..dfe11ada50 --- /dev/null +++ b/stdio/tmpfile.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + + +/* This returns a new stream opened on a temporary file (generated + by tmpnam) The file is opened with mode "w+b" (binary read/write). + If we couldn't generate a unique filename or the file couldn't + be opened, NULL is returned. */ +FILE * +DEFUN_VOID(tmpfile) +{ + char *filename; + FILE *f; + + filename = __stdio_gen_tempname ((char *) NULL, "tmpf", 0, + (size_t *) NULL, &f); + if (filename == NULL) + return NULL; + + /* Note that this relies on the Unix semantics that + a file is not really removed until it is closed. */ + (void) remove (filename); + + return f; +} diff --git a/stdio/tmpnam.c b/stdio/tmpnam.c new file mode 100644 index 0000000000..88dd0a4ca5 --- /dev/null +++ b/stdio/tmpnam.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + + +/* Generate a unique filename in P_tmpdir. */ +char * +DEFUN(tmpnam, (s), register char *s) +{ + register char *t = __stdio_gen_tempname((CONST char *) NULL, + (CONST char *) NULL, 0, + (size_t *) NULL, (FILE **) NULL); + + if (t == NULL) + return NULL; + + if (s != NULL) + (void) strcpy(s, t); + else + s = t; + + return s; +} diff --git a/stdio/tst-fileno.c b/stdio/tst-fileno.c new file mode 100644 index 0000000000..81945f7b44 --- /dev/null +++ b/stdio/tst-fileno.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <unistd.h> + +static int +DEFUN(check, (name, stream, fd), CONST char *name AND FILE *stream AND int fd) +{ + int sfd = fileno (stream); + printf ("(fileno (%s) = %d) %c= %d\n", name, sfd, sfd == fd ? '=' : '!', fd); + return sfd != fd; +} + +int +DEFUN_VOID(main) +{ + exit (check ("stdin", stdin, STDIN_FILENO) || + check ("stdout", stdout, STDOUT_FILENO) || + check ("stderr", stderr, STDERR_FILENO)); +} diff --git a/stdio/tst-printf.c b/stdio/tst-printf.c new file mode 100644 index 0000000000..c177da18b2 --- /dev/null +++ b/stdio/tst-printf.c @@ -0,0 +1,298 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#ifdef BSD +#include </usr/include/stdio.h> +#define EXIT_SUCCESS 0 +#else +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#endif + +#include <float.h> + + +void +DEFUN(fmtchk, (fmt), CONST char *fmt) +{ + (void) fputs(fmt, stdout); + (void) printf(":\t`"); + (void) printf(fmt, 0x12); + (void) printf("'\n"); +} + +void +DEFUN(fmtst1chk, (fmt), CONST char *fmt) +{ + (void) fputs(fmt, stdout); + (void) printf(":\t`"); + (void) printf(fmt, 4, 0x12); + (void) printf("'\n"); +} + +void +DEFUN(fmtst2chk, (fmt), CONST char *fmt) +{ + (void) fputs(fmt, stdout); + (void) printf(":\t`"); + (void) printf(fmt, 4, 4, 0x12); + (void) printf("'\n"); +} + +/* This page is covered by the following copyright: */ + +/* (C) Copyright C E Chew + * + * Feel free to copy, use and distribute this software provided: + * + * 1. you do not pretend that you wrote it + * 2. you leave this copyright notice intact. + */ + +/* + * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans. + */ + +#define DEC -123 +#define INT 255 +#define UNS (~0) + +/* Formatted Output Test + * + * This exercises the output formatting code. + */ + +void +DEFUN_VOID(fp_test) +{ + int i, j, k, l; + char buf[7]; + char *prefix = buf; + char tp[20]; + + puts("\nFormatted output test"); + printf("prefix 6d 6o 6x 6X 6u\n"); + strcpy(prefix, "%"); + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + for (l = 0; l < 2; l++) { + strcpy(prefix, "%"); + if (i == 0) strcat(prefix, "-"); + if (j == 0) strcat(prefix, "+"); + if (k == 0) strcat(prefix, "#"); + if (l == 0) strcat(prefix, "0"); + printf("%5s |", prefix); + strcpy(tp, prefix); + strcat(tp, "6d |"); + printf(tp, DEC); + strcpy(tp, prefix); + strcat(tp, "6o |"); + printf(tp, INT); + strcpy(tp, prefix); + strcat(tp, "6x |"); + printf(tp, INT); + strcpy(tp, prefix); + strcat(tp, "6X |"); + printf(tp, INT); + strcpy(tp, prefix); + strcat(tp, "6u |"); + printf(tp, UNS); + printf("\n"); + } + } + } + } + printf("%10s\n", (char *) NULL); + printf("%-10s\n", (char *) NULL); +} + +int +DEFUN_VOID(main) +{ + static char shortstr[] = "Hi, Z."; + static char longstr[] = "Good morning, Doctor Chandra. This is Hal. \ +I am ready for my first lesson today."; + + fmtchk("%.4x"); + fmtchk("%04x"); + fmtchk("%4.4x"); + fmtchk("%04.4x"); + fmtchk("%4.3x"); + fmtchk("%04.3x"); + + fmtst1chk("%.*x"); + fmtst1chk("%0*x"); + fmtst2chk("%*.*x"); + fmtst2chk("%0*.*x"); + +#ifndef BSD + printf("bad format:\t\"%z\"\n"); + printf("nil pointer (padded):\t\"%10p\"\n", (PTR) NULL); +#endif + + printf("decimal negative:\t\"%d\"\n", -2345); + printf("octal negative:\t\"%o\"\n", -2345); + printf("hex negative:\t\"%x\"\n", -2345); + printf("long decimal number:\t\"%ld\"\n", -123456L); + printf("long octal negative:\t\"%lo\"\n", -2345L); + printf("long unsigned decimal number:\t\"%lu\"\n", -123456L); + printf("zero-padded LDN:\t\"%010ld\"\n", -123456L); + printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456); + printf("space-padded LDN:\t\"%10ld\"\n", -123456L); + printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L); + + printf("zero-padded string:\t\"%010s\"\n", shortstr); + printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr); + printf("space-padded string:\t\"%10s\"\n", shortstr); + printf("left-adjusted S string:\t\"%-10s\"\n", shortstr); + printf("null string:\t\"%s\"\n", (char *)NULL); + printf("limited string:\t\"%.22s\"\n", longstr); + + printf("e-style >= 1:\t\"%e\"\n", 12.34); + printf("e-style >= .1:\t\"%e\"\n", 0.1234); + printf("e-style < .1:\t\"%e\"\n", 0.001234); + printf("e-style big:\t\"%.60e\"\n", 1e20); + printf ("e-style == .1:\t\"%e\"\n", 0.1); + printf("f-style >= 1:\t\"%f\"\n", 12.34); + printf("f-style >= .1:\t\"%f\"\n", 0.1234); + printf("f-style < .1:\t\"%f\"\n", 0.001234); + printf("g-style >= 1:\t\"%g\"\n", 12.34); + printf("g-style >= .1:\t\"%g\"\n", 0.1234); + printf("g-style < .1:\t\"%g\"\n", 0.001234); + printf("g-style big:\t\"%.60g\"\n", 1e20); + + printf (" %6.5f\n", .099999999860301614); + printf (" %6.5f\n", .1); + printf ("x%5.4fx\n", .5); + + printf ("%#03x\n", 1); + + { + double d = FLT_MIN; + int niter = 17; + + while (niter-- != 0) + printf ("%.17e\n", d / 2); + fflush (stdout); + } + + printf ("%15.5e\n", 4.9406564584124654e-324); + +#define FORMAT "|%12.4f|%12.4e|%12.4g|\n" + printf (FORMAT, 0.0, 0.0, 0.0); + printf (FORMAT, 1.0, 1.0, 1.0); + printf (FORMAT, -1.0, -1.0, -1.0); + printf (FORMAT, 100.0, 100.0, 100.0); + printf (FORMAT, 1000.0, 1000.0, 1000.0); + printf (FORMAT, 10000.0, 10000.0, 10000.0); + printf (FORMAT, 12345.0, 12345.0, 12345.0); + printf (FORMAT, 100000.0, 100000.0, 100000.0); + printf (FORMAT, 123456.0, 123456.0, 123456.0); +#undef FORMAT + + { + char buf[20]; + printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n", + snprintf (buf, sizeof (buf), "%30s", "foo"), sizeof (buf), buf); + } + + fp_test (); + + printf ("%e should be 1.234568e+06\n", 1234567.8); + printf ("%f should be 1234567.800000\n", 1234567.8); + printf ("%g should be 1.23457e+06\n", 1234567.8); + printf ("%g should be 123.456\n", 123.456); + printf ("%g should be 1e+06\n", 1000000.0); + printf ("%g should be 10\n", 10.0); + printf ("%g should be 0.02\n", 0.02); + + { + double x=1.0; + printf("%.17f\n",(1.0/x/10.0+1.0)*x-x); + } + + puts ("--- Should be no further output. ---"); + rfg1 (); + rfg2 (); + + exit(EXIT_SUCCESS); +} + +rfg1 () +{ + char buf[100]; + + sprintf (buf, "%5.s", "xyz"); + if (strcmp (buf, " ") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " "); + sprintf (buf, "%5.f", 33.3); + if (strcmp (buf, " 33") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 33"); + sprintf (buf, "%8.e", 33.3e7); + if (strcmp (buf, " 3e+08") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 3e+08"); + sprintf (buf, "%8.E", 33.3e7); + if (strcmp (buf, " 3E+08") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 3E+08"); + sprintf (buf, "%.g", 33.3); + if (strcmp (buf, "3e+01") != 0) + printf ("got: '%s', expected: '%s'\n", buf, "3e+01"); + sprintf (buf, "%.G", 33.3); + if (strcmp (buf, "3E+01") != 0) + printf ("got: '%s', expected: '%s'\n", buf, "3E+01"); + return 0; +} + +rfg2 () +{ + int prec; + char buf[100]; + + prec = 0; + sprintf (buf, "%.*g", prec, 3.3); + if (strcmp (buf, "3") != 0) + printf ("got: '%s', expected: '%s'\n", buf, "3"); + prec = 0; + sprintf (buf, "%.*G", prec, 3.3); + if (strcmp (buf, "3") != 0) + printf ("got: '%s', expected: '%s'\n", buf, "3"); + prec = 0; + sprintf (buf, "%7.*G", prec, 3.33); + if (strcmp (buf, " 3") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 3"); + prec = 3; + sprintf (buf, "%04.*o", prec, 33); + if (strcmp (buf, " 041") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 041"); + prec = 7; + sprintf (buf, "%09.*u", prec, 33); + if (strcmp (buf, " 0000033") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 0000033"); + prec = 3; + sprintf (buf, "%04.*x", prec, 33); + if (strcmp (buf, " 021") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 021"); + prec = 3; + sprintf (buf, "%04.*X", prec, 33); + if (strcmp (buf, " 021") != 0) + printf ("got: '%s', expected: '%s'\n", buf, " 021"); + return 0; +} diff --git a/stdio/tstgetln.c b/stdio/tstgetln.c new file mode 100644 index 0000000000..ea8ea817da --- /dev/null +++ b/stdio/tstgetln.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + char *buf = NULL; + size_t size = 0; + ssize_t len; + + while ((len = getline (&buf, &size, stdin)) != -1) + { + printf ("bufsize %u; read %d: ", size, len); + if (fwrite (buf, len, 1, stdout) != 1) + { + perror ("fwrite"); + return 1; + } + } + + if (ferror (stdin)) + { + perror ("getline"); + return 1; + } + + return 0; +} diff --git a/stdio/tstgetln.input b/stdio/tstgetln.input new file mode 100644 index 0000000000..d04ed5bf78 --- /dev/null +++ b/stdio/tstgetln.input @@ -0,0 +1,3 @@ +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy +z diff --git a/stdio/tstscanf.c b/stdio/tstscanf.c new file mode 100644 index 0000000000..53d4b0ac47 --- /dev/null +++ b/stdio/tstscanf.c @@ -0,0 +1,100 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#ifdef BSD +#include </usr/include/stdio.h> +#else +#include <stdio.h> +#endif +#include <stdlib.h> +#include <string.h> + + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + char buf[BUFSIZ]; + FILE *in = stdin, *out = stdout; + + if (argc == 2 && !strcmp (argv[1], "-opipe")) + { + out = popen ("/bin/cat", "w"); + if (out == NULL) + { + perror ("popen: /bin/cat"); + exit (EXIT_FAILURE); + } + } + else if (argc == 3 && !strcmp (argv[1], "-ipipe")) + { + sprintf (buf, "/bin/cat %s", argv[2]); + in = popen (buf, "r"); + } + + { + char name[50]; + fprintf (out, + "sscanf (\"thompson\", \"%%s\", name) == %d, name == \"%s\"\n", + sscanf ("thompson", "%s", name), + name); + } + + fputs ("Testing scanf (vfscanf)\n", out); + + fputs ("Test 1:\n", out); + { + int n, i; + float x; + char name[50]; + n = fscanf (in, "%d%f%s", &i, &x, name); + fprintf (out, "n = %d, i = %d, x = %f, name = \"%.50s\"\n", + n, i, x, name); + } + fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in)); + fputs ("Test 2:\n", out); + { + int i; + float x; + char name[50]; + (void) fscanf (in, "%2d%f%*d %[0123456789]", &i, &x, name); + fprintf (out, "i = %d, x = %f, name = \"%.50s\"\n", i, x, name); + } + fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in)); + fputs ("Test 3:\n", out); + { + float quant; + char units[21], item[21]; + while (!feof (in) && !ferror (in)) + { + int count; + quant = 0.0; + units[0] = item[0] = '\0'; + count = fscanf (in, "%f%20s of %20s", &quant, units, item); + (void) fscanf (in, "%*[^\n]"); + fprintf (out, "count = %d, quant = %f, item = %.21s, units = %.21s\n", + count, quant, item, units); + } + } + fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in)); + + if (out != stdout) + pclose (out); + + exit(EXIT_SUCCESS); +} diff --git a/stdio/tstscanf.input b/stdio/tstscanf.input new file mode 100644 index 0000000000..26158652dd --- /dev/null +++ b/stdio/tstscanf.input @@ -0,0 +1,7 @@ +25 54.32E-1 thompson +56789 0123 56a72 +2 quarts of oil +-12.8degrees Celsius +lots of luck +10.0LBS of fertilizer +100ergs of energy diff --git a/stdio/ungetc.c b/stdio/ungetc.c new file mode 100644 index 0000000000..7b22a200f6 --- /dev/null +++ b/stdio/ungetc.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Push the character C back onto the input stream of STREAM. */ +int +DEFUN(ungetc, (c, stream), register int c AND register FILE *stream) +{ + if (!__validfp(stream) || !stream->__mode.__read) + { + errno = EINVAL; + return EOF; + } + + if (c == EOF) + return EOF; + + if (stream->__pushed_back) + /* There is already a char pushed back. */ + return EOF; + + if ((stream->__linebuf_active || stream->__put_limit > stream->__buffer) && + /* This is a read-write stream with something in its buffer. + Flush the stream. */ + __flshfp (stream, EOF) == EOF) + return EOF; + + stream->__pushback = (unsigned char) c; + /* Tell __fillbf we've pushed back a char. */ + stream->__pushed_back = 1; + stream->__pushback_bufp = stream->__bufp; + /* Make the next getc call __fillbf. It will return C. */ + stream->__bufp = stream->__get_limit; + + /* We just gave it another character to read, so it's not at EOF. */ + stream->__eof = 0; + + return stream->__pushback; +} diff --git a/stdio/vasprintf.c b/stdio/vasprintf.c new file mode 100644 index 0000000000..d2ad6b1da6 --- /dev/null +++ b/stdio/vasprintf.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + + +/* Enlarge STREAM's buffer. */ +static void +DEFUN(enlarge_buffer, (stream, c), + register FILE *stream AND int c) +{ + ptrdiff_t bufp_offset = stream->__bufp - stream->__buffer; + char *newbuf; + + stream->__bufsize += 100; + newbuf = (char *) realloc ((PTR) stream->__buffer, stream->__bufsize); + if (newbuf == NULL) + { + free ((PTR) stream->__buffer); + stream->__buffer = stream->__bufp + = stream->__put_limit = stream->__get_limit = NULL; + stream->__error = 1; + } + else + { + stream->__buffer = newbuf; + stream->__bufp = stream->__buffer + bufp_offset; + stream->__get_limit = stream->__put_limit; + stream->__put_limit = stream->__buffer + stream->__bufsize; + if (c != EOF) + *stream->__bufp++ = (unsigned char) c; + } +} + +/* Write formatted output from FORMAT to a string which is + allocated with malloc and stored in *STRING_PTR. */ +int +DEFUN(vasprintf, (string_ptr, format, args), + char **string_ptr AND CONST char *format AND va_list args) +{ + FILE f; + int done; + + memset ((PTR) &f, 0, sizeof (f)); + f.__magic = _IOMAGIC; + f.__bufsize = 100; + f.__buffer = (char *) malloc (f.__bufsize); + if (f.__buffer == NULL) + return -1; + f.__bufp = f.__buffer; + f.__put_limit = f.__buffer + f.__bufsize; + f.__mode.__write = 1; + f.__room_funcs.__output = enlarge_buffer; + f.__seen = 1; + + done = vfprintf (&f, format, args); + if (done < 0) + return done; + + *string_ptr = realloc (f.__buffer, (f.__bufp - f.__buffer) + 1); + if (*string_ptr == NULL) + *string_ptr = f.__buffer; + (*string_ptr)[f.__bufp - f.__buffer] = '\0'; + return done; +} diff --git a/stdio/vdprintf.c b/stdio/vdprintf.c new file mode 100644 index 0000000000..9df4e537bc --- /dev/null +++ b/stdio/vdprintf.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + + +/* Write formatted output to file descriptor D according to the format string + FORMAT, using the argument list in ARG. */ +int +DEFUN(vdprintf, (d, format, arg), + int d AND CONST char *format AND va_list arg) +{ + int done; + FILE f; + + /* Create an unbuffered stream talking to D on the stack. */ + memset ((PTR) &f, 0, sizeof(f)); + f.__magic = _IOMAGIC; + f.__mode.__write = 1; + f.__cookie = (PTR) (long int) d; /* Casting to long quiets GCC on Alpha. */ + f.__room_funcs = __default_room_functions; + f.__io_funcs = __default_io_functions; + f.__seen = 1; + f.__userbuf = 1; + + /* vfprintf will use a buffer on the stack for the life of the call, + and flush it when finished. */ + done = vfprintf (&f, format, arg); + + return done; +} diff --git a/stdio/vfprintf.c b/stdio/vfprintf.c new file mode 100644 index 0000000000..c480a93ab9 --- /dev/null +++ b/stdio/vfprintf.c @@ -0,0 +1,907 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <ctype.h> +#include <errno.h> +#include <float.h> +#include <limits.h> +#include <math.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <printf.h> +#include <assert.h> +#include <stddef.h> +#include "_itoa.h" + +/* This function from the GNU C library is also used in libio. + To compile for use in libio, compile with -DUSE_IN_LIBIO. */ + +#ifdef USE_IN_LIBIO +/* This code is for use in libio. */ +#include <libioP.h> +#define PUT(f, s, n) _IO_sputn (f, s, n) +#define PAD(padchar) _IO_padn (s, padchar, width) +#define PUTC(c, f) _IO_putc(c, f) +#define vfprintf _IO_vfprintf +#define size_t _IO_size_t +#define FILE _IO_FILE +#define va_list _IO_va_list +#undef BUFSIZ +#define BUFSIZ _IO_BUFSIZ +#define ARGCHECK(s, format) \ + do \ + { \ + /* Check file argument for consistence. */ \ + CHECK_FILE(s, -1); \ + if (s->_flags & _IO_NO_WRITES || format == NULL) \ + { \ + MAYBE_SET_EINVAL; \ + return -1; \ + } \ + } while (0) +#define UNBUFFERED_P(s) ((s)->_IO_file_flags & _IO_UNBUFFERED) +#else /* ! USE_IN_LIBIO */ +/* This code is for use in the GNU C library. */ +#include <stdio.h> +#define PUTC(c, f) putc (c, f) +#define PUT(f, s, n) fwrite (s, 1, n, f) +ssize_t __printf_pad __P ((FILE *, char pad, int n)); +#define PAD(padchar) __printf_pad (s, padchar, width) +#define ARGCHECK(s, format) \ + do \ + { \ + /* Check file argument for consistence. */ \ + if (!__validfp(s) || !s->__mode.__write || format == NULL) \ + { \ + errno = EINVAL; \ + return -1; \ + } \ + if (!s->__seen) \ + { \ + if (__flshfp (s, EOF) == EOF) \ + return -1; \ + } \ + } while (0) +#define UNBUFFERED_P(s) ((s)->__buffer == NULL) +#endif /* USE_IN_LIBIO */ + + +#define outchar(x) \ + do \ + { \ + register CONST int outc = (x); \ + if (putc(outc, s) == EOF) \ + return -1; \ + else \ + ++done; \ + } while (0) + +/* Advances STRING after writing LEN chars of it. */ +#define outstring(string, len) \ + do \ + { \ + if (len > 20) \ + { \ + if (PUT (s, string, len) != len) \ + return -1; \ + done += len; \ + string += len; \ + } \ + else \ + while (len-- > 0) \ + outchar (*string++); \ + } while (0) + +/* Helper function to provide temporary buffering for unbuffered streams. */ +static int buffered_vfprintf __P ((FILE *stream, const char *fmt, va_list)); + +/* Cast the next arg, of type ARGTYPE, into CASTTYPE, and put it in VAR. */ +#define castarg(var, argtype, casttype) \ + var = (casttype) va_arg(args, argtype) +/* Get the next arg, of type TYPE, and put it in VAR. */ +#define nextarg(var, type) castarg(var, type, type) + +static printf_function printf_unknown; + +extern printf_function **__printf_function_table; + +#ifdef __GNUC__ +#define HAVE_LONGLONG +#define LONGLONG long long +#else +#define LONGLONG long +#endif + +static char *group_number __P ((char *, char *, const char *, wchar_t)); + +int +DEFUN(vfprintf, (s, format, args), + register FILE *s AND CONST char *format AND va_list args) +{ + /* The character used as thousands separator. */ + wchar_t thousands_sep; + + /* The string describing the size of groups of digits. */ + const char *grouping; + + /* Pointer into the format string. */ + register CONST char *f; + + /* Number of characters written. */ + register size_t done = 0; + + ARGCHECK (s, format); + + if (UNBUFFERED_P (s)) + /* Use a helper function which will allocate a local temporary buffer + for the stream and then call us again. */ + return buffered_vfprintf (s, format, args); + + /* Reset multibyte characters to their initial state. */ + (void) mblen ((char *) NULL, 0); + + /* Figure out the thousands seperator character. */ + if (mbtowc (&thousands_sep, _numeric_info->thousands_sep, + strlen (_numeric_info->thousands_sep)) <= 0) + thousands_sep = (wchar_t) *_numeric_info->thousands_sep; + grouping = _numeric_info->grouping; /* Cache the grouping info array. */ + if (*grouping == '\0' || thousands_sep == L'\0') + grouping = NULL; + + f = format; + while (*f != '\0') + { + /* Type modifiers. */ + char is_short, is_long, is_long_double; +#ifdef HAVE_LONGLONG + /* We use the `L' modifier for `long long int'. */ +#define is_longlong is_long_double +#else +#define is_longlong 0 +#endif + /* Format spec modifiers. */ + char space, showsign, left, alt, group; + + /* Padding character: ' ' or '0'. */ + char pad; + /* Width of a field. */ + register int width; + /* Precision of a field. */ + int prec; + + /* Decimal integer is negative. */ + char is_neg; + + /* Current character of the format. */ + char fc; + + /* Base of a number to be written. */ + int base; + /* Integral values to be written. */ + unsigned LONGLONG int num; + LONGLONG int signed_num; + + /* String to be written. */ + CONST char *str; + char errorbuf[1024]; /* Buffer sometimes used by %m. */ + + /* Auxiliary function to do output. */ + printf_function *function; + + if (!isascii(*f)) + { + /* Non-ASCII, may be a multibyte. */ + int len = mblen (f, strlen (f)); + if (len > 0) + { + outstring (f, len); + continue; + } + } + + if (*f != '%') + { + /* This isn't a format spec, so write everything out until the + next one. To properly handle multibyte characters, we cannot + just search for a '%'. Since multibyte characters are hairy + (and dealt with above), if we hit any byte above 127 (only + those can start a multibyte character) we just punt back to + that code. */ + do + outchar (*f++); + while (*f != '\0' && *f != '%' && isascii (*f)); + continue; + } + + ++f; + + /* Check for "%%". Note that although the ANSI standard lists + '%' as a conversion specifier, it says "The complete format + specification shall be `%%'," so we can avoid all the width + and precision processing. */ + if (*f == '%') + { + ++f; + outchar('%'); + continue; + } + + /* Check for spec modifiers. */ + space = showsign = left = alt = group = 0; + pad = ' '; + while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0' || + *f == '\'') + switch (*f++) + { + case ' ': + /* Output a space in place of a sign, when there is no sign. */ + space = 1; + break; + case '+': + /* Always output + or - for numbers. */ + showsign = 1; + break; + case '-': + /* Left-justify things. */ + left = 1; + break; + case '#': + /* Use the "alternate form": + Hex has 0x or 0X, FP always has a decimal point. */ + alt = 1; + break; + case '0': + /* Pad with 0s. */ + pad = '0'; + break; + case '\'': + /* Show grouping in numbers if the locale information + indicates any. */ + group = 1; + break; + } + if (left) + pad = ' '; + + /* Get the field width. */ + width = 0; + if (*f == '*') + { + /* The field width is given in an argument. + A negative field width indicates left justification. */ + nextarg(width, int); + if (width < 0) + { + width = - width; + left = 1; + } + ++f; + } + else + while (isdigit (*f)) + { + width *= 10; + width += *f++ - '0'; + } + + /* Get the precision. */ + /* -1 means none given; 0 means explicit 0. */ + prec = -1; + if (*f == '.') + { + ++f; + if (*f == '*') + { + /* The precision is given in an argument. */ + nextarg(prec, int); + /* Avoid idiocy. */ + if (prec < 0) + prec = -1; + ++f; + } + else if (isdigit (*f)) + { + prec = *f++ - '0'; + while (*f != '\0' && isdigit (*f)) + { + prec *= 10; + prec += *f++ - '0'; + } + } + else + /* "%.?" is treated like "%.0?". */ + prec = 0; + } + + /* If there was a precision specified, ignore the 0 flag and always + pad with spaces. */ + if (prec != -1) + pad = ' '; + + /* Check for type modifiers. */ + is_short = is_long = is_long_double = 0; + while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'q') + switch (*f++) + { + case 'h': + /* int's are short int's. */ + is_short = 1; + break; + case 'l': +#ifdef HAVE_LONGLONG + if (is_long) + /* A double `l' is equivalent to an `L'. */ + is_longlong = 1; + else +#endif + /* int's are long int's. */ + is_long = 1; + break; + case 'L': + /* double's are long double's, and int's are long long int's. */ + is_long_double = 1; + break; + + case 'Z': + /* int's are size_t's. */ +#ifdef HAVE_LONGLONG + assert (sizeof(size_t) <= sizeof(unsigned long long int)); + is_longlong = sizeof(size_t) > sizeof(unsigned long int); +#endif + is_long = sizeof(size_t) > sizeof(unsigned int); + break; + + case 'q': + /* 4.4 uses this for long long. */ +#ifdef HAVE_LONGLONG + is_longlong = 1; +#else + is_long = 1; +#endif + break; + } + + /* Format specification. */ + fc = *f++; + function = (__printf_function_table == NULL ? NULL : + __printf_function_table[fc]); + if (function == NULL) + switch (fc) + { + case 'i': + case 'd': + /* Decimal integer. */ + base = 10; + if (is_longlong) + nextarg(signed_num, LONGLONG int); + else if (is_long) + nextarg(signed_num, long int); + else if (!is_short) + castarg(signed_num, int, long int); + else + castarg(signed_num, int, short int); + + is_neg = signed_num < 0; + num = is_neg ? (- signed_num) : signed_num; + goto number; + + case 'u': + /* Decimal unsigned integer. */ + base = 10; + goto unsigned_number; + + case 'o': + /* Octal unsigned integer. */ + base = 8; + goto unsigned_number; + + case 'X': + /* Hexadecimal unsigned integer. */ + case 'x': + /* Hex with lower-case digits. */ + + base = 16; + + unsigned_number: + /* Unsigned number of base BASE. */ + + if (is_longlong) + castarg(num, LONGLONG int, unsigned LONGLONG int); + else if (is_long) + castarg(num, long int, unsigned long int); + else if (!is_short) + castarg(num, int, unsigned int); + else + castarg(num, int, unsigned short int); + + /* ANSI only specifies the `+' and + ` ' flags for signed conversions. */ + is_neg = showsign = space = 0; + + number: + /* Number of base BASE. */ + { + char work[BUFSIZ]; + char *CONST workend = &work[sizeof(work) - 1]; + register char *w; + + /* Supply a default precision if none was given. */ + if (prec == -1) + prec = 1; + + /* Put the number in WORK. */ + w = _itoa (num, workend + 1, base, fc == 'X') - 1; + if (group && grouping) + w = group_number (w, workend, grouping, thousands_sep); + width -= workend - w; + prec -= workend - w; + + if (alt && base == 8 && prec <= 0) + { + *w-- = '0'; + --width; + } + + if (prec > 0) + { + width -= prec; + while (prec-- > 0) + *w-- = '0'; + } + + if (alt && base == 16) + width -= 2; + + if (is_neg || showsign || space) + --width; + + if (!left && pad == ' ') + PAD (' '); + + if (is_neg) + outchar('-'); + else if (showsign) + outchar('+'); + else if (space) + outchar(' '); + + if (alt && base == 16) + { + outchar ('0'); + outchar (fc); + } + + if (!left && pad == '0') + PAD ('0'); + + /* Write the number. */ + while (++w <= workend) + outchar(*w); + + if (left) + PAD (' '); + } + break; + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + { + /* Floating-point number. */ + extern printf_function __printf_fp; + function = __printf_fp; + goto use_function; + } + + case 'c': + /* Character. */ + nextarg(num, int); + if (!left) + { + --width; + PAD (' '); + } + outchar ((unsigned char) num); + if (left) + PAD (' '); + break; + + case 's': + { + static CONST char null[] = "(null)"; + size_t len; + + nextarg(str, CONST char *); + + string: + + if (str == NULL) + /* Write "(null)" if there's space. */ + if (prec == -1 || prec >= (int) sizeof(null) - 1) + { + str = null; + len = sizeof(null) - 1; + } + else + { + str = ""; + len = 0; + } + else + len = strlen(str); + + if (prec != -1 && (size_t) prec < len) + len = prec; + width -= len; + + if (!left) + PAD (' '); + outstring (str, len); + if (left) + PAD (' '); + } + break; + + case 'p': + /* Generic pointer. */ + { + CONST PTR ptr; + nextarg(ptr, CONST PTR); + if (ptr != NULL) + { + /* If the pointer is not NULL, write it as a %#x spec. */ + base = 16; + fc = 'x'; + alt = 1; + num = (unsigned LONGLONG int) (unsigned long int) ptr; + is_neg = 0; + group = 0; + goto number; + } + else + { + /* Write "(nil)" for a nil pointer. */ + static CONST char nil[] = "(nil)"; + register CONST char *p; + + width -= sizeof (nil) - 1; + if (!left) + PAD (' '); + for (p = nil; *p != '\0'; ++p) + outchar (*p); + if (left) + PAD (' '); + } + } + break; + + case 'n': + /* Answer the count of characters written. */ + if (is_longlong) + { + LONGLONG int *p; + nextarg(p, LONGLONG int *); + *p = done; + } + else if (is_long) + { + long int *p; + nextarg(p, long int *); + *p = done; + } + else if (!is_short) + { + int *p; + nextarg(p, int *); + *p = done; + } + else + { + short int *p; + nextarg(p, short int *); + *p = done; + } + break; + + case 'm': + { + extern char *_strerror_internal __P ((int, char buf[1024])); + str = _strerror_internal (errno, errorbuf); + goto string; + } + + default: + /* Unrecognized format specifier. */ + function = printf_unknown; + goto use_function; + } + else + use_function: + { + int function_done; + struct printf_info info; + + info.prec = prec; + info.width = width; + info.spec = fc; + info.is_long_double = is_long_double; + info.is_short = is_short; + info.is_long = is_long; + info.alt = alt; + info.space = space; + info.left = left; + info.showsign = showsign; + info.group = group; + info.pad = pad; + + function_done = (*function) (s, &info, &args); + if (function_done < 0) + return -1; + + done += function_done; + } + } + + return done; +} + + +static int +DEFUN(printf_unknown, (s, info, arg), + FILE *s AND CONST struct printf_info *info AND va_list *arg) +{ + int done = 0; + char work[BUFSIZ]; + char *CONST workend = &work[sizeof(work) - 1]; + register char *w; + register int prec = info->prec, width = info->width; + + outchar('%'); + + if (info->alt) + outchar ('#'); + if (info->group) + outchar ('\''); + if (info->showsign) + outchar ('+'); + else if (info->space) + outchar (' '); + if (info->left) + outchar ('-'); + if (info->pad == '0') + outchar ('0'); + + w = workend; + while (width > 0) + { + *w-- = '0' + (width % 10); + width /= 10; + } + while (++w <= workend) + outchar(*w); + + if (info->prec != -1) + { + outchar('.'); + w = workend; + while (prec > 0) + { + *w-- = '0' + (prec % 10); + prec /= 10; + } + while (++w <= workend) + outchar(*w); + } + + outchar(info->spec); + + return done; +} + +/* Group the digits according to the grouping rules of the current locale. + The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */ + +static char * +group_number (char *w, char *workend, const char *grouping, + wchar_t thousands_sep) +{ + int len; + char *src, *s; + + /* We treat all negative values like CHAR_MAX. */ + + if (*grouping == CHAR_MAX || *grouping < 0) + /* No grouping should be done. */ + return w; + + len = *grouping; + + /* Copy existing string so that nothing gets overwritten. */ + src = (char *) alloca (workend - w); + memcpy (src, w + 1, workend - w); + s = &src[workend - w - 1]; + w = workend; + + /* Process all characters in the string. */ + while (s >= src) + { + *w-- = *s--; + + if (--len == 0 && s >= src) + { + /* A new group begins. */ + *w-- = thousands_sep; + + len = *grouping++; + if (*grouping == '\0') + /* The previous grouping repeats ad infinitum. */ + --grouping; + else if (*grouping == CHAR_MAX || *grouping < 0) + { + /* No further grouping to be done. + Copy the rest of the number. */ + do + *w-- = *s--; + while (s >= src); + break; + } + } + } + + return w; +} + +#ifdef USE_IN_LIBIO +/* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */ +struct helper_file + { + struct _IO_FILE_plus _f; + _IO_FILE *_put_stream; + }; + +static int +DEFUN(_IO_helper_overflow, (s, c), _IO_FILE *s AND int c) +{ + _IO_FILE *target = ((struct helper_file*) s)->_put_stream; + int used = s->_IO_write_ptr - s->_IO_write_base; + if (used) + { + _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used); + s->_IO_write_ptr -= written; + } + return _IO_putc (c, s); +} + +static const struct _IO_jump_t _IO_helper_jumps = + { + _IO_helper_overflow, + _IO_default_underflow, + _IO_default_xsputn, + _IO_default_xsgetn, + _IO_default_read, + _IO_default_write, + _IO_default_doallocate, + _IO_default_pbackfail, + _IO_default_setbuf, + _IO_default_sync, + _IO_default_finish, + _IO_default_close, + _IO_default_stat, + _IO_default_seek, + _IO_default_seekoff, + _IO_default_seekpos, + _IO_default_uflow + }; + +static int +DEFUN(buffered_vfprintf, (s, format, args), + register _IO_FILE *s AND char CONST *format AND _IO_va_list args) +{ + char buf[_IO_BUFSIZ]; + struct helper_file helper; + register _IO_FILE *hp = (_IO_FILE *) &helper; + int result, to_flush; + + /* Initialize helper. */ + helper._put_stream = s; + hp->_IO_write_base = buf; + hp->_IO_write_ptr = buf; + hp->_IO_write_end = buf + sizeof buf; + hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS; + hp->_jumps = (struct _IO_jump_t *) &_IO_helper_jumps; + + /* Now print to helper instead. */ + result = _IO_vfprintf (hp, format, args); + + /* Now flush anything from the helper to the S. */ + if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0) + { + if (_IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush) + return -1; + } + + return result; +} + +#else /* !USE_IN_LIBIO */ + +static int +DEFUN(buffered_vfprintf, (s, format, args), + register FILE *s AND char CONST *format AND va_list args) +{ + char buf[BUFSIZ]; + int result; + + s->__bufp = s->__buffer = buf; + s->__bufsize = sizeof buf; + s->__put_limit = s->__buffer + s->__bufsize; + s->__get_limit = s->__buffer; + + /* Now use buffer to print. */ + result = vfprintf (s, format, args); + + if (fflush (s) == EOF) + return -1; + s->__buffer = s->__bufp = s->__get_limit = s->__put_limit = NULL; + s->__bufsize = 0; + + return result; +} + + +/* Pads string with given number of a specified character. + This code is taken from iopadn.c of the GNU I/O library. */ +#define PADSIZE 16 +static const char blanks[PADSIZE] = +{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static const char zeroes[PADSIZE] = +{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +ssize_t +__printf_pad (s, pad, count) + FILE *s; + char pad; + int count; +{ + CONST char *padptr; + register int i; + size_t written = 0, w; + + padptr = pad == ' ' ? blanks : zeroes; + + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = PUT(s, padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + if (i > 0) + { + w = PUT(s, padptr, i); + written += w; + } + return written; +} +#undef PADSIZE +#endif /* USE_IN_LIBIO */ diff --git a/stdio/vfscanf.c b/stdio/vfscanf.c new file mode 100644 index 0000000000..681e89819b --- /dev/null +++ b/stdio/vfscanf.c @@ -0,0 +1,570 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <errno.h> +#include <limits.h> +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +#ifdef __GNUC__ +#define HAVE_LONGLONG +#define LONGLONG long long +#else +#define LONGLONG long +#endif + + +#define inchar() ((c = getc(s)) == EOF ? EOF : (++read_in, c)) +#define conv_error() return ((c == EOF || ungetc(c, s)), done) +#define input_error() return (done == 0 ? EOF : done) +#define memory_error() return ((errno = ENOMEM), EOF) + + +/* Read formatted input from S according to the format string + FORMAT, using the argument list in ARG. + Return the number of assignments made, or -1 for an input error. */ +int +DEFUN(__vfscanf, (s, format, arg), + FILE *s AND CONST char *format AND va_list argptr) +{ + va_list arg = (va_list) argptr; + + register CONST char *f = format; + register char fc; /* Current character of the format. */ + register size_t done = 0; /* Assignments done. */ + register size_t read_in = 0; /* Chars read in. */ + register int c; /* Last char read. */ + register int do_assign; /* Whether to do an assignment. */ + register int width; /* Maximum field width. */ + + /* Type modifiers. */ + char is_short, is_long, is_long_double; +#ifdef HAVE_LONGLONG + /* We use the `L' modifier for `long long int'. */ +#define is_longlong is_long_double +#else +#define is_longlong 0 +#endif + int malloc_string; /* Args are char ** to be filled in. */ + /* Status for reading F-P nums. */ + char got_dot, got_e; + /* If a [...] is a [^...]. */ + char not_in; + /* Base for integral numbers. */ + int base; + /* Signedness for integral numbers. */ + int number_signed; + /* Integral holding variables. */ + long int num; + unsigned long int unum; + /* Character-buffer pointer. */ + register char *str, **strptr; + size_t strsize; + /* Workspace. */ + char work[200]; + char *w; /* Pointer into WORK. */ + wchar_t decimal; /* Decimal point character. */ + + if (!__validfp(s) || !s->__mode.__read || format == NULL) + { + errno = EINVAL; + return EOF; + } + + /* Figure out the decimal point character. */ + if (mbtowc(&decimal, _numeric_info->decimal_point, + strlen(_numeric_info->decimal_point)) <= 0) + decimal = (wchar_t) *_numeric_info->decimal_point; + + c = inchar(); + + /* Run through the format string. */ + while (*f != '\0') + { + if (!isascii(*f)) + { + /* Non-ASCII, may be a multibyte. */ + int len = mblen(f, strlen(f)); + if (len > 0) + { + while (len-- > 0) + if (c == EOF) + input_error(); + else if (c == *f++) + (void) inchar(); + else + conv_error(); + continue; + } + } + + fc = *f++; + if (fc != '%') + { + /* Characters other than format specs must just match. */ + if (c == EOF) + input_error(); + if (isspace(fc)) + { + /* Whitespace characters match any amount of whitespace. */ + while (isspace (c)) + inchar (); + continue; + } + else if (c == fc) + (void) inchar(); + else + conv_error(); + continue; + } + + /* Check for the assignment-suppressant. */ + if (*f == '*') + { + do_assign = 0; + ++f; + } + else + do_assign = 1; + + /* Find the maximum field width. */ + width = 0; + while (isdigit(*f)) + { + width *= 10; + width += *f++ - '0'; + } + if (width == 0) + width = -1; + + /* Check for type modifiers. */ + is_short = is_long = is_long_double = malloc_string = 0; + while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q') + switch (*f++) + { + case 'h': + /* int's are short int's. */ + is_short = 1; + break; + case 'l': + if (is_long) + /* A double `l' is equivalent to an `L'. */ + is_longlong = 1; + else + /* int's are long int's. */ + is_long = 1; + break; + case 'q': + case 'L': + /* double's are long double's, and int's are long long int's. */ + is_long_double = 1; + break; + case 'a': + /* String conversions (%s, %[) take a `char **' + arg and fill it in with a malloc'd pointer. */ + malloc_string = 1; + break; + } + + /* End of the format string? */ + if (*f == '\0') + conv_error(); + + /* Find the conversion specifier. */ + w = work; + fc = *f++; + if (fc != '[' && fc != 'c' && fc != 'n') + /* Eat whitespace. */ + while (isspace(c)) + (void) inchar(); + switch (fc) + { + case '%': /* Must match a literal '%'. */ + if (c != fc) + conv_error(); + break; + + case 'n': /* Answer number of assignments done. */ + if (do_assign) + *va_arg(arg, int *) = read_in; + break; + + case 'c': /* Match characters. */ + if (do_assign) + { + str = va_arg (arg, char *); + if (str == NULL) + conv_error (); + } + + if (c == EOF) + input_error(); + + if (width == -1) + width = 1; + + if (do_assign) + { + do + *str++ = c; + while (inchar() != EOF && --width > 0); + } + else + while (inchar() != EOF && width > 0) + --width; + + if (do_assign) + ++done; + + break; + + case 's': /* Read a string. */ +#define STRING_ARG \ + if (do_assign) \ + { \ + if (malloc_string) \ + { \ + /* The string is to be stored in a malloc'd buffer. */ \ + strptr = va_arg (arg, char **); \ + if (strptr == NULL) \ + conv_error (); \ + /* Allocate an initial buffer. */ \ + strsize = 100; \ + *strptr = str = malloc (strsize); \ + } \ + else \ + str = va_arg (arg, char *); \ + if (str == NULL) \ + conv_error (); \ + } + STRING_ARG; + + if (c == EOF) + input_error (); + + do + { + if (isspace (c)) + break; +#define STRING_ADD_CHAR(c) \ + if (do_assign) \ + { \ + *str++ = c; \ + if (malloc_string && str == *strptr + strsize) \ + { \ + /* Enlarge the buffer. */ \ + str = realloc (*strptr, strsize * 2); \ + if (str == NULL) \ + { \ + /* Can't allocate that much. Last-ditch effort. */\ + str = realloc (*strptr, strsize + 1); \ + if (str == NULL) \ + { \ + /* We lose. Oh well. \ + Terminate the string and stop converting, \ + so at least we don't swallow any input. */ \ + (*strptr)[strsize] = '\0'; \ + ++done; \ + conv_error (); \ + } \ + else \ + { \ + *strptr = str; \ + str += strsize; \ + ++strsize; \ + } \ + } \ + else \ + { \ + *strptr = str; \ + str += strsize; \ + strsize *= 2; \ + } \ + } \ + } + STRING_ADD_CHAR (c); + } while (inchar () != EOF && (width <= 0 || --width > 0)); + + if (do_assign) + { + *str = '\0'; + ++done; + } + break; + + case 'x': /* Hexadecimal integer. */ + case 'X': /* Ditto. */ + base = 16; + number_signed = 0; + goto number; + + case 'o': /* Octal integer. */ + base = 8; + number_signed = 0; + goto number; + + case 'u': /* Unsigned decimal integer. */ + base = 10; + number_signed = 0; + goto number; + + case 'd': /* Signed decimal integer. */ + base = 10; + number_signed = 1; + goto number; + + case 'i': /* Generic number. */ + base = 0; + number_signed = 1; + + number: + if (c == EOF) + input_error(); + + /* Check for a sign. */ + if (c == '-' || c == '+') + { + *w++ = c; + if (width > 0) + --width; + (void) inchar(); + } + + /* Look for a leading indication of base. */ + if (c == '0') + { + if (width > 0) + --width; + *w++ = '0'; + + (void) inchar(); + + if (tolower(c) == 'x') + { + if (base == 0) + base = 16; + if (base == 16) + { + if (width > 0) + --width; + (void) inchar(); + } + } + else if (base == 0) + base = 8; + } + + if (base == 0) + base = 10; + + /* Read the number into WORK. */ + do + { + if (base == 16 ? !isxdigit(c) : + (!isdigit(c) || c - '0' >= base)) + break; + *w++ = c; + if (width > 0) + --width; + } while (inchar() != EOF && width != 0); + + if (w == work || + (w - work == 1 && (work[0] == '+' || work[0] == '-'))) + /* There was on number. */ + conv_error(); + + /* Convert the number. */ + *w = '\0'; + if (number_signed) + num = strtol (work, &w, base); + else + unum = strtoul (work, &w, base); + if (w == work) + conv_error (); + + if (do_assign) + { + if (! number_signed) + { + if (is_longlong) + *va_arg (arg, unsigned LONGLONG int *) = unum; + else if (is_long) + *va_arg (arg, unsigned long int *) = unum; + else if (is_short) + *va_arg (arg, unsigned short int *) + = (unsigned short int) unum; + else + *va_arg(arg, unsigned int *) = (unsigned int) unum; + } + else + { + if (is_longlong) + *va_arg(arg, LONGLONG int *) = num; + else if (is_long) + *va_arg(arg, long int *) = num; + else if (is_short) + *va_arg(arg, short int *) = (short int) num; + else + *va_arg(arg, int *) = (int) num; + } + ++done; + } + break; + + case 'e': /* Floating-point numbers. */ + case 'E': + case 'f': + case 'g': + case 'G': + if (c == EOF) + input_error(); + + /* Check for a sign. */ + if (c == '-' || c == '+') + { + *w++ = c; + if (inchar() == EOF) + /* EOF is only an input error before we read any chars. */ + conv_error(); + if (width > 0) + --width; + } + + got_dot = got_e = 0; + do + { + if (isdigit(c)) + *w++ = c; + else if (got_e && w[-1] == 'e' && (c == '-' || c == '+')) + *w++ = c; + else if (!got_e && tolower(c) == 'e') + { + *w++ = 'e'; + got_e = got_dot = 1; + } + else if (c == decimal && !got_dot) + { + *w++ = c; + got_dot = 1; + } + else + break; + if (width > 0) + --width; + } while (inchar() != EOF && width != 0); + + if (w == work) + conv_error(); + if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e') + conv_error(); + + /* Convert the number. */ + *w = '\0'; + if (is_long_double) + { + long double d = __strtold (work, &w); + if (do_assign && w != work) + *va_arg (arg, long double *) = d; + } + else if (is_long) + { + double d = strtod (work, &w); + if (do_assign && w != work) + *va_arg (arg, double *) = d; + } + else + { + float d = __strtof (work, &w); + if (do_assign && w != work) + *va_arg (arg, float *) = d; + } + + if (w == work) + conv_error (); + + if (do_assign) + ++done; + break; + + case '[': /* Character class. */ + STRING_ARG; + + if (c == EOF) + input_error(); + + if (*f == '^') + { + ++f; + not_in = 1; + } + else + not_in = 0; + + while ((fc = *f++) != '\0' && fc != ']') + { + if (fc == '-' && *f != '\0' && *f != ']' && + w > work && w[-1] <= *f) + /* Add all characters from the one before the '-' + up to (but not including) the next format char. */ + for (fc = w[-1] + 1; fc < *f; ++fc) + *w++ = fc; + else + /* Add the character to the list. */ + *w++ = fc; + } + if (fc == '\0') + conv_error(); + + *w = '\0'; + unum = read_in; + do + { + if ((strchr (work, c) == NULL) != not_in) + break; + STRING_ADD_CHAR (c); + if (width > 0) + --width; + } while (inchar () != EOF && width != 0); + if (read_in == unum) + conv_error (); + + if (do_assign) + { + *str = '\0'; + ++done; + } + break; + + case 'p': /* Generic pointer. */ + base = 16; + /* A PTR must be the same size as a `long int'. */ + is_long = 1; + goto number; + } + } + + conv_error(); +} + +weak_alias (__vfscanf, vfscanf) diff --git a/stdio/vprintf.c b/stdio/vprintf.c new file mode 100644 index 0000000000..97264f475c --- /dev/null +++ b/stdio/vprintf.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#undef __OPTIMIZE__ /* Avoid inline `vprintf' function. */ +#include <stdio.h> + +#undef vprintf + + +/* Write formatted output to stdout according to the + format string FORMAT, using the argument list in ARG. */ +int +DEFUN(vprintf, (format, arg), CONST char *format AND __gnuc_va_list arg) +{ + return vfprintf (stdout, format, arg); +} diff --git a/stdio/vscanf.c b/stdio/vscanf.c new file mode 100644 index 0000000000..0d829440e9 --- /dev/null +++ b/stdio/vscanf.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> + +#undef vscanf + + +/* Read formatted input from stdin according to the format + string in FORMAT, using the argument list in ARG. */ +int +DEFUN(vscanf, (format, arg), CONST char *format AND va_list arg) +{ + return vfscanf (stdin, format, arg); +} diff --git a/stdio/vsnprintf.c b/stdio/vsnprintf.c new file mode 100644 index 0000000000..a02c259131 --- /dev/null +++ b/stdio/vsnprintf.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + + +/* + * Write formatted output to S according to the format string + * FORMAT, using the argument list in ARG, writing no more + * than MAXLEN characters. + */ +int +DEFUN(vsnprintf, (s, maxlen, format, arg), + char *s AND size_t maxlen AND CONST char *format AND va_list arg) +{ + int done; + FILE f; + + memset((PTR) &f, 0, sizeof(f)); + f.__magic = _IOMAGIC; + f.__mode.__write = 1; + /* The buffer size is one less than MAXLEN + so we have space for the null terminator. */ + f.__bufp = f.__buffer = (char *) s; + f.__bufsize = maxlen - 1; + f.__put_limit = f.__buffer + f.__bufsize; + f.__get_limit = f.__buffer; + /* After the buffer is full (MAXLEN characters have been written), + any more characters written will go to the bit bucket. */ + f.__room_funcs = __default_room_functions; + f.__io_funcs.__write = NULL; + f.__seen = 1; + + done = vfprintf(&f, format, arg); + *f.__bufp = '\0'; + + return done; +} diff --git a/stdio/vsprintf.c b/stdio/vsprintf.c new file mode 100644 index 0000000000..82be90f1fa --- /dev/null +++ b/stdio/vsprintf.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + + +/* Write formatted output to S according to the format string + FORMAT, using the argument list in ARG. */ +int +DEFUN(vsprintf, (s, format, arg), + char *s AND CONST char *format AND va_list arg) +{ + int done; + FILE f; + + memset((PTR) &f, 0, sizeof(f)); + f.__magic = _IOMAGIC; + f.__mode.__write = 1; + f.__bufp = f.__buffer = (char *) s; + f.__put_limit = (char *) ULONG_MAX; + f.__bufsize = (size_t) (f.__put_limit - f.__bufp); + f.__get_limit = f.__buffer; + f.__room_funcs.__output = NULL; + f.__seen = 1; + + done = vfprintf(&f, format, arg); + *f.__bufp = '\0'; + + return done; +} diff --git a/stdio/vsscanf.c b/stdio/vsscanf.c new file mode 100644 index 0000000000..6f027d5065 --- /dev/null +++ b/stdio/vsscanf.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#undef vsscanf + + +/* Read formatted input from S according to the format + string FORMAT, using the argument list in ARG. */ +int +DEFUN(__vsscanf, (s, format, arg), + CONST char *s AND CONST char *format AND va_list arg) +{ + FILE f; + + if (s == NULL) + { + errno = EINVAL; + return -1; + } + + memset((PTR) &f, 0, sizeof(f)); + f.__magic = _IOMAGIC; + f.__mode.__read = 1; + f.__bufp = f.__buffer = (char *) s; + f.__bufsize = strlen(s); + f.__get_limit = f.__buffer + f.__bufsize; + f.__put_limit = f.__buffer; + /* After the buffer is empty (strlen(S) characters have been read), + any more read attempts will get EOF. */ + f.__room_funcs.__input = NULL; + f.__seen = 1; + + return __vfscanf(&f, format, arg); +} + + +weak_alias (__vsscanf, vsscanf) diff --git a/stdio/xbug.c b/stdio/xbug.c new file mode 100644 index 0000000000..ec648f5566 --- /dev/null +++ b/stdio/xbug.c @@ -0,0 +1,63 @@ +#include <stdio.h> + +typedef struct _Buffer { + char *buff; + int room, used; +} Buffer; + +#define INIT_BUFFER_SIZE 10000 + +void InitBuffer(b) + Buffer *b; +{ + b->room = INIT_BUFFER_SIZE; + b->used = 0; + b->buff = (char *)malloc(INIT_BUFFER_SIZE*sizeof(char)); +} + +void AppendToBuffer(b, str, len) + register Buffer *b; + char *str; + register int len; +{ + while (b->used + len > b->room) { + b->buff = (char *)realloc(b->buff, 2*b->room*(sizeof(char))); + b->room *= 2; + } + strncpy(b->buff + b->used, str, len); + b->used += len; +} + +void ReadFile(buffer, input) + register Buffer *buffer; + FILE *input; +{ + char buf[BUFSIZ + 1]; + register int bytes; + + buffer->used = 0; + while (!feof(input) && (bytes = fread(buf, 1, BUFSIZ, input)) > 0) { + AppendToBuffer(buffer, buf, bytes); + } + AppendToBuffer(buffer, "", 1); +} + +main() +{ + char * filename = "xbug.c"; + FILE *input; + Buffer buffer; + + InitBuffer(&buffer); + + if (!freopen (filename, "r", stdin)) + fprintf(stderr, "cannot open file\n"); + + if (!(input = popen("/bin/cat", "r"))) + fprintf(stderr, "cannot run \n"); + + ReadFile(&buffer, input); + pclose(input); + + return 0; +} diff --git a/stdlib.h b/stdlib.h new file mode 100644 index 0000000000..c0887a99e9 --- /dev/null +++ b/stdlib.h @@ -0,0 +1 @@ +#include <stdlib/stdlib.h> diff --git a/stdlib/Makefile b/stdlib/Makefile new file mode 100644 index 0000000000..1a1498c662 --- /dev/null +++ b/stdlib/Makefile @@ -0,0 +1,43 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for stdlib routines +# +subdir := stdlib + +headers := stdlib.h alloca.h + +routines := \ + atof atoi atol \ + abort \ + bsearch qsort msort \ + getenv putenv setenv \ + exit on_exit atexit \ + abs labs \ + div ldiv \ + mblen mbstowcs mbtowc wcstombs wctomb \ + random rand \ + strtol strtoul strtoq strtouq \ + strtof strtod strtold \ + system + +distribute := exit.h +tests := tst-strtol tst-strtod testmb testrand testsort testdiv + +include ../Rules diff --git a/stdlib/abs.c b/stdlib/abs.c new file mode 100644 index 0000000000..b8db100b41 --- /dev/null +++ b/stdlib/abs.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef abs + +/* Return the absolute value of I. */ +__CONSTVALUE +int +DEFUN(abs, (i), int i) +{ + return(i < 0 ? -i : i); +} diff --git a/stdlib/alloca.h b/stdlib/alloca.h new file mode 100644 index 0000000000..4e9de464a3 --- /dev/null +++ b/stdlib/alloca.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _ALLOCA_H +#define _ALLOCA_H 1 +#include <features.h> + +#define __need_size_t +#include <stddef.h> + +__BEGIN_DECLS + +/* Remove any previous definitions. */ +#undef __alloca +#undef alloca + +/* Allocate a block that will be freed when the calling function exits. */ +extern __ptr_t __alloca __P ((size_t __size)); +extern __ptr_t alloca __P ((size_t __size)); + +#ifdef __GNUC__ +#define __alloca(size) __builtin_alloca(size) +#endif /* GCC. */ + +#define alloca(size) __alloca(size) + +__END_DECLS + +#endif /* alloca.h */ diff --git a/stdlib/atexit.c b/stdlib/atexit.c new file mode 100644 index 0000000000..a2ab453576 --- /dev/null +++ b/stdlib/atexit.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include "exit.h" + + +/* Register FUNC to be executed by `exit'. */ +int +DEFUN(atexit, (func), void EXFUN((*func), (NOARGS))) +{ + struct exit_function *new = __new_exitfn(); + + if (new == NULL) + return -1; + + new->flavor = ef_at; + new->func.at = func; + return 0; +} + + +static struct exit_function_list fnlist = { NULL, 0, }; +struct exit_function_list *__exit_funcs = &fnlist; + +struct exit_function * +DEFUN_VOID(__new_exitfn) +{ + register struct exit_function_list *l; + + for (l = __exit_funcs; l != NULL; l = l->next) + { + register size_t i; + for (i = 0; i < l->idx; ++i) + if (l->fns[i].flavor == ef_free) + return &l->fns[i]; + if (l->idx < sizeof(l->fns) / sizeof(l->fns[0])) + return &l->fns[l->idx++]; + } + + l = (struct exit_function_list *) malloc(sizeof(struct exit_function_list)); + if (l == NULL) + return NULL; + l->next = __exit_funcs; + __exit_funcs = l; + + l->idx = 1; + return &l->fns[0]; +} diff --git a/stdlib/atof.c b/stdlib/atof.c new file mode 100644 index 0000000000..79585464d1 --- /dev/null +++ b/stdlib/atof.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef atof + + +/* Convert a string to a double. */ +double +DEFUN(atof, (nptr), CONST char *nptr) +{ + return(strtod(nptr, (char **) NULL)); +} diff --git a/stdlib/atoi.c b/stdlib/atoi.c new file mode 100644 index 0000000000..9fe280cc3e --- /dev/null +++ b/stdlib/atoi.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef atoi + + +/* Convert a string to an int. */ +int +DEFUN(atoi, (nptr), CONST char *nptr) +{ + return((int) strtol(nptr, (char **) NULL, 10)); +} diff --git a/stdlib/atol.c b/stdlib/atol.c new file mode 100644 index 0000000000..75f599c107 --- /dev/null +++ b/stdlib/atol.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef atol + + +/* Convert a string to a long int. */ +long int +DEFUN(atol, (nptr), CONST char *nptr) +{ + return(strtol(nptr, (char **) NULL, 10)); +} diff --git a/stdlib/bsearch.c b/stdlib/bsearch.c new file mode 100644 index 0000000000..d798eabd2b --- /dev/null +++ b/stdlib/bsearch.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + + +/* Perform a binary search for KEY in BASE which has NMEMB elements + of SIZE bytes each. The comparisons are done by (*COMPAR)(). */ +PTR +DEFUN(bsearch, (key, base, nmemb, size, compar), + register CONST PTR key AND register CONST PTR base AND + size_t nmemb AND register size_t size AND + register int EXFUN((*compar), (CONST PTR, CONST PTR))) +{ + register size_t l, u, idx; + register CONST PTR p; + register int comparison; + + l = 0; + u = nmemb; + while (l < u) + { + idx = (l + u) / 2; + p = (PTR) (((CONST char *) base) + (idx * size)); + comparison = (*compar)(key, p); + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return (PTR) p; + } + + return NULL; +} diff --git a/stdlib/div.c b/stdlib/div.c new file mode 100644 index 0000000000..5a0ee7da38 --- /dev/null +++ b/stdlib/div.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * Copyright (c) 1990 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 <ansidecl.h> +#include <stdlib.h> + + +/* Return the `div_t' representation of NUMER over DENOM. */ +__CONSTVALUE +div_t +DEFUN(div, (numer, denom), int numer AND int denom) +{ + div_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ + + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } + + return result; +} diff --git a/stdlib/exit.c b/stdlib/exit.c new file mode 100644 index 0000000000..4f33a25cc4 --- /dev/null +++ b/stdlib/exit.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "exit.h" + +#ifdef HAVE_GNU_LD +#include "set-hooks.h" +DEFINE_HOOK (__libc_atexit, (void)) +#endif + + +/* Call all functions registered with `atexit' and `on_exit', + in the reverse of the order in which they were registered + perform stdio cleanup, and terminate program execution with STATUS. */ +void +DEFUN(exit, (status), int status) +{ + register CONST struct exit_function_list *l; + + for (l = __exit_funcs; l != NULL; l = l->next) + { + register size_t i = l->idx; + while (i-- > 0) + { + CONST struct exit_function *CONST f = &l->fns[i]; + switch (f->flavor) + { + case ef_free: + break; + case ef_on: + (*f->func.on.fn)(status, f->func.on.arg); + break; + case ef_at: + (*f->func.at)(); + break; + } + } + } + +#ifdef HAVE_GNU_LD + RUN_HOOK (__libc_atexit, ()); +#else + { + extern void EXFUN(_cleanup, (NOARGS)); + _cleanup(); + } +#endif + + _exit(status); +} + diff --git a/stdlib/exit.h b/stdlib/exit.h new file mode 100644 index 0000000000..214217853e --- /dev/null +++ b/stdlib/exit.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _EXIT_H + +struct exit_function + { + enum { ef_free, ef_on, ef_at } flavor; /* `ef_free' MUST be zero! */ + union + { + void EXFUN((*at), (NOARGS)); + struct + { + void EXFUN((*fn), (int status, PTR arg)); + PTR arg; + } on; + } func; + }; +struct exit_function_list + { + struct exit_function_list *next; + size_t idx; + struct exit_function fns[32]; + }; +extern struct exit_function_list *__exit_funcs; + +extern struct exit_function *EXFUN(__new_exitfn, (NOARGS)); + +#endif /* exit.h */ diff --git a/stdlib/labs.c b/stdlib/labs.c new file mode 100644 index 0000000000..c54339f02b --- /dev/null +++ b/stdlib/labs.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef labs + + +/* Return the absolute value of I. */ +__CONSTVALUE +long int +DEFUN(labs, (i), long int i) +{ + return(i < 0 ? -i : i); +} diff --git a/stdlib/ldiv.c b/stdlib/ldiv.c new file mode 100644 index 0000000000..661f1bdbcd --- /dev/null +++ b/stdlib/ldiv.c @@ -0,0 +1,92 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * Copyright (c) 1990 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 <ansidecl.h> +#include <stdlib.h> + + +/* Return the `ldiv_t' representation of NUMER over DENOM. */ +__CONSTVALUE +ldiv_t +DEFUN(ldiv, (numer, denom), long int numer AND long int denom) +{ + ldiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + /* The ANSI standard says that |QUOT| <= |NUMER / DENOM|, where + NUMER / DENOM is to be computed in infinite precision. In + other words, we should always truncate the quotient towards + zero, never -infinity. Machine division and remainer may + work either way when one or both of NUMER or DENOM is + negative. If only one is negative and QUOT has been + truncated towards -infinity, REM will have the same sign as + DENOM and the opposite sign of NUMER; if both are negative + and QUOT has been truncated towards -infinity, REM will be + positive (will have the opposite sign of NUMER). These are + considered `wrong'. If both are NUM and DENOM are positive, + RESULT will always be positive. This all boils down to: if + NUMER >= 0, but REM < 0, we got the wrong answer. In that + case, to get the right answer, add 1 to QUOT and subtract + DENOM from REM. */ + + if (numer >= 0 && result.rem < 0) + { + ++result.quot; + result.rem -= denom; + } + + return result; +} diff --git a/stdlib/mblen.c b/stdlib/mblen.c new file mode 100644 index 0000000000..5393ce433c --- /dev/null +++ b/stdlib/mblen.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef mblen + + +/* Return the length of the multibyte character (if there is one) + at S which is no longer than N characters. */ +int +DEFUN(mblen, (s, n), CONST char *s AND size_t n) +{ + return(mbtowc((wchar_t *) NULL, s, n)); +} diff --git a/stdlib/mbstowcs.c b/stdlib/mbstowcs.c new file mode 100644 index 0000000000..38c710279a --- /dev/null +++ b/stdlib/mbstowcs.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <ctype.h> +#include <stddef.h> +#include <stdlib.h> + + +extern int _mb_shift; /* Defined in mbtowc.c. */ + +/* Convert the string of multibyte characters in S to `wchar_t's in + PWCS, writing no more than N. Return the number written, + or (size_t) -1 if an invalid multibyte character is encountered. */ +size_t +DEFUN(mbstowcs, (pwcs, s, n), + register wchar_t *pwcs AND register CONST char *s AND register size_t n) +{ + int save_shift; + register size_t written = 0; + + /* Save the shift state. */ + save_shift = _mb_shift; + /* Reset the shift state. */ + _mb_shift = 0; + + while (*s != '\0') + { + int len; + if (isascii (*s)) + { + *pwcs = (wchar_t) *s; + len = 1; + } + else + len = mbtowc (pwcs, s, n); + + if (len < 1) + { + /* Return an error. */ + written = (size_t) -1; + break; + } + else + { + /* Multibyte character converted. */ + ++pwcs; + ++written; + s += len; + n -= len; + } + } + + /* Terminate the string if it has space. */ + if (n > 0) + *pwcs = (wchar_t) 0; + + /* Restore the old shift state. */ + _mb_shift = save_shift; + + /* Return how many we wrote (or maybe an error). */ + return written; +} diff --git a/stdlib/mbtowc.c b/stdlib/mbtowc.c new file mode 100644 index 0000000000..62103407c0 --- /dev/null +++ b/stdlib/mbtowc.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <ctype.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +long int _mb_shift = 0; + +/* Convert the multibyte character at S, which is no longer + than N characters, to its `wchar_t' representation, placing + this n *PWC and returning its length. */ +int +DEFUN(mbtowc, (pwc, s, n), wchar_t *pwc AND CONST char *s AND size_t n) +{ + register CONST mb_char *mb; + register wchar_t i; + + if (s == NULL) + return _mb_shift != 0; + + if (*s == '\0') + /* ANSI 4.10.7.2, line 19. */ + return 0; + + if (isascii (*s)) + { + /* A normal ASCII character translates to itself. */ + if (pwc != NULL) + *pwc = (wchar_t) *s; + return 1; + } + + if (_ctype_info->mbchar == NULL || + _ctype_info->mbchar->mb_chars == NULL) + return -1; + + if (n > MB_CUR_MAX) + n = MB_CUR_MAX; + + for (i = 0; i < WCHAR_MAX; ++i) + { + mb = &_ctype_info->mbchar->mb_chars[i]; + /* EOF and NUL aren't MB chars. */ + if (i == (wchar_t) EOF || i == (wchar_t) '\0') + continue; + /* Normal ASCII values can't start MB chars. */ + else if (isascii(i)) + continue; + else if (mb->string == NULL || mb->len == 0) + continue; + else if (mb->len > n) + continue; + else if (!strncmp(mb->string, s, mb->len)) + { + _mb_shift += mb->shift; + if (pwc != NULL) + *pwc = i; + return mb->len; + } + } + + return -1; +} diff --git a/stdlib/msort.c b/stdlib/msort.c new file mode 100644 index 0000000000..92ba5182ed --- /dev/null +++ b/stdlib/msort.c @@ -0,0 +1,103 @@ +/* msort -- an alternative to qsort, with an identical interface. + Copyright (C) 1992 Free Software Foundation, Inc. + Written by Mike Haertel, September 1988. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <string.h> + +#define MEMCPY(dst, src, s) \ + ((s) == sizeof (int) \ + ? (*(int *) (dst) = *(int *) (src), (dst)) \ + : memcpy (dst, src, s)) + +static void +DEFUN(msort_with_tmp, (b, n, s, cmp, t), + PTR b AND size_t n AND size_t s AND __compar_fn_t cmp AND char *t) +{ + char *tmp; + char *b1, *b2; + size_t n1, n2; + + if (n <= 1) + return; + + n1 = n / 2; + n2 = n - n1; + b1 = b; + b2 = (char *) b + (n1 * s); + + msort_with_tmp (b1, n1, s, cmp, t); + msort_with_tmp (b2, n2, s, cmp, t); + + tmp = t; + + while (n1 > 0 && n2 > 0) + { + if ((*cmp) (b1, b2) <= 0) + { + MEMCPY (tmp, b1, s); + b1 += s; + --n1; + } + else + { + MEMCPY (tmp, b2, s); + b2 += s; + --n2; + } + tmp += s; + } + if (n1 > 0) + memcpy (tmp, b1, n1 * s); + memcpy (b, t, (n - n2) * s); +} + +void +DEFUN(qsort, (b, n, s, cmp), + PTR b AND size_t n AND size_t s AND __compar_fn_t cmp) +{ + CONST size_t size = n * s; + + if (size < 1024) + /* The temporary array is small, so put it on the stack. */ + msort_with_tmp (b, n, s, cmp, __alloca (size)); + else + { + /* It's somewhat large, so malloc it. */ + int save = errno; + char *tmp = malloc (size); + if (tmp == NULL) + { + /* Couldn't get space, so use the slower algorithm + that doesn't need a temporary array. */ + extern void EXFUN(_quicksort, (PTR __base, + size_t __nmemb, size_t __size, + __compar_fn_t __compar)); + _quicksort (b, n, s, cmp); + } + else + { + msort_with_tmp (b, n, s, cmp, tmp); + free (tmp); + } + errno = save; + } +} diff --git a/stdlib/on_exit.c b/stdlib/on_exit.c new file mode 100644 index 0000000000..bd100be895 --- /dev/null +++ b/stdlib/on_exit.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include "exit.h" + +/* Register a function to be called by exit. */ +int +DEFUN(on_exit, (func, arg), + void EXFUN((*func), (int status, PTR arg)) AND PTR arg) +{ + struct exit_function *new = __new_exitfn(); + + if (new == NULL) + return -1; + + new->flavor = ef_on; + new->func.on.fn = func; + new->func.on.arg = arg; + return 0; +} diff --git a/stdlib/qsort.c b/stdlib/qsort.c new file mode 100644 index 0000000000..bc8d171b79 --- /dev/null +++ b/stdlib/qsort.c @@ -0,0 +1,243 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <string.h> + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of MAX_INT is allocated on the + stack. Assuming a 32-bit integer, this needs only 32 * + sizeof(stack_node) == 136 bits. Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segements. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (n) + stack size is needed (actually O(1) in this case)! */ + +void +DEFUN(_quicksort, (pbase, total_elems, size, cmp), + PTR CONST pbase AND size_t total_elems AND size_t size AND + int EXFUN((*cmp), (CONST PTR, CONST PTR))) +{ + register char *base_ptr = (char *) pbase; + + /* Allocating SIZE bytes for a pivot buffer facilitates a better + algorithm below since we can do comparisons directly on the pivot. */ + char *pivot_buffer = (char *) __alloca (size); + CONST size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + /* Largest size needed for 32-bit int!!! */ + stack_node stack[STACK_SIZE]; + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + + char *pivot = pivot_buffer; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp)((PTR) mid, (PTR) lo) < 0) + SWAP(mid, lo, size); + if ((*cmp)((PTR) hi, (PTR) mid) < 0) + SWAP(mid, hi, size); + else + goto jump_over; + if ((*cmp)((PTR) mid, (PTR) lo) < 0) + SWAP(mid, lo, size); + jump_over:; + memcpy(pivot, mid, size); + pivot = pivot_buffer; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp)((PTR) left_ptr, (PTR) pivot) < 0) + left_ptr += size; + + while ((*cmp)((PTR) pivot, (PTR) right_ptr) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP(left_ptr, right_ptr, size); + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP(lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH(lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH(left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *CONST end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + register char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP(tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} + diff --git a/stdlib/rand.c b/stdlib/rand.c new file mode 100644 index 0000000000..1353432850 --- /dev/null +++ b/stdlib/rand.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +#undef rand + + +/* Return a random integer between 0 and RAND_MAX. */ +int +DEFUN_VOID(rand) +{ + return (int) __random(); +} diff --git a/stdlib/random.c b/stdlib/random.c new file mode 100644 index 0000000000..fb32b36b87 --- /dev/null +++ b/stdlib/random.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * This is derived from the Berkeley source: + * @(#)random.c 5.5 (Berkeley) 7/6/88 + * It was reworked for the GNU C Library by Roland McGrath. + */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> + + +/* An improved random number generation package. In addition to the standard + rand()/srand() like interface, this package also has a special state info + interface. The initstate() routine is called with a seed, an array of + bytes, and a count of how many bytes are being passed in; this array is + then initialized to contain information for random number generation with + that much state information. Good sizes for the amount of state + information are 32, 64, 128, and 256 bytes. The state can be switched by + calling the setstate() function with the same array as was initiallized + with initstate(). By default, the package runs with 128 bytes of state + information and generates far better random numbers than a linear + congruential generator. If the amount of state information is less than + 32 bytes, a simple linear congruential R.N.G. is used. Internally, the + state information is treated as an array of longs; the zeroeth element of + the array is the type of R.N.G. being used (small integer); the remainder + of the array is the state information for the R.N.G. Thus, 32 bytes of + state information will give 7 longs worth of state information, which will + allow a degree seven polynomial. (Note: The zeroeth word of state + information also has some other information stored in it; see setstate + for details). The random number generation technique is a linear feedback + shift register approach, employing trinomials (since there are fewer terms + to sum up that way). In this approach, the least significant bit of all + the numbers in the state table will act as a linear feedback shift register, + and will have period 2^deg - 1 (where deg is the degree of the polynomial + being used, assuming that the polynomial is irreducible and primitive). + The higher order bits will have longer periods, since their values are + also influenced by pseudo-random carries out of the lower bits. The + total period of the generator is approximately deg*(2**deg - 1); thus + doubling the amount of state information has a vast influence on the + period of the generator. Note: The deg*(2**deg - 1) is an approximation + only good for large deg, when the period of the shift register 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. */ + + + +/* For each of the currently supported random number generators, we have a + break value on the amount of state information (you need at least thi + bytes of state info to support this random number generator), a degree for + the polynomial (actually a trinomial) that the R.N.G. is based on, and + separation between the two lower order coefficients of the trinomial. */ + +/* Linear congruential. */ +#define TYPE_0 0 +#define BREAK_0 8 +#define DEG_0 0 +#define SEP_0 0 + +/* x**7 + x**3 + 1. */ +#define TYPE_1 1 +#define BREAK_1 32 +#define DEG_1 7 +#define SEP_1 3 + +/* x**15 + x + 1. */ +#define TYPE_2 2 +#define BREAK_2 64 +#define DEG_2 15 +#define SEP_2 1 + +/* x**31 + x**3 + 1. */ +#define TYPE_3 3 +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +/* x**63 + x + 1. */ +#define TYPE_4 4 +#define BREAK_4 256 +#define DEG_4 63 +#define SEP_4 1 + + +/* Array versions of the above information to make code run faster. + Relies on fact that TYPE_i == i. */ + +#define MAX_TYPES 5 /* Max number of types above. */ + +static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; +static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; + + + +/* Initially, everything is set up as if from: + initstate(1, randtbl, 128); + Note that this initialization takes advantage of the fact that srandom + advances the front and rear pointers 10*rand_deg times, and hence the + rear pointer which starts at 0 will also end up at zero; thus the zeroeth + element of the state information, which contains info about the current + position of the rear pointer is just + (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */ + +static long int randtbl[DEG_3 + 1] = + { + TYPE_3, + -851904987, -43806228, -2029755270, 1390239686, -1912102820, + -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712, + -1714531963, 1800685987, -2015299881, 654595283, -1149023258, + -1470005550, -1143256056, -1325577603, -1568001885, 1275120390, + -607508183, -205999574, -1696891592, 1492211999, -1528267240, + -952028296, -189082757, 362343714, 1424981831, 2039449641, + }; + +/* FPTR and RPTR are two pointers into the state info, a front and a rear + pointer. These two pointers are always rand_sep places aparts, as they + cycle through the state information. (Yes, this does mean we could get + away with just one pointer, but the code for random is more efficient + this way). The pointers are left positioned as they would be from the call: + initstate(1, randtbl, 128); + (The position of the rear pointer, rptr, is really 0 (as explained above + in the initialization of randtbl) because the state table pointer is set + to point to randtbl[1] (as explained below).) */ + +static long int *fptr = &randtbl[SEP_3 + 1]; +static long int *rptr = &randtbl[1]; + + + +/* The following things are the pointer to the state information table, + the type of the current generator, the degree of the current polynomial + being used, and the separation between the two pointers. + Note that for efficiency of random, we remember the first location of + the state information, not the zeroeth. Hence it is valid to access + state[-1], which is used to store the type of the R.N.G. + Also, we remember the last location, since this is more efficient than + indexing every time to find the address of the last element to see if + the front and rear pointers have wrapped. */ + +static long int *state = &randtbl[1]; + +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; + +static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])]; + +/* Initialize the random number generator based on the given seed. If the + type is the trivial no-state-information type, just remember the seed. + Otherwise, initializes state[] based on the given "seed" via a linear + congruential generator. Then, the pointers are set to known locations + that are exactly rand_sep places apart. Lastly, it cycles the state + information a given number of times to get rid of any initial dependencies + introduced by the L.C.R.N.G. Note that the initialization of randtbl[] + for default usage relies on values produced by this routine. */ +void +DEFUN(__srandom, (x), unsigned int x) +{ + state[0] = x; + if (rand_type != TYPE_0) + { + register long int i; + for (i = 1; i < rand_deg; ++i) + state[i] = (1103515145 * state[i - 1]) + 12345; + fptr = &state[rand_sep]; + rptr = &state[0]; + for (i = 0; i < 10 * rand_deg; ++i) + (void) __random(); + } +} + +weak_alias (__srandom, srandom) +weak_alias (__srandom, srand) + +/* Initialize the state information in the given array of N bytes for + future random number generation. Based on the number of bytes we + are given, and the break values for the different R.N.G.'s, we choose + the best (largest) one we can and set things up for it. srandom is + then called to initialize the state information. Note that on return + from srandom, we set state[-1] to be the type multiplexed with the current + value of the rear pointer; this is so successive calls to initstate won't + lose this information and will be able to restart with setstate. + Note: The first thing we do is save the current state, if any, just like + setstate so that it doesn't matter when initstate is called. + Returns a pointer to the old state. */ +PTR +DEFUN(__initstate, (seed, arg_state, n), + unsigned int seed AND PTR arg_state AND size_t n) +{ + PTR ostate = (PTR) &state[-1]; + + if (rand_type == TYPE_0) + state[-1] = rand_type; + else + state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; + if (n < BREAK_1) + { + if (n < BREAK_0) + { + errno = EINVAL; + return NULL; + } + rand_type = TYPE_0; + rand_deg = DEG_0; + rand_sep = SEP_0; + } + else if (n < BREAK_2) + { + rand_type = TYPE_1; + rand_deg = DEG_1; + rand_sep = SEP_1; + } + else if (n < BREAK_3) + { + rand_type = TYPE_2; + rand_deg = DEG_2; + rand_sep = SEP_2; + } + else if (n < BREAK_4) + { + rand_type = TYPE_3; + rand_deg = DEG_3; + rand_sep = SEP_3; + } + else + { + rand_type = TYPE_4; + rand_deg = DEG_4; + rand_sep = SEP_4; + } + + state = &((long int *) arg_state)[1]; /* First location. */ + /* Must set END_PTR before srandom. */ + end_ptr = &state[rand_deg]; + __srandom(seed); + if (rand_type == TYPE_0) + state[-1] = rand_type; + else + state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; + + return ostate; +} + +weak_alias (__initstate, initstate) + +/* Restore the state from the given state array. + Note: It is important that we also remember the locations of the pointers + in the current state information, and restore the locations of the pointers + from the old state information. This is done by multiplexing the pointer + location into the zeroeth word of the state information. Note that due + to the order in which things are done, it is OK to call setstate with the + same state as the current state + Returns a pointer to the old state information. */ +PTR +DEFUN(__setstate, (arg_state), PTR arg_state) +{ + register long int *new_state = (long int *) arg_state; + register int type = new_state[0] % MAX_TYPES; + register int rear = new_state[0] / MAX_TYPES; + PTR ostate = (PTR) &state[-1]; + + if (rand_type == TYPE_0) + state[-1] = rand_type; + else + state[-1] = (MAX_TYPES * (rptr - state)) + rand_type; + + switch (type) + { + case TYPE_0: + case TYPE_1: + case TYPE_2: + case TYPE_3: + case TYPE_4: + rand_type = type; + rand_deg = degrees[type]; + rand_sep = seps[type]; + break; + default: + /* State info munged. */ + errno = EINVAL; + return NULL; + } + + state = &new_state[1]; + if (rand_type != TYPE_0) + { + rptr = &state[rear]; + fptr = &state[(rear + rand_sep) % rand_deg]; + } + /* Set end_ptr too. */ + end_ptr = &state[rand_deg]; + + return ostate; +} + +weak_alias (__setstate, setstate) + +/* If we are using the trivial TYPE_0 R.N.G., just do the old linear + congruential bit. Otherwise, we do our fancy trinomial stuff, which is the + same in all ther other cases due to all the global variables that have been + set up. The basic operation is to add the number at the rear pointer into + the one at the front pointer. Then both pointers are advanced to the next + location cyclically in the table. The value returned is the sum generated, + reduced to 31 bits by throwing away the "least random" low bit. + Note: The code takes advantage of the fact that both the front and + rear pointers can't wrap on the same call by not testing the rear + pointer if the front one has wrapped. Returns a 31-bit random number. */ + +long int +DEFUN_VOID(__random) +{ + if (rand_type == TYPE_0) + { + state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX; + return state[0]; + } + else + { + long int i; + *fptr += *rptr; + /* Chucking least random bit. */ + i = (*fptr >> 1) & LONG_MAX; + ++fptr; + if (fptr >= end_ptr) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end_ptr) + rptr = state; + } + return i; + } +} + +weak_alias (__random, random) diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h new file mode 100644 index 0000000000..d64a2ffb7c --- /dev/null +++ b/stdlib/stdlib.h @@ -0,0 +1,289 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.10 GENERAL UTILITIES <stdlib.h> + */ + +#ifndef _STDLIB_H + +#define _STDLIB_H 1 +#include <features.h> + +/* Get size_t, wchar_t and NULL from <stddef.h>. */ +#define __need_size_t +#define __need_wchar_t +#define __need_NULL +#include <stddef.h> + +#define __need_Emath +#include <errno.h> + +__BEGIN_DECLS + +/* Returned by `div'. */ +typedef struct + { + int quot; /* Quotient. */ + int rem; /* Remainder. */ + } div_t; + +/* Returned by `ldiv'. */ +typedef struct + { + long int quot; /* Quotient. */ + long int rem; /* Remainder. */ + } ldiv_t; + + +/* The largest number rand will return (same as INT_MAX). */ +#define RAND_MAX 2147483647 + + +/* We define these the same for all machines. + Changes from this to the outside world should be done in `_exit'. */ +#define EXIT_FAILURE 1 /* Failing exit status. */ +#define EXIT_SUCCESS 0 /* Successful exit status. */ + + +/* Maximum length of a multibyte character in the current locale. + This is just one until the fancy locale support is finished. */ +#define MB_CUR_MAX 1 + + +/* Convert a string to a floating-point number. */ +extern double atof __P ((__const char *__nptr)); +/* Convert a string to an integer. */ +extern int atoi __P ((__const char *__nptr)); +/* Convert a string to a long integer. */ +extern long int atol __P ((__const char *__nptr)); + +/* Convert a string to a floating-point number. */ +extern double strtod __P ((__const char *__nptr, char **__endptr)); + +#ifdef __USE_GNU +/* Likewise for `float' and `long double' sizes of floating-point numbers. */ +extern float __strtof __P ((__const char *__nptr, char **__endptr)); +extern float strtof __P ((__const char *__nptr, char **__endptr)); +extern __long_double_t __strtold __P ((__const char *__nptr, char **__endptr)); +extern __long_double_t strtold __P ((__const char *__nptr, char **__endptr)); +#endif + +/* Convert a string to a long integer. */ +extern long int strtol __P ((__const char *__nptr, char **__endptr, + int __base)); +/* Convert a string to an unsigned long integer. */ +extern unsigned long int strtoul __P ((__const char *__nptr, + char **__endptr, int __base)); + +#if defined (__GNUC__) && defined (__USE_BSD) +/* Convert a string to a quadword integer. */ +extern long long int strtoq __P ((__const char *__nptr, char **__endptr, + int __base)); +/* Convert a string to an unsigned quadword integer. */ +extern unsigned long long int strtouq __P ((__const char *__nptr, + char **__endptr, int __base)); +#endif /* GCC and use BSD. */ + +#if defined (__OPTIMIZE__) && __GNUC__ >= 2 +extern __inline double atof (__const char *__nptr) +{ return strtod(__nptr, (char **) NULL); } +extern __inline int atoi (__const char *__nptr) +{ return (int) strtol (__nptr, (char **) NULL, 10); } +extern __inline long int atol (__const char *__nptr) +{ return strtol (__nptr, (char **) NULL, 10); } +#endif /* Optimizing GCC >=2. */ + + +/* Return a random integer between 0 and RAND_MAX inclusive. */ +extern int rand __P ((void)); +/* Seed the random number generator with the given number. */ +extern void srand __P ((unsigned int __seed)); + +/* These are the functions that actually do things. The `random', `srandom', + `initstate' and `setstate' functions are those from BSD Unices. + The `rand' and `srand' functions are required by the ANSI standard. + We provide both interfaces to the same random number generator. */ +/* Return a random long integer between 0 and RAND_MAX inclusive. */ +extern long int __random __P ((void)); +/* Seed the random number generator with the given number. */ +extern void __srandom __P ((unsigned int __seed)); + +/* Initialize the random number generator to use state buffer STATEBUF, + of length STATELEN, and seed it with SEED. Optimal lengths are 8, 16, + 32, 64, 128 and 256, the bigger the better; values less than 8 will + cause an error and values greater than 256 will be rounded down. */ +extern __ptr_t __initstate __P ((unsigned int __seed, __ptr_t __statebuf, + size_t __statelen)); +/* Switch the random number generator to state buffer STATEBUF, + which should have been previously initialized by `initstate'. */ +extern __ptr_t __setstate __P ((__ptr_t __statebuf)); + +#ifdef __USE_BSD +extern long int random __P ((void)); +extern void srandom __P ((unsigned int __seed)); +extern __ptr_t initstate __P ((unsigned int __seed, __ptr_t __statebuf, + size_t __statelen)); +extern __ptr_t setstate __P ((__ptr_t __statebuf)); + +#if defined (__OPTIMIZE__) && __GNUC__ >= 2 +extern __inline long int random (void) +{ return __random(); } +extern __inline void srandom (unsigned int __seed) +{ __srandom(__seed); } +extern __inline __ptr_t initstate (unsigned int __seed, + __ptr_t __statebuf, size_t __statelen) +{ return __initstate (__seed, __statebuf, __statelen); } +extern __inline __ptr_t setstate (__ptr_t __statebuf) +{ return __setstate (__statebuf); } +#endif /* Optimizing GCC >=2. */ +#endif /* Use BSD. */ + + +/* Allocate SIZE bytes of memory. */ +extern __ptr_t malloc __P ((size_t __size)); +/* Re-allocate the previously allocated block + in __ptr_t, making the new block SIZE bytes long. */ +extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size)); +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +extern __ptr_t calloc __P ((size_t __nmemb, size_t __size)); +/* Free a block allocated by `malloc', `realloc' or `calloc'. */ +extern void free __P ((__ptr_t __ptr)); + +#ifdef __USE_MISC +/* Free a block. An alias for `free'. (Sun Unices). */ +extern void cfree __P ((__ptr_t __ptr)); +#endif /* Use misc. */ + +#if defined(__USE_GNU) || defined(__USE_BSD) || defined(__USE_MISC) +#include <alloca.h> +#endif /* Use GNU, BSD, or misc. */ + +#ifdef __USE_BSD +/* Allocate SIZE bytes on a page boundary. The storage cannot be freed. */ +extern __ptr_t valloc __P ((size_t __size)); +#endif + + +/* Abort execution and generate a core-dump. */ +extern void abort __P ((void)) __attribute__ ((__noreturn__)); + + +/* Register a function to be called when `exit' is called. */ +extern int atexit __P ((void (*__func) (void))); + +#ifdef __USE_MISC +/* Register a function to be called with the status + given to `exit' and the given argument. */ +extern int on_exit __P ((void (*__func) (int __status, __ptr_t __arg), + __ptr_t __arg)); +#endif + +/* Call all functions registered with `atexit' and `on_exit', + in the reverse of the order in which they were registered + perform stdio cleanup, and terminate program execution with STATUS. */ +extern void exit __P ((int __status)) __attribute__ ((__noreturn__)); + + +/* Return the value of envariable NAME, or NULL if it doesn't exist. */ +extern char *getenv __P ((__const char *__name)); + +#ifdef __USE_SVID +/* The SVID says this is in <stdio.h>, but this seems a better place. */ +/* Put STRING, which is of the form "NAME=VALUE", in the environment. + If there is no `=', remove NAME from the environment. */ +extern int putenv __P ((__const char *__string)); +#endif + +#ifdef __USE_BSD +/* Set NAME to VALUE in the environment. + If REPLACE is nonzero, overwrite an existing value. */ +extern int setenv __P ((__const char *__name, __const char *__value, + int __replace)); +#endif + +/* Execute the given line as a shell command. */ +extern int system __P ((__const char *__command)); + + +/* Shorthand for type of comparison functions. */ +typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t)); + +#ifdef __USE_GNU +typedef __compar_fn_t comparison_fn_t; +#endif + +/* Do a binary search for KEY in BASE, which consists of NMEMB elements + of SIZE bytes each, using COMPAR to perform the comparisons. */ +extern __ptr_t bsearch __P ((__const __ptr_t __key, __const __ptr_t __base, + size_t __nmemb, size_t __size, + __compar_fn_t __compar)); + +/* Sort NMEMB elements of BASE, of SIZE bytes each, + using COMPAR to perform the comparisons. */ +extern void qsort __P ((__ptr_t __base, size_t __nmemb, size_t __size, + __compar_fn_t __compar)); + + +#ifndef __CONSTVALUE +#ifdef __GNUC__ +/* The `const' keyword tells GCC that a function's return value is + based solely on its arguments, and there are no side-effects. */ +#define __CONSTVALUE __const +#else +#define __CONSTVALUE +#endif /* GCC. */ +#endif /* __CONSTVALUE not defined. */ + +/* Return the absolute value of X. */ +extern __CONSTVALUE int abs __P ((int __x)); +extern __CONSTVALUE long int labs __P ((long int __x)); + + +/* Return the `div_t' or `ldiv_t' representation + of the value of NUMER over DENOM. */ +/* GCC may have built-ins for these someday. */ +extern __CONSTVALUE div_t div __P ((int __numer, int __denom)); +extern __CONSTVALUE ldiv_t ldiv __P ((long int __numer, long int __denom)); + + +/* Return the length of the multibyte character + in S, which is no longer than N. */ +extern int mblen __P ((__const char *__s, size_t __n)); +/* Return the length of the given multibyte character, + putting its `wchar_t' representation in *PWC. */ +extern int mbtowc __P ((wchar_t * __pwc, __const char *__s, size_t __n)); +/* Put the multibyte character represented + by WCHAR in S, returning its length. */ +extern int wctomb __P ((char *__s, wchar_t __wchar)); + +#if defined (__OPTIMIZE__) && __GNUC__ >= 2 +extern __inline int mblen (__const char *__s, size_t __n) +{ return mbtowc ((wchar_t *) NULL, __s, __n); } +#endif /* Optimizing GCC >=2. */ + + +/* Convert a multibyte string to a wide char string. */ +extern size_t mbstowcs __P ((wchar_t * __pwcs, __const char *__s, size_t __n)); +/* Convert a wide char string to multibyte string. */ +extern size_t wcstombs __P ((char *__s, __const wchar_t * __pwcs, size_t __n)); + + +__END_DECLS + +#endif /* stdlib.h */ diff --git a/stdlib/strtod.c b/stdlib/strtod.c new file mode 100644 index 0000000000..d647753e79 --- /dev/null +++ b/stdlib/strtod.c @@ -0,0 +1,1027 @@ +/* Read decimal floating point numbers. +Copyright (C) 1995 Free Software Foundation, Inc. +Contributed by Ulrich Drepper. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Configuration part. These macros are defined by `strtold.c' and `strtof.c' + to produce the `long double' and `float' versions of the reader. */ +#ifndef FLOAT +#define FLOAT double +#define FLT DBL +#define STRTOF strtod +#define MPN2FLOAT __mpn_construct_double +#define FLOAT_HUGE_VAL HUGE_VAL +#endif +/* End of configuration part. */ + +#include <ctype.h> +#include <errno.h> +#include <float.h> +#include <localeinfo.h> +#include <math.h> +#include <stdlib.h> +#include "../stdio/gmp.h" +#include "../stdio/gmp-impl.h" +#include <gmp-mparam.h> +#include "../stdio/longlong.h" +#include "../stdio/fpioconst.h" + +/* #define NDEBUG 1 */ +#include <assert.h> + + +/* Constants we need from float.h; select the set for the FLOAT precision. */ +#define MANT_DIG FLT##_MANT_DIG +#define MAX_EXP FLT##_MAX_EXP +#define MIN_EXP FLT##_MIN_EXP +#define MAX_10_EXP FLT##_MAX_10_EXP +#define MIN_10_EXP FLT##_MIN_10_EXP +#define MAX_10_EXP_LOG FLT##_MAX_10_EXP_LOG + + +/* Function to construct a floating point number from an MP integer + containing the fraction bits, a base 2 exponent, and a sign flag. */ +extern FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative); + +/* Definitions according to limb size used. */ +#if BITS_PER_MP_LIMB == 32 +# define MAX_DIG_PER_LIMB 9 +# define MAX_FAC_PER_LIMB 1000000000L +#elif BITS_PER_MP_LIMB == 64 +# define MAX_DIG_PER_LIMB 19 +# define MAX_FAC_PER_LIMB 10000000000000000000L +#else +# error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + +/* Local data structure. */ +static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB] = +{ 0, 10, 100, + 1000, 10000, 100000, + 1000000, 10000000, 100000000 +#if BITS_PER_MP_LIMB > 32 + , 1000000000, 10000000000, 100000000000, + 1000000000000, 10000000000000, 100000000000000, + 1000000000000000, 10000000000000000, 100000000000000000, + 1000000000000000000 +#endif +#if BITS_PER_MP_LIMB > 64 + #error "Need to expand tens_in_limb table to" MAX_DIG_PER_LIMB +#endif +}; + +#ifndef howmany +#define howmany(x,y) (((x)+((y)-1))/(y)) +#endif +#define SWAP(x, y) ({ typeof(x) _tmp = x; x = y; y = _tmp; }) + +#define NDIG (MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG) +#define RETURN_LIMB_SIZE howmany (MANT_DIG, BITS_PER_MP_LIMB) + +#define RETURN(val,end) \ + do { if (endptr != 0) *endptr = (char *) end; return val; } while (0) + +/* Maximum size necessary for mpn integers to hold floating point numbers. */ +#define MPNSIZE (howmany (MAX_EXP + MANT_DIG, BITS_PER_MP_LIMB) + 1) +/* Declare an mpn integer variable that big. */ +#define MPN_VAR(name) mp_limb name[MPNSIZE]; mp_size_t name##size +/* Copy an mpn integer value. */ +#define MPN_ASSIGN(dst, src) \ + memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb)) + + +/* Return a floating point number of the needed type according to the given + multi-precision number after possible rounding. */ +static inline FLOAT +round_and_return (mp_limb *retval, int exponent, int negative, + mp_limb round_limb, mp_size_t round_bit, int more_bits) +{ + if (exponent < MIN_EXP) + { + mp_size_t shift = MIN_EXP - 1 - exponent; + + if (shift >= MANT_DIG) + { + errno = EDOM; + return 0.0; + } + + more_bits |= (round_limb & ((1 << round_bit) - 1)) != 0; + if (shift >= BITS_PER_MP_LIMB) + { + round_limb = retval[(shift - 1) / BITS_PER_MP_LIMB]; + round_bit = (shift - 1) % BITS_PER_MP_LIMB; +#if RETURN_LIMB_SIZE <= 2 + assert (RETURN_LIMB_SIZE == 2); + more_bits |= retval[0] != 0; + retval[0] = retval[1]; + retval[1] = 0; +#else + int disp = shift / BITS_PER_MP_LIMB; + int i = 0; + while (retval[i] == 0 && i < disp) + ++i; + more_bits |= i < disp; + for (i = disp; i < RETURN_LIMB_SIZE; ++i) + retval[i - disp] = retval[i]; + MPN_ZERO (&retval[RETURN_LIMB_SIZE - disp], disp); +#endif + shift %= BITS_PER_MP_LIMB; + } + else + { + round_limb = retval[0]; + round_bit = shift - 1; + } + (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift); + exponent = MIN_EXP - 2; + } + + if ((round_limb & (1 << round_bit)) != 0 && + (more_bits || (retval[0] & 1) != 0 || + (round_limb & ((1 << round_bit) - 1)) != 0)) + { + mp_limb cy = __mpn_add_1 (retval, retval, RETURN_LIMB_SIZE, 1); + if (cy || (retval[RETURN_LIMB_SIZE - 1] + & (1 << (MANT_DIG % BITS_PER_MP_LIMB))) != 0) + { + ++exponent; + (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, 1); + retval[RETURN_LIMB_SIZE - 1] |= 1 << (MANT_DIG % BITS_PER_MP_LIMB); + } + } + + if (exponent > MAX_EXP) + return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL; + + return MPN2FLOAT (retval, exponent, negative); +} + + +/* Read a multi-precision integer starting at STR with exactly DIGCNT digits + into N. Return the size of the number limbs in NSIZE at the first + character od the string that is not part of the integer as the function + value. If the EXPONENT is small enough to be taken as an additional + factor for the resulting number (see code) multiply by it. */ +static inline const char * +str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize, + int *exponent) +{ + /* Number of digits for actual limb. */ + int cnt = 0; + mp_limb low = 0; + mp_limb base; + + *nsize = 0; + assert (digcnt > 0); + do + { + if (cnt == MAX_DIG_PER_LIMB) + { + if (*nsize == 0) + n[0] = low; + else + { + mp_limb cy; + cy = __mpn_mul_1 (n, n, *nsize, MAX_FAC_PER_LIMB); + cy += __mpn_add_1 (n, n, *nsize, low); + if (cy != 0) + n[*nsize] = cy; + } + ++(*nsize); + cnt = 0; + low = 0; + } + + /* There might be thousands separators or radix characters in the string. + But these all can be ignored because we know the format of the number + is correct and we have an exact number of characters to read. */ + while (!isdigit (*str)) + ++str; + low = low * 10 + *str++ - '0'; + ++cnt; + } + while (--digcnt > 0); + + if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB) + { + low *= _tens_in_limb[*exponent]; + base = _tens_in_limb[cnt + *exponent]; + *exponent = 0; + } + else + base = _tens_in_limb[cnt]; + + if (*nsize == 0) + { + n[0] = low; + *nsize = 1; + } + else + { + mp_limb cy; + cy = __mpn_mul_1 (n, n, *nsize, base); + cy += __mpn_add_1 (n, n, *nsize, low); + if (cy != 0) + n[(*nsize)++] = cy; + } + return str; +} + + +/* Shift {PTR, SIZE} COUNT bits to the left, and fill the vacated bits + with the COUNT most significant bits of LIMB. + + Tege doesn't like this function so I have to write it here myself. :) + --drepper */ +static inline void +__mpn_lshift_1 (mp_limb *ptr, mp_size_t size, unsigned int count, mp_limb limb) +{ + if (count == BITS_PER_MP_LIMB) + { + /* Optimize the case of shifting by exactly a word: + just copy words, with no actual bit-shifting. */ + mp_size_t i; + for (i = size - 1; i > 0; --i) + ptr[i] = ptr[i - 1]; + ptr[0] = limb; + } + else + { + (void) __mpn_lshift (ptr, ptr, size, count); + ptr[0] |= limb >> (BITS_PER_MP_LIMB - count); + } +} + + +/* Return a floating point number with the value of the given string NPTR. + Set *ENDPTR to the character after the last used one. If the number is + smaller than the smallest representable number, set `errno' to ERANGE and + return 0.0. If the number is too big to be represented, set `errno' to + ERANGE and return HUGE_VAL with the approriate sign. */ +FLOAT +STRTOF (nptr, endptr) + const char *nptr; + char **endptr; +{ + int negative; /* The sign of the number. */ + MPN_VAR (num); /* MP representation of the number. */ + int exponent; /* Exponent of the number. */ + + /* When we have to compute fractional digits we form a fraction with a + second multi-precision number (and we sometimes need a second for + temporary results). */ + MPN_VAR (den); + + /* Representation for the return value. */ + mp_limb retval[RETURN_LIMB_SIZE]; + /* Number of bits currently in result value. */ + int bits; + + /* Running pointer after the last character processed in the string. */ + const char *cp; + /* Start of significant part of the number. */ + const char *startp; + /* Points at the character following the integer and fractional digits. */ + const char *expp; + /* Total number of digit and number of digits in integer part. */ + int dig_no, int_no; + /* Contains the last character read. */ + char c; + + /* The radix character of the current locale. */ + wchar_t decimal; +#ifdef USE_GROUPING + /* The thousands character of the current locale. */ + wchar_t thousands; + /* The numeric grouping specification of the current locale, + in the format described in <locale.h>. */ + const char *grouping; + + /* Check the grouping of the integer part at [BEGIN,END). + Return zero iff a separator is found out of place. */ + int grouping_ok (const char *begin, const char *end) + { + if (grouping) + while (end > begin) + { + const char *p = end; + do + --p; + while (*p != thousands && p > begin); + if (end - 1 - p != *grouping++) + return 0; /* Wrong number of digits in this group. */ + end = p; /* Correct group; trim it off the end. */ + + if (*grouping == 0) + --grouping; /* Same grouping repeats in next iteration. */ + else if (*grouping == CHAR_MAX || *grouping < 0) + { + /* No further grouping allowed. */ + while (end > begin) + if (*--end == thousands) + return 0; + } + } + return 1; + } + /* Return with no conversion if the grouping of [STARTP,CP) is bad. */ +#define CHECK_GROUPING if (! grouping_ok (startp, cp)) RETURN (0.0, nptr); else + + grouping = _numeric_info->grouping; /* Cache the grouping info array. */ + if (*grouping <= 0 || *grouping == CHAR_MAX) + grouping = NULL; + else + { + /* Figure out the thousands seperator character. */ + if (mbtowc (&thousands_sep, _numeric_info->thousands_sep, + strlen (_numeric_info->thousands_sep)) <= 0) + thousands = (wchar_t) *_numeric_info->thousands_sep; + if (thousands == L'\0') + grouping = NULL; + } +#else +#define grouping NULL +#define thousands L'\0' +#define CHECK_GROUPING ((void) 0) +#endif + + /* Find the locale's decimal point character. */ + if (mbtowc (&decimal, _numeric_info->decimal_point, + strlen (_numeric_info->decimal_point)) <= 0) + decimal = (wchar_t) *_numeric_info->decimal_point; + + + /* Prepare number representation. */ + exponent = 0; + negative = 0; + bits = 0; + + /* Parse string to get maximal legal prefix. We need the number of + characters of the interger part, the fractional part and the exponent. */ + cp = nptr - 1; + /* Ignore leading white space. */ + do + c = *++cp; + while (isspace (c)); + + /* Get sign of the result. */ + if (c == '-') + { + negative = 1; + c = *++cp; + } + else if (c == '+') + c = *++cp; + + /* Return 0.0 if no legal string is found. + No character is used even if a sign was found. */ + if (!isdigit (c)) + RETURN (0.0, nptr); + + /* Record the start of the digits, in case we will check their grouping. */ + startp = cp; + + /* Ignore leading zeroes. This helps us to avoid useless computations. */ + while (c == '0' || (thousands != L'\0' && c == thousands)) + c = *++cp; + + CHECK_GROUPING; + + /* If no other digit but a '0' is found the result is 0.0. + Return current read pointer. */ + if (!isdigit (c) && c != decimal) + RETURN (0.0, cp); + + /* Remember first significant digit and read following characters until the + decimal point, exponent character or any non-FP number character. */ + startp = cp; + dig_no = 0; + while (dig_no < NDIG || + /* If parsing grouping info, keep going past useful digits + so we can check all the grouping separators. */ + grouping) + { + if (isdigit (c)) + ++dig_no; + else if (thousands == L'\0' || c != thousands) + /* Not a digit or separator: end of the integer part. */ + break; + c = *++cp; + } + + CHECK_GROUPING; + + if (dig_no >= NDIG) + /* Too many digits to be representable. Assigning this to EXPONENT + allows us to read the full number but return HUGE_VAL after parsing. */ + exponent = MAX_10_EXP; + + /* We have the number digits in the integer part. Whether these are all or + any is really a fractional digit will be decided later. */ + int_no = dig_no; + + /* Read the fractional digits. */ + if (c == decimal) + { + if (isdigit (cp[1])) + { + ++cp; + do + { + ++dig_no; + c = *++cp; + } + while (isdigit (c)); + } + } + + /* Remember start of exponent (if any). */ + expp = cp; + + /* Read exponent. */ + if (tolower (c) == 'e') + { + int exp_negative = 0; + + c = *++cp; + if (c == '-') + { + exp_negative = 1; + c = *++cp; + } + else if (c == '+') + c = *++cp; + + if (isdigit (c)) + { + do + { + if ((!exp_negative && exponent * 10 + int_no > MAX_10_EXP) + || (exp_negative + && exponent * 10 + int_no > -MIN_10_EXP + MANT_DIG)) + /* The exponent is too large/small to represent a valid + number. */ + { + FLOAT retval; + + /* Overflow or underflow. */ + errno = ERANGE; + retval = (exp_negative ? 0.0 : + negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL); + + /* Accept all following digits as part of the exponent. */ + do + ++cp; + while (isdigit (*cp)); + + RETURN (retval, cp); + /* NOTREACHED */ + } + + exponent *= 10; + exponent += c - '0'; + c = *++cp; + } + while (isdigit (c)); + } + else + cp = expp; + + if (exp_negative) + exponent = -exponent; + } + + /* We don't want to have to work with trailing zeroes after the radix. */ + if (dig_no > int_no) + { + while (expp[-1] == '0') + { + --expp; + --dig_no; + } + assert (dig_no >= int_no); + } + + /* The whole string is parsed. Store the address of the next character. */ + if (endptr) + *endptr = (char *) cp; + + if (dig_no == 0) + return 0.0; + + /* Now we have the number of digits in total and the integer digits as well + as the exponent and its sign. We can decide whether the read digits are + really integer digits or belong to the fractional part; i.e. we normalize + 123e-2 to 1.23. */ + { + register int incr = exponent < 0 ? MAX (-int_no, exponent) + : MIN (dig_no - int_no, exponent); + int_no += incr; + exponent -= incr; + } + + if (int_no + exponent > MAX_10_EXP) + { + errno = ERANGE; + return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL; + } + + if (int_no - dig_no + exponent < MIN_10_EXP - MANT_DIG) + { + errno = ERANGE; + return 0.0; + } + + if (int_no > 0) + { + /* Read the integer part as a multi-precision number to NUM. */ + startp = str_to_mpn (startp, int_no, num, &numsize, &exponent); + + if (exponent > 0) + { + /* We now multiply the gained number by the given power of ten. */ + mp_limb *psrc = num; + mp_limb *pdest = den; + int expbit = 1; + const struct mp_power *ttab = &_fpioconst_pow10[0]; + + assert (exponent < (1 << (MAX_10_EXP_LOG + 1))); + do + { + if ((exponent & expbit) != 0) + { + mp_limb cy; + exponent ^= expbit; + + /* FIXME: not the whole multiplication has to be done. + If we have the needed number of bits we only need the + information whether more non-zero bits follow. */ + if (numsize >= ttab->arraysize - 2) + cy = __mpn_mul (pdest, psrc, numsize, + &ttab->array[2], ttab->arraysize - 2); + else + cy = __mpn_mul (pdest, &ttab->array[2], + ttab->arraysize - 2, + psrc, numsize); + numsize += ttab->arraysize - 2; + if (cy == 0) + --numsize; + SWAP (psrc, pdest); + } + expbit <<= 1; + ++ttab; + } + while (exponent != 0); + + if (psrc == den) + memcpy (num, den, numsize * sizeof (mp_limb)); + } + + /* Determine how many bits of the result we already have. */ + count_leading_zeros (bits, num[numsize - 1]); + bits = numsize * BITS_PER_MP_LIMB - bits; + + /* We have already the first BITS bits of the result. Together with + the information whether more non-zero bits follow this is enough + to determine the result. */ + if (bits > MANT_DIG) + { + const mp_size_t least_idx = (bits - MANT_DIG) / BITS_PER_MP_LIMB; + const mp_size_t least_bit = (bits - MANT_DIG) % BITS_PER_MP_LIMB; + const mp_size_t round_idx = least_bit == 0 ? least_idx - 1 + : least_idx; + const mp_size_t round_bit = least_bit == 0 ? BITS_PER_MP_LIMB - 1 + : least_idx - 1; + int i; + + if (least_bit == 0) + memcpy (retval, &num[least_idx], + RETURN_LIMB_SIZE * sizeof (mp_limb)); + else + (void) __mpn_rshift (retval, &num[least_idx], + numsize - least_idx + 1, least_bit); + + /* Check whether any limb beside the ones in RETVAL are non-zero. */ + for (i = 0; num[i] == 0; ++i) + ; + + return round_and_return (retval, bits - 1, negative, + num[round_idx], round_bit, + int_no < dig_no || i < round_idx); + /* NOTREACHED */ + } + else if (dig_no == int_no) + { + const mp_size_t target_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB; + const mp_size_t is_bit = (bits - 1) % BITS_PER_MP_LIMB; + + if (target_bit == is_bit) + { + memcpy (&retval[RETURN_LIMB_SIZE - numsize], num, + numsize * sizeof (mp_limb)); + /* FIXME: the following loop can be avoided if we assume a + maximal MANT_DIG value. */ + MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize); + } + else if (target_bit > is_bit) + { + (void) __mpn_lshift (&retval[RETURN_LIMB_SIZE - numsize], + num, numsize, target_bit - is_bit); + /* FIXME: the following loop can be avoided if we assume a + maximal MANT_DIG value. */ + MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize); + } + else + { + mp_limb cy; + assert (numsize < RETURN_LIMB_SIZE); + + cy = __mpn_rshift (&retval[RETURN_LIMB_SIZE - numsize], + num, numsize, is_bit - target_bit); + retval[RETURN_LIMB_SIZE - numsize - 1] = cy; + /* FIXME: the following loop can be avoided if we assume a + maximal MANT_DIG value. */ + MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize - 1); + } + + return round_and_return (retval, bits - 1, negative, 0, 0, 0); + /* NOTREACHED */ + } + + /* Store the bits we already have. */ + memcpy (retval, num, numsize * sizeof (mp_limb)); +#if RETURN_LIMB_SIZE > 1 + if (numsize < RETURN_LIMB_SIZE) + retval[numsize] = 0; +#endif + } + + /* We have to compute at least some of the fractional digits. */ + { + /* We construct a fraction and the result of the division gives us + the needed digits. The denominator is 1.0 multiplied by the + exponent of the lowest digit; i.e. 0.123 gives 123 / 1000 and + 123e6 gives 123 / 1000000. */ + + int expbit; + int cnt; + mp_limb cy; + mp_limb *psrc = den; + mp_limb *pdest = num; + int neg_exp = dig_no - int_no - exponent; + const struct mp_power *ttab = &_fpioconst_pow10[0]; + + assert (dig_no > int_no && exponent <= 0); + + /* Construct the denominator. */ + densize = 0; + expbit = 1; + do + { + if ((neg_exp & expbit) != 0) + { + mp_limb cy; + neg_exp ^= expbit; + + if (densize == 0) + memcpy (psrc, &ttab->array[2], + (densize = ttab->arraysize - 2) * sizeof (mp_limb)); + else + { + cy = __mpn_mul (pdest, &ttab->array[2], ttab->arraysize - 2, + psrc, densize); + densize += ttab->arraysize - 2; + if (cy == 0) + --densize; + SWAP (psrc, pdest); + } + } + expbit <<= 1; + ++ttab; + } + while (neg_exp != 0); + + if (psrc == num) + memcpy (den, num, densize * sizeof (mp_limb)); + + /* Read the fractional digits from the string. */ + (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent); + + + /* We now have to shift both numbers so that the highest bit in the + denominator is set. In the same process we copy the numerator to + a high place in the array so that the division constructs the wanted + digits. This is done by a "quasi fix point" number representation. + + num: ddddddddddd . 0000000000000000000000 + |--- m ---| + den: ddddddddddd n >= m + |--- n ---| + */ + + count_leading_zeros (cnt, den[densize - 1]); + + (void) __mpn_lshift (den, den, densize, cnt); + cy = __mpn_lshift (num, num, numsize, cnt); + if (cy != 0) + num[numsize++] = cy; + + /* Now we are ready for the division. But it is not necessary to + do a full multi-precision division because we only need a small + number of bits for the result. So we do not use __mpn_divmod + here but instead do the division here by hand and stop whenever + the needed number of bits is reached. The code itself comes + from the GNU MP Library by Torbj\"orn Granlund. */ + + exponent = bits; + + switch (densize) + { + case 1: + { + mp_limb d, n, quot; + int used = 0; + + n = num[0]; + d = den[0]; + assert (numsize == 1 && n < d); + + do + { + udiv_qrnnd (quot, n, n, 0, d); + +#define got_limb \ + if (bits == 0) \ + { \ + register int cnt; \ + if (quot == 0) \ + cnt = BITS_PER_MP_LIMB; \ + else \ + count_leading_zeros (cnt, quot); \ + exponent -= cnt; \ + if (BITS_PER_MP_LIMB - cnt > MANT_DIG) \ + { \ + used = cnt + MANT_DIG; \ + retval[0] = quot >> (BITS_PER_MP_LIMB - used); \ + bits -= BITS_PER_MP_LIMB - used; \ + } \ + else \ + { \ + /* Note that we only clear the second element. */ \ + retval[1] = 0; \ + retval[0] = quot; \ + bits -= cnt; \ + } \ + } \ + else if (bits + BITS_PER_MP_LIMB <= MANT_DIG) \ + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, BITS_PER_MP_LIMB, \ + quot); \ + else \ + { \ + used = MANT_DIG - bits; \ + if (used > 0) \ + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, quot); \ + } \ + bits += BITS_PER_MP_LIMB + + got_limb; + } + while (bits <= MANT_DIG); + + return round_and_return (retval, exponent - 1, negative, + quot, BITS_PER_MP_LIMB - 1 - used, + n != 0); + } + case 2: + { + mp_limb d0, d1, n0, n1; + mp_limb quot = 0; + int used = 0; + + d0 = den[0]; + d1 = den[1]; + + if (numsize < densize) + { + if (bits <= 0) + exponent -= BITS_PER_MP_LIMB; + else + { + if (bits + BITS_PER_MP_LIMB <= MANT_DIG) + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, + BITS_PER_MP_LIMB, 0); + else + { + used = MANT_DIG - bits; + if (used > 0) + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0); + } + bits += BITS_PER_MP_LIMB; + } + n1 = num[0]; + n0 = 0; + } + else + { + n1 = num[1]; + n0 = num[0]; + } + + while (bits <= MANT_DIG) + { + mp_limb r; + + if (n1 == d1) + { + /* QUOT should be either 111..111 or 111..110. We need + special treatment of this rare case as normal division + would give overflow. */ + quot = ~(mp_limb) 0; + + r = n0 + d1; + if (r < d1) /* Carry in the addition? */ + { + add_ssaaaa (n1, n0, r - d0, 0, 0, d0); + goto have_quot; + } + n1 = d0 - (d0 != 0); + n0 = -d0; + } + else + { + udiv_qrnnd (quot, r, n1, n0, d1); + umul_ppmm (n1, n0, d0, quot); + } + + q_test: + if (n1 > r || (n1 == r && n0 > 0)) + { + /* The estimated QUOT was too large. */ + --quot; + + sub_ddmmss (n1, n0, n1, n0, 0, d0); + r += d1; + if (r >= d1) /* If not carry, test QUOT again. */ + goto q_test; + } + sub_ddmmss (n1, n0, r, 0, n1, n0); + + have_quot: + got_limb; + } + + return round_and_return (retval, exponent - 1, negative, + quot, BITS_PER_MP_LIMB - 1 - used, + n1 != 0 || n0 != 0); + } + default: + { + int i; + mp_limb cy, dX, d1, n0, n1; + mp_limb quot = 0; + int used = 0; + + dX = den[densize - 1]; + d1 = den[densize - 2]; + + /* The division does not work if the upper limb of the two-limb + numerator is greater than the denominator. */ + if (num[numsize - 1] > dX) + num[numsize++] = 0; + + if (numsize < densize) + { + mp_size_t empty = densize - numsize; + + if (bits <= 0) + { + register int i; + for (i = numsize; i > 0; --i) + num[i + empty] = num[i - 1]; + MPN_ZERO (num, empty + 1); + exponent -= empty * BITS_PER_MP_LIMB; + } + else + { + if (bits + empty * BITS_PER_MP_LIMB <= MANT_DIG) + { + /* We make a difference here because the compiler + cannot optimize the `else' case that good and + this reflects all currently used FLOAT types + and GMP implementations. */ + register int i; +#if RETURN_LIMB_SIZE <= 2 + assert (empty == 1); + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, + BITS_PER_MP_LIMB, 0); +#else + for (i = RETURN_LIMB_SIZE; i > empty; --i) + retval[i] = retval[i - empty]; +#endif + retval[1] = 0; + for (i = numsize; i > 0; --i) + num[i + empty] = num[i - 1]; + MPN_ZERO (num, empty + 1); + } + else + { + used = MANT_DIG - bits; + if (used >= BITS_PER_MP_LIMB) + { + register int i; + (void) __mpn_lshift (&retval[used + / BITS_PER_MP_LIMB], + retval, RETURN_LIMB_SIZE, + used % BITS_PER_MP_LIMB); + for (i = used / BITS_PER_MP_LIMB; i >= 0; --i) + retval[i] = 0; + } + else if (used > 0) + __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0); + } + bits += empty * BITS_PER_MP_LIMB; + } + } + else + { + int i; + assert (numsize == densize); + for (i = numsize; i > 0; --i) + num[i] = num[i - 1]; + } + + den[densize] = 0; + n0 = num[densize]; + + while (bits <= MANT_DIG) + { + if (n0 == dX) + /* This might over-estimate QUOT, but it's probably not + worth the extra code here to find out. */ + quot = ~(mp_limb) 0; + else + { + mp_limb r; + + udiv_qrnnd (quot, r, n0, num[densize - 1], dX); + umul_ppmm (n1, n0, d1, quot); + + while (n1 > r || (n1 == r && n0 > num[densize - 2])) + { + --quot; + r += dX; + if (r < dX) /* I.e. "carry in previous addition?" */ + break; + n1 -= n0 < d1; + n0 -= d1; + } + } + + /* Possible optimization: We already have (q * n0) and (1 * n1) + after the calculation of QUOT. Taking advantage of this, we + could make this loop make two iterations less. */ + + cy = __mpn_submul_1 (num, den, densize + 1, quot); + + if (num[densize] != cy) + { + cy = __mpn_add_n (num, num, den, densize); + assert (cy != 0); + --quot; + } + n0 = num[densize] = num[densize - 1]; + for (i = densize - 1; i > 0; --i) + num[i] = num[i - 1]; + + got_limb; + } + + for (i = densize - 1; num[i] != 0 && i >= 0; --i) + ; + return round_and_return (retval, exponent - 1, negative, + quot, BITS_PER_MP_LIMB - 1 - used, + i >= 0); + } + } + } + + /* NOTREACHED */ +} diff --git a/stdlib/strtof.c b/stdlib/strtof.c new file mode 100644 index 0000000000..bf1349b108 --- /dev/null +++ b/stdlib/strtof.c @@ -0,0 +1,12 @@ +/* The actual implementation for all floating point sizes is in strtod.c. + These macros tell it to produce the `float' version, `strtof'. */ + +#define FLOAT float +#define FLT FLT +#define STRTOF __strtof +#define MPN2FLOAT __mpn_construct_float +#define FLOAT_HUGE_VAL HUGE_VALf + +#include "strtod.c" + +weak_alias (__strtof, strtof) diff --git a/stdlib/strtol.c b/stdlib/strtol.c new file mode 100644 index 0000000000..888a94e4d7 --- /dev/null +++ b/stdlib/strtol.c @@ -0,0 +1,189 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ctype.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <errno.h> + +/* Nonzero if we are defining `strtoul' or `strtouq', operating on unsigned + integers. */ +#ifndef UNSIGNED +#define UNSIGNED 0 +#endif + +/* If QUAD is defined, we are defining `strtoq' or `strtouq', + operating on `long long int's. */ +#ifdef QUAD +#if UNSIGNED +#define strtoul strtouq +#else +#define strtol strtoq +#endif +#define LONG long long +#undef LONG_MIN +#define LONG_MIN LONG_LONG_MIN +#undef LONG_MAX +#define LONG_MAX LONG_LONG_MAX +#undef ULONG_MAX +#define ULONG_MAX ULONG_LONG_MAX +#if __GNUC__ == 2 && __GNUC_MINOR__ < 7 +/* Work around gcc bug with using this constant. */ +static const unsigned long long int maxquad = ULONG_LONG_MAX; +#undef ULONG_MAX +#define ULONG_MAX maxquad +#endif +#else +#define LONG long +#endif + +/* Convert NPTR to an `unsigned long int' or `long int' in base BASE. + If BASE is 0 the base is determined by the presence of a leading + zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. + If BASE is < 2 or > 36, it is reset to 10. + If ENDPTR is not NULL, a pointer to the character after the last + one converted is stored in *ENDPTR. */ +#if UNSIGNED +unsigned LONG int +#define strtol strtoul +#else +LONG int +#endif +strtol (nptr, endptr, base) + const char *nptr; + char **endptr; + int base; +{ + int negative; + register unsigned LONG int cutoff; + register unsigned int cutlim; + register unsigned LONG int i; + register const char *s; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + + /* Skip white space. */ + while (isspace (*s)) + ++s; + if (*s == '\0') + goto noconv; + + /* Check for a sign. */ + if (*s == '-') + { + negative = 1; + ++s; + } + else if (*s == '+') + { + negative = 0; + ++s; + } + else + negative = 0; + + if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X') + s += 2; + + /* If BASE is zero, figure it out ourselves. */ + if (base == 0) + if (*s == '0') + { + if (toupper (s[1]) == 'X') + { + s += 2; + base = 16; + } + else + base = 8; + } + else + base = 10; + + /* Save the pointer so we can check later if anything happened. */ + save = s; + + cutoff = ULONG_MAX / (unsigned LONG int) base; + cutlim = ULONG_MAX % (unsigned LONG int) base; + + overflow = 0; + i = 0; + for (c = *s; c != '\0'; c = *++s) + { + if (isdigit (c)) + c -= '0'; + else if (isalpha (c)) + c = toupper (c) - 'A' + 10; + else + break; + if (c >= base) + break; + /* Check for overflow. */ + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (unsigned LONG int) base; + i += c; + } + } + + /* Check if anything actually happened. */ + if (s == save) + goto noconv; + + /* Store in ENDPTR the address of one character + past the last character we converted. */ + if (endptr != NULL) + *endptr = (char *) s; + +#if !UNSIGNED + /* Check for a value that is within the range of + `unsigned LONG int', but outside the range of `LONG int'. */ + if (i > (negative ? + -(unsigned LONG int) LONG_MIN : (unsigned LONG int) LONG_MAX)) + overflow = 1; +#endif + + if (overflow) + { + errno = ERANGE; +#if UNSIGNED + return ULONG_MAX; +#else + return negative ? LONG_MIN : LONG_MAX; +#endif + } + + /* Return the result of the appropriate sign. */ + return (negative ? -i : i); + +noconv: + /* There was no number to convert. */ + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; +} diff --git a/stdlib/strtold.c b/stdlib/strtold.c new file mode 100644 index 0000000000..2595725add --- /dev/null +++ b/stdlib/strtold.c @@ -0,0 +1,12 @@ +/* The actual implementation for all floating point sizes is in strtod.c. + These macros tell it to produce the `long double' version, `strtold'. */ + +#define FLOAT long double +#define FLT LDBL +#define STRTOF __strtold +#define MPN2FLOAT __mpn_construct_long_double +#define FLOAT_HUGE_VAL HUGE_VALl + +#include "strtod.c" + +weak_alias (__strtold, strtold) diff --git a/stdlib/strtoq.c b/stdlib/strtoq.c new file mode 100644 index 0000000000..be1f723b13 --- /dev/null +++ b/stdlib/strtoq.c @@ -0,0 +1,22 @@ +/* strtoq -- Function to parse a `long long int' from text. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define QUAD 1 + +#include <strtol.c> diff --git a/stdlib/strtoul.c b/stdlib/strtoul.c new file mode 100644 index 0000000000..386cc7a357 --- /dev/null +++ b/stdlib/strtoul.c @@ -0,0 +1,21 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define UNSIGNED 1 + +#include <strtol.c> diff --git a/stdlib/strtouq.c b/stdlib/strtouq.c new file mode 100644 index 0000000000..4eea0b22ee --- /dev/null +++ b/stdlib/strtouq.c @@ -0,0 +1,22 @@ +/* strtouq -- Function to parse an `unsigned long long int' from text. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define QUAD 1 + +#include <strtoul.c> diff --git a/stdlib/testdiv.c b/stdlib/testdiv.c new file mode 100644 index 0000000000..b86a58d42c --- /dev/null +++ b/stdlib/testdiv.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + int i, j; + while (scanf ("%d %d\n", &i, &j) == 2) + { + div_t d = div (i, j); + printf ("%d / %d = %d + %d/%d\n", i, j, d.quot, d.rem, j); + } + return 0; +} diff --git a/stdlib/testdiv.input b/stdlib/testdiv.input new file mode 100644 index 0000000000..415b7b4f54 --- /dev/null +++ b/stdlib/testdiv.input @@ -0,0 +1,2 @@ +10 3 +-10 3 diff --git a/stdlib/testmb.c b/stdlib/testmb.c new file mode 100644 index 0000000000..c840ce195b --- /dev/null +++ b/stdlib/testmb.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stdlib.h> + +int +main () +{ + wchar_t w[10]; + char c[10]; + int i; + int lose = 0; + + i = mbstowcs (w, "bar", 4); + if (!(i == 3 && w[1] == 'a')) + { + puts ("mbstowcs FAILED!"); + lose = 1; + } + + mbstowcs (w, "blah", 5); + i = wcstombs (c, w, 10); + if (i != 4) + { + puts ("wcstombs FAILED!"); + lose = 1; + } + + if (mblen ("foobar", 7) != 1) + { + puts ("mblen 1 FAILED!"); + lose = 1; + } + + if (mblen ("", 1) != 0) + { + puts ("mblen 2 FAILED!"); + lose = 1; + } + + { + int r; + char c = 'x'; + wchar_t wc; + char *mbc; + + mbc = (char *) malloc (MB_CUR_MAX); + mbc[0] = c; + mbc[1] = '\0'; + + if ((r = mbtowc (&wc, &c, MB_CUR_MAX)) <= 0) + { + printf ("conversion to wide failed, result: %d\n", r); + lose = 1; + } + else + { + printf ("wide value: 0x%04x\n", (unsigned long) wc); + mbc[0] = '\0'; + if ((r = wctomb (mbc, wc)) <= 0) + { + printf ("conversion to multibyte failed, result: %d\n", r); + lose = 1; + } + } + + } + + puts (lose ? "Test FAILED!" : "Test succeeded."); + return lose; +} diff --git a/stdlib/testrand.c b/stdlib/testrand.c new file mode 100644 index 0000000000..b66dca9899 --- /dev/null +++ b/stdlib/testrand.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <stdio.h> + +int +DEFUN_VOID(main) +{ + int i1, i2; + int j1, j2; + + /* The C standard says that "If rand is called before any calls to + srand have been made, the same sequence shall be generated as + when srand is first called with a seed value of 1." */ + i1 = rand(); + i2 = rand(); + srand (1); + j1 = rand(); + j2 = rand(); + if (j1 == i1 && j2 == i2) + { + puts ("Test succeeded."); + return 0; + } + else + { + if (j1 != i1) + printf ("%d != %d\n", j1, i1); + if (j2 != i2) + printf ("%d != %d\n", j2, i2); + puts ("Test FAILED!"); + return 1; + } +} diff --git a/stdlib/testsort.c b/stdlib/testsort.c new file mode 100644 index 0000000000..a171a62130 --- /dev/null +++ b/stdlib/testsort.c @@ -0,0 +1,38 @@ +#include <ansidecl.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +int +DEFUN(compare, (a, b), CONST PTR a AND CONST PTR b) +{ + return strcmp (*(char **) a, *(char **) b); +} + + +int +DEFUN_VOID(main) +{ + char bufs[500][20]; + char *lines[500]; + size_t lens[500]; + size_t i, j; + + srandom (1); + + for (i = 0; i < 500; ++i) + { + lens[i] = random() % 19; + lines[i] = bufs[i]; + for (j = 0; j < lens[i]; ++j) + lines[i][j] = random() % 26 + 'a'; + lines[i][j] = '\0'; + } + + qsort (lines, 500, sizeof (char *), compare); + + for (i = 0; i < 500 && lines[i] != NULL; ++i) + puts (lines[i]); + + return 0; +} diff --git a/stdlib/tst-strtod.c b/stdlib/tst-strtod.c new file mode 100644 index 0000000000..a38ff4a74b --- /dev/null +++ b/stdlib/tst-strtod.c @@ -0,0 +1,94 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +struct ltest + { + CONST char *str; /* Convert this. */ + double expect; /* To get this. */ + char left; /* With this left over. */ + int err; /* And this in errno. */ + }; +static CONST struct ltest tests[] = + { + { "12.345", 12.345, '\0', 0 }, + { "12.345e19", 12.345e19, '\0', 0 }, + { "-.1e+9", -.1e+9, '\0', 0 }, + { ".125", .125, '\0', 0 }, + { "1e20", 1e20, '\0', 0 }, + { NULL, 0, '\0', 0 } + }; + +static void EXFUN(expand, (char *dst, int c)); + +int +DEFUN_VOID(main) +{ + register CONST struct ltest *lt; + char *ep; + int status = 0; + + for (lt = tests; lt->str != NULL; ++lt) + { + double d; + + errno = 0; + d = strtod(lt->str, &ep); + printf("strtod(\"%s\") test %u", + lt->str, (unsigned int) (lt - tests)); + if (d == lt->expect && *ep == lt->left && errno == lt->err) + puts("\tOK"); + else + { + puts("\tBAD"); + if (d != lt->expect) + printf(" returns %.60g, expected %.60g\n", d, lt->expect); + if (lt->left != *ep) + { + char exp1[5], exp2[5]; + expand(exp1, *ep); + expand(exp2, lt->left); + printf(" leaves '%s', expected '%s'\n", exp1, exp2); + } + if (errno != lt->err) + printf(" errno %d (%s) instead of %d (%s)\n", + errno, strerror(errno), lt->err, strerror(lt->err)); + status = 1; + } + } + + exit(status ? EXIT_FAILURE : EXIT_SUCCESS); +} + +static void +DEFUN(expand, (dst, c), register char *dst AND register int c) +{ + if (isprint(c)) + { + dst[0] = c; + dst[1] = '\0'; + } + else + (void) sprintf(dst, "%#.3o", (unsigned int) c); +} diff --git a/stdlib/tst-strtol.c b/stdlib/tst-strtol.c new file mode 100644 index 0000000000..0682da3f09 --- /dev/null +++ b/stdlib/tst-strtol.c @@ -0,0 +1,127 @@ +/* My bet is this was written by Chris Torek. + I reformatted and ansidecl-ized it, and tweaked it a little. */ + +#include <ansidecl.h> +#include <ctype.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <strings.h> + +struct ltest + { + CONST char *str; /* Convert this. */ + unsigned long int expect; /* To get this. */ + int base; /* Use this base. */ + char left; /* With this left over. */ + int err; /* And this in errno. */ + }; +static CONST struct ltest tests[] = + { + /* First, signed numbers. */ + { " -17", -17, 0, 0, 0 }, + { " +0x123fg", 0x123f, 0, 'g', 0 }, + { "2147483647", 2147483647, 0, 0, 0 }, + { "2147483648", 2147483647, 0, 0, ERANGE }, + { "214748364888", 2147483647, 0, 0, ERANGE }, + { "2147483650", 2147483647, 0, 0, ERANGE }, + { "-2147483649", -2147483648, 0, 0, ERANGE }, + { "-2147483648", -2147483648, 0, 0, 0 }, + { "0123", 0123, 0, 0, 0 }, + { "0x1122334455z", 2147483647, 16, 'z', ERANGE }, + { "0x0xc", 0, 0, 'x', 0 }, + { "yz!", 34*36+35, 36, '!', 0 }, + { NULL, 0, 0, 0, 0 }, + + /* Then unsigned. */ + { " 0", 0, 0, 0, 0 }, + { "0xffffffffg", 0xffffffff, 0, 'g', 0 }, + { "0xf1f2f3f4f5", 0xffffffff, 0, 0, ERANGE }, + { "-0x123456789", 0xffffffff, 0, 0, ERANGE }, + { "-0xfedcba98", -0xfedcba98, 0, 0, 0 }, + { NULL, 0, 0, 0, 0 }, + }; + +static void EXFUN(expand, (char *dst, int c)); + +int +DEFUN_VOID(main) +{ + register CONST struct ltest *lt; + char *ep; + int status = 0; + + for (lt = tests; lt->str != NULL; ++lt) + { + register long int l; + + errno = 0; + l = strtol(lt->str, &ep, lt->base); + printf("strtol(\"%s\", , %d) test %u", + lt->str, lt->base, (unsigned int) (lt - tests)); + if (l == (long int) lt->expect && *ep == lt->left && errno == lt->err) + puts("\tOK"); + else + { + puts("\tBAD"); + if (l != (long int) lt->expect) + printf(" returns %ld, expected %ld\n", + l, (long int) lt->expect); + if (lt->left != *ep) + { + char exp1[5], exp2[5]; + expand(exp1, *ep); + expand(exp2, lt->left); + printf(" leaves '%s', expected '%s'\n", exp1, exp2); + } + if (errno != lt->err) + printf(" errno %d (%s) instead of %d (%s)\n", + errno, strerror(errno), lt->err, strerror(lt->err)); + status = 1; + } + } + + for (++lt; lt->str != NULL; lt++) + { + register unsigned long int ul; + + errno = 0; + ul = strtoul(lt->str, &ep, lt->base); + printf("strtoul(\"%s\", , %d) test %u", + lt->str, lt->base, (unsigned int) (lt - tests)); + if (ul == lt->expect && *ep == lt->left && errno == lt->err) + puts("\tOK"); + else + { + puts("\tBAD"); + if (ul != lt->expect) + printf(" returns %lu, expected %lu\n", + ul, lt->expect); + if (lt->left != *ep) + { + char exp1[5], exp2[5]; + expand(exp1, *ep); + expand(exp2, lt->left); + printf(" leaves '%s', expected '%s'\n", exp1, exp2); + } + if (errno != lt->err) + printf(" errno %d (%s) instead of %d (%s)\n", + errno, strerror(errno), lt->err, strerror(lt->err)); + status = 1; + } + } + + exit(status ? EXIT_FAILURE : EXIT_SUCCESS); +} + +static void +DEFUN(expand, (dst, c), register char *dst AND register int c) +{ + if (isprint(c)) + { + dst[0] = c; + dst[1] = '\0'; + } + else + (void) sprintf(dst, "%#.3o", (unsigned int) c); +} diff --git a/stdlib/wcstombs.c b/stdlib/wcstombs.c new file mode 100644 index 0000000000..acaf15a94e --- /dev/null +++ b/stdlib/wcstombs.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <ctype.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Convert the `wchar_t' string in PWCS to a multibyte character string + in S, writing no more than N characters. Return the number of bytes + written, or (size_t) -1 if an invalid `wchar_t' was found. */ +size_t +DEFUN(wcstombs, (s, pwcs, n), + register char *s AND register CONST wchar_t *pwcs AND register size_t n) +{ + register CONST mb_char *mb; + register int shift = 0; + + register size_t written = 0; + register wchar_t w; + + while ((w = *pwcs++) != (wchar_t) '\0') + { + if (isascii (w)) + { + /* A normal character. */ + *s++ = (unsigned char) w; + --n; + ++written; + } + else + { + mb = &_ctype_info->mbchar->mb_chars[w + shift]; + if (mb->string == NULL || mb->len == 0) + { + written = (size_t) -1; + break; + } + else if (mb->len > n) + break; + else + { + memcpy ((PTR) s, (CONST PTR) mb->string, mb->len); + s += mb->len; + n -= mb->len; + written += mb->len; + shift += mb->shift; + } + } + } + + /* Terminate the string if it has space. */ + if (n > 0) + *s = '\0'; + + /* Return the number of characters written (or maybe an error). */ + return written; +} diff --git a/stdlib/wctomb.c b/stdlib/wctomb.c new file mode 100644 index 0000000000..53f1cef3fc --- /dev/null +++ b/stdlib/wctomb.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + + +extern long int _mb_shift; /* Defined in mbtowc.c. */ + +/* Convert WCHAR into its multibyte character representation, + putting this in S and returning its length. */ +int +DEFUN(wctomb, (s, wchar), register char *s AND wchar_t wchar) +{ + register CONST mb_char *mb; + + if (_ctype_info->mbchar == NULL) + mb = NULL; + else + mb = _ctype_info->mbchar->mb_chars; + + /* If S is NULL, just say if we're shifted or not. */ + if (s == NULL) + return _mb_shift != 0; + + if (wchar == (wchar_t) '\0') + { + _mb_shift = 0; + /* See ANSI 4.4.1.1, line 21. */ + if (s != NULL) + *s = '\0'; + return 1; + } + else if (mb == NULL) + { + if ((wchar_t) (char) wchar == wchar && isascii ((char) wchar)) + { + /* A normal ASCII character translates to itself. */ + if (s != NULL) + *s = (char) wchar; + return 1; + } + return -1; + } + + mb += wchar + _mb_shift; + if (mb->string == NULL || mb->len == 0) + return -1; + memcpy((PTR) s, (CONST PTR) mb->string, mb->len + 1); + _mb_shift += mb->shift; + return mb->len; +} diff --git a/string.h b/string.h new file mode 100644 index 0000000000..b557c65f39 --- /dev/null +++ b/string.h @@ -0,0 +1 @@ +#include <string/string.h> diff --git a/string/.cvsignore b/string/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/string/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/string/Makefile b/string/Makefile new file mode 100644 index 0000000000..a4ba83b465 --- /dev/null +++ b/string/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for string portion of library. +# +subdir := string + +headers := string.h strings.h memory.h endian.h bytesex.h + +routines := strcat strchr strcmp strcoll strcpy strcspn strdup \ + strerror _strerror strlen strncat strncmp strncpy \ + strrchr strpbrk strsignal strspn strstr strtok \ + strxfrm memchr memcmp memmove memset \ + bcopy bzero ffs stpcpy stpncpy \ + strcasecmp strncase \ + memccpy memcpy wordcopy strsep \ + swab strfry memfrob memmem + +tests := tester testcopy test-ffs +distribute := memcopy.h + + +include ../Rules diff --git a/string/endian.h b/string/endian.h new file mode 100644 index 0000000000..8871ff54d4 --- /dev/null +++ b/string/endian.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _ENDIAN_H +#define _ENDIAN_H 1 +#include <features.h> + +/* Definitions for byte order, according to significance of bytes, from low + addresses to high addresses. The value is what you get by putting '4' + in the most significant byte, '3' in the second most significant byte, + '2' in the second least significant byte, and '1' in the least + significant byte. */ + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __PDP_ENDIAN 3412 + +/* This file defines `__BYTE_ORDER' for the particular machine. */ +#include <bytesex.h> + +#ifdef __USE_BSD +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN +#define PDP_ENDIAN __PDP_ENDIAN +#define BYTE_ORDER __BYTE_ORDER +#endif + +#endif /* endian.h */ diff --git a/string/memfrob.c b/string/memfrob.c new file mode 100644 index 0000000000..cf3422bdc7 --- /dev/null +++ b/string/memfrob.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +PTR +DEFUN(memfrob, (s, n), + PTR s AND size_t n) +{ + register char *p = (char *) s; + + while (n-- > 0) + *p++ ^= 42; + + return s; +} diff --git a/string/memory.h b/string/memory.h new file mode 100644 index 0000000000..901a291ea3 --- /dev/null +++ b/string/memory.h @@ -0,0 +1,34 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * SVID + */ + +#ifndef _MEMORY_H + +#define _MEMORY_H 1 +#include <features.h> + + +#ifndef _STRING_H +#include <string.h> +#endif /* string.h */ + + +#endif /* memory.h */ diff --git a/string/strcoll.c b/string/strcoll.c new file mode 100644 index 0000000000..ed4b35f80d --- /dev/null +++ b/string/strcoll.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + + +/* Compare S1 and S2, returning less than, equal to or + greater than zero if the collated form of S1 is lexiographically + less than, equal to or greater than the collated form of S2. */ +int +DEFUN(strcoll, (s1, s2), CONST char *s1 AND CONST char *s2) +{ + if (_collate_info == NULL || _collate_info->values == NULL) + return strcmp(s1, s2); + else + { + CONST unsigned char *CONST values = _collate_info->values; + CONST unsigned char *CONST offsets = _collate_info->offsets; + + while (*s1 != '\0' && *s2 != '\0') + { + CONST unsigned char c1 = *s1++, c2 = *s2++; + CONST unsigned char v1 = values[c1], v2 = values[c2]; + CONST unsigned char o1 = offsets[c1], o2 = offsets[c2]; + + if (v1 == UCHAR_MAX && o1 == 0) + /* This is a non-collating element. Skip it. */ + --s2; + else if (v2 == UCHAR_MAX && o2 == 0) + --s1; + else if (v1 == UCHAR_MAX && o1 == CHAR_MAX) + { + /* This element collates lower than anything else. */ + if (v2 != UCHAR_MAX || o2 != CHAR_MAX) + return -1; + } + else if (v2 == UCHAR_MAX && o2 == CHAR_MAX) + return 1; + else if (v1 != v2) + return v1 - v2; + else if (o1 != o2) + return o1 - o2; + } + + if (*s1 == '\0') + return *s2 == '\0' ? 0 : -1; + else if (*s2 == '\0') + return 1; + return 0; + } +} diff --git a/string/strdup.c b/string/strdup.c new file mode 100644 index 0000000000..2c8aff2796 --- /dev/null +++ b/string/strdup.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + + +/* Duplicate S, returning an identical malloc'd string. */ +char * +DEFUN(strdup, (s), CONST char *s) +{ + size_t len = strlen(s) + 1; + PTR new = malloc(len); + + if (new == NULL) + return NULL; + + memcpy(new, (PTR) s, len); + + return (char *) new; +} diff --git a/string/strerror.c b/string/strerror.c new file mode 100644 index 0000000000..67759703c4 --- /dev/null +++ b/string/strerror.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + +extern char *_strerror_internal __P ((int, char buf[1024])); + +/* Return a string descibing the errno code in ERRNUM. + The storage is good only until the next call to strerror. + Writing to the storage causes undefined behavior. */ +char * +DEFUN(strerror, (errnum), int errnum) +{ + static char buf[1024]; + return _strerror_internal (errnum, buf); +} diff --git a/string/strfry.c b/string/strfry.c new file mode 100644 index 0000000000..c885f66c68 --- /dev/null +++ b/string/strfry.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +char * +DEFUN(strfry, (string), char *string) +{ + static int init = 0; + size_t len, i; + + if (!init) + { + srand (time ((time_t *) NULL)); + init = 1; + } + + len = strlen (string); + for (i = 0; i < len; ++i) + { + size_t j = rand () % len; + char c = string[i]; + string[i] = string[j]; + string[j] = c; + } + + return string; +} diff --git a/string/string.h b/string/string.h new file mode 100644 index 0000000000..905d727f18 --- /dev/null +++ b/string/string.h @@ -0,0 +1,186 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.11 STRING HANDLING <string.h> + */ + +#ifndef _STRING_H + +#define _STRING_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get size_t and NULL from <stddef.h>. */ +#define __need_size_t +#define __need_NULL +#include <stddef.h> + + +/* Copy N bytes of SRC to DEST. */ +extern __ptr_t memcpy __P ((__ptr_t __dest, __const __ptr_t __src, + size_t __n)); +/* Copy N bytes of SRC to DEST, guaranteeing + correct behavior for overlapping strings. */ +extern __ptr_t memmove __P ((__ptr_t __dest, __const __ptr_t __src, + size_t __n)); + +/* Copy no more than N bytes of SRC to DEST, stopping when C is found. + Return the position in DEST one byte past where C was copied, + or NULL if C was not found in the first N bytes of SRC. */ +extern __ptr_t __memccpy __P ((__ptr_t __dest, __const __ptr_t __src, + int __c, size_t __n)); +#if defined (__USE_SVID) || defined (__USE_BSD) +extern __ptr_t memccpy __P ((__ptr_t __dest, __const __ptr_t __src, + int __c, size_t __n)); +#ifdef __OPTIMIZE__ +#define memccpy(dest, src, c, n) __memccpy((dest), (src), (c), (n)) +#endif /* Optimizing. */ +#endif /* SVID. */ + + +/* Set N bytes of S to C. */ +extern __ptr_t memset __P ((__ptr_t __s, int __c, size_t __n)); + +/* Compare N bytes of S1 and S2. */ +extern int memcmp __P ((__const __ptr_t __s1, __const __ptr_t __s2, + size_t __n)); + +/* Search N bytes of S for C. */ +extern __ptr_t memchr __P ((__const __ptr_t __s, int __c, size_t __n)); + + +/* Copy SRC to DEST. */ +extern char *strcpy __P ((char *__dest, __const char *__src)); +/* Copy no more than N characters of SRC to DEST. */ +extern char *strncpy __P ((char *__dest, __const char *__src, size_t __n)); + +/* Append SRC onto DEST. */ +extern char *strcat __P ((char *__dest, __const char *__src)); +/* Append no more than N characters from SRC onto DEST. */ +extern char *strncat __P ((char *__dest, __const char *__src, size_t __n)); + +/* Compare S1 and S2. */ +extern int strcmp __P ((__const char *__s1, __const char *__s2)); +/* Compare N characters of S1 and S2. */ +extern int strncmp __P ((__const char *__s1, __const char *__s2, size_t __n)); + +/* Compare the collated forms of S1 and S2. */ +extern int strcoll __P ((__const char *__s1, __const char *__s2)); +/* Put a transformation of SRC into no more than N bytes of DEST. */ +extern size_t strxfrm __P ((char *__dest, __const char *__src, size_t __n)); + +#if defined (__USE_SVID) || defined (__USE_BSD) +/* Duplicate S, returning an identical malloc'd string. */ +extern char *strdup __P ((__const char *__s)); +#endif + +/* Find the first occurrence of C in S. */ +extern char *strchr __P ((__const char *__s, int __c)); +/* Find the last occurrence of C in S. */ +extern char *strrchr __P ((__const char *__s, int __c)); + +/* Return the length of the initial segment of S which + consists entirely of characters not in REJECT. */ +extern size_t strcspn __P ((__const char *__s, __const char *__reject)); +/* Return the length of the initial segment of S which + consists entirely of characters in ACCEPT. */ +extern size_t strspn __P ((__const char *__s, __const char *__accept)); +/* Find the first occurence in S of any character in ACCEPT. */ +extern char *strpbrk __P ((__const char *__s, __const char *__accept)); +/* Find the first occurence of NEEDLE in HAYSTACK. */ +extern char *strstr __P ((__const char *__haystack, __const char *__needle)); +/* Divide S into tokens separated by characters in DELIM. */ +extern char *strtok __P ((char *__s, __const char *__delim)); + +#ifdef __USE_GNU +/* Find the first occurence of NEEDLE in HAYSTACK. + NEEDLE is NEEDLELEN bytes long; + HAYSTACK is HAYSTACKLEN bytes long. */ +extern __ptr_t memmem __P ((__const __ptr_t __haystack, size_t __haystacklen, + __const __ptr_t __needle, size_t __needlelen)); +#endif + +/* Return the length of S. */ +extern size_t strlen __P ((__const char *__s)); + +/* Return a string describing the meaning of the errno code in ERRNUM. */ +extern char *strerror __P ((int __errnum)); + +#ifdef __USE_BSD +/* Find the first occurrence of C in S (same as strchr). */ +extern char *index __P ((__const char *__s, int __c)); + +/* Find the last occurrence of C in S (same as strrchr). */ +extern char *rindex __P ((__const char *__s, int __c)); + +/* Copy N bytes of SRC to DEST (like memmove, but args reversed). */ +extern void bcopy __P ((__const __ptr_t __src, __ptr_t __dest, size_t __n)); + +/* Set N bytes of S to 0. */ +extern void bzero __P ((__ptr_t __s, size_t __n)); + +/* Compare N bytes of S1 and S2 (same as memcmp). */ +extern int bcmp __P ((__const __ptr_t __s1, __const __ptr_t __s2, size_t __n)); + +/* Return the position of the first bit set in I, or 0 if none are set. + The least-significant bit is position 1, the most-significant 32. */ +extern int ffs __P ((int __i)); + +/* Compare S1 and S2, ignoring case. */ +extern int strcasecmp __P ((__const char *__s1, __const char *__s2)); + +/* Return the next DELIM-delimited token from *STRINGP, + terminating it with a '\0', and update *STRINGP to point past it. */ +extern char *strsep __P ((char **__stringp, __const char *__delim)); +#endif + +/* Copy no more than N characters of SRC to DEST, returning the address of + the last character written into DEST. */ +extern char *__stpncpy __P ((char *__dest, __const char *__src, size_t __n)); + +#ifdef __USE_GNU +/* Compare no more than N chars of S1 and S2, ignoring case. */ +extern int strncasecmp __P ((__const char *__s1, __const char *__s2, + size_t __n)); + +/* Return a string describing the meaning of the signal number in SIG. */ +extern char *strsignal __P ((int __sig)); + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +extern char *stpcpy __P ((char *__dest, __const char *__src)); + +/* Copy no more than N characters of SRC to DEST, returning the address of + the last character written into DEST. */ +extern char *stpncpy __P ((char *__dest, __const char *__src, size_t __n)); + +#ifdef __OPTIMIZE__ +#define stpncpy(dest, src, n) __stpncpy ((dest), (src), (n)) +#endif + +/* Sautee STRING briskly. */ +extern char *strfry __P ((char *__string)); + +/* Frobnicate N bytes of S. */ +extern __ptr_t memfrob __P ((__ptr_t __s, size_t __n)); +#endif + +__END_DECLS + +#endif /* string.h */ diff --git a/string/strings.h b/string/strings.h new file mode 100644 index 0000000000..235c3e5c9e --- /dev/null +++ b/string/strings.h @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Compatibility with BSD string(3). */ + +#ifndef _STRINGS_H + +#define _STRINGS_H 1 +#include <features.h> + + +#ifndef _STRING_H +#include <string.h> +#endif /* string.h */ + + +#endif /* strings.h */ diff --git a/string/strsignal.c b/string/strsignal.c new file mode 100644 index 0000000000..c2c8835a19 --- /dev/null +++ b/string/strsignal.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + + +#ifndef HAVE_GNU_LD +#define _sys_siglist sys_siglist +#endif + +/* Defined in , 1992siglist.c. */ +extern CONST char *CONST _sys_siglist[]; + + +/* Return a string describing the meaning of the signal number SIGNUM. */ +char * +DEFUN(strsignal, (signum), int signum) +{ + if (signum < 0 || signum > NSIG) + { + static char unknown_signal[] = "Unknown signal 000000000000000000"; + static char fmt[] = "Unknown signal%d"; + size_t len = sprintf(unknown_signal, fmt, signum); + if (len < sizeof(fmt) - 2) + return NULL; + unknown_signal[len] = '\0'; + return unknown_signal; + } + + return (char *) _sys_siglist[signum]; +} diff --git a/string/strtok.c b/string/strtok.c new file mode 100644 index 0000000000..0b95084f53 --- /dev/null +++ b/string/strtok.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <string.h> + + +static char *olds = NULL; + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the last string strtok() was called with is + used. For example: + char s[] = "-abc=-def"; + x = strtok(s, "-"); // x = "abc" + x = strtok(NULL, "=-"); // x = "def" + x = strtok(NULL, "="); // x = NULL + // s = "abc\0-def\0" +*/ +char * +DEFUN(strtok, (s, delim), + register char *s AND register CONST char *delim) +{ + char *token; + + if (s == NULL) + { + if (olds == NULL) + { + errno = EINVAL; + return NULL; + } + else + s = olds; + } + + /* Scan leading delimiters. */ + s += strspn(s, delim); + if (*s == '\0') + { + olds = NULL; + return NULL; + } + + /* Find the end of the token. */ + token = s; + s = strpbrk(token, delim); + if (s == NULL) + /* This token finishes the string. */ + olds = NULL; + else + { + /* Terminate the token and make OLDS point past it. */ + *s = '\0'; + olds = s + 1; + } + return token; +} diff --git a/string/strxfrm.c b/string/strxfrm.c new file mode 100644 index 0000000000..cdca280e78 --- /dev/null +++ b/string/strxfrm.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + + +/* Transform SRC into a form such that the result of strcmp + on two strings that have been transformed by strxfrm is + the same as the result of strcoll on the two strings before + their transformation. The transformed string is put in at + most N characters of DEST and its length is returned. */ +size_t +DEFUN(strxfrm, (dest, src, n), char *dest AND CONST char *src AND size_t n) +{ + CONST unsigned char *CONST values + = _collate_info != NULL ? _collate_info->values : NULL; + CONST unsigned char *CONST offsets + = _collate_info != NULL ? _collate_info->offsets : NULL; + register size_t done = 0; + + while (*src != '\0') + { + CONST unsigned char c = *src++; + + ++done; + if (offsets != NULL && offsets[c] != 0) + { + ++done; + if (offsets[c] == CHAR_MAX) + ++done; + } + if (done < n && dest != NULL) + { + if (values == NULL) + *dest++ = c; + else if (values[c] == UCHAR_MAX && offsets[c] == 0) + /* This is a non-collating element. Skip it. */ + ; + else if (values[c] == UCHAR_MAX && offsets[c] == CHAR_MAX) + { + /* This element collates lower than anything else. */ + *dest++ = '\001'; + *dest++ = '\001'; + *dest++ = '\001'; + } + else + { + *dest++ = values[c]; + *dest++ = offsets[c]; + } + } + } + + if (dest != NULL) + *dest = '\0'; + return done; +} diff --git a/string/swab.c b/string/swab.c new file mode 100644 index 0000000000..350d9a3303 --- /dev/null +++ b/string/swab.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> + +void +DEFUN(swab, (from, to, n), + CONST char *from AND char *to AND size_t n) +{ + while (n > 1) + { + CONST char b0 = from[--n], b1 = from[--n]; + to[n] = b0; + to[n + 1] = b1; + } +} diff --git a/string/test-ffs.c b/string/test-ffs.c new file mode 100644 index 0000000000..bbe62786e0 --- /dev/null +++ b/string/test-ffs.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +int +DEFUN(main, (argc, argv), + int argc AND char **argv) +{ + int failures = 0; + int i; + void try (int value, int expected) + { + if (ffs (value) != expected) + { + fprintf (stderr, "%#x expected %d got %d\n", + value, expected, ffs (value)); + ++failures; + } + } + + try (0, 0); + for (i=0 ; i<32 ; i++) + try (1<<i, i+1); + try (0x80008000, 16); + + if (failures) + printf ("Test FAILED! %d failure%s.\n", failures, &"s"[failures == 1]); + else + puts ("Test succeeded."); + + exit (failures); +} diff --git a/string/testcopy.c b/string/testcopy.c new file mode 100644 index 0000000000..9ec5c7761c --- /dev/null +++ b/string/testcopy.c @@ -0,0 +1,111 @@ +/* Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <malloc.h> + +int +DEFUN(main, (argc, argv), + int argc AND char **argv) +{ + char *mem, *memp; + char *rand_mem; + char *lo_around, *hi_around; + int size, max_size; + int src_off, dst_off; + int i; + int space_around = 10; + + max_size = 256; + + mem = malloc (max_size + 2 * max_size + 2 * space_around); + rand_mem = malloc (max_size); + lo_around = malloc (space_around); + hi_around = malloc (space_around); + memp = mem + space_around; + + /* Fill RAND_MEM with random bytes, each non-zero. */ + for (i = 0; i < max_size; i++) + { + int x; + do + x = random (); + while (x == 0); + rand_mem[i] = x; + } + + for (size = 0; size < max_size; size++) + { + printf("phase %d\n", size); + for (src_off = 0; src_off <= 16; src_off++) + { + for (dst_off = 0; dst_off <= 16; dst_off++) + { + /* Put zero around the intended destination, to check + that it's not clobbered. */ + for (i = 1; i < space_around; i++) + { + memp[dst_off - i] = 0; + memp[dst_off + size - 1 + i] = 0; + } + + /* Fill the source area with known contents. */ + for (i = 0; i < size; i++) + memp[src_off + i] = rand_mem[i]; + + /* Remember the contents around the destination area. + (It might not be what we wrote some lines above, since + the src area and the dst area overlap.) */ + for (i = 1; i < space_around; i++) + { + lo_around[i] = memp[dst_off - i]; + hi_around[i] = memp[dst_off + size - 1 + i]; + } + + memmove (memp + dst_off, memp + src_off, size); + + /* Check that the destination area has the same + contents we wrote to the source area. */ + for (i = 0; i < size; i++) + { + if (memp[dst_off + i] != rand_mem[i]) + abort (); + } + + /* Check that the area around the destination is not + clobbered. */ + for (i = 1; i < space_around; i++) + { + if (memp[dst_off - i] != lo_around[i]) + abort (); + if (memp[dst_off + size - 1 + i] != hi_around[i]) + abort (); + } + } + } + } + + puts ("Test succeeded."); + + return 0; +} diff --git a/string/tester.c b/string/tester.c new file mode 100644 index 0000000000..74ac34541e --- /dev/null +++ b/string/tester.c @@ -0,0 +1,570 @@ +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <fcntl.h> + +#ifndef HAVE_GNU_LD +#define _sys_nerr sys_nerr +#define _sys_errlist sys_errlist +#endif + +#define STREQ(a, b) (strcmp((a), (b)) == 0) + +CONST char *it = "<UNSET>"; /* Routine name for message routines. */ +size_t errors = 0; + +/* Complain if condition is not true. */ +void +DEFUN(check, (thing, number), int thing AND int number) +{ + if (!thing) + { + printf("%s flunked test %d\n", it, number); + ++errors; + } +} + +/* Complain if first two args don't strcmp as equal. */ +void +DEFUN(equal, (a, b, number), CONST char *a AND CONST char *b AND int number) +{ + check(a != NULL && b != NULL && STREQ(a, b), number); +} + +char one[50]; +char two[50]; + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + /* Test strcmp first because we use it to test other things. */ + it = "strcmp"; + check(strcmp("", "") == 0, 1); /* Trivial case. */ + check(strcmp("a", "a") == 0, 2); /* Identity. */ + check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */ + check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */ + check(strcmp("abcd", "abc") > 0, 5); + check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */ + check(strcmp("abce", "abcd") > 0, 7); + check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */ + check(strcmp("a\203", "a\003") > 0, 9); + + /* Test strcpy next because we need it to set up other tests. */ + it = "strcpy"; + check(strcpy(one, "abcd") == one, 1); /* Returned value. */ + equal(one, "abcd", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + equal(one, "x", 3); /* Writeover. */ + equal(one+2, "cd", 4); /* Wrote too much? */ + + (void) strcpy(two, "hi there"); + (void) strcpy(one, two); + equal(one, "hi there", 5); /* Basic test encore. */ + equal(two, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + equal(one, "", 7); /* Boundary condition. */ + + /* strcat. */ + it = "strcat"; + (void) strcpy(one, "ijk"); + check(strcat(one, "lmn") == one, 1); /* Returned value. */ + equal(one, "ijklmn", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + (void) strcat(one, "yz"); + equal(one, "xyz", 3); /* Writeover. */ + equal(one+4, "mn", 4); /* Wrote too much? */ + + (void) strcpy(one, "gh"); + (void) strcpy(two, "ef"); + (void) strcat(one, two); + equal(one, "ghef", 5); /* Basic test encore. */ + equal(two, "ef", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + (void) strcat(one, ""); + equal(one, "", 7); /* Boundary conditions. */ + (void) strcpy(one, "ab"); + (void) strcat(one, ""); + equal(one, "ab", 8); + (void) strcpy(one, ""); + (void) strcat(one, "cd"); + equal(one, "cd", 9); + + /* strncat - first test it as strcat, with big counts, + then test the count mechanism. */ + it = "strncat"; + (void) strcpy(one, "ijk"); + check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */ + equal(one, "ijklmn", 2); /* Basic test. */ + + (void) strcpy(one, "x"); + (void) strncat(one, "yz", 99); + equal(one, "xyz", 3); /* Writeover. */ + equal(one+4, "mn", 4); /* Wrote too much? */ + + (void) strcpy(one, "gh"); + (void) strcpy(two, "ef"); + (void) strncat(one, two, 99); + equal(one, "ghef", 5); /* Basic test encore. */ + equal(two, "ef", 6); /* Stomped on source? */ + + (void) strcpy(one, ""); + (void) strncat(one, "", 99); + equal(one, "", 7); /* Boundary conditions. */ + (void) strcpy(one, "ab"); + (void) strncat(one, "", 99); + equal(one, "ab", 8); + (void) strcpy(one, ""); + (void) strncat(one, "cd", 99); + equal(one, "cd", 9); + + (void) strcpy(one, "ab"); + (void) strncat(one, "cdef", 2); + equal(one, "abcd", 10); /* Count-limited. */ + + (void) strncat(one, "gh", 0); + equal(one, "abcd", 11); /* Zero count. */ + + (void) strncat(one, "gh", 2); + equal(one, "abcdgh", 12); /* Count and length equal. */ + + /* strncmp - first test as strcmp with big counts, + then test count code. */ + it = "strncmp"; + check(strncmp("", "", 99) == 0, 1); /* Trivial case. */ + check(strncmp("a", "a", 99) == 0, 2); /* Identity. */ + check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */ + check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */ + check(strncmp("abcd", "abc", 99) > 0, 5); + check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */ + check(strncmp("abce", "abcd", 99) > 0, 7); + check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */ + check(strncmp("a\203", "a\003", 2) > 0, 9); + check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */ + check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */ + check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */ + check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */ + + /* strncpy - testing is a bit different because of odd semantics. */ + it = "strncpy"; + check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 2); + equal(one, "xycdefgh", 3); /* Copy cut by count. */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */ + equal(one, "xyzdefgh", 4); + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */ + equal(one, "xyz", 5); + equal(one+4, "efgh", 6); /* Wrote too much? */ + + (void) strcpy(one, "abcdefgh"); + (void) strncpy(one, "xyz", 5); /* Copy includes padding. */ + equal(one, "xyz", 7); + equal(one+4, "", 8); + equal(one+5, "fgh", 9); + + (void) strcpy(one, "abc"); + (void) strncpy(one, "xyz", 0); /* Zero-length copy. */ + equal(one, "abc", 10); + + (void) strncpy(one, "", 2); /* Zero-length source. */ + equal(one, "", 11); + equal(one+1, "", 12); + equal(one+2, "c", 13); + + (void) strcpy(one, "hi there"); + (void) strncpy(two, one, 9); + equal(two, "hi there", 14); /* Just paranoia. */ + equal(one, "hi there", 15); /* Stomped on source? */ + + /* strlen. */ + it = "strlen"; + check(strlen("") == 0, 1); /* Empty. */ + check(strlen("a") == 1, 2); /* Single char. */ + check(strlen("abcd") == 4, 3); /* Multiple chars. */ + + /* strchr. */ + it = "strchr"; + check(strchr("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strchr(one, 'c') == one+2, 2); /* Basic test. */ + check(strchr(one, 'd') == one+3, 3); /* End of string. */ + check(strchr(one, 'a') == one, 4); /* Beginning. */ + check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(strchr(one, 'b') == one+1, 6); /* Finding first. */ + (void) strcpy(one, ""); + check(strchr(one, 'b') == NULL, 7); /* Empty string. */ + check(strchr(one, '\0') == one, 8); /* NUL in empty string. */ + +#if 0 + /* index - just like strchr. */ + it = "index"; + check(index("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(index(one, 'c') == one+2, 2); /* Basic test. */ + check(index(one, 'd') == one+3, 3); /* End of string. */ + check(index(one, 'a') == one, 4); /* Beginning. */ + check(index(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(index(one, 'b') == one+1, 6); /* Finding first. */ + (void) strcpy(one, ""); + check(index(one, 'b') == NULL, 7); /* Empty string. */ + check(index(one, '\0') == one, 8); /* NUL in empty string. */ +#endif + + /* strrchr. */ + it = "strrchr"; + check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strrchr(one, 'c') == one+2, 2); /* Basic test. */ + check(strrchr(one, 'd') == one+3, 3); /* End of string. */ + check(strrchr(one, 'a') == one, 4); /* Beginning. */ + check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(strrchr(one, 'b') == one+3, 6); /* Finding last. */ + (void) strcpy(one, ""); + check(strrchr(one, 'b') == NULL, 7); /* Empty string. */ + check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */ + +#if 0 + /* rindex - just like strrchr. */ + it = "rindex"; + check(rindex("abcd", 'z') == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(rindex(one, 'c') == one+2, 2); /* Basic test. */ + check(rindex(one, 'd') == one+3, 3); /* End of string. */ + check(rindex(one, 'a') == one, 4); /* Beginning. */ + check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(rindex(one, 'b') == one+3, 6); /* Finding last. */ + (void) strcpy(one, ""); + check(rindex(one, 'b') == NULL, 7); /* Empty string. */ + check(rindex(one, '\0') == one, 8); /* NUL in empty string. */ +#endif + + /* strpbrk - somewhat like strchr. */ + it = "strpbrk"; + check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(strpbrk(one, "c") == one+2, 2); /* Basic test. */ + check(strpbrk(one, "d") == one+3, 3); /* End of string. */ + check(strpbrk(one, "a") == one, 4); /* Beginning. */ + check(strpbrk(one, "") == NULL, 5); /* Empty search list. */ + check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */ + (void) strcpy(one, "abcabdea"); + check(strpbrk(one, "b") == one+1, 7); /* Finding first. */ + check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */ + check(strpbrk(one, "db") == one+1, 9); /* Another variant. */ + (void) strcpy(one, ""); + check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */ + check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */ + + /* strstr - somewhat like strchr. */ + it = "strstr"; + check(strstr("abcd", "z") == NULL, 1); /* Not found. */ + check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */ + (void) strcpy(one, "abcd"); + check(strstr(one, "c") == one+2, 3); /* Basic test. */ + check(strstr(one, "bc") == one+1, 4); /* Multichar. */ + check(strstr(one, "d") == one+3, 5); /* End of string. */ + check(strstr(one, "cd") == one+2, 6); /* Tail of string. */ + check(strstr(one, "abc") == one, 7); /* Beginning. */ + check(strstr(one, "abcd") == one, 8); /* Exact match. */ + check(strstr(one, "abcde") == NULL, 9); /* Too long. */ + check(strstr(one, "de") == NULL, 10); /* Past end. */ + check(strstr(one, "") == one, 11); /* Finding empty. */ + (void) strcpy(one, "ababa"); + check(strstr(one, "ba") == one+1, 12); /* Finding first. */ + (void) strcpy(one, ""); + check(strstr(one, "b") == NULL, 13); /* Empty string. */ + check(strstr(one, "") == one, 14); /* Empty in empty string. */ + (void) strcpy(one, "bcbca"); + check(strstr(one, "bca") == one+2, 15); /* False start. */ + (void) strcpy(one, "bbbcabbca"); + check(strstr(one, "bbca") == one+1, 16); /* With overlap. */ + + /* strspn. */ + it = "strspn"; + check(strspn("abcba", "abc") == 5, 1); /* Whole string. */ + check(strspn("abcba", "ab") == 2, 2); /* Partial. */ + check(strspn("abc", "qx") == 0, 3); /* None. */ + check(strspn("", "ab") == 0, 4); /* Null string. */ + check(strspn("abc", "") == 0, 5); /* Null search list. */ + + /* strcspn. */ + it = "strcspn"; + check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */ + check(strcspn("abcba", "cx") == 2, 2); /* Partial. */ + check(strcspn("abc", "abc") == 0, 3); /* None. */ + check(strcspn("", "ab") == 0, 4); /* Null string. */ + check(strcspn("abc", "") == 3, 5); /* Null search list. */ + + /* strtok - the hard one. */ + it = "strtok"; + (void) strcpy(one, "first, second, third"); + equal(strtok(one, ", "), "first", 1); /* Basic test. */ + equal(one, "first", 2); + equal(strtok((char *)NULL, ", "), "second", 3); + equal(strtok((char *)NULL, ", "), "third", 4); + check(strtok((char *)NULL, ", ") == NULL, 5); + (void) strcpy(one, ", first, "); + equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */ + check(strtok((char *)NULL, ", ") == NULL, 7); + (void) strcpy(one, "1a, 1b; 2a, 2b"); + equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */ + equal(strtok((char *)NULL, "; "), "1b", 9); + equal(strtok((char *)NULL, ", "), "2a", 10); + (void) strcpy(two, "x-y"); + equal(strtok(two, "-"), "x", 11); /* New string before done. */ + equal(strtok((char *)NULL, "-"), "y", 12); + check(strtok((char *)NULL, "-") == NULL, 13); + (void) strcpy(one, "a,b, c,, ,d"); + equal(strtok(one, ", "), "a", 14); /* Different separators. */ + equal(strtok((char *)NULL, ", "), "b", 15); + equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */ + equal(strtok((char *)NULL, " ,"), "d", 17); + check(strtok((char *)NULL, ", ") == NULL, 18); + check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */ + (void) strcpy(one, ", "); + check(strtok(one, ", ") == NULL, 20); /* No tokens. */ + (void) strcpy(one, ""); + check(strtok(one, ", ") == NULL, 21); /* Empty string. */ + (void) strcpy(one, "abc"); + equal(strtok(one, ", "), "abc", 22); /* No delimiters. */ + check(strtok((char *)NULL, ", ") == NULL, 23); + (void) strcpy(one, "abc"); + equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */ + check(strtok((char *)NULL, "") == NULL, 25); + (void) strcpy(one, "abcdefgh"); + (void) strcpy(one, "a,b,c"); + equal(strtok(one, ","), "a", 26); /* Basics again... */ + equal(strtok((char *)NULL, ","), "b", 27); + equal(strtok((char *)NULL, ","), "c", 28); + check(strtok((char *)NULL, ",") == NULL, 29); + equal(one+6, "gh", 30); /* Stomped past end? */ + equal(one, "a", 31); /* Stomped old tokens? */ + equal(one+2, "b", 32); + equal(one+4, "c", 33); + + /* memcmp. */ + it = "memcmp"; + check(memcmp("a", "a", 1) == 0, 1); /* Identity. */ + check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ + check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */ + check(memcmp("abce", "abcd", 4) > 0, 4); + check(memcmp("alph", "beta", 4) < 0, 5); + check(memcmp("a\203", "a\003", 2) > 0, 6); + check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */ + check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */ + + /* memchr. */ + it = "memchr"; + check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */ + (void) strcpy(one, "abcd"); + check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */ + check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */ + check(memchr(one, 'a', 4) == one, 4); /* Beginning. */ + check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */ + (void) strcpy(one, "ababa"); + check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */ + check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */ + check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */ + (void) strcpy(one, "a\203b"); + check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */ + + /* memcpy - need not work for overlap. */ + it = "memcpy"; + check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) memcpy(one+1, "xyz", 2); + equal(one, "axydefgh", 3); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) memcpy(one, "xyz", 0); + equal(one, "abc", 4); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) memcpy(two, one, 9); + equal(two, "hi there", 5); /* Just paranoia. */ + equal(one, "hi there", 6); /* Stomped on source? */ + + /* memmove - must work on overlap. */ + it = "memmove"; + check(memmove(one, "abc", 4) == one, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) memmove(one+1, "xyz", 2); + equal(one, "axydefgh", 3); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) memmove(one, "xyz", 0); + equal(one, "abc", 4); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) memmove(two, one, 9); + equal(two, "hi there", 5); /* Just paranoia. */ + equal(one, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, "abcdefgh"); + (void) memmove(one+1, one, 9); + equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */ + + (void) strcpy(one, "abcdefgh"); + (void) memmove(one+1, one+2, 7); + equal(one, "acdefgh", 8); /* Overlap, left-to-right. */ + + (void) strcpy(one, "abcdefgh"); + (void) memmove(one, one, 9); + equal(one, "abcdefgh", 9); /* 100% overlap. */ + + /* memccpy - first test like memcpy, then the search part + The SVID, the only place where memccpy is mentioned, says + overlap might fail, so we don't try it. Besides, it's hard + to see the rationale for a non-left-to-right memccpy. */ + it = "memccpy"; + check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */ + equal(one, "abc", 2); /* Did the copy go right? */ + + (void) strcpy(one, "abcdefgh"); + (void) memccpy(one+1, "xyz", 'q', 2); + equal(one, "axydefgh", 3); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) memccpy(one, "xyz", 'q', 0); + equal(one, "abc", 4); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) memccpy(two, one, 'q', 9); + equal(two, "hi there", 5); /* Just paranoia. */ + equal(one, "hi there", 6); /* Stomped on source? */ + + (void) strcpy(one, "abcdefgh"); + (void) strcpy(two, "horsefeathers"); + check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */ + equal(one, "abcdefgh", 8); /* Source intact? */ + equal(two, "abcdefeathers", 9); /* Copy correct? */ + + (void) strcpy(one, "abcd"); + (void) strcpy(two, "bumblebee"); + check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */ + equal(two, "aumblebee", 11); + check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */ + equal(two, "abcdlebee", 13); + (void) strcpy(one, "xyz"); + check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */ + equal(two, "xbcdlebee", 15); + + /* memset. */ + it = "memset"; + (void) strcpy(one, "abcdefgh"); + check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */ + equal(one, "axxxefgh", 2); /* Basic test. */ + + (void) memset(one+2, 'y', 0); + equal(one, "axxxefgh", 3); /* Zero-length set. */ + + (void) memset(one+5, 0, 1); + equal(one, "axxxe", 4); /* Zero fill. */ + equal(one+6, "gh", 5); /* And the leftover. */ + + (void) memset(one+2, 010045, 1); + equal(one, "ax\045xe", 6); /* Unsigned char convert. */ + + /* bcopy - much like memcpy. + Berklix manual is silent about overlap, so don't test it. */ + it = "bcopy"; + (void) bcopy("abc", one, 4); + equal(one, "abc", 1); /* Simple copy. */ + + (void) strcpy(one, "abcdefgh"); + (void) bcopy("xyz", one+1, 2); + equal(one, "axydefgh", 2); /* Basic test. */ + + (void) strcpy(one, "abc"); + (void) bcopy("xyz", one, 0); + equal(one, "abc", 3); /* Zero-length copy. */ + + (void) strcpy(one, "hi there"); + (void) strcpy(two, "foo"); + (void) bcopy(one, two, 9); + equal(two, "hi there", 4); /* Just paranoia. */ + equal(one, "hi there", 5); /* Stomped on source? */ + + /* bzero. */ + it = "bzero"; + (void) strcpy(one, "abcdef"); + bzero(one+2, 2); + equal(one, "ab", 1); /* Basic test. */ + equal(one+3, "", 2); + equal(one+4, "ef", 3); + + (void) strcpy(one, "abcdef"); + bzero(one+2, 0); + equal(one, "abcdef", 4); /* Zero-length copy. */ + +#if 0 + /* bcmp - somewhat like memcmp. */ + it = "bcmp"; + check(bcmp("a", "a", 1) == 0, 1); /* Identity. */ + check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ + check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */ + check(bcmp("abce", "abcd", 4) != 0, 4); + check(bcmp("alph", "beta", 4) != 0, 5); + check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */ + check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */ +#endif + + { + char text[] = "This,is,a,test"; + char *list = text; + it = "strsep"; + check (!strcmp ("This", strsep (&list, ",")), 1); + check (!strcmp ("is", strsep (&list, ",")), 2); + check (!strcmp ("a", strsep (&list, ",")), 3); + check (!strcmp ("test", strsep (&list, ",")), 4); + check (strsep (&list, ",") == NULL, 5); + } + + /* strerror - VERY system-dependent. */ + { + int f; + it = "strerror"; + f = __open("/", O_WRONLY); /* Should always fail. */ + check(f < 0 && errno > 0 && errno < _sys_nerr, 1); + equal(strerror(errno), _sys_errlist[errno], 2); + } + + { + int status; + if (errors == 0) + { + status = EXIT_SUCCESS; + puts("No errors."); + } + else + { + status = EXIT_FAILURE; + printf("%Z errors.\n", errors); + } + exit(status); + } +} diff --git a/strings.h b/strings.h new file mode 100644 index 0000000000..b1bb339d3d --- /dev/null +++ b/strings.h @@ -0,0 +1 @@ +#include <string/strings.h> diff --git a/sunrpc/.cvsignore b/sunrpc/.cvsignore new file mode 100644 index 0000000000..048c2371e5 --- /dev/null +++ b/sunrpc/.cvsignore @@ -0,0 +1,6 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* + +rpcsrc-4.0 diff --git a/sunrpc/Makefile b/sunrpc/Makefile new file mode 100644 index 0000000000..6a5f895722 --- /dev/null +++ b/sunrpc/Makefile @@ -0,0 +1,128 @@ +# Copyright (C) 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Sub-makefile for sunrpc portion of the library. +# +subdir := sunrpc + +# The code in this subdirectory is taken verbatim from Sun's RPCSRC-4.0 +# distribution. A few files needed trivial modifications to compile in the +# GNU environment; these changes are marked by comments that say +# `roland@gnu'. All the code from Sun's rpc, etc, and rpcgen +# subdirectories is in this directory; the rpc subdirectory contains only +# the header files. Other than that, several files were renamed so as not +# to exceed 14-character file name limits: +# +# authunix_prot.c -> authuxprot.c +# bindresvport.c -> bindrsvprt.c +# clnt_generic.c -> clnt_gen.c +# clnt_perror.c -> clnt_perr.c +# clnt_simple.c -> clnt_simp.c +# get_myaddress.c -> get_myaddr.c +# pmap_getmaps.c -> pm_getmaps.c +# pmap_getport.c -> pm_getport.c +# rpc_callmsg.c -> rpc_cmsg.c +# rpc_commondata.c -> rpc_common.c +# rpc_dtablesize.c -> rpc_dtable.c +# svc_auth_unix.c -> svc_authux.c +# xdr_reference.c -> xdr_ref.c +# rpcsvc/bootparam_prot.x -> rpcsvc/bootparam.x + +headers = $(addprefix rpc/,auth.h auth_unix.h clnt.h netdb.h pmap_clnt.h \ + pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h \ + svc_auth.h types.h xdr.h) \ + $(rpcsvc:%=rpcsvc/%) $(rpcsvc:%.x=rpcsvc/%.h) +rpcsvc = bootparam.x nlm_prot.x rstat.x \ + yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \ + rnusers.x spray.x nfs_prot.x rquota.x yp.x +install-others = $(includedir)/rpcsvc/bootparam_prot.h \ + $(sysconfdir)/rpc +generated = $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) + +routines := auth_none auth_unix authuxprot bindrsvprt \ + clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \ + clnt_udp rpc_dtable get_myaddr getrpcent getrpcport \ + pmap_clnt pm_getmaps pm_getport pmap_prot \ + pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \ + svc svc_auth svc_authux svc_raw svc_run svc_simple \ + svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \ + xdr_rec xdr_ref xdr_stdio + +install-lib := librpcsvc.a +install-bin := rpcgen +install-sbin := rpcinfo portmap +rpcsvc-objs = $(rpcsvc:%.x=x%.o) +rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ + rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o +extra-objs = $(rpcgen-objs) $(rpcsvc-objs) +omit-deps = $(basename $(rpcsvc-objs)) +# These headers are part of rpcgen. +distribute := rpc_util.h rpc_parse.h rpc_scan.h $(rpcgen-objs:.o=.c) etc.rpc + +others := portmap rpcinfo + +# Sun's code is not too clean. +override +gccwarn := -w + +include ../Rules + +$(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) $(libc.a) + $(+link) + +rpcgen-cmd = $(dir $(word 2,$^))$(notdir $(word 2,$^)) + +# The proper file name is longer than 14 chars, so we install it under +# a shorter name. But if the filesystem can handle it, we want to +# install under the proper name as well. +$(includedir)/rpcsvc/bootparam_prot.h: $(includedir)/rpcsvc/bootparam.h + @echo It is safe to ignore an error here if this file name is too long. + -$(do-install) + +# Install the rpc data base file. +$(sysconfdir)/rpc: etc.rpc + $(do-install) + +defines := $(defines) -D_PATH_RPC='"$(sysconfdir)/rpc"' + +# Build the `rpcsvc' library of XDR functions. + +lib: $(objpfx)librpcsvc.a + +$(objpfx)librpcsvc.a: $(addprefix $(objpfx),$(rpcsvc-objs)) +# This library is small enough that it's simplest to recreate the archive +# from scratch each time. + rm -f $@ +ifdef objdir + cd $(objdir); $(AR) cq$(verbose) $@ $(^:$(objpfx)%=%) +else + $(AR) cq$(verbose) $@ $^ +endif + $(RANLIB) $@ + +# Generate the rpcsvc headers with rpcgen. +$(objpfx)rpcsvc/%.h: rpcsvc/%.x $(objpfx)rpcgen + $(make-target-directory) + $(rpcgen-cmd) -h $< -o $@ +# Generate the rpcsvc XDR functions with rpcgen. +$(objpfx)x%.c: rpcsvc/%.x $(objpfx)rpcgen + $(rpcgen-cmd) -c $< -o $@ +# The generated source files depend on the corresponding generated headers. +# Gratuitous dependency on generated .c file here just gets it mentioned to +# avoid being an intermediate file and getting removed. +$(rpcsvc:%.x=$(objpfx)x%.o): $(objpfx)x%.o: $(objpfx)x%.c $(objpfx)rpcsvc/%.h diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c new file mode 100644 index 0000000000..630037fb47 --- /dev/null +++ b/sunrpc/auth_none.c @@ -0,0 +1,133 @@ +/* @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_none.c + * Creates a client authentication handle for passing "null" + * credentials and verifiers to remote systems. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#define MAX_MARSHEL_SIZE 20 + +/* + * Authenticator operations routines + */ +static void authnone_verf(); +static void authnone_destroy(); +static bool_t authnone_marshal(); +static bool_t authnone_validate(); +static bool_t authnone_refresh(); + +static struct auth_ops ops = { + authnone_verf, + authnone_marshal, + authnone_validate, + authnone_refresh, + authnone_destroy +}; + +static struct authnone_private { + AUTH no_client; + char marshalled_client[MAX_MARSHEL_SIZE]; + u_int mcnt; +} *authnone_private; + +AUTH * +authnone_create() +{ + register struct authnone_private *ap = authnone_private; + XDR xdr_stream; + register XDR *xdrs; + + if (ap == 0) { + ap = (struct authnone_private *)calloc(1, sizeof (*ap)); + if (ap == 0) + return (0); + authnone_private = ap; + } + if (!ap->mcnt) { + ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; + ap->no_client.ah_ops = &ops; + xdrs = &xdr_stream; + xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, + XDR_ENCODE); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); + ap->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + } + return (&ap->no_client); +} + +/*ARGSUSED*/ +static bool_t +authnone_marshal(client, xdrs) + AUTH *client; + XDR *xdrs; +{ + register struct authnone_private *ap = authnone_private; + + if (ap == 0) + return (0); + return ((*xdrs->x_ops->x_putbytes)(xdrs, + ap->marshalled_client, ap->mcnt)); +} + +static void +authnone_verf() +{ +} + +static bool_t +authnone_validate() +{ + + return (TRUE); +} + +static bool_t +authnone_refresh() +{ + + return (FALSE); +} + +static void +authnone_destroy() +{ +} diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c new file mode 100644 index 0000000000..87ff2b648b --- /dev/null +++ b/sunrpc/auth_unix.c @@ -0,0 +1,319 @@ +/* @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_unix.c, Implements UNIX style authentication parameters. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The system is very weak. The client uses no encryption for it's + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + * + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * Unix authenticator operations vector + */ +static void authunix_nextverf(); +static bool_t authunix_marshal(); +static bool_t authunix_validate(); +static bool_t authunix_refresh(); +static void authunix_destroy(); + +static struct auth_ops auth_unix_ops = { + authunix_nextverf, + authunix_marshal, + authunix_validate, + authunix_refresh, + authunix_destroy +}; + +/* + * This struct is pointed to by the ah_private field of an auth_handle. + */ +struct audata { + struct opaque_auth au_origcred; /* original credentials */ + struct opaque_auth au_shcred; /* short hand cred */ + u_long au_shfaults; /* short hand cache faults */ + char au_marshed[MAX_AUTH_BYTES]; + u_int au_mpos; /* xdr pos at end of marshed */ +}; +#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) + +static bool_t marshal_new_auth(); + + +/* + * Create a unix style authenticator. + * Returns an auth handle with the given stuff in it. + */ +AUTH * +authunix_create(machname, uid, gid, len, aup_gids) + char *machname; + int uid; + int gid; + register int len; + int *aup_gids; +{ + struct authunix_parms aup; + char mymem[MAX_AUTH_BYTES]; + struct timeval now; + XDR xdrs; + register AUTH *auth; + register struct audata *au; + + /* + * Allocate and set up auth handle + */ + auth = (AUTH *)mem_alloc(sizeof(*auth)); +#ifndef KERNEL + if (auth == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + au = (struct audata *)mem_alloc(sizeof(*au)); +#ifndef KERNEL + if (au == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + auth->ah_ops = &auth_unix_ops; + auth->ah_private = (caddr_t)au; + auth->ah_verf = au->au_shcred = _null_auth; + au->au_shfaults = 0; + + /* + * fill in param struct from the given params + */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + aup.aup_machname = machname; + aup.aup_uid = uid; + aup.aup_gid = gid; + aup.aup_len = (u_int)len; + aup.aup_gids = aup_gids; + + /* + * Serialize the parameters into origcred + */ + xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); + if (! xdr_authunix_parms(&xdrs, &aup)) + abort(); + au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); + au->au_origcred.oa_flavor = AUTH_UNIX; +#ifdef KERNEL + au->au_origcred.oa_base = mem_alloc((u_int) len); +#else + if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + bcopy(mymem, au->au_origcred.oa_base, (u_int)len); + + /* + * set auth handle to reflect new cred. + */ + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); + return (auth); +} + +/* + * Returns an auth handle with parameters determined by doing lots of + * syscalls. + */ +AUTH * +authunix_create_default() +{ + register int len; + char machname[MAX_MACHINE_NAME + 1]; + register int uid; + register int gid; + int gids[NGRPS]; + + if (gethostname(machname, MAX_MACHINE_NAME) == -1) + abort(); + machname[MAX_MACHINE_NAME] = 0; + uid = geteuid(); + gid = getegid(); + if ((len = getgroups(NGRPS, gids)) < 0) + abort(); + return (authunix_create(machname, uid, gid, len, gids)); +} + +/* + * authunix operations + */ + +static void +authunix_nextverf(auth) + AUTH *auth; +{ + /* no action necessary */ +} + +static bool_t +authunix_marshal(auth, xdrs) + AUTH *auth; + XDR *xdrs; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); +} + +static bool_t +authunix_validate(auth, verf) + register AUTH *auth; + struct opaque_auth verf; +{ + register struct audata *au; + XDR xdrs; + + if (verf.oa_flavor == AUTH_SHORT) { + au = AUTH_PRIVATE(auth); + xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE); + + if (au->au_shcred.oa_base != NULL) { + mem_free(au->au_shcred.oa_base, + au->au_shcred.oa_length); + au->au_shcred.oa_base = NULL; + } + if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { + auth->ah_cred = au->au_shcred; + } else { + xdrs.x_op = XDR_FREE; + (void)xdr_opaque_auth(&xdrs, &au->au_shcred); + au->au_shcred.oa_base = NULL; + auth->ah_cred = au->au_origcred; + } + marshal_new_auth(auth); + } + return (TRUE); +} + +static bool_t +authunix_refresh(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + struct authunix_parms aup; + struct timeval now; + XDR xdrs; + register int stat; + + if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { + /* there is no hope. Punt */ + return (FALSE); + } + au->au_shfaults ++; + + /* first deserialize the creds back into a struct authunix_parms */ + aup.aup_machname = NULL; + aup.aup_gids = (int *)NULL; + xdrmem_create(&xdrs, au->au_origcred.oa_base, + au->au_origcred.oa_length, XDR_DECODE); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + + /* update the time and serialize in place */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + xdrs.x_op = XDR_ENCODE; + XDR_SETPOS(&xdrs, 0); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); +done: + /* free the struct authunix_parms created by deserializing */ + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, &aup); + XDR_DESTROY(&xdrs); + return (stat); +} + +static void +authunix_destroy(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); + + if (au->au_shcred.oa_base != NULL) + mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); + + mem_free(auth->ah_private, sizeof(struct audata)); + + if (auth->ah_verf.oa_base != NULL) + mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); + + mem_free((caddr_t)auth, sizeof(*auth)); +} + +/* + * Marshals (pre-serializes) an auth struct. + * sets private data, au_marshed and au_mpos + */ +static bool_t +marshal_new_auth(auth) + register AUTH *auth; +{ + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + register struct audata *au = AUTH_PRIVATE(auth); + + xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); + if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || + (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { + perror("auth_none.c - Fatal marshalling problem"); + } else { + au->au_mpos = XDR_GETPOS(xdrs); + } + XDR_DESTROY(xdrs); +} diff --git a/sunrpc/authuxprot.c b/sunrpc/authuxprot.c new file mode 100644 index 0000000000..a60d99a57b --- /dev/null +++ b/sunrpc/authuxprot.c @@ -0,0 +1,66 @@ +/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * authunix_prot.c + * XDR for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * XDR for unix authentication parameters. + */ +bool_t +xdr_authunix_parms(xdrs, p) + register XDR *xdrs; + register struct authunix_parms *p; +{ + + if (xdr_u_long(xdrs, &(p->aup_time)) + && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) + && xdr_int(xdrs, &(p->aup_uid)) + && xdr_int(xdrs, &(p->aup_gid)) + && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), + &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) { + return (TRUE); + } + return (FALSE); +} + diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c new file mode 100644 index 0000000000..71803dd41c --- /dev/null +++ b/sunrpc/bindrsvprt.c @@ -0,0 +1,78 @@ +static char sccsid[] = "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI"; +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + */ + +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/socket.h> +#include <netinet/in.h> + +/* + * Bind a socket to a privileged IP port + */ +bindresvport(sd, sin) + int sd; + struct sockaddr_in *sin; +{ + int res; + static short port; + struct sockaddr_in myaddr; + extern int errno; + int i; + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + + if (sin == (struct sockaddr_in *)0) { + sin = &myaddr; + bzero(sin, sizeof (*sin)); + sin->sin_family = AF_INET; + } else if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + return (-1); + } + if (port == 0) { + port = (getpid() % NPORTS) + STARTPORT; + } + res = -1; + errno = EADDRINUSE; + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { + sin->sin_port = htons(port++); + if (port > ENDPORT) { + port = STARTPORT; + } + res = bind(sd, sin, sizeof(struct sockaddr_in)); + } + return (res); +} diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c new file mode 100644 index 0000000000..e54e77828b --- /dev/null +++ b/sunrpc/clnt_gen.c @@ -0,0 +1,110 @@ +/* @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI"; +#endif +/* + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/errno.h> +#include <netdb.h> + +/* + * Generic client creation: takes (hostname, program-number, protocol) and + * returns client handle. Default options are set, which the user can + * change using the rpc equivalent of ioctl()'s. + */ +CLIENT * +clnt_create(hostname, prog, vers, proto) + char *hostname; + unsigned prog; + unsigned vers; + char *proto; +{ + struct hostent *h; + struct protoent *p; + struct sockaddr_in sin; + int sock; + struct timeval tv; + CLIENT *client; + + h = gethostbyname(hostname); + if (h == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNHOST; + return (NULL); + } + if (h->h_addrtype != AF_INET) { + /* + * Only support INET for now + */ + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; + return (NULL); + } + sin.sin_family = h->h_addrtype; + sin.sin_port = 0; + bzero(sin.sin_zero, sizeof(sin.sin_zero)); + bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length); + p = getprotobyname(proto); + if (p == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + sock = RPC_ANYSOCK; + switch (p->p_proto) { + case IPPROTO_UDP: + tv.tv_sec = 5; + tv.tv_usec = 0; + client = clntudp_create(&sin, prog, vers, tv, &sock); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + case IPPROTO_TCP: + client = clnttcp_create(&sin, prog, vers, &sock, 0, 0); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + tv.tv_usec = 0; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + default: + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + return (client); +} diff --git a/sunrpc/clnt_perr.c b/sunrpc/clnt_perr.c new file mode 100644 index 0000000000..1876c7f163 --- /dev/null +++ b/sunrpc/clnt_perr.c @@ -0,0 +1,305 @@ +/* @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_perror.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/auth.h> +#include <rpc/clnt.h> + +extern char *sys_errlist[]; +/* extern char *sprintf(); --roland@gnu */ +static char *auth_errmsg(); + +extern char *strcpy(); + +static char *buf; + +static char * +_buf() +{ + + if (buf == 0) + buf = (char *)malloc(256); + return (buf); +} + +/* + * Print reply error info + */ +char * +clnt_sperror(rpch, s) + CLIENT *rpch; + char *s; +{ + struct rpc_err e; + void clnt_perrno(); + char *err; + char *str = _buf(); + char *strstart = str; + + if (str == 0) + return (0); + CLNT_GETERR(rpch, &e); + + (void) sprintf(str, "%s: ", s); + str += strlen(str); + + (void) strcpy(str, clnt_sperrno(e.re_status)); + str += strlen(str); + + switch (e.re_status) { + case RPC_SUCCESS: + case RPC_CANTENCODEARGS: + case RPC_CANTDECODERES: + case RPC_TIMEDOUT: + case RPC_PROGUNAVAIL: + case RPC_PROCUNAVAIL: + case RPC_CANTDECODEARGS: + case RPC_SYSTEMERROR: + case RPC_UNKNOWNHOST: + case RPC_UNKNOWNPROTO: + case RPC_PMAPFAILURE: + case RPC_PROGNOTREGISTERED: + case RPC_FAILED: + break; + + case RPC_CANTSEND: + case RPC_CANTRECV: + (void) sprintf(str, "; errno = %s", + sys_errlist[e.re_errno]); + str += strlen(str); + break; + + case RPC_VERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + case RPC_AUTHERROR: + err = auth_errmsg(e.re_why); + (void) sprintf(str,"; why = "); + str += strlen(str); + if (err != NULL) { + (void) sprintf(str, "%s",err); + } else { + (void) sprintf(str, + "(unknown authentication error - %d)", + (int) e.re_why); + } + str += strlen(str); + break; + + case RPC_PROGVERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + default: /* unknown */ + (void) sprintf(str, + "; s1 = %lu, s2 = %lu", + e.re_lb.s1, e.re_lb.s2); + str += strlen(str); + break; + } + (void) sprintf(str, "\n"); + return(strstart) ; +} + +void +clnt_perror(rpch, s) + CLIENT *rpch; + char *s; +{ + (void) fprintf(stderr,"%s",clnt_sperror(rpch,s)); +} + + +struct rpc_errtab { + enum clnt_stat status; + char *message; +}; + +static struct rpc_errtab rpc_errlist[] = { + { RPC_SUCCESS, + "RPC: Success" }, + { RPC_CANTENCODEARGS, + "RPC: Can't encode arguments" }, + { RPC_CANTDECODERES, + "RPC: Can't decode result" }, + { RPC_CANTSEND, + "RPC: Unable to send" }, + { RPC_CANTRECV, + "RPC: Unable to receive" }, + { RPC_TIMEDOUT, + "RPC: Timed out" }, + { RPC_VERSMISMATCH, + "RPC: Incompatible versions of RPC" }, + { RPC_AUTHERROR, + "RPC: Authentication error" }, + { RPC_PROGUNAVAIL, + "RPC: Program unavailable" }, + { RPC_PROGVERSMISMATCH, + "RPC: Program/version mismatch" }, + { RPC_PROCUNAVAIL, + "RPC: Procedure unavailable" }, + { RPC_CANTDECODEARGS, + "RPC: Server can't decode arguments" }, + { RPC_SYSTEMERROR, + "RPC: Remote system error" }, + { RPC_UNKNOWNHOST, + "RPC: Unknown host" }, + { RPC_UNKNOWNPROTO, + "RPC: Unknown protocol" }, + { RPC_PMAPFAILURE, + "RPC: Port mapper failure" }, + { RPC_PROGNOTREGISTERED, + "RPC: Program not registered"}, + { RPC_FAILED, + "RPC: Failed (unspecified error)"} +}; + + +/* + * This interface for use by clntrpc + */ +char * +clnt_sperrno(stat) + enum clnt_stat stat; +{ + int i; + + for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { + if (rpc_errlist[i].status == stat) { + return (rpc_errlist[i].message); + } + } + return ("RPC: (unknown error code)"); +} + +void +clnt_perrno(num) + enum clnt_stat num; +{ + (void) fprintf(stderr,"%s",clnt_sperrno(num)); +} + + +char * +clnt_spcreateerror(s) + char *s; +{ + extern int sys_nerr; + extern char *sys_errlist[]; + char *str = _buf(); + + if (str == 0) + return(0); + (void) sprintf(str, "%s: ", s); + (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); + switch (rpc_createerr.cf_stat) { + case RPC_PMAPFAILURE: + (void) strcat(str, " - "); + (void) strcat(str, + clnt_sperrno(rpc_createerr.cf_error.re_status)); + break; + + case RPC_SYSTEMERROR: + (void) strcat(str, " - "); + if (rpc_createerr.cf_error.re_errno > 0 + && rpc_createerr.cf_error.re_errno < sys_nerr) + (void) strcat(str, + sys_errlist[rpc_createerr.cf_error.re_errno]); + else + (void) sprintf(&str[strlen(str)], "Error %d", + rpc_createerr.cf_error.re_errno); + break; + } + (void) strcat(str, "\n"); + return (str); +} + +void +clnt_pcreateerror(s) + char *s; +{ + (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); +} + +struct auth_errtab { + enum auth_stat status; + char *message; +}; + +static struct auth_errtab auth_errlist[] = { + { AUTH_OK, + "Authentication OK" }, + { AUTH_BADCRED, + "Invalid client credential" }, + { AUTH_REJECTEDCRED, + "Server rejected credential" }, + { AUTH_BADVERF, + "Invalid client verifier" }, + { AUTH_REJECTEDVERF, + "Server rejected verifier" }, + { AUTH_TOOWEAK, + "Client credential too weak" }, + { AUTH_INVALIDRESP, + "Invalid server verifier" }, + { AUTH_FAILED, + "Failed (unspecified error)" }, +}; + +static char * +auth_errmsg(stat) + enum auth_stat stat; +{ + int i; + + for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) { + if (auth_errlist[i].status == stat) { + return(auth_errlist[i].message); + } + } + return(NULL); +} diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c new file mode 100644 index 0000000000..89059ae2da --- /dev/null +++ b/sunrpc/clnt_raw.c @@ -0,0 +1,238 @@ +/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_raw.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Memory based rpc for simple testing and timing. + * Interface to create an rpc client and server in the same process. + * This lets us similate rpc and get round trip overhead, without + * any interference from the kernal. + */ + +#include <rpc/rpc.h> + +#define MCALL_MSG_SIZE 24 + +/* + * This is the "network" we will be moving stuff over. + */ +static struct clntraw_private { + CLIENT client_object; + XDR xdr_stream; + char _raw_buf[UDPMSGSIZE]; + char mashl_callmsg[MCALL_MSG_SIZE]; + u_int mcnt; +} *clntraw_private; + +static enum clnt_stat clntraw_call(); +static void clntraw_abort(); +static void clntraw_geterr(); +static bool_t clntraw_freeres(); +static bool_t clntraw_control(); +static void clntraw_destroy(); + +static struct clnt_ops client_ops = { + clntraw_call, + clntraw_abort, + clntraw_geterr, + clntraw_freeres, + clntraw_destroy, + clntraw_control +}; + +void svc_getreq(); + +/* + * Create a client handle for memory based rpc. + */ +CLIENT * +clntraw_create(prog, vers) + u_long prog; + u_long vers; +{ + register struct clntraw_private *clp = clntraw_private; + struct rpc_msg call_msg; + XDR *xdrs = &clp->xdr_stream; + CLIENT *client = &clp->client_object; + + if (clp == 0) { + clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); + if (clp == 0) + return (0); + clntraw_private = clp; + } + /* + * pre-serialize the staic part of the call msg and stash it away + */ + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); + if (! xdr_callhdr(xdrs, &call_msg)) { + perror("clnt_raw.c - Fatal header serialization error."); + } + clp->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + + /* + * Set xdrmem for client/server shared buffer + */ + xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); + + /* + * create client handle + */ + client->cl_ops = &client_ops; + client->cl_auth = authnone_create(); + return (client); +} + +static enum clnt_stat +clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) + CLIENT *h; + u_long proc; + xdrproc_t xargs; + caddr_t argsp; + xdrproc_t xresults; + caddr_t resultsp; + struct timeval timeout; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + struct rpc_msg msg; + enum clnt_stat status; + struct rpc_err error; + + if (clp == 0) + return (RPC_FAILED); +call_again: + /* + * send request + */ + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; + if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) { + return (RPC_CANTENCODEARGS); + } + (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ + + /* + * We have to call server input routine here because this is + * all going on in one process. Yuk. + */ + svc_getreq(1); + + /* + * get results + */ + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = resultsp; + msg.acpted_rply.ar_results.proc = xresults; + if (! xdr_replymsg(xdrs, &msg)) + return (RPC_CANTDECODERES); + _seterr_reply(&msg, &error); + status = error.re_status; + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + } /* end successful completion */ + else { + if (AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + if (msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); + } + } + + return (status); +} + +static void +clntraw_geterr() +{ +} + + +static bool_t +clntraw_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + bool_t rval; + + if (clp == 0) + { + rval = (bool_t) RPC_FAILED; + return (rval); + } + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntraw_abort() +{ +} + +static bool_t +clntraw_control() +{ + return (FALSE); +} + +static void +clntraw_destroy() +{ +} diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c new file mode 100644 index 0000000000..043ce0a3eb --- /dev/null +++ b/sunrpc/clnt_simp.c @@ -0,0 +1,112 @@ +/* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <strings.h> + +static struct callrpc_private { + CLIENT *client; + int socket; + int oldprognum, oldversnum, valid; + char *oldhost; +} *callrpc_private; + +callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) + char *host; + xdrproc_t inproc, outproc; + char *in, *out; +{ + register struct callrpc_private *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent *hp; + struct timeval timeout, tottimeout; + + if (crp == 0) { + crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); + if (crp == 0) + return (0); + callrpc_private = crp; + } + if (crp->oldhost == NULL) { + crp->oldhost = malloc(256); + crp->oldhost[0] = 0; + crp->socket = RPC_ANYSOCK; + } + if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum + && strcmp(crp->oldhost, host) == 0) { + /* reuse old client */ + } else { + crp->valid = 0; + (void)close(crp->socket); + crp->socket = RPC_ANYSOCK; + if (crp->client) { + clnt_destroy(crp->client); + crp->client = NULL; + } + if ((hp = gethostbyname(host)) == NULL) + return ((int) RPC_UNKNOWNHOST); + timeout.tv_usec = 0; + timeout.tv_sec = 5; + bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, + (u_long)versnum, timeout, &crp->socket)) == NULL) + return ((int) rpc_createerr.cf_stat); + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strcpy(crp->oldhost, host); + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call(crp->client, procnum, inproc, in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return ((int) clnt_stat); +} diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c new file mode 100644 index 0000000000..2222bc6577 --- /dev/null +++ b/sunrpc/clnt_tcp.c @@ -0,0 +1,466 @@ +/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_tcp.c, Implements a TCP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * TCP based RPC supports 'batched calls'. + * A sequence of calls may be batched-up in a send buffer. The rpc call + * return immediately to the client even though the call was not necessarily + * sent. The batching occurs if the results' xdr routine is NULL (0) AND + * the rpc timeout value is zero (see clnt.h, rpc). + * + * Clients should NOT casually batch calls that in fact return results; that is, + * the server side should be aware that a call is batched and not produce any + * return message. Batched calls that produce many result messages can + * deadlock (netlock) the client and the server.... + * + * Now go hang yourself. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +#define MCALL_MSG_SIZE 24 + +extern int errno; + +static int readtcp(); +static int writetcp(); + +static enum clnt_stat clnttcp_call(); +static void clnttcp_abort(); +static void clnttcp_geterr(); +static bool_t clnttcp_freeres(); +static bool_t clnttcp_control(); +static void clnttcp_destroy(); + +static struct clnt_ops tcp_ops = { + clnttcp_call, + clnttcp_abort, + clnttcp_geterr, + clnttcp_freeres, + clnttcp_destroy, + clnttcp_control +}; + +struct ct_data { + int ct_sock; + bool_t ct_closeit; + struct timeval ct_wait; + bool_t ct_waitset; /* wait set by clnt_control? */ + struct sockaddr_in ct_addr; + struct rpc_err ct_error; + char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ + u_int ct_mpos; /* pos after marshal */ + XDR ct_xdrs; +}; + +/* + * Create a client handle for a tcp/ip connection. + * If *sockp<0, *sockp is set to a newly created TCP socket and it is + * connected to raddr. If *sockp non-negative then + * raddr is ignored. The rpc/tcp package does buffering + * similar to stdio, so the client must pick send and receive buffer sizes,]; + * 0 => use the default. + * If raddr->sin_port is 0, then a binder on the remote machine is + * consulted for the right port number. + * NB: *sockp is copied into a private area. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this + * something more useful. + */ +CLIENT * +clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long prog; + u_long vers; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *h; + register struct ct_data *ct; + struct timeval now; + struct rpc_msg call_msg; + + h = (CLIENT *)mem_alloc(sizeof(*h)); + if (h == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + ct = (struct ct_data *)mem_alloc(sizeof(*ct)); + if (ct == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + + /* + * If no port number given ask the pmap for one + */ + if (raddr->sin_port == 0) { + u_short port; + if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); + } + raddr->sin_port = htons(port); + } + + /* + * If no socket given, open one + */ + if (*sockp < 0) { + *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + if ((*sockp < 0) + || (connect(*sockp, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + (void)close(*sockp); + goto fooy; + } + ct->ct_closeit = TRUE; + } else { + ct->ct_closeit = FALSE; + } + + /* + * Set up private data struct + */ + ct->ct_sock = *sockp; + ct->ct_wait.tv_usec = 0; + ct->ct_waitset = FALSE; + ct->ct_addr = *raddr; + + /* + * Initialize call message + */ + (void)gettimeofday(&now, (struct timezone *)0); + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the staic part of the call msg and stash it away + */ + xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, + XDR_ENCODE); + if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { + if (ct->ct_closeit) { + (void)close(*sockp); + } + goto fooy; + } + ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); + XDR_DESTROY(&(ct->ct_xdrs)); + + /* + * Create a client handle which uses xdrrec for serialization + * and authnone for authentication. + */ + xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, + (caddr_t)ct, readtcp, writetcp); + h->cl_ops = &tcp_ops; + h->cl_private = (caddr_t) ct; + h->cl_auth = authnone_create(); + return (h); + +fooy: + /* + * Something goofed, free stuff and barf + */ + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +static enum clnt_stat +clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + register CLIENT *h; + u_long proc; + xdrproc_t xdr_args; + caddr_t args_ptr; + xdrproc_t xdr_results; + caddr_t results_ptr; + struct timeval timeout; +{ + register struct ct_data *ct = (struct ct_data *) h->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */ + register bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 + && timeout.tv_usec == 0) ? FALSE : TRUE; + +call_again: + xdrs->x_op = XDR_ENCODE; + ct->ct_error.re_status = RPC_SUCCESS; + x_id = ntohl(--(*msg_x_id)); + if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xdr_args)(xdrs, args_ptr))) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTENCODEARGS; + (void)xdrrec_endofrecord(xdrs, TRUE); + return (ct->ct_error.re_status); + } + if (! xdrrec_endofrecord(xdrs, shipnow)) + return (ct->ct_error.re_status = RPC_CANTSEND); + if (! shipnow) + return (RPC_SUCCESS); + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return(ct->ct_error.re_status = RPC_TIMEDOUT); + } + + + /* + * Keep receiving until we get a valid transaction id + */ + xdrs->x_op = XDR_DECODE; + while (TRUE) { + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = NULL; + reply_msg.acpted_rply.ar_results.proc = xdr_void; + if (! xdrrec_skiprecord(xdrs)) + return (ct->ct_error.re_status); + /* now decode and validate the response header */ + if (! xdr_replymsg(xdrs, &reply_msg)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; + return (ct->ct_error.re_status); + } + if (reply_msg.rm_xid == x_id) + break; + } + + /* + * process header + */ + _seterr_reply(&reply_msg, &(ct->ct_error)); + if (ct->ct_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { + ct->ct_error.re_status = RPC_AUTHERROR; + ct->ct_error.re_why = AUTH_INVALIDRESP; + } else if (! (*xdr_results)(xdrs, results_ptr)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; + } + /* free verifier ... */ + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (refreshes-- && AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + return (ct->ct_error.re_status); +} + +static void +clnttcp_geterr(h, errp) + CLIENT *h; + struct rpc_err *errp; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + *errp = ct->ct_error; +} + +static bool_t +clnttcp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clnttcp_abort() +{ +} + +static bool_t +clnttcp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + ct->ct_wait = *(struct timeval *)info; + ct->ct_waitset = TRUE; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = ct->ct_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = ct->ct_addr; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +static void +clnttcp_destroy(h) + CLIENT *h; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + if (ct->ct_closeit) { + (void)close(ct->ct_sock); + } + XDR_DESTROY(&(ct->ct_xdrs)); + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); +} + +/* + * Interface between xdr serializer and tcp connection. + * Behaves like the system calls, read & write, but keeps some error state + * around for the rpc level. + */ +static int +readtcp(ct, buf, len) + register struct ct_data *ct; + caddr_t buf; + register int len; +{ +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + if (len == 0) + return (0); + FD_ZERO(&mask); + FD_SET(ct->ct_sock, &mask); +#else + register int mask = 1 << (ct->ct_sock); + int readfds; + + if (len == 0) + return (0); + +#endif /* def FD_SETSIZE */ + while (TRUE) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &(ct->ct_wait))) { + case 0: + ct->ct_error.re_status = RPC_TIMEDOUT; + return (-1); + + case -1: + if (errno == EINTR) + continue; + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = errno; + return (-1); + } + break; + } + switch (len = read(ct->ct_sock, buf, len)) { + + case 0: + /* premature eof */ + ct->ct_error.re_errno = ECONNRESET; + ct->ct_error.re_status = RPC_CANTRECV; + len = -1; /* it's really an error */ + break; + + case -1: + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTRECV; + break; + } + return (len); +} + +static int +writetcp(ct, buf, len) + struct ct_data *ct; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(ct->ct_sock, buf, cnt)) == -1) { + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTSEND; + return (-1); + } + } + return (len); +} diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c new file mode 100644 index 0000000000..815cbb4ed2 --- /dev/null +++ b/sunrpc/clnt_udp.c @@ -0,0 +1,442 @@ +/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_udp.c, Implements a UDP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +extern int errno; + +/* + * UDP bases client side rpc operations + */ +static enum clnt_stat clntudp_call(); +static void clntudp_abort(); +static void clntudp_geterr(); +static bool_t clntudp_freeres(); +static bool_t clntudp_control(); +static void clntudp_destroy(); + +static struct clnt_ops udp_ops = { + clntudp_call, + clntudp_abort, + clntudp_geterr, + clntudp_freeres, + clntudp_destroy, + clntudp_control +}; + +/* + * Private data kept per client handle + */ +struct cu_data { + int cu_sock; + bool_t cu_closeit; + struct sockaddr_in cu_raddr; + int cu_rlen; + struct timeval cu_wait; + struct timeval cu_total; + struct rpc_err cu_error; + XDR cu_outxdrs; + u_int cu_xdrpos; + u_int cu_sendsz; + char *cu_outbuf; + u_int cu_recvsz; + char cu_inbuf[1]; +}; + +/* + * Create a UDP based client handle. + * If *sockp<0, *sockp is set to a newly created UPD socket. + * If raddr->sin_port is 0 a binder on the remote machine + * is consulted for the correct port number. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is initialized to null authentication. + * Caller may wish to set this something more useful. + * + * wait is the amount of time used between retransmitting a call if + * no response has been heard; retransmition occurs until the actual + * rpc call times out. + * + * sendsz and recvsz are the maximum allowable packet sizes that can be + * sent and received. + */ +CLIENT * +clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *cl; + register struct cu_data *cu; + struct timeval now; + struct rpc_msg call_msg; + + cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); + if (cl == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + sendsz = ((sendsz + 3) / 4) * 4; + recvsz = ((recvsz + 3) / 4) * 4; + cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); + if (cu == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + cu->cu_outbuf = &cu->cu_inbuf[recvsz]; + + (void)gettimeofday(&now, (struct timezone *)0); + if (raddr->sin_port == 0) { + u_short port; + if ((port = + pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { + goto fooy; + } + raddr->sin_port = htons(port); + } + cl->cl_ops = &udp_ops; + cl->cl_private = (caddr_t)cu; + cu->cu_raddr = *raddr; + cu->cu_rlen = sizeof (cu->cu_raddr); + cu->cu_wait = wait; + cu->cu_total.tv_sec = -1; + cu->cu_total.tv_usec = -1; + cu->cu_sendsz = sendsz; + cu->cu_recvsz = recvsz; + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = program; + call_msg.rm_call.cb_vers = version; + xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, + sendsz, XDR_ENCODE); + if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { + goto fooy; + } + cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); + if (*sockp < 0) { + int dontblock = 1; + + *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*sockp < 0) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + /* attempt to bind to prov port */ + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + /* the sockets rpc controls are non-blocking */ + (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); + cu->cu_closeit = TRUE; + } else { + cu->cu_closeit = FALSE; + } + cu->cu_sock = *sockp; + cl->cl_auth = authnone_create(); + return (cl); +fooy: + if (cu) + mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); + if (cl) + mem_free((caddr_t)cl, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +CLIENT * +clntudp_create(raddr, program, version, wait, sockp) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; +{ + + return(clntudp_bufcreate(raddr, program, version, wait, sockp, + UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum clnt_stat +clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) + register CLIENT *cl; /* client handle */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + struct timeval utimeout; /* seconds to wait before giving up */ +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs; + register int outlen; + register int inlen; + int fromlen; +#ifdef FD_SETSIZE + fd_set readfds; + fd_set mask; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + struct sockaddr_in from; + struct rpc_msg reply_msg; + XDR reply_xdrs; + struct timeval time_waited; + bool_t ok; + int nrefreshes = 2; /* number of times to refresh cred */ + struct timeval timeout; + + if (cu->cu_total.tv_usec == -1) { + timeout = utimeout; /* use supplied timeout */ + } else { + timeout = cu->cu_total; /* use default timeout */ + } + + time_waited.tv_sec = 0; + time_waited.tv_usec = 0; +call_again: + xdrs = &(cu->cu_outxdrs); + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, cu->cu_xdrpos); + /* + * the transaction is the first thing in the out buffer + */ + (*(u_short *)(cu->cu_outbuf))++; + if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) + return (cu->cu_error.re_status = RPC_CANTENCODEARGS); + outlen = (int)XDR_GETPOS(xdrs); + +send_again: + if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, + (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) + != outlen) { + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTSEND); + } + + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return (cu->cu_error.re_status = RPC_TIMEDOUT); + } + /* + * sub-optimal code appears here because we have + * some clock time to spare while the packets are in flight. + * (We assume that this is actually only executed once.) + */ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(cu->cu_sock, &mask); +#else + mask = 1 << cu->cu_sock; +#endif /* def FD_SETSIZE */ + for (;;) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &(cu->cu_wait))) { + + case 0: + time_waited.tv_sec += cu->cu_wait.tv_sec; + time_waited.tv_usec += cu->cu_wait.tv_usec; + while (time_waited.tv_usec >= 1000000) { + time_waited.tv_sec++; + time_waited.tv_usec -= 1000000; + } + if ((time_waited.tv_sec < timeout.tv_sec) || + ((time_waited.tv_sec == timeout.tv_sec) && + (time_waited.tv_usec < timeout.tv_usec))) + goto send_again; + return (cu->cu_error.re_status = RPC_TIMEDOUT); + + /* + * buggy in other cases because time_waited is not being + * updated. + */ + case -1: + if (errno == EINTR) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + do { + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, + (int) cu->cu_recvsz, 0, + (struct sockaddr *)&from, &fromlen); + } while (inlen < 0 && errno == EINTR); + if (inlen < 0) { + if (errno == EWOULDBLOCK) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + if (inlen < sizeof(u_long)) + continue; + /* see if reply transaction id matches sent id */ + if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf))) + continue; + /* we now assume we have the proper reply */ + break; + } + + /* + * now decode and validate the response + */ + xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); + ok = xdr_replymsg(&reply_xdrs, &reply_msg); + /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ + if (ok) { + _seterr_reply(&reply_msg, &(cu->cu_error)); + if (cu->cu_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(cl->cl_auth, + &reply_msg.acpted_rply.ar_verf)) { + cu->cu_error.re_status = RPC_AUTHERROR; + cu->cu_error.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, + &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) { + nrefreshes--; + goto call_again; + } + } /* end of unsuccessful completion */ + } /* end of valid reply message */ + else { + cu->cu_error.re_status = RPC_CANTDECODERES; + } + return (cu->cu_error.re_status); +} + +static void +clntudp_geterr(cl, errp) + CLIENT *cl; + struct rpc_err *errp; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + *errp = cu->cu_error; +} + + +static bool_t +clntudp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs = &(cu->cu_outxdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntudp_abort(/*h*/) + /*CLIENT *h;*/ +{ +} + +static bool_t +clntudp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + cu->cu_total = *(struct timeval *)info; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = cu->cu_total; + break; + case CLSET_RETRY_TIMEOUT: + cu->cu_wait = *(struct timeval *)info; + break; + case CLGET_RETRY_TIMEOUT: + *(struct timeval *)info = cu->cu_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = cu->cu_raddr; + break; + default: + return (FALSE); + } + return (TRUE); +} + +static void +clntudp_destroy(cl) + CLIENT *cl; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + if (cu->cu_closeit) { + (void)close(cu->cu_sock); + } + XDR_DESTROY(&(cu->cu_outxdrs)); + mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); + mem_free((caddr_t)cl, sizeof(CLIENT)); +} diff --git a/sunrpc/etc.rpc b/sunrpc/etc.rpc new file mode 100644 index 0000000000..bebfb51b73 --- /dev/null +++ b/sunrpc/etc.rpc @@ -0,0 +1,33 @@ +# +# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI +# +portmapper 100000 portmap sunrpc +rstatd 100001 rstat rstat_svc rup perfmeter +rusersd 100002 rusers +nfs 100003 nfsprog +ypserv 100004 ypprog +mountd 100005 mount showmount +ypbind 100007 +walld 100008 rwall shutdown +yppasswdd 100009 yppasswd +etherstatd 100010 etherstat +rquotad 100011 rquotaprog quota rquota +sprayd 100012 spray +3270_mapper 100013 +rje_mapper 100014 +selection_svc 100015 selnsvc +database_svc 100016 +rexd 100017 rex +alis 100018 +sched 100019 +llockmgr 100020 +nlockmgr 100021 +x25.inr 100022 +statmon 100023 +status 100024 +bootparam 100026 +ypupdated 100028 ypupdate +keyserv 100029 keyserver +tfsd 100037 +nsed 100038 +nsemntd 100039 diff --git a/sunrpc/get_myaddr.c b/sunrpc/get_myaddr.c new file mode 100644 index 0000000000..9692f852f9 --- /dev/null +++ b/sunrpc/get_myaddr.c @@ -0,0 +1,91 @@ +/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * get_myaddress.c + * + * Get client's IP address via ioctl. This avoids using the yellowpages. + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/pmap_prot.h> +#include <sys/socket.h> +#include <stdio.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +/* Order of following two #includes reversed by roland@gnu */ +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * don't use gethostbyname, which would invoke yellow pages + */ +get_myaddress(addr) + struct sockaddr_in *addr; +{ + int s; + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int len; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("get_myaddress: socket"); + exit(1); + } + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("get_myaddress: ioctl (get interface configuration)"); + exit(1); + } + ifr = ifc.ifc_req; + for (len = ifc.ifc_len; len; len -= sizeof ifreq) { + ifreq = *ifr; + if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("get_myaddress: ioctl"); + exit(1); + } + if ((ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + *addr = *((struct sockaddr_in *)&ifr->ifr_addr); + addr->sin_port = htons(PMAPPORT); + break; + } + ifr++; + } + (void) close(s); +} diff --git a/sunrpc/getrpcent.c b/sunrpc/getrpcent.c new file mode 100644 index 0000000000..8ef65618b0 --- /dev/null +++ b/sunrpc/getrpcent.c @@ -0,0 +1,235 @@ +/* @(#)getrpcent.c 2.2 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +/* + * Internet version. + */ +struct rpcdata { + FILE *rpcf; + char *current; + int currentlen; + int stayopen; +#define MAXALIASES 35 + char *rpc_aliases[MAXALIASES]; + struct rpcent rpc; + char line[BUFSIZ+1]; + char *domain; +} *rpcdata, *_rpcdata(); + +static struct rpcent *interpret(); +struct hostent *gethostent(); +char *inet_ntoa(); +extern char *index(); /* Changed from static by roland@gnu */ + +static char RPCDB[] = _PATH_RPC; /* Changed from "/etc/rpc" by roland@gnu */ + +static struct rpcdata * +_rpcdata() +{ + register struct rpcdata *d = rpcdata; + + if (d == 0) { + d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); + rpcdata = d; + } + return (d); +} + +struct rpcent * +getrpcbynumber(number) + register int number; +{ + register struct rpcdata *d = _rpcdata(); + register struct rpcent *p; + int reason; + char adrstr[16], *val = NULL; + int vallen; + + if (d == 0) + return (0); + setrpcent(0); + while (p = getrpcent()) { + if (p->r_number == number) + break; + } + endrpcent(); + return (p); +} + +struct rpcent * +getrpcbyname(name) + const char *name; /* const added by roland@gnu */ +{ + struct rpcent *rpc; + char **rp; + + setrpcent(0); + while(rpc = getrpcent()) { + if (strcmp(rpc->r_name, name) == 0) + return (rpc); + for (rp = rpc->r_aliases; *rp != NULL; rp++) { + if (strcmp(*rp, name) == 0) + return (rpc); + } + } + endrpcent(); + return (NULL); +} + +setrpcent(f) + int f; +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->rpcf == NULL) + d->rpcf = fopen(RPCDB, "r"); + else + rewind(d->rpcf); + if (d->current) + free(d->current); + d->current = NULL; + d->stayopen |= f; +} + +endrpcent() +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->current && !d->stayopen) { + free(d->current); + d->current = NULL; + } + if (d->rpcf && !d->stayopen) { + fclose(d->rpcf); + d->rpcf = NULL; + } +} + +struct rpcent * +getrpcent() +{ + struct rpcent *hp; + int reason; + char *key = NULL, *val = NULL; + int keylen, vallen; + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return(NULL); + if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) + return (NULL); + if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) + return (NULL); + return interpret(d->line, strlen(d->line)); +} + +static struct rpcent * +interpret(val, len) +{ + register struct rpcdata *d = _rpcdata(); + char *p; + register char *cp, **q; + + if (d == 0) + return; + strncpy(d->line, val, len); + p = d->line; + d->line[len] = '\n'; + if (*p == '#') + return (getrpcent()); + cp = index(p, '#'); + if (cp == NULL) + { + cp = index(p, '\n'); + if (cp == NULL) + return (getrpcent()); + } + *cp = '\0'; + cp = index(p, ' '); + if (cp == NULL) + { + cp = index(p, '\t'); + if (cp == NULL) + return (getrpcent()); + } + *cp++ = '\0'; + /* THIS STUFF IS INTERNET SPECIFIC */ + d->rpc.r_name = d->line; + while (*cp == ' ' || *cp == '\t') + cp++; + d->rpc.r_number = atoi(cp); + q = d->rpc.r_aliases = d->rpc_aliases; + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &(d->rpc_aliases[MAXALIASES - 1])) + *q++ = cp; + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&d->rpc); +} diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c new file mode 100644 index 0000000000..9b13bac6b0 --- /dev/null +++ b/sunrpc/getrpcport.c @@ -0,0 +1,55 @@ +/* @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +getrpcport(host, prognum, versnum, proto) + char *host; +{ + struct sockaddr_in addr; + struct hostent *hp; + + if ((hp = gethostbyname(host)) == NULL) + return (0); + bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = 0; + return (pmap_getport(&addr, prognum, versnum, proto)); +} diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c new file mode 100644 index 0000000000..c5f72af87b --- /dev/null +++ b/sunrpc/pm_getmaps.c @@ -0,0 +1,86 @@ +/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getmap.c + * Client interface to pmap rpc service. + * contains pmap_getmaps, which is only tcp service involved + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <errno.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +#define NAMELEN 255 +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; + +/* + * Get a copy of the current port maps. + * Calls the pmap service remotely to do get the maps. + */ +struct pmaplist * +pmap_getmaps(address) + struct sockaddr_in *address; +{ + struct pmaplist *head = (struct pmaplist *)NULL; + int socket = -1; + struct timeval minutetimeout; + register CLIENT *client; + + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + address->sin_port = htons(PMAPPORT); + client = clnttcp_create(address, PMAPPROG, + PMAPVERS, &socket, 50, 500); + if (client != (CLIENT *)NULL) { + if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, + &head, minutetimeout) != RPC_SUCCESS) { + clnt_perror(client, "pmap_getmaps rpc problem"); + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (head); +} diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c new file mode 100644 index 0000000000..2e1cc5aded --- /dev/null +++ b/sunrpc/pm_getport.c @@ -0,0 +1,89 @@ +/* @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getport.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +/* + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +u_short +pmap_getport(address, program, version, protocol) + struct sockaddr_in *address; + u_long program; + u_long version; + u_int protocol; +{ + u_short port = 0; + int socket = -1; + register CLIENT *client; + struct pmap parms; + + address->sin_port = htons(PMAPPORT); + client = clntudp_bufcreate(address, PMAPPROG, + PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *)NULL) { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, + xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (port); +} diff --git a/sunrpc/pmap_clnt.c b/sunrpc/pmap_clnt.c new file mode 100644 index 0000000000..09220e77b1 --- /dev/null +++ b/sunrpc/pmap_clnt.c @@ -0,0 +1,115 @@ +/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_clnt.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +void clnt_perror(); + + +/* + * Set a mapping between program,version and port. + * Calls the pmap service remotely to do the mapping. + */ +bool_t +pmap_set(program, version, protocol, port) + u_long program; + u_long version; + int protocol; + u_short port; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = port; + if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout) != RPC_SUCCESS) { + clnt_perror(client, "Cannot register service"); + return (FALSE); + } + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} + +/* + * Remove the mapping between program,version and port. + * Calls the pmap service remotely to do the un-mapping. + */ +bool_t +pmap_unset(program, version) + u_long program; + u_long version; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_port = parms.pm_prot = 0; + CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout); + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} diff --git a/sunrpc/pmap_prot.c b/sunrpc/pmap_prot.c new file mode 100644 index 0000000000..643c2ff6a2 --- /dev/null +++ b/sunrpc/pmap_prot.c @@ -0,0 +1,57 @@ +/* @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.h> + + +bool_t +xdr_pmap(xdrs, regs) + XDR *xdrs; + struct pmap *regs; +{ + + if (xdr_u_long(xdrs, ®s->pm_prog) && + xdr_u_long(xdrs, ®s->pm_vers) && + xdr_u_long(xdrs, ®s->pm_prot)) + return (xdr_u_long(xdrs, ®s->pm_port)); + return (FALSE); +} diff --git a/sunrpc/pmap_prot2.c b/sunrpc/pmap_prot2.c new file mode 100644 index 0000000000..e2a8214d48 --- /dev/null +++ b/sunrpc/pmap_prot2.c @@ -0,0 +1,116 @@ +/* @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot2.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.h> + + +/* + * What is going on with linked lists? (!) + * First recall the link list declaration from pmap_prot.h: + * + * struct pmaplist { + * struct pmap pml_map; + * struct pmaplist *pml_map; + * }; + * + * Compare that declaration with a corresponding xdr declaration that + * is (a) pointer-less, and (b) recursive: + * + * typedef union switch (bool_t) { + * + * case TRUE: struct { + * struct pmap; + * pmaplist_t foo; + * }; + * + * case FALSE: struct {}; + * } pmaplist_t; + * + * Notice that the xdr declaration has no nxt pointer while + * the C declaration has no bool_t variable. The bool_t can be + * interpreted as ``more data follows me''; if FALSE then nothing + * follows this bool_t; if TRUE then the bool_t is followed by + * an actual struct pmap, and then (recursively) by the + * xdr union, pamplist_t. + * + * This could be implemented via the xdr_union primitive, though this + * would cause a one recursive call per element in the list. Rather than do + * that we can ``unwind'' the recursion + * into a while loop and do the union arms in-place. + * + * The head of the list is what the C programmer wishes to past around + * the net, yet is the data that the pointer points to which is interesting; + * this sounds like a job for xdr_reference! + */ +bool_t +xdr_pmaplist(xdrs, rp) + register XDR *xdrs; + register struct pmaplist **rp; +{ + /* + * more_elements is pre-computed in case the direction is + * XDR_ENCODE or XDR_FREE. more_elements is overwritten by + * xdr_bool when the direction is XDR_DECODE. + */ + bool_t more_elements; + register int freeing = (xdrs->x_op == XDR_FREE); + register struct pmaplist **next; + + while (TRUE) { + more_elements = (bool_t)(*rp != NULL); + if (! xdr_bool(xdrs, &more_elements)) + return (FALSE); + if (! more_elements) + return (TRUE); /* we are done */ + /* + * the unfortunate side effect of non-recursion is that in + * the case of freeing we must remember the next object + * before we free the current object ... + */ + if (freeing) + next = &((*rp)->pml_next); + if (! xdr_reference(xdrs, (caddr_t *)rp, + (u_int)sizeof(struct pmaplist), xdr_pmap)) + return (FALSE); + rp = (freeing) ? next : &((*rp)->pml_next); + } +} diff --git a/sunrpc/pmap_rmt.c b/sunrpc/pmap_rmt.c new file mode 100644 index 0000000000..32c829da2d --- /dev/null +++ b/sunrpc/pmap_rmt.c @@ -0,0 +1,392 @@ +/* @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_rmt.c + * Client interface to pmap rpc service. + * remote call and broadcast service + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <rpc/pmap_rmt.h> +#include <sys/socket.h> +#include <stdio.h> +#include <errno.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; +static struct timeval timeout = { 3, 0 }; + + +/* + * pmapper remote-call-service interface. + * This routine is used to call the pmapper remote call service + * which will look up a service program in the port maps, and then + * remotely call that routine with the given parameters. This allows + * programs to do a lookup and call in one step. +*/ +enum clnt_stat +pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) + struct sockaddr_in *addr; + u_long prog, vers, proc; + xdrproc_t xdrargs, xdrres; + caddr_t argsp, resp; + struct timeval tout; + u_long *port_ptr; +{ + int socket = -1; + register CLIENT *client; + struct rmtcallargs a; + struct rmtcallres r; + enum clnt_stat stat; + + addr->sin_port = htons(PMAPPORT); + client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); + if (client != (CLIENT *)NULL) { + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.args_ptr = argsp; + a.xdr_args = xdrargs; + r.port_ptr = port_ptr; + r.results_ptr = resp; + r.xdr_results = xdrres; + stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a, + xdr_rmtcallres, &r, tout); + CLNT_DESTROY(client); + } else { + stat = RPC_FAILED; + } + (void)close(socket); + addr->sin_port = 0; + return (stat); +} + + +/* + * XDR remote call arguments + * written for XDR_ENCODE direction only + */ +bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + u_int lenposition, argposition, position; + + if (xdr_u_long(xdrs, &(cap->prog)) && + xdr_u_long(xdrs, &(cap->vers)) && + xdr_u_long(xdrs, &(cap->proc))) { + lenposition = XDR_GETPOS(xdrs); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + argposition = XDR_GETPOS(xdrs); + if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) + return (FALSE); + position = XDR_GETPOS(xdrs); + cap->arglen = (u_long)position - (u_long)argposition; + XDR_SETPOS(xdrs, lenposition); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + XDR_SETPOS(xdrs, position); + return (TRUE); + } + return (FALSE); +} + +/* + * XDR remote call results + * written for XDR_DECODE direction only + */ +bool_t +xdr_rmtcallres(xdrs, crp) + register XDR *xdrs; + register struct rmtcallres *crp; +{ + caddr_t port_ptr; + + port_ptr = (caddr_t)crp->port_ptr; + if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), + xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { + crp->port_ptr = (u_long *)port_ptr; + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); + } + return (FALSE); +} + + +/* + * The following is kludged-up support for simple rpc broadcasts. + * Someday a large, complicated system will replace these trivial + * routines which only support udp/ip . + */ + +static int +getbroadcastnets(addrs, sock, buf) + struct in_addr *addrs; + int sock; /* any valid socket will do */ + char *buf; /* why allocxate more when we can use existing... */ +{ + struct ifconf ifc; + struct ifreq ifreq, *ifr; + struct sockaddr_in *sin; + int n, i; + + ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("broadcast: ioctl (get interface configuration)"); + return (0); + } + ifr = ifc.ifc_req; + for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) { + ifreq = *ifr; + if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("broadcast: ioctl (get interface flags)"); + continue; + } + if ((ifreq.ifr_flags & IFF_BROADCAST) && + (ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + sin = (struct sockaddr_in *)&ifr->ifr_addr; +#ifdef SIOCGIFBRDADDR /* 4.3BSD */ + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { + addrs[i++] = inet_makeaddr(inet_netof + /* Changed to pass struct instead of s_addr member + by roland@gnu. */ + (sin->sin_addr), INADDR_ANY); + } else { + addrs[i++] = ((struct sockaddr_in*) + &ifreq.ifr_addr)->sin_addr; + } +#else /* 4.2 BSD */ + addrs[i++] = inet_makeaddr(inet_netof + (sin->sin_addr.s_addr), INADDR_ANY); +#endif + } + } + return (i); +} + +typedef bool_t (*resultproc_t)(); + +enum clnt_stat +clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) + u_long prog; /* program number */ + u_long vers; /* version number */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + resultproc_t eachresult; /* call with each result obtained */ +{ + enum clnt_stat stat; + AUTH *unix_auth = authunix_create_default(); + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + int outlen, inlen, fromlen, nets; + register int sock; + int on = 1; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + register int i; + bool_t done = FALSE; + register u_long xid; + u_long port; + struct in_addr addrs[20]; + struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ + struct rmtcallargs a; + struct rmtcallres r; + struct rpc_msg msg; + struct timeval t; + char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + + /* + * initialization: create a socket, a broadcast address, and + * preserialize the arguments into a send buffer. + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("Cannot create socket for broadcast rpc"); + stat = RPC_CANTSEND; + goto done_broad; + } +#ifdef SO_BROADCAST + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + perror("Cannot set socket option SO_BROADCAST"); + stat = RPC_CANTSEND; + goto done_broad; + } +#endif /* def SO_BROADCAST */ +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + mask = (1 << sock); +#endif /* def FD_SETSIZE */ + nets = getbroadcastnets(addrs, sock, inbuf); + bzero((char *)&baddr, sizeof (baddr)); + baddr.sin_family = AF_INET; + baddr.sin_port = htons(PMAPPORT); + baddr.sin_addr.s_addr = htonl(INADDR_ANY); +/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ + (void)gettimeofday(&t, (struct timezone *)0); + msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; + t.tv_usec = 0; + msg.rm_direction = CALL; + msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + msg.rm_call.cb_prog = PMAPPROG; + msg.rm_call.cb_vers = PMAPVERS; + msg.rm_call.cb_proc = PMAPPROC_CALLIT; + msg.rm_call.cb_cred = unix_auth->ah_cred; + msg.rm_call.cb_verf = unix_auth->ah_verf; + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.xdr_args = xargs; + a.args_ptr = argsp; + r.port_ptr = &port; + r.xdr_results = xresults; + r.results_ptr = resultsp; + xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); + if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { + stat = RPC_CANTENCODEARGS; + goto done_broad; + } + outlen = (int)xdr_getpos(xdrs); + xdr_destroy(xdrs); + /* + * Basic loop: broadcast a packet and wait a while for response(s). + * The response timeout grows larger per iteration. + */ + for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { + for (i = 0; i < nets; i++) { + baddr.sin_addr = addrs[i]; + if (sendto(sock, outbuf, outlen, 0, + (struct sockaddr *)&baddr, + sizeof (struct sockaddr)) != outlen) { + perror("Cannot send broadcast packet"); + stat = RPC_CANTSEND; + goto done_broad; + } + } + if (eachresult == NULL) { + stat = RPC_SUCCESS; + goto done_broad; + } + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t)&r; + msg.acpted_rply.ar_results.proc = xdr_rmtcallres; + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &t)) { + + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; + + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror("Broadcast select problem"); + stat = RPC_CANTRECV; + goto done_broad; + + } /* end of select results switch */ + try_again: + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, + (struct sockaddr *)&raddr, &fromlen); + if (inlen < 0) { + if (errno == EINTR) + goto try_again; + perror("Cannot receive reply to broadcast"); + stat = RPC_CANTRECV; + goto done_broad; + } + if (inlen < sizeof(u_long)) + goto recv_again; + /* + * see if reply transaction id matches sent id. + * If so, decode the results. + */ + xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); + if (xdr_replymsg(xdrs, &msg)) { + if ((msg.rm_xid == xid) && + (msg.rm_reply.rp_stat == MSG_ACCEPTED) && + (msg.acpted_rply.ar_stat == SUCCESS)) { + raddr.sin_port = htons((u_short)port); + done = (*eachresult)(resultsp, &raddr); + } + /* otherwise, we just ignore the errors ... */ + } else { +#ifdef notdef + /* some kind of deserialization problem ... */ + if (msg.rm_xid == xid) + fprintf(stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ +#endif + } + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = xdr_void; + (void)xdr_replymsg(xdrs, &msg); + (void)(*xresults)(xdrs, resultsp); + xdr_destroy(xdrs); + if (done) { + stat = RPC_SUCCESS; + goto done_broad; + } else { + goto recv_again; + } + } +done_broad: + (void)close(sock); + AUTH_DESTROY(unix_auth); + return (stat); +} + diff --git a/sunrpc/portmap.c b/sunrpc/portmap.c new file mode 100644 index 0000000000..adfdef955e --- /dev/null +++ b/sunrpc/portmap.c @@ -0,0 +1,481 @@ +/* @(#)portmap.c 2.3 88/08/11 4.0 RPCSRC */ +#ifndef lint +static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; +#endif + +/* + * Copyright (c) 1984 by Sun Microsystems, Inc. + */ + +/* + * portmap.c, Implements the program,version to port number mapping for + * rpc. + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <stdio.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <sys/signal.h> + +char *malloc(); +int reg_service(); +void reap(); +struct pmaplist *pmaplist; +static int debugging = 0; + +main() +{ + SVCXPRT *xprt; + int sock, pid, t; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + register struct pmaplist *pml; + +#ifndef DEBUG + pid = fork(); + if (pid < 0) { + perror("portmap: fork"); + exit(1); + } + if (pid != 0) + exit(0); + for (t = 0; t < 20; t++) + close(t); + open("/", 0); + dup2(0, 1); + dup2(0, 2); + t = open("/dev/tty", 2); + if (t >= 0) { + ioctl(t, TIOCNOTTY, (char *)0); + close(t); + } +#endif + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("portmap cannot create socket"); + exit(1); + } + + addr.sin_addr.s_addr = 0; + addr.sin_family = AF_INET; + addr.sin_port = htons(PMAPPORT); + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + exit(1); + } + + if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do udp_create\n"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_next = 0; + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_UDP; + pml->pml_map.pm_port = PMAPPORT; + pmaplist = pml; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("portmap cannot create socket"); + exit(1); + } + if (bind(sock, (struct sockaddr *)&addr, len) != 0) { + perror("portmap cannot bind"); + exit(1); + } + if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) + == (SVCXPRT *)NULL) { + fprintf(stderr, "couldn't do tcp_create\n"); + exit(1); + } + /* make an entry for ourself */ + pml = (struct pmaplist *)malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_prot = IPPROTO_TCP; + pml->pml_map.pm_port = PMAPPORT; + pml->pml_next = pmaplist; + pmaplist = pml; + + (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + + (void)signal(SIGCHLD, reap); + svc_run(); + fprintf(stderr, "run_svc returned unexpectedly\n"); + abort(); +} + +static struct pmaplist * +find_service(prog, vers, prot) + u_long prog; + u_long vers; +{ + register struct pmaplist *hit = NULL; + register struct pmaplist *pml; + + for (pml = pmaplist; pml != NULL; pml = pml->pml_next) { + if ((pml->pml_map.pm_prog != prog) || + (pml->pml_map.pm_prot != prot)) + continue; + hit = pml; + if (pml->pml_map.pm_vers == vers) + break; + } + return (hit); +} + +/* + * 1 OK, 0 not + */ +reg_service(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct pmap reg; + struct pmaplist *pml, *prevpml, *fnd; + int ans, port; + caddr_t t; + +#ifdef DEBUG + fprintf(stderr, "server: about do a switch\n"); +#endif + switch (rqstp->rq_proc) { + + case PMAPPROC_NULL: + /* + * Null proc call + */ + if ((!svc_sendreply(xprt, xdr_void, NULL)) && debugging) { + abort(); + } + break; + + case PMAPPROC_SET: + /* + * Set a program,version to port mapping + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + /* + * check to see if already used + * find_service returns a hit even if + * the versions don't match, so check for it + */ + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) { + if (fnd->pml_map.pm_port == reg.pm_port) { + ans = 1; + goto done; + } + else { + ans = 0; + goto done; + } + } else { + /* + * add to END of list + */ + pml = (struct pmaplist *) + malloc((u_int)sizeof(struct pmaplist)); + pml->pml_map = reg; + pml->pml_next = 0; + if (pmaplist == 0) { + pmaplist = pml; + } else { + for (fnd= pmaplist; fnd->pml_next != 0; + fnd = fnd->pml_next); + fnd->pml_next = pml; + } + ans = 1; + } + done: + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_UNSET: + /* + * Remove a program,version to port mapping. + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + ans = 0; + for (prevpml = NULL, pml = pmaplist; pml != NULL; ) { + if ((pml->pml_map.pm_prog != reg.pm_prog) || + (pml->pml_map.pm_vers != reg.pm_vers)) { + /* both pml & prevpml move forwards */ + prevpml = pml; + pml = pml->pml_next; + continue; + } + /* found it; pml moves forward, prevpml stays */ + ans = 1; + t = (caddr_t)pml; + pml = pml->pml_next; + if (prevpml == NULL) + pmaplist = pml; + else + prevpml->pml_next = pml; + free(t); + } + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_GETPORT: + /* + * Lookup the mapping for a program,version and return its port + */ + if (!svc_getargs(xprt, xdr_pmap, ®)) + svcerr_decode(xprt); + else { + fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd) + port = fnd->pml_map.pm_port; + else + port = 0; + if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) && + debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_DUMP: + /* + * Return the current set of mapped program,version + */ + if (!svc_getargs(xprt, xdr_void, NULL)) + svcerr_decode(xprt); + else { + if ((!svc_sendreply(xprt, xdr_pmaplist, + (caddr_t)&pmaplist)) && debugging) { + fprintf(stderr, "svc_sendreply\n"); + abort(); + } + } + break; + + case PMAPPROC_CALLIT: + /* + * Calls a procedure on the local machine. If the requested + * procedure is not registered this procedure does not return + * error information!! + * This procedure is only supported on rpc/udp and calls via + * rpc/udp. It passes null authentication parameters. + */ + callit(rqstp, xprt); + break; + + default: + svcerr_noproc(xprt); + break; + } +} + + +/* + * Stuff for the rmtcall service + */ +#define ARGSIZE 9000 + +typedef struct encap_parms { + u_long arglen; + char *args; +}; + +static bool_t +xdr_encap_parms(xdrs, epp) + XDR *xdrs; + struct encap_parms *epp; +{ + + return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE)); +} + +typedef struct rmtcallargs { + u_long rmt_prog; + u_long rmt_vers; + u_long rmt_port; + u_long rmt_proc; + struct encap_parms rmt_args; +}; + +static bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + + /* does not get a port number */ + if (xdr_u_long(xdrs, &(cap->rmt_prog)) && + xdr_u_long(xdrs, &(cap->rmt_vers)) && + xdr_u_long(xdrs, &(cap->rmt_proc))) { + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + } + return (FALSE); +} + +static bool_t +xdr_rmtcall_result(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + if (xdr_u_long(xdrs, &(cap->rmt_port))) + return (xdr_encap_parms(xdrs, &(cap->rmt_args))); + return (FALSE); +} + +/* + * only worries about the struct encap_parms part of struct rmtcallargs. + * The arglen must already be set!! + */ +static bool_t +xdr_opaque_parms(xdrs, cap) + XDR *xdrs; + struct rmtcallargs *cap; +{ + + return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen)); +} + +/* + * This routine finds and sets the length of incoming opaque paraters + * and then calls xdr_opaque_parms. + */ +static bool_t +xdr_len_opaque_parms(xdrs, cap) + register XDR *xdrs; + struct rmtcallargs *cap; +{ + register u_int beginpos, lowpos, highpos, currpos, pos; + + beginpos = lowpos = pos = xdr_getpos(xdrs); + highpos = lowpos + ARGSIZE; + while ((int)(highpos - lowpos) >= 0) { + currpos = (lowpos + highpos) / 2; + if (xdr_setpos(xdrs, currpos)) { + pos = currpos; + lowpos = currpos + 1; + } else { + highpos = currpos - 1; + } + } + xdr_setpos(xdrs, beginpos); + cap->rmt_args.arglen = pos - beginpos; + return (xdr_opaque_parms(xdrs, cap)); +} + +/* + * Call a remote procedure service + * This procedure is very quiet when things go wrong. + * The proc is written to support broadcast rpc. In the broadcast case, + * a machine should shut-up instead of complain, less the requestor be + * overrun with complaints at the expense of not hearing a valid reply ... + * + * This now forks so that the program & process that it calls can call + * back to the portmapper. + */ +static +callit(rqstp, xprt) + struct svc_req *rqstp; + SVCXPRT *xprt; +{ + struct rmtcallargs a; + struct pmaplist *pml; + u_short port; + struct sockaddr_in me; + int pid, socket = -1; + CLIENT *client; + struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred; + struct timeval timeout; + char buf[ARGSIZE]; + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + a.rmt_args.args = buf; + if (!svc_getargs(xprt, xdr_rmtcall_args, &a)) + return; + if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL) + return; + /* + * fork a child to do the work. Parent immediately returns. + * Child exits upon completion. + */ + if ((pid = fork()) != 0) { + if (debugging && (pid < 0)) { + fprintf(stderr, "portmap CALLIT: cannot fork.\n"); + } + return; + } + port = pml->pml_map.pm_port; + get_myaddress(&me); + me.sin_port = htons(port); + client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket); + if (client != (CLIENT *)NULL) { + if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { + client->cl_auth = authunix_create(au->aup_machname, + au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids); + } + a.rmt_port = (u_long)port; + if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a, + xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) { + svc_sendreply(xprt, xdr_rmtcall_result, &a); + } + AUTH_DESTROY(client->cl_auth); + clnt_destroy(client); + } + (void)close(socket); + exit(0); +} + +void +reap() +{ + while (wait3(NULL, WNOHANG, NULL) > 0); +} diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h new file mode 100644 index 0000000000..cb19555472 --- /dev/null +++ b/sunrpc/rpc/auth.h @@ -0,0 +1,166 @@ +/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +#if 1 /* (mc68000 || sparc || vax || i386) --roland@gnu */ +typedef u_long u_int32; /* 32-bit unsigned integers */ +#endif + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +extern bool_t xdr_des_block(); + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf)(); + int (*ah_marshal)(); /* nextverf & serialize */ + int (*ah_validate)(); /* validate varifier */ + int (*ah_refresh)(); /* refresh credentials */ + void (*ah_destroy)(); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +extern struct opaque_auth _null_auth; + + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +extern AUTH *authunix_create(); +extern AUTH *authunix_create_default(); /* takes no parameters */ +extern AUTH *authnone_create(); /* takes no parameters */ +extern AUTH *authdes_create(); + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/sunrpc/rpc/auth_unix.h b/sunrpc/rpc/auth_unix.h new file mode 100644 index 0000000000..705741e139 --- /dev/null +++ b/sunrpc/rpc/auth_unix.h @@ -0,0 +1,72 @@ +/* @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)auth_unix.h 1.5 86/07/16 SMI */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +extern bool_t xdr_authunix_parms(); + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h new file mode 100644 index 0000000000..8c002a19fa --- /dev/null +++ b/sunrpc/rpc/clnt.h @@ -0,0 +1,331 @@ +/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _CLNT_ +#define _CLNT_ + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_long low; /* lowest verion supported */ + u_long high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + long s1; + long s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + enum clnt_stat (*cl_call)(); /* call remote procedure */ + void (*cl_abort)(); /* abort a call */ + void (*cl_geterr)(); /* get specific error code */ + bool_t (*cl_freeres)(); /* frees results */ + void (*cl_destroy)();/* destroy this structure */ + bool_t (*cl_control)();/* the ioctl() of rpc */ + } *cl_ops; + caddr_t cl_private; /* private stuff */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_long)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +extern CLIENT *clntraw_create(); + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + */ +extern CLIENT * +clnt_create(/*host, prog, vers, prot*/); /* + char *host; -- hostname + u_long prog; -- program number + u_long vers; -- version number + char *prot; -- protocol +*/ + + + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clnttcp_create(); + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clntudp_create(); +extern CLIENT *clntudp_bufcreate(); + +/* + * Print why creation failed + */ +void clnt_pcreateerror(/* char *msg */); /* stderr */ +char *clnt_spcreateerror(/* char *msg */); /* string */ + +/* + * Like clnt_perror(), but is more verbose in its output + */ +void clnt_perrno(/* enum clnt_stat num */); /* stderr */ + +/* + * Print an English error message, given the client error code + */ +void clnt_perror(/* CLIENT *clnt, char *msg */); /* stderr */ +char *clnt_sperror(/* CLIENT *clnt, char *msg */); /* string */ + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + + +/* + * Copy error message to buffer. + */ +char *clnt_sperrno(/* enum clnt_stat num */); /* string */ + + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /*!_CLNT_*/ diff --git a/sunrpc/rpc/netdb.h b/sunrpc/rpc/netdb.h new file mode 100644 index 0000000000..23413cf7ba --- /dev/null +++ b/sunrpc/rpc/netdb.h @@ -0,0 +1,52 @@ +/* @(#)netdb.h 2.1 88/07/29 3.9 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc.h 1.8 87/07/24 SMI */ + +/* Cleaned up for GNU C library roland@gnu.ai.mit.edu: + added multiple inclusion protection and use of <sys/cdefs.h>. + In GNU this file is #include'd by <netdb.h>. */ + +#ifndef _RPC_NETDB_H +#define _RPC_NETDB_H +#include <sys/cdefs.h> + +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +__BEGIN_DECLS +struct rpcent *getrpcbyname __P((const char *)); +struct rpcent *getrpcbynumber __P((int)); +struct rpcent *getrpcent __P((void)); +__END_DECLS + +#endif diff --git a/sunrpc/rpc/pmap_clnt.h b/sunrpc/rpc/pmap_clnt.h new file mode 100644 index 0000000000..d2ea2a88e9 --- /dev/null +++ b/sunrpc/rpc/pmap_clnt.h @@ -0,0 +1,65 @@ +/* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +extern bool_t pmap_set(); +extern bool_t pmap_unset(); +extern struct pmaplist *pmap_getmaps(); +enum clnt_stat pmap_rmtcall(); +enum clnt_stat clnt_broadcast(); +extern u_short pmap_getport(); diff --git a/sunrpc/rpc/pmap_prot.h b/sunrpc/rpc/pmap_prot.h new file mode 100644 index 0000000000..ccf7a77b41 --- /dev/null +++ b/sunrpc/rpc/pmap_prot.h @@ -0,0 +1,94 @@ +/* @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +extern bool_t xdr_pmap(); + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +extern bool_t xdr_pmaplist(); diff --git a/sunrpc/rpc/pmap_rmt.h b/sunrpc/rpc/pmap_rmt.h new file mode 100644 index 0000000000..ee68cebec2 --- /dev/null +++ b/sunrpc/rpc/pmap_rmt.h @@ -0,0 +1,53 @@ +/* @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +bool_t xdr_rmtcall_args(); + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +bool_t xdr_rmtcallres(); diff --git a/sunrpc/rpc/rpc.h b/sunrpc/rpc/rpc.h new file mode 100644 index 0000000000..83a124a3ed --- /dev/null +++ b/sunrpc/rpc/rpc.h @@ -0,0 +1,73 @@ +/* @(#)rpc.h 2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef __RPC_HEADER__ +#define __RPC_HEADER__ + +#include <rpc/types.h> /* some typedefs */ +#include <netinet/in.h> + +/* external data representation interfaces */ +#include <rpc/xdr.h> /* generic (de)serializer */ + +/* Client side only authentication */ +#include <rpc/auth.h> /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include <rpc/clnt.h> /* generic rpc stuff */ + +/* semi-private protocol headers */ +#include <rpc/rpc_msg.h> /* protocol for rpc messages */ +#include <rpc/auth_unix.h> /* protocol for unix style cred */ +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +/*#include <rpc/auth_des.h> /* protocol for des style cred */ + +/* Server side only remote procedure callee */ +#include <rpc/svc.h> /* service manager and multiplexer */ +#include <rpc/svc_auth.h> /* service side authenticator */ + +/* + * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION + * OF UNIX BASED ON NFSSRC. These systems will already have the structures + * defined by <rpc/netdb.h> included in <netdb.h>. + */ +/* routines for parsing /etc/rpc */ +#include <rpc/netdb.h> /* structures and routines to parse /etc/rpc */ + +#endif /* ndef __RPC_HEADER__ */ diff --git a/sunrpc/rpc/rpc_msg.h b/sunrpc/rpc/rpc_msg.h new file mode 100644 index 0000000000..b78872b6a8 --- /dev/null +++ b/sunrpc/rpc/rpc_msg.h @@ -0,0 +1,187 @@ +/* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc_msg.h 1.7 86/07/16 SMI */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#define RPC_MSG_VERSION ((u_long) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + u_long low; + u_long high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + u_long low; + u_long high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + u_long cb_rpcvers; /* must be equal to two */ + u_long cb_prog; + u_long cb_vers; + u_long cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_long rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + + +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg(); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr(); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg(); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply(); diff --git a/sunrpc/rpc/svc.h b/sunrpc/rpc/svc.h new file mode 100644 index 0000000000..3cb07ef3f3 --- /dev/null +++ b/sunrpc/rpc/svc.h @@ -0,0 +1,280 @@ +/* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __SVC_HEADER__ +#define __SVC_HEADER__ + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + bool_t (*xp_recv)(); /* receive incomming requests */ + enum xprt_stat (*xp_stat)(); /* get transport status */ + bool_t (*xp_getargs)(); /* get arguments */ + bool_t (*xp_reply)(); /* send reply */ + bool_t (*xp_freeargs)();/* free mem allocated for args */ + void (*xp_destroy)(); /* destroy this struct */ + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_long rq_prog; /* service program number */ + u_long rq_vers; /* service protocol version */ + u_long rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; /* like TCP or UDP, zero means do not register + */ +extern bool_t svc_register(); + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +extern void svc_unregister(); + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_register(); + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_unregister(); + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +extern bool_t svc_sendreply(); +extern void svcerr_decode(); +extern void svcerr_weakauth(); +extern void svcerr_noproc(); +extern void svcerr_progvers(); +extern void svcerr_auth(); +extern void svcerr_noprog(); +extern void svcerr_systemerr(); + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +extern void rpctest_service(); + +extern void svc_getreq(); +extern void svc_getreqset(); /* takes fdset instead of int */ +extern void svc_run(); /* never returns */ + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +extern SVCXPRT *svcraw_create(); + +/* + * Udp based rpc. + */ +extern SVCXPRT *svcudp_create(); +extern SVCXPRT *svcudp_bufcreate(); + +/* + * Tcp based rpc. + */ +extern SVCXPRT *svctcp_create(); + + + +#endif !__SVC_HEADER__ diff --git a/sunrpc/rpc/svc_auth.h b/sunrpc/rpc/svc_auth.h new file mode 100644 index 0000000000..a36a01aba8 --- /dev/null +++ b/sunrpc/rpc/svc_auth.h @@ -0,0 +1,42 @@ +/* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)svc_auth.h 1.6 86/07/16 SMI */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +/* + * Server side authenticator + */ +extern enum auth_stat _authenticate(); diff --git a/sunrpc/rpc/types.h b/sunrpc/rpc/types.h new file mode 100644 index 0000000000..1f620eff8f --- /dev/null +++ b/sunrpc/rpc/types.h @@ -0,0 +1,63 @@ +/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)types.h 1.18 87/07/24 SMI */ + +/* + * Rpc additions to <sys/types.h> + */ +#ifndef __TYPES_RPC_HEADER__ +#define __TYPES_RPC_HEADER__ + +#define bool_t int +#define enum_t int +#define FALSE (0) +#define TRUE (1) +#define __dontcare__ -1 +#ifndef NULL +# define NULL 0 +#endif + +extern char *malloc(); +#define mem_alloc(bsize) malloc(bsize) +#define mem_free(ptr, bsize) free(ptr) + +#ifndef makedev /* ie, we haven't already included it */ +#include <sys/types.h> +#endif +#include <sys/time.h> + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_long)0x7F000001 +#endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#endif /* ndef __TYPES_RPC_HEADER__ */ diff --git a/sunrpc/rpc/xdr.h b/sunrpc/rpc/xdr.h new file mode 100644 index 0000000000..6cd3e6fe03 --- /dev/null +++ b/sunrpc/rpc/xdr.h @@ -0,0 +1,270 @@ +/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)xdr.h 1.19 87/04/22 SMI */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __XDR_HEADER__ +#define __XDR_HEADER__ + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * <type> *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + * bool_t (*xdrproc_t)(XDR *, caddr_t *); + */ +typedef bool_t (*xdrproc_t)(); + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +typedef struct { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + bool_t (*x_getlong)(); /* get a long from underlying stream */ + bool_t (*x_putlong)(); /* put a long to " */ + bool_t (*x_getbytes)();/* get some bytes from " */ + bool_t (*x_putbytes)();/* put some bytes to " */ + u_int (*x_getpostn)();/* returns bytes off from beginning */ + bool_t (*x_setpostn)();/* lets you reposition the stream */ + long * (*x_inline)(); /* buf quick ptr to buffered data */ + void (*x_destroy)(); /* free privates of this xdr_stream */ + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + int x_handy; /* extra private word */ +} XDR; + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +extern bool_t xdr_void(); +extern bool_t xdr_int(); +extern bool_t xdr_u_int(); +extern bool_t xdr_long(); +extern bool_t xdr_u_long(); +extern bool_t xdr_short(); +extern bool_t xdr_u_short(); +extern bool_t xdr_bool(); +extern bool_t xdr_enum(); +extern bool_t xdr_array(); +extern bool_t xdr_bytes(); +extern bool_t xdr_opaque(); +extern bool_t xdr_string(); +extern bool_t xdr_union(); +extern bool_t xdr_char(); +extern bool_t xdr_u_char(); +extern bool_t xdr_vector(); +extern bool_t xdr_float(); +extern bool_t xdr_double(); +extern bool_t xdr_reference(); +extern bool_t xdr_pointer(); +extern bool_t xdr_wrapstring(); + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj(); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +extern void xdrmem_create(); /* XDR using memory buffers */ +extern void xdrstdio_create(); /* XDR using stdio library */ +extern void xdrrec_create(); /* XDR pseudo records for tcp */ +extern bool_t xdrrec_endofrecord(); /* make end of xdr record */ +extern bool_t xdrrec_skiprecord(); /* move to beginning of next record */ +extern bool_t xdrrec_eof(); /* true if no more input */ + +#endif !__XDR_HEADER__ diff --git a/sunrpc/rpc_clntout.c b/sunrpc/rpc_clntout.c new file mode 100644 index 0000000000..555681bd2a --- /dev/null +++ b/sunrpc/rpc_clntout.c @@ -0,0 +1,126 @@ +/* @(#)rpc_clntout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_clntout.c 1.2 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_parse.h" +#include "rpc_util.h" + +#define DEFAULT_TIMEOUT 25 /* in seconds */ + +void +write_stubs() +{ + list *l; + definition *def; + + f_print(fout, + "\n/* Default timeout can be changed using clnt_control() */\n"); + f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n", + DEFAULT_TIMEOUT); + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + write_program(def); + } + } +} + + +static +write_program(def) + definition *def; +{ + version_list *vp; + proc_list *proc; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\n"); + ptype(proc->res_prefix, proc->res_type, 1); + f_print(fout, "*\n"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "(argp, clnt)\n"); + f_print(fout, "\t"); + ptype(proc->arg_prefix, proc->arg_type, 1); + f_print(fout, "*argp;\n"); + f_print(fout, "\tCLIENT *clnt;\n"); + f_print(fout, "{\n"); + printbody(proc); + f_print(fout, "}\n\n"); + } + } +} + +static char * +ampr(type) + char *type; +{ + if (isvectordef(type, REL_ALIAS)) { + return (""); + } else { + return ("&"); + } +} + +static +printbody(proc) + proc_list *proc; +{ + f_print(fout, "\tstatic "); + if (streq(proc->res_type, "void")) { + f_print(fout, "char "); + } else { + ptype(proc->res_prefix, proc->res_type, 0); + } + f_print(fout, "res;\n"); + f_print(fout, "\n"); + f_print(fout, "\tbzero((char *)%sres, sizeof(res));\n", + ampr(proc->res_type)); + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, argp, xdr_%s, %sres, TIMEOUT) != RPC_SUCCESS) {\n", + proc->proc_name, stringfix(proc->arg_type), + stringfix(proc->res_type), ampr(proc->res_type)); + f_print(fout, "\t\treturn (NULL);\n"); + f_print(fout, "\t}\n"); + if (streq(proc->res_type, "void")) { + f_print(fout, "\treturn ((void *)%sres);\n", + ampr(proc->res_type)); + } else { + f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type)); + } +} diff --git a/sunrpc/rpc_cmsg.c b/sunrpc/rpc_cmsg.c new file mode 100644 index 0000000000..d9d815a6fb --- /dev/null +++ b/sunrpc/rpc_cmsg.c @@ -0,0 +1,190 @@ +/* @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_callmsg.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* + * XDR a call message + */ +bool_t +xdr_callmsg(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + register long *buf; + register struct opaque_auth *oa; + + if (xdrs->x_op == XDR_ENCODE) { + if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_cred.oa_length) + + 2 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_verf.oa_length)); + if (buf != NULL) { + IXDR_PUT_LONG(buf, cmsg->rm_xid); + IXDR_PUT_ENUM(buf, cmsg->rm_direction); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); + oa = &cmsg->rm_call.cb_cred; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + buf += RNDUP(oa->oa_length) / sizeof (long); + } + oa = &cmsg->rm_call.cb_verf; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / sizeof (long); + */ + } + return (TRUE); + } + } + if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); + if (buf != NULL) { + cmsg->rm_xid = IXDR_GET_LONG(buf); + cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); + oa = &cmsg->rm_call.cb_cred; + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + oa = &cmsg->rm_call.cb_verf; + buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || + xdr_u_int(xdrs, &oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + } + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + return (TRUE); + } + } + if ( + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + (cmsg->rm_direction == CALL) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) && + xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) + return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); + return (FALSE); +} + diff --git a/sunrpc/rpc_common.c b/sunrpc/rpc_common.c new file mode 100644 index 0000000000..75cead0875 --- /dev/null +++ b/sunrpc/rpc_common.c @@ -0,0 +1,41 @@ +/* @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#include <rpc/rpc.h> +/* + * This file should only contain common data (global data) that is exported + * by public interfaces + */ +struct opaque_auth _null_auth; +#ifdef FD_SETSIZE +fd_set svc_fdset; +#else +int svc_fds; +#endif /* def FD_SETSIZE */ +struct rpc_createerr rpc_createerr; diff --git a/sunrpc/rpc_cout.c b/sunrpc/rpc_cout.c new file mode 100644 index 0000000000..86d38652f5 --- /dev/null +++ b/sunrpc/rpc_cout.c @@ -0,0 +1,350 @@ +/* @(#)rpc_cout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_cout.c 1.8 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_util.h" +#include "rpc_parse.h" + +/* + * Emit the C-routine for the given definition + */ +void +emit(def) + definition *def; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + return; + } + print_header(def); + switch (def->def_kind) { + case DEF_UNION: + emit_union(def); + break; + case DEF_ENUM: + emit_enum(def); + break; + case DEF_STRUCT: + emit_struct(def); + break; + case DEF_TYPEDEF: + emit_typedef(def); + break; + } + print_trailer(); +} + +static +findtype(def, type) + definition *def; + char *type; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +static +undefined(type) + char *type; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findtype); + return (def == NULL); +} + + +static +print_header(def) + definition *def; +{ + space(); + f_print(fout, "bool_t\n"); + f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name); + f_print(fout, "\tXDR *xdrs;\n"); + f_print(fout, "\t%s ", def->def_name); + if (def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, def->def.ty.rel)) { + f_print(fout, "*"); + } + f_print(fout, "objp;\n"); + f_print(fout, "{\n"); +} + +static +print_trailer() +{ + f_print(fout, "\treturn (TRUE);\n"); + f_print(fout, "}\n"); + space(); +} + + +static +print_ifopen(indent, name) + int indent; + char *name; +{ + tabify(fout, indent); + f_print(fout, "if (!xdr_%s(xdrs", name); +} + + +static +print_ifarg(arg) + char *arg; +{ + f_print(fout, ", %s", arg); +} + + +static +print_ifsizeof(prefix, type) + char *prefix; + char *type; +{ + if (streq(type, "bool")) { + f_print(fout, ", sizeof(bool_t), xdr_bool"); + } else { + f_print(fout, ", sizeof("); + if (undefined(type) && prefix) { + f_print(fout, "%s ", prefix); + } + f_print(fout, "%s), xdr_%s", type, type); + } +} + +static +print_ifclose(indent) + int indent; +{ + f_print(fout, ")) {\n"); + tabify(fout, indent); + f_print(fout, "\treturn (FALSE);\n"); + tabify(fout, indent); + f_print(fout, "}\n"); +} + +static +space() +{ + f_print(fout, "\n\n"); +} + +static +print_ifstat(indent, prefix, type, rel, amax, objname, name) + int indent; + char *prefix; + char *type; + relation rel; + char *amax; + char *objname; + char *name; +{ + char *alt = NULL; + + switch (rel) { + case REL_POINTER: + print_ifopen(indent, "pointer"); + print_ifarg("(char **)"); + f_print(fout, "%s", objname); + print_ifsizeof(prefix, type); + break; + case REL_VECTOR: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "opaque"; + } + if (alt) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + print_ifopen(indent, "vector"); + print_ifarg("(char *)"); + f_print(fout, "%s", objname); + } + print_ifarg(amax); + if (!alt) { + print_ifsizeof(prefix, type); + } + break; + case REL_ARRAY: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "bytes"; + } + if (streq(type, "string")) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + if (alt) { + print_ifopen(indent, alt); + } else { + print_ifopen(indent, "array"); + } + print_ifarg("(char **)"); + if (*objname == '&') { + f_print(fout, "%s.%s_val, (u_int *)%s.%s_len", + objname, name, objname, name); + } else { + f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", + objname, name, objname, name); + } + } + print_ifarg(amax); + if (!alt) { + print_ifsizeof(prefix, type); + } + break; + case REL_ALIAS: + print_ifopen(indent, type); + print_ifarg(objname); + break; + } + print_ifclose(indent); +} + + +/* ARGSUSED */ +static +emit_enum(def) + definition *def; +{ + print_ifopen(1, "enum"); + print_ifarg("(enum_t *)objp"); + print_ifclose(1); +} + + +static +emit_union(def) + definition *def; +{ + declaration *dflt; + case_list *cl; + declaration *cs; + char *object; + char *format = "&objp->%s_u.%s"; + + print_stat(&def->def.un.enum_decl); + f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); + for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { + cs = &cl->case_decl; + f_print(fout, "\tcase %s:\n", cl->case_name); + if (!streq(cs->type, "void")) { + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(cs->name) + 1); + s_print(object, format, def->def_name, cs->name); + print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, + object, cs->name); + free(object); + } + f_print(fout, "\t\tbreak;\n"); + } + dflt = def->def.un.default_decl; + if (dflt != NULL) { + if (!streq(dflt->type, "void")) { + f_print(fout, "\tdefault:\n"); + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(dflt->name) + 1); + s_print(object, format, def->def_name, dflt->name); + print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, + dflt->array_max, object, dflt->name); + free(object); + f_print(fout, "\t\tbreak;\n"); + } + } else { + f_print(fout, "\tdefault:\n"); + f_print(fout, "\t\treturn (FALSE);\n"); + } + f_print(fout, "\t}\n"); +} + + + +static +emit_struct(def) + definition *def; +{ + decl_list *dl; + + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { + print_stat(&dl->decl); + } +} + + + + +static +emit_typedef(def) + definition *def; +{ + char *prefix = def->def.ty.old_prefix; + char *type = def->def.ty.old_type; + char *amax = def->def.ty.array_max; + relation rel = def->def.ty.rel; + + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); +} + + + + + +static +print_stat(dec) + declaration *dec; +{ + char *prefix = dec->prefix; + char *type = dec->type; + char *amax = dec->array_max; + relation rel = dec->rel; + char name[256]; + + if (isvectordef(type, rel)) { + s_print(name, "objp->%s", dec->name); + } else { + s_print(name, "&objp->%s", dec->name); + } + print_ifstat(1, prefix, type, rel, amax, name, dec->name); +} diff --git a/sunrpc/rpc_dtable.c b/sunrpc/rpc_dtable.c new file mode 100644 index 0000000000..a8488172e4 --- /dev/null +++ b/sunrpc/rpc_dtable.c @@ -0,0 +1,46 @@ +/* @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro"; +#endif + +/* + * Cache the result of getdtablesize(), so we don't have to do an + * expensive system call every time. + */ +_rpc_dtablesize() +{ + static int size; + + if (size == 0) { + size = getdtablesize(); + } + return (size); +} diff --git a/sunrpc/rpc_hout.c b/sunrpc/rpc_hout.c new file mode 100644 index 0000000000..1bf009738d --- /dev/null +++ b/sunrpc/rpc_hout.c @@ -0,0 +1,370 @@ +/* @(#)rpc_hout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_hout.c 1.6 87/07/28 (C) 1987 SMI"; +#endif + +/* + * rpc_hout.c, Header file outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include "rpc_util.h" +#include "rpc_parse.h" + + +/* + * Print the C-version of an xdr definition + */ +void +print_datadef(def) + definition *def; +{ + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } + switch (def->def_kind) { + case DEF_STRUCT: + pstructdef(def); + break; + case DEF_UNION: + puniondef(def); + break; + case DEF_ENUM: + penumdef(def); + break; + case DEF_TYPEDEF: + ptypedef(def); + break; + case DEF_PROGRAM: + pprogramdef(def); + break; + case DEF_CONST: + pconstdef(def); + break; + } + if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { + f_print(fout, "bool_t xdr_%s();\n", def->def_name); + } + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } +} + +static +pconstdef(def) + definition *def; +{ + pdefine(def->def_name, def->def.co); +} + +static +pstructdef(def) + definition *def; +{ + decl_list *l; + char *name = def->def_name; + + f_print(fout, "struct %s {\n", name); + for (l = def->def.st.decls; l != NULL; l = l->next) { + pdeclaration(name, &l->decl, 1); + } + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + +static +puniondef(def) + definition *def; +{ + case_list *l; + char *name = def->def_name; + declaration *decl; + + f_print(fout, "struct %s {\n", name); + decl = &def->def.un.enum_decl; + if (streq(decl->type, "bool")) { + f_print(fout, "\tbool_t %s;\n", decl->name); + } else { + f_print(fout, "\t%s %s;\n", decl->type, decl->name); + } + f_print(fout, "\tunion {\n"); + for (l = def->def.un.cases; l != NULL; l = l->next) { + pdeclaration(name, &l->case_decl, 2); + } + decl = def->def.un.default_decl; + if (decl && !streq(decl->type, "void")) { + pdeclaration(name, decl, 2); + } + f_print(fout, "\t} %s_u;\n", name); + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + + + +static +pdefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s %s\n", name, num); +} + +static +puldefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s ((u_long)%s)\n", name, num); +} + +static +define_printed(stop, start) + proc_list *stop; + version_list *start; +{ + version_list *vers; + proc_list *proc; + + for (vers = start; vers != NULL; vers = vers->next) { + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (proc == stop) { + return (0); + } else if (streq(proc->proc_name, stop->proc_name)) { + return (1); + } + } + } + abort(); + /* NOTREACHED */ +} + + +static +pprogramdef(def) + definition *def; +{ + version_list *vers; + proc_list *proc; + + puldefine(def->def_name, def->def.pr.prog_num); + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { + puldefine(vers->vers_name, vers->vers_num); + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (!define_printed(proc, def->def.pr.versions)) { + puldefine(proc->proc_name, proc->proc_num); + } + pprocdef(proc, vers); + } + } +} + + +pprocdef(proc, vp) + proc_list *proc; + version_list *vp; +{ + f_print(fout, "extern "); + if (proc->res_prefix) { + if (streq(proc->res_prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(proc->res_type, "bool")) { + f_print(fout, "bool_t *"); + } else if (streq(proc->res_type, "string")) { + f_print(fout, "char **"); + } else { + f_print(fout, "%s *", fixtype(proc->res_type)); + } + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "();\n"); +} + +static +penumdef(def) + definition *def; +{ + char *name = def->def_name; + enumval_list *l; + char *last = NULL; + int count = 0; + + f_print(fout, "enum %s {\n", name); + for (l = def->def.en.vals; l != NULL; l = l->next) { + f_print(fout, "\t%s", l->name); + if (l->assignment) { + f_print(fout, " = %s", l->assignment); + last = l->assignment; + count = 1; + } else { + if (last == NULL) { + f_print(fout, " = %d", count++); + } else { + f_print(fout, " = %s + %d", last, count++); + } + } + f_print(fout, ",\n"); + } + f_print(fout, "};\n"); + f_print(fout, "typedef enum %s %s;\n", name, name); +} + +static +ptypedef(def) + definition *def; +{ + char *name = def->def_name; + char *old = def->def.ty.old_type; + char prefix[8]; /* enough to contain "struct ", including NUL */ + relation rel = def->def.ty.rel; + + + if (!streq(name, old)) { + if (streq(old, "string")) { + old = "char"; + rel = REL_POINTER; + } else if (streq(old, "opaque")) { + old = "char"; + } else if (streq(old, "bool")) { + old = "bool_t"; + } + if (undefined2(old, name) && def->def.ty.old_prefix) { + s_print(prefix, "%s ", def->def.ty.old_prefix); + } else { + prefix[0] = 0; + } + f_print(fout, "typedef "); + switch (rel) { + case REL_ARRAY: + f_print(fout, "struct {\n"); + f_print(fout, "\tu_int %s_len;\n", name); + f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); + f_print(fout, "} %s", name); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, old, name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, old, name, + def->def.ty.array_max); + break; + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, old, name); + break; + } + f_print(fout, ";\n"); + } +} + + +static +pdeclaration(name, dec, tab) + char *name; + declaration *dec; + int tab; +{ + char buf[8]; /* enough to hold "struct ", include NUL */ + char *prefix; + char *type; + + if (streq(dec->type, "void")) { + return; + } + tabify(fout, tab); + if (streq(dec->type, name) && !dec->prefix) { + f_print(fout, "struct "); + } + if (streq(dec->type, "string")) { + f_print(fout, "char *%s", dec->name); + } else { + prefix = ""; + if (streq(dec->type, "bool")) { + type = "bool_t"; + } else if (streq(dec->type, "opaque")) { + type = "char"; + } else { + if (dec->prefix) { + s_print(buf, "%s ", dec->prefix); + prefix = buf; + } + type = dec->type; + } + switch (dec->rel) { + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, type, dec->name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, + dec->array_max); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, type, dec->name); + break; + case REL_ARRAY: + f_print(fout, "struct {\n"); + tabify(fout, tab); + f_print(fout, "\tu_int %s_len;\n", dec->name); + tabify(fout, tab); + f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); + tabify(fout, tab); + f_print(fout, "} %s", dec->name); + break; + } + } + f_print(fout, ";\n"); +} + + + +static +undefined2(type, stop) + char *type; + char *stop; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + if (streq(def->def_name, stop)) { + return (1); + } else if (streq(def->def_name, type)) { + return (0); + } + } + } + return (1); +} diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c new file mode 100644 index 0000000000..795bf2aa57 --- /dev/null +++ b/sunrpc/rpc_main.c @@ -0,0 +1,433 @@ +/* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_main.c, Top level of the RPC protocol compiler. + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include "rpc_util.h" +#include "rpc_parse.h" +#include "rpc_scan.h" + +#define EXTEND 1 /* alias for TRUE */ + +struct commandline { + int cflag; + int hflag; + int lflag; + int sflag; + int mflag; + char *infile; + char *outfile; +}; + +static char *cmdname; +static char CPP[] = "/lib/cpp"; +static char CPPFLAGS[] = "-C"; +static char *allv[] = { + "rpcgen", "-s", "udp", "-s", "tcp", +}; +static int allc = sizeof(allv)/sizeof(allv[0]); + +main(argc, argv) + int argc; + char *argv[]; + +{ + struct commandline cmd; + + if (!parseargs(argc, argv, &cmd)) { + f_print(stderr, + "usage: %s infile\n", cmdname); + f_print(stderr, + " %s [-c | -h | -l | -m] [-o outfile] [infile]\n", + cmdname); + f_print(stderr, + " %s [-s udp|tcp]* [-o outfile] [infile]\n", + cmdname); + exit(1); + } + if (cmd.cflag) { + c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); + } else if (cmd.hflag) { + h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); + } else if (cmd.lflag) { + l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); + } else if (cmd.sflag || cmd.mflag) { + s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, + cmd.outfile, cmd.mflag); + } else { + c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); + reinitialize(); + h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); + reinitialize(); + l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); + reinitialize(); + s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, + "_svc.c", cmd.mflag); + } + exit(0); +} + +/* + * add extension to filename + */ +static char * +extendfile(file, ext) + char *file; + char *ext; +{ + char *res; + char *p; + + res = alloc(strlen(file) + strlen(ext) + 1); + if (res == NULL) { + abort(); + } + p = rindex(file, '.'); + if (p == NULL) { + p = file + strlen(file); + } + (void) strcpy(res, file); + (void) strcpy(res + (p - file), ext); + return (res); +} + +/* + * Open output file with given extension + */ +static +open_output(infile, outfile) + char *infile; + char *outfile; +{ + if (outfile == NULL) { + fout = stdout; + return; + } + if (infile != NULL && streq(outfile, infile)) { + f_print(stderr, "%s: output would overwrite %s\n", cmdname, + infile); + crash(); + } + fout = fopen(outfile, "w"); + if (fout == NULL) { + f_print(stderr, "%s: unable to open ", cmdname); + perror(outfile); + crash(); + } + record_open(outfile); +} + +/* + * Open input file with given define for C-preprocessor + */ +static +open_input(infile, define) + char *infile; + char *define; +{ + int pd[2]; + + infilename = (infile == NULL) ? "<stdin>" : infile; + (void) pipe(pd); + switch (fork()) { + case 0: + (void) close(1); + (void) dup2(pd[1], 1); + (void) close(pd[0]); + execl(CPP, CPP, CPPFLAGS, define, infile, NULL); + perror("execl"); + exit(1); + case -1: + perror("fork"); + exit(1); + } + (void) close(pd[1]); + fin = fdopen(pd[0], "r"); + if (fin == NULL) { + f_print(stderr, "%s: ", cmdname); + perror(infilename); + crash(); + } +} + +/* + * Compile into an XDR routine output file + */ +static +c_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *include; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + tell = ftell(fout); + while (def = get_definition()) { + emit(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an XDR header file + */ +static +h_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + tell = ftell(fout); + while (def = get_definition()) { + print_datadef(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an RPC service + */ +static +s_output(argc, argv, infile, define, extend, outfile, nomain) + int argc; + char *argv[]; + char *infile; + char *define; + int extend; + char *outfile; + int nomain; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + if (nomain) { + write_programs((char *)NULL); + } else { + write_most(); + do_registers(argc, argv); + write_rest(); + write_programs("static"); + } +} + +static +l_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + write_stubs(); +} + +/* + * Perform registrations for service output + */ +static +do_registers(argc, argv) + int argc; + char *argv[]; + +{ + int i; + + for (i = 1; i < argc; i++) { + if (streq(argv[i], "-s")) { + write_register(argv[i + 1]); + i++; + } + } +} + +/* + * Parse command line arguments + */ +static +parseargs(argc, argv, cmd) + int argc; + char *argv[]; + struct commandline *cmd; + +{ + int i; + int j; + char c; + char flag[(1 << 8 * sizeof(char))]; + int nflags; + + cmdname = argv[0]; + cmd->infile = cmd->outfile = NULL; + if (argc < 2) { + return (0); + } + flag['c'] = 0; + flag['h'] = 0; + flag['s'] = 0; + flag['o'] = 0; + flag['l'] = 0; + flag['m'] = 0; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + if (cmd->infile) { + return (0); + } + cmd->infile = argv[i]; + } else { + for (j = 1; argv[i][j] != 0; j++) { + c = argv[i][j]; + switch (c) { + case 'c': + case 'h': + case 'l': + case 'm': + if (flag[c]) { + return (0); + } + flag[c] = 1; + break; + case 'o': + case 's': + if (argv[i][j - 1] != '-' || + argv[i][j + 1] != 0) { + return (0); + } + flag[c] = 1; + if (++i == argc) { + return (0); + } + if (c == 's') { + if (!streq(argv[i], "udp") && + !streq(argv[i], "tcp")) { + return (0); + } + } else if (c == 'o') { + if (cmd->outfile) { + return (0); + } + cmd->outfile = argv[i]; + } + goto nextarg; + + default: + return (0); + } + } + nextarg: + ; + } + } + cmd->cflag = flag['c']; + cmd->hflag = flag['h']; + cmd->sflag = flag['s']; + cmd->lflag = flag['l']; + cmd->mflag = flag['m']; + nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; + if (nflags == 0) { + if (cmd->outfile != NULL || cmd->infile == NULL) { + return (0); + } + } else if (nflags > 1) { + return (0); + } + return (1); +} diff --git a/sunrpc/rpc_parse.c b/sunrpc/rpc_parse.c new file mode 100644 index 0000000000..9e4663fb36 --- /dev/null +++ b/sunrpc/rpc_parse.c @@ -0,0 +1,419 @@ +/* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI"; +#endif + +/* + * rpc_parse.c, Parser for the RPC protocol compiler + * Copyright (C) 1987 Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_util.h" +#include "rpc_scan.h" +#include "rpc_parse.h" + +/* + * return the next definition you see + */ +definition * +get_definition() +{ + definition *defp; + token tok; + + defp = ALLOC(definition); + get_token(&tok); + switch (tok.kind) { + case TOK_STRUCT: + def_struct(defp); + break; + case TOK_UNION: + def_union(defp); + break; + case TOK_TYPEDEF: + def_typedef(defp); + break; + case TOK_ENUM: + def_enum(defp); + break; + case TOK_PROGRAM: + def_program(defp); + break; + case TOK_CONST: + def_const(defp); + break; + case TOK_EOF: + return (NULL); + break; + default: + error("definition keyword expected"); + } + scan(TOK_SEMICOLON, &tok); + isdefined(defp); + return (defp); +} + +static +isdefined(defp) + definition *defp; +{ + STOREVAL(&defined, defp); +} + + +static +def_struct(defp) + definition *defp; +{ + token tok; + declaration dec; + decl_list *decls; + decl_list **tailp; + + defp->def_kind = DEF_STRUCT; + + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.st.decls; + do { + get_declaration(&dec, DEF_STRUCT); + decls = ALLOC(decl_list); + decls->decl = dec; + *tailp = decls; + tailp = &decls->next; + scan(TOK_SEMICOLON, &tok); + peek(&tok); + } while (tok.kind != TOK_RBRACE); + get_token(&tok); + *tailp = NULL; +} + +static +def_program(defp) + definition *defp; +{ + token tok; + version_list *vlist; + version_list **vtailp; + proc_list *plist; + proc_list **ptailp; + + defp->def_kind = DEF_PROGRAM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + vtailp = &defp->def.pr.versions; + scan(TOK_VERSION, &tok); + do { + scan(TOK_IDENT, &tok); + vlist = ALLOC(version_list); + vlist->vers_name = tok.str; + scan(TOK_LBRACE, &tok); + ptailp = &vlist->procs; + do { + plist = ALLOC(proc_list); + get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM); + if (streq(plist->res_type, "opaque")) { + error("illegal result type"); + } + scan(TOK_IDENT, &tok); + plist->proc_name = tok.str; + scan(TOK_LPAREN, &tok); + get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); + if (streq(plist->arg_type, "opaque")) { + error("illegal argument type"); + } + scan(TOK_RPAREN, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + scan(TOK_SEMICOLON, &tok); + plist->proc_num = tok.str; + *ptailp = plist; + ptailp = &plist->next; + peek(&tok); + } while (tok.kind != TOK_RBRACE); + *vtailp = vlist; + vtailp = &vlist->next; + scan(TOK_RBRACE, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + vlist->vers_num = tok.str; + scan(TOK_SEMICOLON, &tok); + scan2(TOK_VERSION, TOK_RBRACE, &tok); + } while (tok.kind == TOK_VERSION); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + defp->def.pr.prog_num = tok.str; + *vtailp = NULL; +} + +static +def_enum(defp) + definition *defp; +{ + token tok; + enumval_list *elist; + enumval_list **tailp; + + defp->def_kind = DEF_ENUM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.en.vals; + do { + scan(TOK_IDENT, &tok); + elist = ALLOC(enumval_list); + elist->name = tok.str; + elist->assignment = NULL; + scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); + if (tok.kind == TOK_EQUAL) { + scan_num(&tok); + elist->assignment = tok.str; + scan2(TOK_COMMA, TOK_RBRACE, &tok); + } + *tailp = elist; + tailp = &elist->next; + } while (tok.kind != TOK_RBRACE); + *tailp = NULL; +} + +static +def_const(defp) + definition *defp; +{ + token tok; + + defp->def_kind = DEF_CONST; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_EQUAL, &tok); + scan2(TOK_IDENT, TOK_STRCONST, &tok); + defp->def.co = tok.str; +} + +static +def_union(defp) + definition *defp; +{ + token tok; + declaration dec; + case_list *cases; + case_list **tailp; + + defp->def_kind = DEF_UNION; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_SWITCH, &tok); + scan(TOK_LPAREN, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.enum_decl = dec; + tailp = &defp->def.un.cases; + scan(TOK_RPAREN, &tok); + scan(TOK_LBRACE, &tok); + scan(TOK_CASE, &tok); + while (tok.kind == TOK_CASE) { + scan(TOK_IDENT, &tok); + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + cases->case_decl = dec; + *tailp = cases; + tailp = &cases->next; + scan(TOK_SEMICOLON, &tok); + scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); + } + *tailp = NULL; + if (tok.kind == TOK_DEFAULT) { + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.default_decl = ALLOC(declaration); + *defp->def.un.default_decl = dec; + scan(TOK_SEMICOLON, &tok); + scan(TOK_RBRACE, &tok); + } else { + defp->def.un.default_decl = NULL; + } +} + + +static +def_typedef(defp) + definition *defp; +{ + declaration dec; + + defp->def_kind = DEF_TYPEDEF; + get_declaration(&dec, DEF_TYPEDEF); + defp->def_name = dec.name; + defp->def.ty.old_prefix = dec.prefix; + defp->def.ty.old_type = dec.type; + defp->def.ty.rel = dec.rel; + defp->def.ty.array_max = dec.array_max; +} + + +static +get_declaration(dec, dkind) + declaration *dec; + defkind dkind; +{ + token tok; + + get_type(&dec->prefix, &dec->type, dkind); + dec->rel = REL_ALIAS; + if (streq(dec->type, "void")) { + return; + } + scan2(TOK_STAR, TOK_IDENT, &tok); + if (tok.kind == TOK_STAR) { + dec->rel = REL_POINTER; + scan(TOK_IDENT, &tok); + } + dec->name = tok.str; + if (peekscan(TOK_LBRACKET, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_VECTOR; + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RBRACKET, &tok); + } else if (peekscan(TOK_LANGLE, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_ARRAY; + if (peekscan(TOK_RANGLE, &tok)) { + dec->array_max = "~0"; /* unspecified size, use max */ + } else { + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RANGLE, &tok); + } + } + if (streq(dec->type, "opaque")) { + if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { + error("array declaration expected"); + } + } else if (streq(dec->type, "string")) { + if (dec->rel != REL_ARRAY) { + error("variable-length array declaration expected"); + } + } +} + + +static +get_type(prefixp, typep, dkind) + char **prefixp; + char **typep; + defkind dkind; +{ + token tok; + + *prefixp = NULL; + get_token(&tok); + switch (tok.kind) { + case TOK_IDENT: + *typep = tok.str; + break; + case TOK_STRUCT: + case TOK_ENUM: + case TOK_UNION: + *prefixp = tok.str; + scan(TOK_IDENT, &tok); + *typep = tok.str; + break; + case TOK_UNSIGNED: + unsigned_dec(typep); + break; + case TOK_SHORT: + *typep = "short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_LONG: + *typep = "long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_VOID: + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { + error("voids allowed only inside union and program definitions"); + } + *typep = tok.str; + break; + case TOK_STRING: + case TOK_OPAQUE: + case TOK_CHAR: + case TOK_INT: + case TOK_FLOAT: + case TOK_DOUBLE: + case TOK_BOOL: + *typep = tok.str; + break; + default: + error("expected type specifier"); + } +} + + +static +unsigned_dec(typep) + char **typep; +{ + token tok; + + peek(&tok); + switch (tok.kind) { + case TOK_CHAR: + get_token(&tok); + *typep = "u_char"; + break; + case TOK_SHORT: + get_token(&tok); + *typep = "u_short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_LONG: + get_token(&tok); + *typep = "u_long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT: + get_token(&tok); + *typep = "u_int"; + break; + default: + *typep = "u_int"; + break; + } +} diff --git a/sunrpc/rpc_parse.h b/sunrpc/rpc_parse.h new file mode 100644 index 0000000000..b53cc56ff8 --- /dev/null +++ b/sunrpc/rpc_parse.h @@ -0,0 +1,157 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI */ + +/* + * rpc_parse.h, Definitions for the RPCL parser + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +enum defkind { + DEF_CONST, + DEF_STRUCT, + DEF_UNION, + DEF_ENUM, + DEF_TYPEDEF, + DEF_PROGRAM +}; +typedef enum defkind defkind; + +typedef char *const_def; + +enum relation { + REL_VECTOR, /* fixed length array */ + REL_ARRAY, /* variable length array */ + REL_POINTER, /* pointer */ + REL_ALIAS, /* simple */ +}; +typedef enum relation relation; + +struct typedef_def { + char *old_prefix; + char *old_type; + relation rel; + char *array_max; +}; +typedef struct typedef_def typedef_def; + + +struct enumval_list { + char *name; + char *assignment; + struct enumval_list *next; +}; +typedef struct enumval_list enumval_list; + +struct enum_def { + enumval_list *vals; +}; +typedef struct enum_def enum_def; + + +struct declaration { + char *prefix; + char *type; + char *name; + relation rel; + char *array_max; +}; +typedef struct declaration declaration; + + +struct decl_list { + declaration decl; + struct decl_list *next; +}; +typedef struct decl_list decl_list; + +struct struct_def { + decl_list *decls; +}; +typedef struct struct_def struct_def; + + +struct case_list { + char *case_name; + declaration case_decl; + struct case_list *next; +}; +typedef struct case_list case_list; + +struct union_def { + declaration enum_decl; + case_list *cases; + declaration *default_decl; +}; +typedef struct union_def union_def; + + + +struct proc_list { + char *proc_name; + char *proc_num; + char *arg_type; + char *arg_prefix; + char *res_type; + char *res_prefix; + struct proc_list *next; +}; +typedef struct proc_list proc_list; + + +struct version_list { + char *vers_name; + char *vers_num; + proc_list *procs; + struct version_list *next; +}; +typedef struct version_list version_list; + +struct program_def { + char *prog_num; + version_list *versions; +}; +typedef struct program_def program_def; + +struct definition { + char *def_name; + defkind def_kind; + union { + const_def co; + struct_def st; + union_def un; + enum_def en; + typedef_def ty; + program_def pr; + } def; +}; +typedef struct definition definition; + +/* @(#)rpc_parse.h 2.1 88/08/01 4.0 RPCSRC */ +definition *get_definition(); diff --git a/sunrpc/rpc_prot.c b/sunrpc/rpc_prot.c new file mode 100644 index 0000000000..4b1319ad56 --- /dev/null +++ b/sunrpc/rpc_prot.c @@ -0,0 +1,289 @@ +/* @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_prot.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements the rpc message definition, + * its serializer and some common rpc utility routines. + * The routines are meant for various implementations of rpc - + * they are NOT for the rpc client or rpc service implementations! + * Because authentication stuff is easy and is part of rpc, the opaque + * routines are also in this program. + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ + +struct opaque_auth _null_auth; + +/* + * XDR an opaque authentication struct + * (see auth.h) + */ +bool_t +xdr_opaque_auth(xdrs, ap) + register XDR *xdrs; + register struct opaque_auth *ap; +{ + + if (xdr_enum(xdrs, &(ap->oa_flavor))) + return (xdr_bytes(xdrs, &ap->oa_base, + &ap->oa_length, MAX_AUTH_BYTES)); + return (FALSE); +} + +/* + * XDR a DES block + */ +bool_t +xdr_des_block(xdrs, blkp) + register XDR *xdrs; + register des_block *blkp; +{ + return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); +} + +/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ + +/* + * XDR the MSG_ACCEPTED part of a reply message union + */ +bool_t +xdr_accepted_reply(xdrs, ar) + register XDR *xdrs; + register struct accepted_reply *ar; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) + return (FALSE); + if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) + return (FALSE); + switch (ar->ar_stat) { + + case SUCCESS: + return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); + + case PROG_MISMATCH: + if (! xdr_u_long(xdrs, &(ar->ar_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(ar->ar_vers.high))); + } + return (TRUE); /* TRUE => open ended set of problems */ +} + +/* + * XDR the MSG_DENIED part of a reply message union + */ +bool_t +xdr_rejected_reply(xdrs, rr) + register XDR *xdrs; + register struct rejected_reply *rr; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) + return (FALSE); + switch (rr->rj_stat) { + + case RPC_MISMATCH: + if (! xdr_u_long(xdrs, &(rr->rj_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(rr->rj_vers.high))); + + case AUTH_ERROR: + return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); + } + return (FALSE); +} + +static struct xdr_discrim reply_dscrm[3] = { + { (int)MSG_ACCEPTED, xdr_accepted_reply }, + { (int)MSG_DENIED, xdr_rejected_reply }, + { __dontcare__, NULL_xdrproc_t } }; + +/* + * XDR a reply message + */ +bool_t +xdr_replymsg(xdrs, rmsg) + register XDR *xdrs; + register struct rpc_msg *rmsg; +{ + if ( + xdr_u_long(xdrs, &(rmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && + (rmsg->rm_direction == REPLY) ) + return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), + (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); + return (FALSE); +} + + +/* + * Serializes the "static part" of a call message header. + * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. + * The rm_xid is not really static, but the user can easily munge on the fly. + */ +bool_t +xdr_callhdr(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + + cmsg->rm_direction = CALL; + cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; + if ( + (xdrs->x_op == XDR_ENCODE) && + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) ) + return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers))); + return (FALSE); +} + +/* ************************** Client utility routine ************* */ + +static void +accepted(acpt_stat, error) + register enum accept_stat acpt_stat; + register struct rpc_err *error; +{ + + switch (acpt_stat) { + + case PROG_UNAVAIL: + error->re_status = RPC_PROGUNAVAIL; + return; + + case PROG_MISMATCH: + error->re_status = RPC_PROGVERSMISMATCH; + return; + + case PROC_UNAVAIL: + error->re_status = RPC_PROCUNAVAIL; + return; + + case GARBAGE_ARGS: + error->re_status = RPC_CANTDECODEARGS; + return; + + case SYSTEM_ERR: + error->re_status = RPC_SYSTEMERROR; + return; + + case SUCCESS: + error->re_status = RPC_SUCCESS; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_ACCEPTED; + error->re_lb.s2 = (long)acpt_stat; +} + +static void +rejected(rjct_stat, error) + register enum reject_stat rjct_stat; + register struct rpc_err *error; +{ + + switch (rjct_stat) { + + case RPC_VERSMISMATCH: + error->re_status = RPC_VERSMISMATCH; + return; + + case AUTH_ERROR: + error->re_status = RPC_AUTHERROR; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_DENIED; + error->re_lb.s2 = (long)rjct_stat; +} + +/* + * given a reply message, fills in the error + */ +void +_seterr_reply(msg, error) + register struct rpc_msg *msg; + register struct rpc_err *error; +{ + + /* optimized for normal, SUCCESSful case */ + switch (msg->rm_reply.rp_stat) { + + case MSG_ACCEPTED: + if (msg->acpted_rply.ar_stat == SUCCESS) { + error->re_status = RPC_SUCCESS; + return; + }; + accepted(msg->acpted_rply.ar_stat, error); + break; + + case MSG_DENIED: + rejected(msg->rjcted_rply.rj_stat, error); + break; + + default: + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); + break; + } + switch (error->re_status) { + + case RPC_VERSMISMATCH: + error->re_vers.low = msg->rjcted_rply.rj_vers.low; + error->re_vers.high = msg->rjcted_rply.rj_vers.high; + break; + + case RPC_AUTHERROR: + error->re_why = msg->rjcted_rply.rj_why; + break; + + case RPC_PROGVERSMISMATCH: + error->re_vers.low = msg->acpted_rply.ar_vers.low; + error->re_vers.high = msg->acpted_rply.ar_vers.high; + break; + } +} diff --git a/sunrpc/rpc_scan.c b/sunrpc/rpc_scan.c new file mode 100644 index 0000000000..e46a1b5f2b --- /dev/null +++ b/sunrpc/rpc_scan.c @@ -0,0 +1,473 @@ +/* @(#)rpc_scan.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_scan.c, Scanner for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include <strings.h> +#include "rpc_scan.h" +#include "rpc_util.h" + +#define startcomment(where) (where[0] == '/' && where[1] == '*') +#define endcomment(where) (where[-1] == '*' && where[0] == '/') + +static int pushed = 0; /* is a token pushed */ +static token lasttok; /* last token, if pushed */ + +/* + * scan expecting 1 given token + */ +void +scan(expect, tokp) + tok_kind expect; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect) { + expected1(expect); + } +} + +/* + * scan expecting 2 given tokens + */ +void +scan2(expect1, expect2, tokp) + tok_kind expect1; + tok_kind expect2; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect1 && tokp->kind != expect2) { + expected2(expect1, expect2); + } +} + +/* + * scan expecting 3 given token + */ +void +scan3(expect1, expect2, expect3, tokp) + tok_kind expect1; + tok_kind expect2; + tok_kind expect3; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect1 && tokp->kind != expect2 + && tokp->kind != expect3) { + expected3(expect1, expect2, expect3); + } +} + + +/* + * scan expecting a constant, possibly symbolic + */ +void +scan_num(tokp) + token *tokp; +{ + get_token(tokp); + switch (tokp->kind) { + case TOK_IDENT: + break; + default: + error("constant or identifier expected"); + } +} + + +/* + * Peek at the next token + */ +void +peek(tokp) + token *tokp; +{ + get_token(tokp); + unget_token(tokp); +} + + +/* + * Peek at the next token and scan it if it matches what you expect + */ +int +peekscan(expect, tokp) + tok_kind expect; + token *tokp; +{ + peek(tokp); + if (tokp->kind == expect) { + get_token(tokp); + return (1); + } + return (0); +} + + + +/* + * Get the next token, printing out any directive that are encountered. + */ +void +get_token(tokp) + token *tokp; +{ + int commenting; + + if (pushed) { + pushed = 0; + *tokp = lasttok; + return; + } + commenting = 0; + for (;;) { + if (*where == 0) { + for (;;) { + if (!fgets(curline, MAXLINESIZE, fin)) { + tokp->kind = TOK_EOF; + *where = 0; + return; + } + linenum++; + if (commenting) { + break; + } else if (cppline(curline)) { + docppline(curline, &linenum, + &infilename); + } else if (directive(curline)) { + printdirective(curline); + } else { + break; + } + } + where = curline; + } else if (isspace(*where)) { + while (isspace(*where)) { + where++; /* eat */ + } + } else if (commenting) { + where++; + if (endcomment(where)) { + where++; + commenting--; + } + } else if (startcomment(where)) { + where += 2; + commenting++; + } else { + break; + } + } + + /* + * 'where' is not whitespace, comment or directive Must be a token! + */ + switch (*where) { + case ':': + tokp->kind = TOK_COLON; + where++; + break; + case ';': + tokp->kind = TOK_SEMICOLON; + where++; + break; + case ',': + tokp->kind = TOK_COMMA; + where++; + break; + case '=': + tokp->kind = TOK_EQUAL; + where++; + break; + case '*': + tokp->kind = TOK_STAR; + where++; + break; + case '[': + tokp->kind = TOK_LBRACKET; + where++; + break; + case ']': + tokp->kind = TOK_RBRACKET; + where++; + break; + case '{': + tokp->kind = TOK_LBRACE; + where++; + break; + case '}': + tokp->kind = TOK_RBRACE; + where++; + break; + case '(': + tokp->kind = TOK_LPAREN; + where++; + break; + case ')': + tokp->kind = TOK_RPAREN; + where++; + break; + case '<': + tokp->kind = TOK_LANGLE; + where++; + break; + case '>': + tokp->kind = TOK_RANGLE; + where++; + break; + + case '"': + tokp->kind = TOK_STRCONST; + findstrconst(&where, &tokp->str); + break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tokp->kind = TOK_IDENT; + findconst(&where, &tokp->str); + break; + + + default: + if (!(isalpha(*where) || *where == '_')) { + char buf[100]; + char *p; + + s_print(buf, "illegal character in file: "); + p = buf + strlen(buf); + if (isprint(*where)) { + s_print(p, "%c", *where); + } else { + s_print(p, "%d", *where); + } + error(buf); + } + findkind(&where, tokp); + break; + } +} + + + +static +unget_token(tokp) + token *tokp; +{ + lasttok = *tokp; + pushed = 1; +} + + +static +findstrconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + do { + *p++; + } while (*p && *p != '"'); + if (*p == 0) { + error("unterminated string constant"); + } + p++; + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + +static +findconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + if (*p == '0' && *(p + 1) == 'x') { + p++; + do { + p++; + } while (isxdigit(*p)); + } else { + do { + p++; + } while (isdigit(*p)); + } + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + + + +static token symbols[] = { + {TOK_CONST, "const"}, + {TOK_UNION, "union"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_STRUCT, "struct"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_ENUM, "enum"}, + {TOK_OPAQUE, "opaque"}, + {TOK_BOOL, "bool"}, + {TOK_VOID, "void"}, + {TOK_CHAR, "char"}, + {TOK_INT, "int"}, + {TOK_UNSIGNED, "unsigned"}, + {TOK_SHORT, "short"}, + {TOK_LONG, "long"}, + {TOK_FLOAT, "float"}, + {TOK_DOUBLE, "double"}, + {TOK_STRING, "string"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"}, +}; + + +static +findkind(mark, tokp) + char **mark; + token *tokp; +{ + + int len; + token *s; + char *str; + + str = *mark; + for (s = symbols; s->kind != TOK_EOF; s++) { + len = strlen(s->str); + if (strncmp(str, s->str, len) == 0) { + if (!isalnum(str[len]) && str[len] != '_') { + tokp->kind = s->kind; + tokp->str = s->str; + *mark = str + len; + return; + } + } + } + tokp->kind = TOK_IDENT; + for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); + tokp->str = alloc(len + 1); + (void) strncpy(tokp->str, str, len); + tokp->str[len] = 0; + *mark = str + len; +} + +static +cppline(line) + char *line; +{ + return (line == curline && *line == '#'); +} + +static +directive(line) + char *line; +{ + return (line == curline && *line == '%'); +} + +static +printdirective(line) + char *line; +{ + f_print(fout, "%s", line + 1); +} + +static +docppline(line, lineno, fname) + char *line; + int *lineno; + char **fname; +{ + char *file; + int num; + char *p; + + line++; + while (isspace(*line)) { + line++; + } + num = atoi(line); + while (isdigit(*line)) { + line++; + } + while (isspace(*line)) { + line++; + } + if (*line != '"') { + error("preprocessor error"); + } + line++; + p = file = alloc(strlen(line) + 1); + while (*line && *line != '"') { + *p++ = *line++; + } + if (*line == 0) { + error("preprocessor error"); + } + *p = 0; + if (*file == 0) { + *fname = NULL; + } else { + *fname = file; + } + *lineno = num - 1; +} diff --git a/sunrpc/rpc_scan.h b/sunrpc/rpc_scan.h new file mode 100644 index 0000000000..ad243d59c1 --- /dev/null +++ b/sunrpc/rpc_scan.h @@ -0,0 +1,101 @@ +/* @(#)rpc_scan.h 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc_scan.h 1.3 87/03/09 (C) 1987 SMI */ + +/* + * rpc_scan.h, Definitions for the RPCL scanner + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +/* + * kinds of tokens + */ +enum tok_kind { + TOK_IDENT, + TOK_STRCONST, + TOK_LPAREN, + TOK_RPAREN, + TOK_LBRACE, + TOK_RBRACE, + TOK_LBRACKET, + TOK_RBRACKET, + TOK_LANGLE, + TOK_RANGLE, + TOK_STAR, + TOK_COMMA, + TOK_EQUAL, + TOK_COLON, + TOK_SEMICOLON, + TOK_CONST, + TOK_STRUCT, + TOK_UNION, + TOK_SWITCH, + TOK_CASE, + TOK_DEFAULT, + TOK_ENUM, + TOK_TYPEDEF, + TOK_INT, + TOK_SHORT, + TOK_LONG, + TOK_UNSIGNED, + TOK_FLOAT, + TOK_DOUBLE, + TOK_OPAQUE, + TOK_CHAR, + TOK_STRING, + TOK_BOOL, + TOK_VOID, + TOK_PROGRAM, + TOK_VERSION, + TOK_EOF +}; +typedef enum tok_kind tok_kind; + +/* + * a token + */ +struct token { + tok_kind kind; + char *str; +}; +typedef struct token token; + + +/* + * routine interface + */ +void scanprint(); +void scan(); +void scan2(); +void scan3(); +void scan_num(); +void peek(); +int peekscan(); +void get_token(); diff --git a/sunrpc/rpc_svcout.c b/sunrpc/rpc_svcout.c new file mode 100644 index 0000000000..7289b0da6e --- /dev/null +++ b/sunrpc/rpc_svcout.c @@ -0,0 +1,275 @@ +/* @(#)rpc_svcout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_svcout.c 1.6 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_parse.h" +#include "rpc_util.h" + +static char RQSTP[] = "rqstp"; +static char TRANSP[] = "transp"; +static char ARG[] = "argument"; +static char RESULT[] = "result"; +static char ROUTINE[] = "local"; + + +/* + * write most of the service, that is, everything but the registrations. + */ +void +write_most() +{ + list *l; + definition *def; + version_list *vp; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\nstatic void "); + pvname(def->def_name, vp->vers_num); + f_print(fout, "();"); + } + } + } + f_print(fout, "\n\n"); + f_print(fout, "main()\n"); + f_print(fout, "{\n"); + f_print(fout, "\tSVCXPRT *%s;\n", TRANSP); + f_print(fout, "\n"); + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\t(void)pmap_unset(%s, %s);\n", def->def_name, vp->vers_name); + } + } +} + + +/* + * write a registration for the given transport + */ +void +write_register(transp) + char *transp; +{ + list *l; + definition *def; + version_list *vp; + + f_print(fout, "\n"); + f_print(fout, "\t%s = svc%s_create(RPC_ANYSOCK", TRANSP, transp); + if (streq(transp, "tcp")) { + f_print(fout, ", 0, 0"); + } + f_print(fout, ");\n"); + f_print(fout, "\tif (%s == NULL) {\n", TRANSP); + f_print(fout, "\t\t(void)fprintf(stderr, \"cannot create %s service.\\n\");\n", transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, + "\tif (!svc_register(%s, %s, %s, ", + TRANSP, def->def_name, vp->vers_name); + pvname(def->def_name, vp->vers_num); + f_print(fout, ", IPPROTO_%s)) {\n", + streq(transp, "udp") ? "UDP" : "TCP"); + f_print(fout, + "\t\t(void)fprintf(stderr, \"unable to register (%s, %s, %s).\\n\");\n", + def->def_name, vp->vers_name, transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + } + } +} + + +/* + * write the rest of the service + */ +void +write_rest() +{ + f_print(fout, "\tsvc_run();\n"); + f_print(fout, "\t(void)fprintf(stderr, \"svc_run returned\\n\");\n"); + f_print(fout, "\texit(1);\n"); + f_print(fout, "}\n"); +} + +void +write_programs(storage) + char *storage; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + write_program(def, storage); + } + } +} + + +static +write_program(def, storage) + definition *def; + char *storage; +{ + version_list *vp; + proc_list *proc; + int filled; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\n"); + if (storage != NULL) { + f_print(fout, "%s ", storage); + } + f_print(fout, "void\n"); + pvname(def->def_name, vp->vers_num); + f_print(fout, "(%s, %s)\n", RQSTP, TRANSP); + f_print(fout, " struct svc_req *%s;\n", RQSTP); + f_print(fout, " SVCXPRT *%s;\n", TRANSP); + f_print(fout, "{\n"); + + filled = 0; + f_print(fout, "\tunion {\n"); + for (proc = vp->procs; proc != NULL; proc = proc->next) { + if (streq(proc->arg_type, "void")) { + continue; + } + filled = 1; + f_print(fout, "\t\t"); + ptype(proc->arg_prefix, proc->arg_type, 0); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_arg;\n"); + } + if (!filled) { + f_print(fout, "\t\tint fill;\n"); + } + f_print(fout, "\t} %s;\n", ARG); + f_print(fout, "\tchar *%s;\n", RESULT); + f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT); + f_print(fout, "\tchar *(*%s)();\n", ROUTINE); + f_print(fout, "\n"); + f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); + + if (!nullproc(vp->procs)) { + f_print(fout, "\tcase NULLPROC:\n"); + f_print(fout, "\t\t(void)svc_sendreply(%s, xdr_void, (char *)NULL);\n", TRANSP); + f_print(fout, "\t\treturn;\n\n"); + } + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\tcase %s:\n", proc->proc_name); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", ARG, + stringfix(proc->arg_type)); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", RESULT, + stringfix(proc->res_type)); + f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, ";\n"); + f_print(fout, "\t\tbreak;\n\n"); + } + f_print(fout, "\tdefault:\n"); + printerr("noproc", TRANSP); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\tbzero((char *)&%s, sizeof(%s));\n", ARG, ARG); + printif("getargs", TRANSP, "&", ARG); + printerr("decode", TRANSP); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\t%s = (*%s)(&%s, %s);\n", RESULT, ROUTINE, ARG, + RQSTP); + f_print(fout, + "\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n", + RESULT, TRANSP, RESULT, RESULT); + printerr("systemerr", TRANSP); + f_print(fout, "\t}\n"); + + printif("freeargs", TRANSP, "&", ARG); + f_print(fout, "\t\t(void)fprintf(stderr, \"unable to free arguments\\n\");\n"); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "}\n\n"); + } +} + +static +printerr(err, transp) + char *err; + char *transp; +{ + f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); +} + +static +printif(proc, transp, prefix, arg) + char *proc; + char *transp; + char *prefix; + char *arg; +{ + f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n", + proc, transp, arg, prefix, arg); +} + + +nullproc(proc) + proc_list *proc; +{ + for (; proc != NULL; proc = proc->next) { + if (streq(proc->proc_num, "0")) { + return (1); + } + } + return (0); +} diff --git a/sunrpc/rpc_util.c b/sunrpc/rpc_util.c new file mode 100644 index 0000000000..8136535b2f --- /dev/null +++ b/sunrpc/rpc_util.c @@ -0,0 +1,436 @@ +/* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +static char sccsid[] = "@(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI"; +#endif + +/* + * rpc_util.c, Utility routines for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +char curline[MAXLINESIZE]; /* current read line */ +char *where = curline; /* current point in line */ +int linenum = 0; /* current line number */ + +char *infilename; /* input filename */ + +#define NFILES 4 +char *outfiles[NFILES]; /* output file names */ +int nfiles; + +FILE *fout; /* file pointer of current output */ +FILE *fin; /* file pointer of current input */ + +list *defined; /* list of defined things */ + +/* + * Reinitialize the world + */ +reinitialize() +{ + bzero(curline, MAXLINESIZE); + where = curline; + linenum = 0; + defined = NULL; +} + +/* + * string equality + */ +streq(a, b) + char *a; + char *b; +{ + return (strcmp(a, b) == 0); +} + +/* + * find a value in a list + */ +char * +findval(lst, val, cmp) + list *lst; + char *val; + int (*cmp) (); + +{ + for (; lst != NULL; lst = lst->next) { + if ((*cmp) (lst->val, val)) { + return (lst->val); + } + } + return (NULL); +} + +/* + * store a value in a list + */ +void +storeval(lstp, val) + list **lstp; + char *val; +{ + list **l; + list *lst; + + for (l = lstp; *l != NULL; l = (list **) & (*l)->next); + lst = ALLOC(list); + lst->val = val; + lst->next = NULL; + *l = lst; +} + + +static +findit(def, type) + definition *def; + char *type; +{ + return (streq(def->def_name, type)); +} + + +static char * +fixit(type, orig) + char *type; + char *orig; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findit); + if (def == NULL || def->def_kind != DEF_TYPEDEF) { + return (orig); + } + switch (def->def.ty.rel) { + case REL_VECTOR: + return (def->def.ty.old_type); + case REL_ALIAS: + return (fixit(def->def.ty.old_type, orig)); + default: + return (orig); + } +} + +char * +fixtype(type) + char *type; +{ + return (fixit(type, type)); +} + +char * +stringfix(type) + char *type; +{ + if (streq(type, "string")) { + return ("wrapstring"); + } else { + return (type); + } +} + +void +ptype(prefix, type, follow) + char *prefix; + char *type; + int follow; +{ + if (prefix != NULL) { + if (streq(prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(type, "bool")) { + f_print(fout, "bool_t "); + } else if (streq(type, "string")) { + f_print(fout, "char *"); + } else { + f_print(fout, "%s ", follow ? fixtype(type) : type); + } +} + + +static +typedefed(def, type) + definition *def; + char *type; +{ + if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +isvectordef(type, rel) + char *type; + relation rel; +{ + definition *def; + + for (;;) { + switch (rel) { + case REL_VECTOR: + return (!streq(type, "string")); + case REL_ARRAY: + return (0); + case REL_POINTER: + return (0); + case REL_ALIAS: + def = (definition *) FINDVAL(defined, type, typedefed); + if (def == NULL) { + return (0); + } + type = def->def.ty.old_type; + rel = def->def.ty.rel; + } + } +} + + +static char * +locase(str) + char *str; +{ + char c; + static char buf[100]; + char *p = buf; + + while (c = *str++) { + *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; + } + *p = 0; + return (buf); +} + + +void +pvname(pname, vnum) + char *pname; + char *vnum; +{ + f_print(fout, "%s_%s", locase(pname), vnum); +} + + +/* + * print a useful (?) error message, and then die + */ +void +error(msg) + char *msg; +{ + printwhere(); + f_print(stderr, "%s, line %d: ", infilename, linenum); + f_print(stderr, "%s\n", msg); + crash(); +} + +/* + * Something went wrong, unlink any files that we may have created and then + * die. + */ +crash() +{ + int i; + + for (i = 0; i < nfiles; i++) { + (void) unlink(outfiles[i]); + } + exit(1); +} + + +void +record_open(file) + char *file; +{ + if (nfiles < NFILES) { + outfiles[nfiles++] = file; + } else { + f_print(stderr, "too many files!\n"); + crash(); + } +} + +static char expectbuf[100]; +static char *toktostr(); + +/* + * error, token encountered was not the expected one + */ +void +expected1(exp1) + tok_kind exp1; +{ + s_print(expectbuf, "expected '%s'", + toktostr(exp1)); + error(expectbuf); +} + +/* + * error, token encountered was not one of two expected ones + */ +void +expected2(exp1, exp2) + tok_kind exp1, exp2; +{ + s_print(expectbuf, "expected '%s' or '%s'", + toktostr(exp1), + toktostr(exp2)); + error(expectbuf); +} + +/* + * error, token encountered was not one of 3 expected ones + */ +void +expected3(exp1, exp2, exp3) + tok_kind exp1, exp2, exp3; +{ + s_print(expectbuf, "expected '%s', '%s' or '%s'", + toktostr(exp1), + toktostr(exp2), + toktostr(exp3)); + error(expectbuf); +} + +void +tabify(f, tab) + FILE *f; + int tab; +{ + while (tab--) { + (void) fputc('\t', f); + } +} + + + +static token tokstrings[] = { + {TOK_IDENT, "identifier"}, + {TOK_CONST, "const"}, + {TOK_RPAREN, ")"}, + {TOK_LPAREN, "("}, + {TOK_RBRACE, "}"}, + {TOK_LBRACE, "{"}, + {TOK_LBRACKET, "["}, + {TOK_RBRACKET, "]"}, + {TOK_STAR, "*"}, + {TOK_COMMA, ","}, + {TOK_EQUAL, "="}, + {TOK_COLON, ":"}, + {TOK_SEMICOLON, ";"}, + {TOK_UNION, "union"}, + {TOK_STRUCT, "struct"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_ENUM, "enum"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_INT, "int"}, + {TOK_SHORT, "short"}, + {TOK_LONG, "long"}, + {TOK_UNSIGNED, "unsigned"}, + {TOK_DOUBLE, "double"}, + {TOK_FLOAT, "float"}, + {TOK_CHAR, "char"}, + {TOK_STRING, "string"}, + {TOK_OPAQUE, "opaque"}, + {TOK_BOOL, "bool"}, + {TOK_VOID, "void"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"} +}; + +static char * +toktostr(kind) + tok_kind kind; +{ + token *sp; + + for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); + return (sp->str); +} + + + +static +printbuf() +{ + char c; + int i; + int cnt; + +# define TABSIZE 4 + + for (i = 0; c = curline[i]; i++) { + if (c == '\t') { + cnt = 8 - (i % TABSIZE); + c = ' '; + } else { + cnt = 1; + } + while (cnt--) { + (void) fputc(c, stderr); + } + } +} + + +static +printwhere() +{ + int i; + char c; + int cnt; + + printbuf(); + for (i = 0; i < where - curline; i++) { + c = curline[i]; + if (c == '\t') { + cnt = 8 - (i % TABSIZE); + } else { + cnt = 1; + } + while (cnt--) { + (void) fputc('^', stderr); + } + } + (void) fputc('\n', stderr); +} diff --git a/sunrpc/rpc_util.h b/sunrpc/rpc_util.h new file mode 100644 index 0000000000..0dd188234a --- /dev/null +++ b/sunrpc/rpc_util.h @@ -0,0 +1,114 @@ +/* @(#)rpc_util.h 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc_util.h 1.6 87/06/24 (C) 1987 SMI */ + +/* + * rpc_util.h, Useful definitions for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +extern char *malloc(); + +#define alloc(size) malloc((unsigned)(size)) +#define ALLOC(object) (object *) malloc(sizeof(object)) + +/* extern char *sprintf(); --roland@gnu */ + +#define s_print (void) sprintf +#define f_print (void) fprintf + +struct list { + char *val; + struct list *next; +}; +typedef struct list list; + +/* + * Global variables + */ +#define MAXLINESIZE 1024 +extern char curline[MAXLINESIZE]; +extern char *where; +extern int linenum; + +extern char *infilename; +extern FILE *fout; +extern FILE *fin; + +extern list *defined; + +/* + * rpc_util routines + */ +void storeval(); + +#define STOREVAL(list,item) \ + storeval(list,(char *)item) + +char *findval(); + +#define FINDVAL(list,item,finder) \ + findval(list, (char *) item, finder) + +char *fixtype(); +char *stringfix(); +void pvname(); +void ptype(); +int isvectordef(); +int streq(); +void error(); +void expected1(); +void expected2(); +void expected3(); +void tabify(); +void record_open(); + +/* + * rpc_cout routines + */ +void cprint(); +void emit(); + +/* + * rpc_hout routines + */ +void print_datadef(); + +/* + * rpc_svcout routines + */ +void write_most(); +void write_register(); +void write_rest(); +void write_programs(); + +/* + * rpc_clntout routines + */ +void write_stubs(); diff --git a/sunrpc/rpcinfo.c b/sunrpc/rpcinfo.c new file mode 100644 index 0000000000..961f9b0b2d --- /dev/null +++ b/sunrpc/rpcinfo.c @@ -0,0 +1,665 @@ +/* @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC */ +#ifndef lint +static char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI"; +#endif + +/* + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +/* + * rpcinfo: ping a particular rpc program + * or dump the portmapper + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <rpc/rpc.h> +#include <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <signal.h> +#include <ctype.h> + +#define MAXHOSTLEN 256 + +#define MIN_VERS ((u_long) 0) +#define MAX_VERS ((u_long) 4294967295L) + +static void udpping(/*u_short portflag, int argc, char **argv*/); +static void tcpping(/*u_short portflag, int argc, char **argv*/); +static int pstatus(/*CLIENT *client, u_long prognum, u_long vers*/); +static void pmapdump(/*int argc, char **argv*/); +static bool_t reply_proc(/*void *res, struct sockaddr_in *who*/); +static void brdcst(/*int argc, char **argv*/); +static void deletereg(/* int argc, char **argv */) ; +static void usage(/*void*/); +static u_long getprognum(/*char *arg*/); +static u_long getvers(/*char *arg*/); +static void get_inet_address(/*struct sockaddr_in *addr, char *host*/); +extern u_long inet_addr(); /* in 4.2BSD, arpa/inet.h called that a in_addr */ +extern char *inet_ntoa(); + +/* + * Functions to be performed. + */ +#define NONE 0 /* no function */ +#define PMAPDUMP 1 /* dump portmapper registrations */ +#define TCPPING 2 /* ping TCP service */ +#define UDPPING 3 /* ping UDP service */ +#define BRDCST 4 /* ping broadcast UDP service */ +#define DELETES 5 /* delete registration for the service */ + +int +main(argc, argv) + int argc; + char **argv; +{ + register int c; + extern char *optarg; + extern int optind; + int errflg; + int function; + u_short portnum; + + function = NONE; + portnum = 0; + errflg = 0; + while ((c = getopt(argc, argv, "ptubdn:")) != EOF) { + switch (c) { + + case 'p': + if (function != NONE) + errflg = 1; + else + function = PMAPDUMP; + break; + + case 't': + if (function != NONE) + errflg = 1; + else + function = TCPPING; + break; + + case 'u': + if (function != NONE) + errflg = 1; + else + function = UDPPING; + break; + + case 'b': + if (function != NONE) + errflg = 1; + else + function = BRDCST; + break; + + case 'n': + portnum = (u_short) atoi(optarg); /* hope we don't get bogus # */ + break; + + case 'd': + if (function != NONE) + errflg = 1; + else + function = DELETES; + break; + + case '?': + errflg = 1; + } + } + + if (errflg || function == NONE) { + usage(); + return (1); + } + + switch (function) { + + case PMAPDUMP: + if (portnum != 0) { + usage(); + return (1); + } + pmapdump(argc - optind, argv + optind); + break; + + case UDPPING: + udpping(portnum, argc - optind, argv + optind); + break; + + case TCPPING: + tcpping(portnum, argc - optind, argv + optind); + break; + + case BRDCST: + if (portnum != 0) { + usage(); + return (1); + } + brdcst(argc - optind, argv + optind); + break; + + case DELETES: + deletereg(argc - optind, argv + optind); + break; + } + + return (0); +} + +static void +udpping(portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) { + usage(); + exit(1); + } + prognum = getprognum(argv[1]); + get_inet_address(&addr, argv[0]); + /* Open the socket here so it will survive calls to clnt_destroy */ + sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + perror("rpcinfo: socket"); + exit(1); + } + failure = 0; + if (argc == 2) { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, (u_long)0, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu is not available\n", + prognum); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, MAX_VERS, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, MAX_VERS); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } else { + (void) pstatus(client, prognum, MAX_VERS); + exit(1); + } + } else { + (void) pstatus(client, prognum, (u_long)0); + exit(1); + } + clnt_destroy(client); + for (vers = minvers; vers <= maxvers; vers++) { + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, vers, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + clnt_destroy(client); + } + } + else { + vers = getvers(argv[2]); + addr.sin_port = htons(portnum); + to.tv_sec = 5; + to.tv_usec = 0; + if ((client = clntudp_create(&addr, prognum, vers, + to, &sock)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + } + (void) close(sock); /* Close it up again */ + if (failure) + exit(1); +} + +static void +tcpping(portnum, argc, argv) + u_short portnum; + int argc; + char **argv; +{ + struct timeval to; + struct sockaddr_in addr; + enum clnt_stat rpc_stat; + CLIENT *client; + u_long prognum, vers, minvers, maxvers; + int sock = RPC_ANYSOCK; + struct rpc_err rpcerr; + int failure; + + if (argc < 2 || argc > 3) { + usage(); + exit(1); + } + prognum = getprognum(argv[1]); + get_inet_address(&addr, argv[0]); + failure = 0; + if (argc == 2) { + /* + * A call to version 0 should fail with a program/version + * mismatch, and give us the range of versions supported. + */ + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, MIN_VERS, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu is not available\n", + prognum); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * Oh dear, it DOES support version 0. + * Let's try version MAX_VERS. + */ + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, MAX_VERS, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, MAX_VERS); + exit(1); + } + to.tv_sec = 10; + to.tv_usec = 0; + rpc_stat = clnt_call(client, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, to); + if (rpc_stat == RPC_PROGVERSMISMATCH) { + clnt_geterr(client, &rpcerr); + minvers = rpcerr.re_vers.low; + maxvers = rpcerr.re_vers.high; + } else if (rpc_stat == RPC_SUCCESS) { + /* + * It also supports version MAX_VERS. + * Looks like we have a wise guy. + * OK, we give them information on all + * 4 billion versions they support... + */ + minvers = 0; + maxvers = MAX_VERS; + } else { + (void) pstatus(client, prognum, MAX_VERS); + exit(1); + } + } else { + (void) pstatus(client, prognum, MIN_VERS); + exit(1); + } + clnt_destroy(client); + (void) close(sock); + sock = RPC_ANYSOCK; /* Re-initialize it for later */ + for (vers = minvers; vers <= maxvers; vers++) { + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, vers, + &sock, 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + clnt_destroy(client); + (void) close(sock); + sock = RPC_ANYSOCK; + } + } + else { + vers = getvers(argv[2]); + addr.sin_port = htons(portnum); + if ((client = clnttcp_create(&addr, prognum, vers, &sock, + 0, 0)) == NULL) { + clnt_pcreateerror("rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + exit(1); + } + to.tv_usec = 0; + to.tv_sec = 10; + rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, + xdr_void, (char *)NULL, to); + if (pstatus(client, prognum, vers) < 0) + failure = 1; + } + if (failure) + exit(1); +} + +/* + * This routine should take a pointer to an "rpc_err" structure, rather than + * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to + * a CLIENT structure rather than a pointer to an "rpc_err" structure. + * As such, we have to keep the CLIENT structure around in order to print + * a good error message. + */ +static int +pstatus(client, prognum, vers) + register CLIENT *client; + u_long prognum; + u_long vers; +{ + struct rpc_err rpcerr; + + clnt_geterr(client, &rpcerr); + if (rpcerr.re_status != RPC_SUCCESS) { + clnt_perror(client, "rpcinfo"); + printf("program %lu version %lu is not available\n", + prognum, vers); + return (-1); + } else { + printf("program %lu version %lu ready and waiting\n", + prognum, vers); + return (0); + } +} + +static void +pmapdump(argc, argv) + int argc; + char **argv; +{ + struct sockaddr_in server_addr; + register struct hostent *hp; + struct pmaplist *head = NULL; + int socket = RPC_ANYSOCK; + struct timeval minutetimeout; + register CLIENT *client; + struct rpcent *rpc; + + if (argc > 1) { + usage(); + exit(1); + } + if (argc == 1) + get_inet_address(&server_addr, argv[0]); + else { + bzero((char *)&server_addr, sizeof server_addr); + server_addr.sin_family = AF_INET; + if ((hp = gethostbyname("localhost")) != NULL) + bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, + hp->h_length); + else + server_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + } + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + server_addr.sin_port = htons(PMAPPORT); + if ((client = clnttcp_create(&server_addr, PMAPPROG, + PMAPVERS, &socket, 50, 500)) == NULL) { + clnt_pcreateerror("rpcinfo: can't contact portmapper"); + exit(1); + } + if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL, + xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { + fprintf(stderr, "rpcinfo: can't contact portmapper: "); + clnt_perror(client, "rpcinfo"); + exit(1); + } + if (head == NULL) { + printf("No remote programs registered.\n"); + } else { + printf(" program vers proto port\n"); + for (; head != NULL; head = head->pml_next) { + printf("%10ld%5ld", + head->pml_map.pm_prog, + head->pml_map.pm_vers); + if (head->pml_map.pm_prot == IPPROTO_UDP) + printf("%6s", "udp"); + else if (head->pml_map.pm_prot == IPPROTO_TCP) + printf("%6s", "tcp"); + else + printf("%6ld", head->pml_map.pm_prot); + printf("%7ld", head->pml_map.pm_port); + rpc = getrpcbynumber(head->pml_map.pm_prog); + if (rpc) + printf(" %s\n", rpc->r_name); + else + printf("\n"); + } + } +} + +/* + * reply_proc collects replies from the broadcast. + * to get a unique list of responses the output of rpcinfo should + * be piped through sort(1) and then uniq(1). + */ + +/*ARGSUSED*/ +static bool_t +reply_proc(res, who) + void *res; /* Nothing comes back */ + struct sockaddr_in *who; /* Who sent us the reply */ +{ + register struct hostent *hp; + + hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr, + AF_INET); + printf("%s %s\n", inet_ntoa(who->sin_addr), + (hp == NULL) ? "(unknown)" : hp->h_name); + return(FALSE); +} + +static void +brdcst(argc, argv) + int argc; + char **argv; +{ + enum clnt_stat rpc_stat; + u_long prognum, vers; + + if (argc != 2) { + usage(); + exit(1); + } + prognum = getprognum(argv[0]); + vers = getvers(argv[1]); + rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void, + (char *)NULL, xdr_void, (char *)NULL, reply_proc); + if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) { + fprintf(stderr, "rpcinfo: broadcast failed: %s\n", + clnt_sperrno(rpc_stat)); + exit(1); + } + exit(0); +} + +static void +deletereg(argc, argv) + int argc; + char **argv; +{ u_long prog_num, version_num ; + + if (argc != 2) { + usage() ; + exit(1) ; + } + if (getuid()) { /* This command allowed only to root */ + fprintf(stderr, "Sorry. You are not root\n") ; + exit(1) ; + } + prog_num = getprognum(argv[0]); + version_num = getvers(argv[1]); + if ((pmap_unset(prog_num, version_num)) == 0) { + fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n", + argv[0], argv[1]) ; + exit(1) ; + } +} + +static void +usage() +{ + fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"); + fprintf(stderr, " rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"); + fprintf(stderr, " rpcinfo -p [ host ]\n"); + fprintf(stderr, " rpcinfo -b prognum versnum\n"); + fprintf(stderr, " rpcinfo -d prognum versnum\n") ; +} + +static u_long +getprognum(arg) + char *arg; +{ + register struct rpcent *rpc; + register u_long prognum; + + if (isalpha(*arg)) { + rpc = getrpcbyname(arg); + if (rpc == NULL) { + fprintf(stderr, "rpcinfo: %s is unknown service\n", + arg); + exit(1); + } + prognum = rpc->r_number; + } else { + prognum = (u_long) atoi(arg); + } + + return (prognum); +} + +static u_long +getvers(arg) + char *arg; +{ + register u_long vers; + + vers = (int) atoi(arg); + return (vers); +} + +static void +get_inet_address(addr, host) + struct sockaddr_in *addr; + char *host; +{ + register struct hostent *hp; + + bzero((char *)addr, sizeof *addr); + addr->sin_addr.s_addr = (u_long) inet_addr(host); + if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) { + if ((hp = gethostbyname(host)) == NULL) { + fprintf(stderr, "rpcinfo: %s is unknown host\n", host); + exit(1); + } + bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length); + } + addr->sin_family = AF_INET; +} diff --git a/sunrpc/rpcsvc/bootparam.x b/sunrpc/rpcsvc/bootparam.x new file mode 100644 index 0000000000..65bc0dcbfb --- /dev/null +++ b/sunrpc/rpcsvc/bootparam.x @@ -0,0 +1,97 @@ +/* @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * RPC for bootparms service. + * There are two procedures: + * WHOAMI takes a net address and returns a client name and also a + * likely net address for routing + * GETFILE takes a client name and file identifier and returns the + * server name, server net address and pathname for the file. + * file identifiers typically include root, swap, pub and dump + */ + +#ifdef RPC_HDR +%#include <rpc/types.h> +%#include <sys/time.h> +%#include <sys/errno.h> +%#include <nfs/nfs.h> +#endif + +const MAX_MACHINE_NAME = 255; +const MAX_PATH_LEN = 1024; +const MAX_FILEID = 32; +const IP_ADDR_TYPE = 1; + +typedef string bp_machine_name_t<MAX_MACHINE_NAME>; +typedef string bp_path_t<MAX_PATH_LEN>; +typedef string bp_fileid_t<MAX_FILEID>; + +struct ip_addr_t { + char net; + char host; + char lh; + char impno; +}; + +union bp_address switch (int address_type) { + case IP_ADDR_TYPE: + ip_addr_t ip_addr; +}; + +struct bp_whoami_arg { + bp_address client_address; +}; + +struct bp_whoami_res { + bp_machine_name_t client_name; + bp_machine_name_t domain_name; + bp_address router_address; +}; + +struct bp_getfile_arg { + bp_machine_name_t client_name; + bp_fileid_t file_id; +}; + +struct bp_getfile_res { + bp_machine_name_t server_name; + bp_address server_address; + bp_path_t server_path; +}; + +program BOOTPARAMPROG { + version BOOTPARAMVERS { + bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1; + bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2; + } = 1; +} = 100026; diff --git a/sunrpc/rpcsvc/klm_prot.x b/sunrpc/rpcsvc/klm_prot.x new file mode 100644 index 0000000000..5f3e12e7d3 --- /dev/null +++ b/sunrpc/rpcsvc/klm_prot.x @@ -0,0 +1,134 @@ +/* @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Kernel/lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between the UNIX kernel (the "client") and the + * local lock manager. The local lock manager is a deamon running + * above the kernel. + */ + +const LM_MAXSTRLEN = 1024; + +/* + * lock manager status returns + */ +enum klm_stats { + klm_granted = 0, /* lock is granted */ + klm_denied = 1, /* lock is denied */ + klm_denied_nolocks = 2, /* no lock entry available */ + klm_working = 3 /* lock is being processed */ +}; + +/* + * lock manager lock identifier + */ +struct klm_lock { + string server_name<LM_MAXSTRLEN>; + netobj fh; /* a counted file handle */ + int pid; /* holder of the lock */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * lock holder identifier + */ +struct klm_holder { + bool exclusive; /* FALSE if shared lock */ + int svid; /* holder of the lock (pid) */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL + */ +struct klm_stat { + klm_stats stat; +}; + +/* + * reply to a KLM_TEST call + */ +union klm_testrply switch (klm_stats stat) { + case klm_denied: + struct klm_holder holder; + default: /* All other cases return no arguments */ + void; +}; + + +/* + * arguments to KLM_LOCK + */ +struct klm_lockargs { + bool block; + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_TEST + */ +struct klm_testargs { + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_UNLOCK + */ +struct klm_unlockargs { + struct klm_lock alock; +}; + +program KLM_PROG { + version KLM_VERS { + + klm_testrply KLM_TEST (struct klm_testargs) = 1; + + klm_stat KLM_LOCK (struct klm_lockargs) = 2; + + klm_stat KLM_CANCEL (struct klm_lockargs) = 3; + /* klm_granted=> the cancel request fails due to lock is already granted */ + /* klm_denied=> the cancel request successfully aborts +lock request */ + + klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4; + } = 1; +} = 100020; + diff --git a/sunrpc/rpcsvc/mount.x b/sunrpc/rpcsvc/mount.x new file mode 100644 index 0000000000..7e0d7f3ad6 --- /dev/null +++ b/sunrpc/rpcsvc/mount.x @@ -0,0 +1,161 @@ +/* @(#)mount.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Protocol description for the mount program + */ + + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; + +/* + * If a status of zero is returned, the call completed successfully, and + * a file handle for the directory follows. A non-zero status indicates + * some sort of error. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath<MNTPATHLEN>; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name<MNTNAMLEN>; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. The only connecting point is the fhandle + * structure, which is the same for both protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; +} = 100005; diff --git a/sunrpc/rpcsvc/nfs_prot.x b/sunrpc/rpcsvc/nfs_prot.x new file mode 100644 index 0000000000..7633e5add4 --- /dev/null +++ b/sunrpc/rpcsvc/nfs_prot.x @@ -0,0 +1,355 @@ +/* @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * nfs_prot.x 1.2 87/10/12 + * Copyright 1987 Sun Microsystems, Inc. + */ +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* prefered block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename<NFS_MAXNAMLEN>; +typedef string nfspath<NFS_MAXPATHLEN>; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data<NFS_MAXDATA>; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data<NFS_MAXDATA>; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +typedef opaque nfscookie[NFS_COOKIESIZE]; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; + diff --git a/sunrpc/rpcsvc/nlm_prot.x b/sunrpc/rpcsvc/nlm_prot.x new file mode 100644 index 0000000000..e60c9315c2 --- /dev/null +++ b/sunrpc/rpcsvc/nlm_prot.x @@ -0,0 +1,179 @@ +/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */ + +/* + * Network lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between local lock manager and remote lock manager + */ + +#ifdef RPC_HDR +%#define LM_MAXSTRLEN 1024 +%#define MAXNAMELEN LM_MAXSTRLEN+1 +#endif + +/* + * status of a call to the lock manager + */ +enum nlm_stats { + nlm_granted = 0, + nlm_denied = 1, + nlm_denied_nolocks = 2, + nlm_blocked = 3, + nlm_denied_grace_period = 4 +}; + +struct nlm_holder { + bool exclusive; + int svid; + netobj oh; + unsigned l_offset; + unsigned l_len; +}; + +union nlm_testrply switch (nlm_stats stat) { + case nlm_denied: + struct nlm_holder holder; + default: + void; +}; + +struct nlm_stat { + nlm_stats stat; +}; + +struct nlm_res { + netobj cookie; + nlm_stat stat; +}; + +struct nlm_testres { + netobj cookie; + nlm_testrply stat; +}; + +struct nlm_lock { + string caller_name<LM_MAXSTRLEN>; + netobj fh; /* identify a file */ + netobj oh; /* identify owner of a lock */ + int svid; /* generated from pid for svid */ + unsigned l_offset; + unsigned l_len; +}; + +struct nlm_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; + bool reclaim; /* used for recovering locks */ + int state; /* specify local status monitor state */ +}; + +struct nlm_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_testargs { + netobj cookie; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_unlockargs { + netobj cookie; + struct nlm_lock alock; +}; + + +#ifdef RPC_HDR +%/* +% * The following enums are actually bit encoded for efficient +% * boolean algebra.... DON'T change them..... +% */ +#endif +enum fsh_mode { + fsm_DN = 0, /* deny none */ + fsm_DR = 1, /* deny read */ + fsm_DW = 2, /* deny write */ + fsm_DRW = 3 /* deny read/write */ +}; + +enum fsh_access { + fsa_NONE = 0, /* for completeness */ + fsa_R = 1, /* read only */ + fsa_W = 2, /* write only */ + fsa_RW = 3 /* read/write */ +}; + +struct nlm_share { + string caller_name<LM_MAXSTRLEN>; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +struct nlm_shareargs { + netobj cookie; + nlm_share share; + bool reclaim; +}; + +struct nlm_shareres { + netobj cookie; + nlm_stats stat; + int sequence; +}; + +struct nlm_notify { + string name<MAXNAMELEN>; + long state; +}; + +/* + * Over-the-wire protocol used between the network lock managers + */ + +program NLM_PROG { + version NLM_VERS { + + nlm_testres NLM_TEST(struct nlm_testargs) = 1; + + nlm_res NLM_LOCK(struct nlm_lockargs) = 2; + + nlm_res NLM_CANCEL(struct nlm_cancargs) = 3; + nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4; + + /* + * remote lock manager call-back to grant lock + */ + nlm_res NLM_GRANTED(struct nlm_testargs)= 5; + /* + * message passing style of requesting lock + */ + void NLM_TEST_MSG(struct nlm_testargs) = 6; + void NLM_LOCK_MSG(struct nlm_lockargs) = 7; + void NLM_CANCEL_MSG(struct nlm_cancargs) =8; + void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9; + void NLM_GRANTED_MSG(struct nlm_testargs) = 10; + void NLM_TEST_RES(nlm_testres) = 11; + void NLM_LOCK_RES(nlm_res) = 12; + void NLM_CANCEL_RES(nlm_res) = 13; + void NLM_UNLOCK_RES(nlm_res) = 14; + void NLM_GRANTED_RES(nlm_res) = 15; + } = 1; + + version NLM_VERSX { + nlm_shareres NLM_SHARE(nlm_shareargs) = 20; + nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21; + nlm_res NLM_NM_LOCK(nlm_lockargs) = 22; + void NLM_FREE_ALL(nlm_notify) = 23; + } = 3; + +} = 100021; + diff --git a/sunrpc/rpcsvc/rex.x b/sunrpc/rpcsvc/rex.x new file mode 100644 index 0000000000..6063fdd28a --- /dev/null +++ b/sunrpc/rpcsvc/rex.x @@ -0,0 +1,229 @@ +/* @(#)rex.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Remote execution (rex) protocol specification + */ + +const STRINGSIZE = 1024; +typedef string rexstring<1024>; + +/* + * values to pass to REXPROC_SIGNAL + */ +const SIGINT = 2; /* interrupt */ + +/* + * Values for rst_flags, below + */ +const REX_INTERACTIVE = 1; /* interactive mode */ + +struct rex_start { + rexstring rst_cmd<>; /* list of command and args */ + rexstring rst_host; /* working directory host name */ + rexstring rst_fsname; /* working directory file system name */ + rexstring rst_dirwithin;/* working directory within file system */ + rexstring rst_env<>; /* list of environment */ + unsigned int rst_port0; /* port for stdin */ + unsigned int rst_port1; /* port for stdout */ + unsigned int rst_port2; /* port for stderr */ + unsigned int rst_flags; /* options - see const above */ +}; + +struct rex_result { + int rlt_stat; /* integer status code */ + rexstring rlt_message; /* string message for human consumption */ +}; + + +struct sgttyb { + unsigned four; /* always equals 4 */ + opaque chars[4]; + /* chars[0] == input speed */ + /* chars[1] == output speed */ + /* chars[2] == kill character */ + /* chars[3] == erase character */ + unsigned flags; +}; +/* values for speeds above (baud rates) */ +const B0 = 0; +const B50 = 1; +const B75 = 2; +const B110 = 3; +const B134 = 4; +const B150 = 5; +const B200 = 6; +const B300 = 7; +const B600 = 8; +const B1200 = 9; +const B1800 = 10; +const B2400 = 11; +const B4800 = 12; +const B9600 = 13; +const B19200 = 14; +const B38400 = 15; + +/* values for flags above */ +const TANDEM = 0x00000001; /* send stopc on out q full */ +const CBREAK = 0x00000002; /* half-cooked mode */ +const LCASE = 0x00000004; /* simulate lower case */ +const ECHO = 0x00000008; /* echo input */ +const CRMOD = 0x00000010; /* map \r to \r\n on output */ +const RAW = 0x00000020; /* no i/o processing */ +const ODDP = 0x00000040; /* get/send odd parity */ +const EVENP = 0x00000080; /* get/send even parity */ +const ANYP = 0x000000c0; /* get any parity/send none */ +const NLDELAY = 0x00000300; /* \n delay */ +const NL0 = 0x00000000; +const NL1 = 0x00000100; /* tty 37 */ +const NL2 = 0x00000200; /* vt05 */ +const NL3 = 0x00000300; +const TBDELAY = 0x00000c00; /* horizontal tab delay */ +const TAB0 = 0x00000000; +const TAB1 = 0x00000400; /* tty 37 */ +const TAB2 = 0x00000800; +const XTABS = 0x00000c00; /* expand tabs on output */ +const CRDELAY = 0x00003000; /* \r delay */ +const CR0 = 0x00000000; +const CR1 = 0x00001000; /* tn 300 */ +const CR2 = 0x00002000; /* tty 37 */ +const CR3 = 0x00003000; /* concept 100 */ +const VTDELAY = 0x00004000; /* vertical tab delay */ +const FF0 = 0x00000000; +const FF1 = 0x00004000; /* tty 37 */ +const BSDELAY = 0x00008000; /* \b delay */ +const BS0 = 0x00000000; +const BS1 = 0x00008000; +const CRTBS = 0x00010000; /* do backspacing for crt */ +const PRTERA = 0x00020000; /* \ ... / erase */ +const CRTERA = 0x00040000; /* " \b " to wipe out char */ +const TILDE = 0x00080000; /* hazeltine tilde kludge */ +const MDMBUF = 0x00100000; /* start/stop output on carrier intr */ +const LITOUT = 0x00200000; /* literal output */ +const TOSTOP = 0x00400000; /* SIGTTOU on background output */ +const FLUSHO = 0x00800000; /* flush output to terminal */ +const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */ +const L001000 = 0x02000000; +const CRTKIL = 0x04000000; /* kill line with " \b " */ +const PASS8 = 0x08000000; +const CTLECH = 0x10000000; /* echo control chars as ^X */ +const PENDIN = 0x20000000; /* tp->t_rawq needs reread */ +const DECCTQ = 0x40000000; /* only ^Q starts after ^S */ +const NOFLSH = 0x80000000; /* no output flush on signal */ + +struct tchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == interrupt char */ + /* chars[1] == quit char */ + /* chars[2] == start output char */ + /* chars[3] == stop output char */ + /* chars[4] == end-of-file char */ + /* chars[5] == input delimeter (like nl) */ +}; + +struct ltchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == stop process signal */ + /* chars[1] == delayed stop process signal */ + /* chars[2] == reprint line */ + /* chars[3] == flush output */ + /* chars[4] == word erase */ + /* chars[5] == literal next character */ + unsigned mode; +}; + +struct rex_ttysize { + int ts_lines; + int ts_cols; +}; + +struct rex_ttymode { + sgttyb basic; /* standard unix tty flags */ + tchars more; /* interrupt, kill characters, etc. */ + ltchars yetmore; /* special Berkeley characters */ + unsigned andmore; /* and Berkeley modes */ +}; + +/* values for andmore above */ +const LCRTBS = 0x0001; /* do backspacing for crt */ +const LPRTERA = 0x0002; /* \ ... / erase */ +const LCRTERA = 0x0004; /* " \b " to wipe out char */ +const LTILDE = 0x0008; /* hazeltine tilde kludge */ +const LMDMBUF = 0x0010; /* start/stop output on carrier intr */ +const LLITOUT = 0x0020; /* literal output */ +const LTOSTOP = 0x0040; /* SIGTTOU on background output */ +const LFLUSHO = 0x0080; /* flush output to terminal */ +const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */ +const LL001000 = 0x0200; +const LCRTKIL = 0x0400; /* kill line with " \b " */ +const LPASS8 = 0x0800; +const LCTLECH = 0x1000; /* echo control chars as ^X */ +const LPENDIN = 0x2000; /* needs reread */ +const LDECCTQ = 0x4000; /* only ^Q starts after ^S */ +const LNOFLSH = 0x8000; /* no output flush on signal */ + +program REXPROG { + version REXVERS { + + /* + * Start remote execution + */ + rex_result + REXPROC_START(rex_start) = 1; + + /* + * Wait for remote execution to terminate + */ + rex_result + REXPROC_WAIT(void) = 2; + + /* + * Send tty modes + */ + void + REXPROC_MODES(rex_ttymode) = 3; + + /* + * Send window size change + */ + void + REXPROC_WINCH(rex_ttysize) = 4; + + /* + * Send other signal + */ + void + REXPROC_SIGNAL(int) = 5; + } = 1; +} = 100017; diff --git a/sunrpc/rpcsvc/rnusers.x b/sunrpc/rpcsvc/rnusers.x new file mode 100644 index 0000000000..257df1e6e9 --- /dev/null +++ b/sunrpc/rpcsvc/rnusers.x @@ -0,0 +1,86 @@ +/* @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Find out about remote users + */ + +const MAXUSERS = 100; +const MAXUTLEN = 256; + +struct utmp { + string ut_line<MAXUTLEN>; + string ut_name<MAXUTLEN>; + string ut_host<MAXUTLEN>; + int ut_time; +}; + + +struct utmpidle { + utmp ui_utmp; + unsigned int ui_idle; +}; + +typedef utmp utmparr<MAXUSERS>; + +typedef utmpidle utmpidlearr<MAXUSERS>; + +program RUSERSPROG { + /* + * Includes idle information + */ + version RUSERSVERS_IDLE { + int + RUSERSPROC_NUM(void) = 1; + + utmpidlearr + RUSERSPROC_NAMES(void) = 2; + + utmpidlearr + RUSERSPROC_ALLNAMES(void) = 3; + } = 1; + + /* + * Old version does not include idle information + */ + version RUSERSVERS_ORIG { + int + RUSERSPROC_NUM(void) = 1; + + utmparr + RUSERSPROC_NAMES(void) = 2; + + utmparr + RUSERSPROC_ALLNAMES(void) = 3; + } = 2; +} = 100002; + diff --git a/sunrpc/rpcsvc/rquota.x b/sunrpc/rpcsvc/rquota.x new file mode 100644 index 0000000000..62888f612a --- /dev/null +++ b/sunrpc/rpcsvc/rquota.x @@ -0,0 +1,61 @@ +/* @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro */ + +/* + * Remote quota protocol + * Requires unix authentication + */ + +const RQ_PATHLEN = 1024; + +struct getquota_args { + string gqa_pathp<RQ_PATHLEN>; /* path to filesystem of interest */ + int gqa_uid; /* inquire about quota for uid */ +}; + +/* + * remote quota structure + */ +struct rquota { + int rq_bsize; /* block size for block counts */ + bool rq_active; /* indicates whether quota is active */ + unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */ + unsigned int rq_bsoftlimit; /* preferred limit on disk blks */ + unsigned int rq_curblocks; /* current block count */ + unsigned int rq_fhardlimit; /* absolute limit on allocated files */ + unsigned int rq_fsoftlimit; /* preferred file limit */ + unsigned int rq_curfiles; /* current # allocated files */ + unsigned int rq_btimeleft; /* time left for excessive disk use */ + unsigned int rq_ftimeleft; /* time left for excessive files */ +}; + +enum gqr_status { + Q_OK = 1, /* quota returned */ + Q_NOQUOTA = 2, /* noquota for uid */ + Q_EPERM = 3 /* no permission to access quota */ +}; + +union getquota_rslt switch (gqr_status status) { +case Q_OK: + rquota gqr_rquota; /* valid if status == Q_OK */ +case Q_NOQUOTA: + void; +case Q_EPERM: + void; +}; + +program RQUOTAPROG { + version RQUOTAVERS { + /* + * Get all quotas + */ + getquota_rslt + RQUOTAPROC_GETQUOTA(getquota_args) = 1; + + /* + * Get active quotas only + */ + getquota_rslt + RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2; + } = 1; +} = 100011; diff --git a/sunrpc/rpcsvc/rstat.x b/sunrpc/rpcsvc/rstat.x new file mode 100644 index 0000000000..6367c43943 --- /dev/null +++ b/sunrpc/rpcsvc/rstat.x @@ -0,0 +1,145 @@ +/* @(#)rstat.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)rstat.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Gather statistics on remote machines + */ + +#ifdef RPC_HDR + +%#ifndef FSCALE +%/* +% * Scale factor for scaled integers used to count load averages. +% */ +%#define FSHIFT 8 /* bits to right of fixed binary point */ +%#define FSCALE (1<<FSHIFT) +% +%#endif /* ndef FSCALE */ + +#endif /* def RPC_HDR */ + +const CPUSTATES = 4; +const DK_NDRIVE = 4; + +/* + * GMT since 0:00, January 1, 1970 + */ +struct rstat_timeval { + unsigned int tv_sec; /* seconds */ + unsigned int tv_usec; /* and microseconds */ +}; + +struct statstime { /* RSTATVERS_TIME */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + int avenrun[3]; /* scaled by FSCALE */ + rstat_timeval boottime; + rstat_timeval curtime; + int if_opackets; +}; + +struct statsswtch { /* RSTATVERS_SWTCH */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + unsigned int avenrun[3];/* scaled by FSCALE */ + rstat_timeval boottime; + int if_opackets; +}; + +struct stats { /* RSTATVERS_ORIG */ + int cp_time[CPUSTATES]; + int dk_xfer[DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + int if_opackets; +}; + + +program RSTATPROG { + /* + * Newest version includes current time and context switching info + */ + version RSTATVERS_TIME { + statstime + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 3; + /* + * Does not have current time + */ + version RSTATVERS_SWTCH { + statsswtch + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 2; + /* + * Old version has no info about current time or context switching + */ + version RSTATVERS_ORIG { + stats + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 1; +} = 100001; diff --git a/sunrpc/rpcsvc/sm_inter.x b/sunrpc/rpcsvc/sm_inter.x new file mode 100644 index 0000000000..2817ebfda3 --- /dev/null +++ b/sunrpc/rpcsvc/sm_inter.x @@ -0,0 +1,116 @@ +/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Status monitor protocol specification + * Copyright (C) 1986 Sun Microsystems, Inc. + * + */ + + +program SM_PROG { + version SM_VERS { + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* if res_stat == stat_succ, state = state number of site sm_name */ + struct sm_stat_res SM_STAT(struct sm_name) = 1; + + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* stat consists of state number of local site */ + struct sm_stat_res SM_MON(struct mon) = 2; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON(struct mon_id) = 3; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON_ALL(struct my_id) = 4; + + void SM_SIMU_CRASH(void) = 5; + + } = 1; +} = 100024; + +const SM_MAXSTRLEN = 1024; + +struct sm_name { + string mon_name<SM_MAXSTRLEN>; +}; + +struct my_id { + string my_name<SM_MAXSTRLEN>; /* name of the site iniates the monitoring request*/ + int my_prog; /* rpc program # of the requesting process */ + int my_vers; /* rpc version # of the requesting process */ + int my_proc; /* rpc procedure # of the requesting process */ +}; + +struct mon_id { + string mon_name<SM_MAXSTRLEN>; /* name of the site to be monitored */ + struct my_id my_id; +}; + + +struct mon{ + struct mon_id mon_id; + opaque priv[16]; /* private information to store at monitor for requesting process */ +}; + + +/* + * state # of status monitor monitonically increases each time + * status of the site changes: + * an even number (>= 0) indicates the site is down and + * an odd number (> 0) indicates the site is up; + */ +struct sm_stat { + int state; /* state # of status monitor */ +}; + +enum res { + stat_succ = 0, /* status monitor agrees to monitor */ + stat_fail = 1 /* status monitor cannot monitor */ +}; + +struct sm_stat_res { + res res_stat; + int state; +}; + +/* + * structure of the status message sent back by the status monitor + * when monitor site status changes + */ +struct status { + string mon_name<SM_MAXSTRLEN>; + int state; + opaque priv[16]; /* stored private information */ +}; diff --git a/sunrpc/rpcsvc/spray.x b/sunrpc/rpcsvc/spray.x new file mode 100644 index 0000000000..b242f0ac75 --- /dev/null +++ b/sunrpc/rpcsvc/spray.x @@ -0,0 +1,84 @@ +/* @(#)spray.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Spray a server with packets + * Useful for testing flakiness of network interfaces + */ + +const SPRAYMAX = 8845; /* max amount can spray */ + +/* + * GMT since 0:00, 1 January 1970 + */ +struct spraytimeval { + unsigned int sec; + unsigned int usec; +}; + +/* + * spray statistics + */ +struct spraycumul { + unsigned int counter; + spraytimeval clock; +}; + +/* + * spray data + */ +typedef opaque sprayarr<SPRAYMAX>; + +program SPRAYPROG { + version SPRAYVERS { + /* + * Just throw away the data and increment the counter + * This call never returns, so the client should always + * time it out. + */ + void + SPRAYPROC_SPRAY(sprayarr) = 1; + + /* + * Get the value of the counter and elapsed time since + * last CLEAR. + */ + spraycumul + SPRAYPROC_GET(void) = 2; + + /* + * Clear the counter and reset the elapsed time + */ + void + SPRAYPROC_CLEAR(void) = 3; + } = 1; +} = 100012; diff --git a/sunrpc/rpcsvc/yp.x b/sunrpc/rpcsvc/yp.x new file mode 100644 index 0000000000..8fe70a2706 --- /dev/null +++ b/sunrpc/rpcsvc/yp.x @@ -0,0 +1,291 @@ +/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Protocol description file for the Yellow Pages Service + */ + +const YPMAXRECORD = 1024; +const YPMAXDOMAIN = 64; +const YPMAXMAP = 64; +const YPMAXPEER = 64; + + +enum ypstat { + YP_TRUE = 1, + YP_NOMORE = 2, + YP_FALSE = 0, + YP_NOMAP = -1, + YP_NODOM = -2, + YP_NOKEY = -3, + YP_BADOP = -4, + YP_BADDB = -5, + YP_YPERR = -6, + YP_BADARGS = -7, + YP_VERS = -8 +}; + + +enum ypxfrstat { + YPXFR_SUCC = 1, + YPXFR_AGE = 2, + YPXFR_NOMAP = -1, + YPXFR_NODOM = -2, + YPXFR_RSRC = -3, + YPXFR_RPC = -4, + YPXFR_MADDR = -5, + YPXFR_YPERR = -6, + YPXFR_BADARGS = -7, + YPXFR_DBM = -8, + YPXFR_FILE = -9, + YPXFR_SKEW = -10, + YPXFR_CLEAR = -11, + YPXFR_FORCE = -12, + YPXFR_XFRERR = -13, + YPXFR_REFUSED = -14 +}; + + +typedef string domainname<YPMAXDOMAIN>; +typedef string mapname<YPMAXMAP>; +typedef string peername<YPMAXPEER>; +typedef opaque keydat<YPMAXRECORD>; +typedef opaque valdat<YPMAXRECORD>; + + +struct ypmap_parms { + domainname domain; + mapname map; + unsigned int ordernum; + peername peer; +}; + +struct ypreq_key { + domainname domain; + mapname map; + keydat key; +}; + +struct ypreq_nokey { + domainname domain; + mapname map; +}; + +struct ypreq_xfr { + ypmap_parms map_parms; + unsigned int transid; + unsigned int prog; + unsigned int port; +}; + + +struct ypresp_val { + ypstat stat; + valdat val; +}; + +struct ypresp_key_val { + ypstat stat; + keydat key; + valdat val; +}; + + +struct ypresp_master { + ypstat stat; + peername peer; +}; + +struct ypresp_order { + ypstat stat; + unsigned int ordernum; +}; + +union ypresp_all switch (bool more) { +case TRUE: + ypresp_key_val val; +case FALSE: + void; +}; + +struct ypresp_xfr { + unsigned int transid; + ypxfrstat xfrstat; +}; + +struct ypmaplist { + mapname map; + ypmaplist *next; +}; + +struct ypresp_maplist { + ypstat stat; + ypmaplist *maps; +}; + +enum yppush_status { + YPPUSH_SUCC = 1, /* Success */ + YPPUSH_AGE = 2, /* Master's version not newer */ + YPPUSH_NOMAP = -1, /* Can't find server for map */ + YPPUSH_NODOM = -2, /* Domain not supported */ + YPPUSH_RSRC = -3, /* Local resource alloc failure */ + YPPUSH_RPC = -4, /* RPC failure talking to server */ + YPPUSH_MADDR = -5, /* Can't get master address */ + YPPUSH_YPERR = -6, /* YP server/map db error */ + YPPUSH_BADARGS = -7, /* Request arguments bad */ + YPPUSH_DBM = -8, /* Local dbm operation failed */ + YPPUSH_FILE = -9, /* Local file I/O operation failed */ + YPPUSH_SKEW = -10, /* Map version skew during transfer */ + YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */ + YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */ + YPPUSH_XFRERR = -13, /* ypxfr error */ + YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */ +}; + +struct yppushresp_xfr { + unsigned transid; + yppush_status status; +}; + +/* + * Response structure and overall result status codes. Success and failure + * represent two separate response message types. + */ + +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +struct ypbind_binding { + opaque ypbind_binding_addr[4]; /* In network order */ + opaque ypbind_binding_port[2]; /* In network order */ +}; + +union ypbind_resp switch (ypbind_resptype ypbind_status) { +case YPBIND_FAIL_VAL: + unsigned ypbind_error; +case YPBIND_SUCC_VAL: + ypbind_binding ypbind_bindinfo; +}; + +/* Detailed failure reason codes for response field ypbind_error*/ + +const YPBIND_ERR_ERR = 1; /* Internal error */ +const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */ +const YPBIND_ERR_RESC = 3; /* System resource allocation failure */ + + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + domainname ypsetdom_domain; + ypbind_binding ypsetdom_binding; + unsigned ypsetdom_vers; +}; + + +/* + * YP access protocol + */ +program YPPROG { + version YPVERS { + void + YPPROC_NULL(void) = 0; + + bool + YPPROC_DOMAIN(domainname) = 1; + + bool + YPPROC_DOMAIN_NONACK(domainname) = 2; + + ypresp_val + YPPROC_MATCH(ypreq_key) = 3; + + ypresp_key_val + YPPROC_FIRST(ypreq_key) = 4; + + ypresp_key_val + YPPROC_NEXT(ypreq_key) = 5; + + ypresp_xfr + YPPROC_XFR(ypreq_xfr) = 6; + + void + YPPROC_CLEAR(void) = 7; + + ypresp_all + YPPROC_ALL(ypreq_nokey) = 8; + + ypresp_master + YPPROC_MASTER(ypreq_nokey) = 9; + + ypresp_order + YPPROC_ORDER(ypreq_nokey) = 10; + + ypresp_maplist + YPPROC_MAPLIST(domainname) = 11; + } = 2; +} = 100004; + + +/* + * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR + */ +program YPPUSH_XFRRESPPROG { + version YPPUSH_XFRRESPVERS { + void + YPPUSHPROC_NULL(void) = 0; + + yppushresp_xfr + YPPUSHPROC_XFRRESP(void) = 1; + } = 1; +} = 0x40000000; /* transient: could be anything up to 0x5fffffff */ + + +/* + * YP binding protocol + */ +program YPBINDPROG { + version YPBINDVERS { + void + YPBINDPROC_NULL(void) = 0; + + ypbind_resp + YPBINDPROC_DOMAIN(domainname) = 1; + + void + YPBINDPROC_SETDOM(ypbind_setdom) = 2; + } = 2; +} = 100007; + + diff --git a/sunrpc/rpcsvc/yppasswd.x b/sunrpc/rpcsvc/yppasswd.x new file mode 100644 index 0000000000..ad349adbfa --- /dev/null +++ b/sunrpc/rpcsvc/yppasswd.x @@ -0,0 +1,63 @@ +/* @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * YP password update protocol + * Requires unix authentication + */ +program YPPASSWDPROG { + version YPPASSWDVERS { + /* + * Update my passwd entry + */ + int + YPPASSWDPROC_UPDATE(yppasswd) = 1; + } = 1; +} = 100009; + + +struct passwd { + string pw_name<>; /* username */ + string pw_passwd<>; /* encrypted password */ + int pw_uid; /* user id */ + int pw_gid; /* group id */ + string pw_gecos<>; /* in real life name */ + string pw_dir<>; /* home directory */ + string pw_shell<>; /* default shell */ +}; + +struct yppasswd { + string oldpass<>; /* unencrypted old password */ + passwd newpw; /* new passwd entry */ +}; + + diff --git a/sunrpc/svc.c b/sunrpc/svc.c new file mode 100644 index 0000000000..3327ee5bdd --- /dev/null +++ b/sunrpc/svc.c @@ -0,0 +1,479 @@ +/* @(#)svc.c 2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * svc.c, Server-side remote procedure call interface. + * + * There are two sets of procedures here. The xprt routines are + * for handling transport handles. The svc routines handle the + * list of service routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <sys/errno.h> +#include <rpc/rpc.h> +#include <rpc/pmap_clnt.h> + +extern int errno; + +#ifdef FD_SETSIZE +static SVCXPRT **xports; +#else +#define NOFILE 32 + +static SVCXPRT *xports[NOFILE]; +#endif /* def FD_SETSIZE */ + +#define NULL_SVC ((struct svc_callout *)0) +#define RQCRED_SIZE 400 /* this size is excessive */ + +/* + * The services list + * Each entry represents a set of procedures (an rpc program). + * The dispatch routine takes request structs and runs the + * apropriate procedure. + */ +static struct svc_callout { + struct svc_callout *sc_next; + u_long sc_prog; + u_long sc_vers; + void (*sc_dispatch)(); +} *svc_head; + +static struct svc_callout *svc_find(); + +/* *************** SVCXPRT related stuff **************** */ + +/* + * Activate a transport handle. + */ +void +xprt_register(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if (xports == NULL) { + xports = (SVCXPRT **) + mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); + } + if (sock < _rpc_dtablesize()) { + xports[sock] = xprt; + FD_SET(sock, &svc_fdset); + } +#else + if (sock < NOFILE) { + xports[sock] = xprt; + svc_fds |= (1 << sock); + } +#endif /* def FD_SETSIZE */ + +} + +/* + * De-activate a transport handle. + */ +void +xprt_unregister(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + FD_CLR(sock, &svc_fdset); + } +#else + if ((sock < NOFILE) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + svc_fds &= ~(1 << sock); + } +#endif /* def FD_SETSIZE */ +} + + +/* ********************** CALLOUT list related stuff ************* */ + +/* + * Add a service program to the callout list. + * The dispatch routine will be called when a rpc request for this + * program number comes in. + */ +bool_t +svc_register(xprt, prog, vers, dispatch, protocol) + SVCXPRT *xprt; + u_long prog; + u_long vers; + void (*dispatch)(); + int protocol; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { + if (s->sc_dispatch == dispatch) + goto pmap_it; /* he is registering another xptr */ + return (FALSE); + } + s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); + if (s == (struct svc_callout *)0) { + return (FALSE); + } + s->sc_prog = prog; + s->sc_vers = vers; + s->sc_dispatch = dispatch; + s->sc_next = svc_head; + svc_head = s; +pmap_it: + /* now register the information with the local binder service */ + if (protocol) { + return (pmap_set(prog, vers, protocol, xprt->xp_port)); + } + return (TRUE); +} + +/* + * Remove a service program from the callout list. + */ +void +svc_unregister(prog, vers) + u_long prog; + u_long vers; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) + return; + if (prev == NULL_SVC) { + svc_head = s->sc_next; + } else { + prev->sc_next = s->sc_next; + } + s->sc_next = NULL_SVC; + mem_free((char *) s, (u_int) sizeof(struct svc_callout)); + /* now unregister the information with the local binder service */ + (void)pmap_unset(prog, vers); +} + +/* + * Search the callout list for a program number, return the callout + * struct. + */ +static struct svc_callout * +svc_find(prog, vers, prev) + u_long prog; + u_long vers; + struct svc_callout **prev; +{ + register struct svc_callout *s, *p; + + p = NULL_SVC; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if ((s->sc_prog == prog) && (s->sc_vers == vers)) + goto done; + p = s; + } +done: + *prev = p; + return (s); +} + +/* ******************* REPLY GENERATION ROUTINES ************ */ + +/* + * Send a reply to an rpc request + */ +bool_t +svc_sendreply(xprt, xdr_results, xdr_location) + register SVCXPRT *xprt; + xdrproc_t xdr_results; + caddr_t xdr_location; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SUCCESS; + rply.acpted_rply.ar_results.where = xdr_location; + rply.acpted_rply.ar_results.proc = xdr_results; + return (SVC_REPLY(xprt, &rply)); +} + +/* + * No procedure error reply + */ +void +svcerr_noproc(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROC_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Can't decode args error reply + */ +void +svcerr_decode(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = GARBAGE_ARGS; + SVC_REPLY(xprt, &rply); +} + +/* + * Some system error + */ +void +svcerr_systemerr(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SYSTEM_ERR; + SVC_REPLY(xprt, &rply); +} + +/* + * Authentication error reply + */ +void +svcerr_auth(xprt, why) + SVCXPRT *xprt; + enum auth_stat why; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_DENIED; + rply.rjcted_rply.rj_stat = AUTH_ERROR; + rply.rjcted_rply.rj_why = why; + SVC_REPLY(xprt, &rply); +} + +/* + * Auth too weak error reply + */ +void +svcerr_weakauth(xprt) + SVCXPRT *xprt; +{ + + svcerr_auth(xprt, AUTH_TOOWEAK); +} + +/* + * Program unavailable error reply + */ +void +svcerr_noprog(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Program version mismatch error reply + */ +void +svcerr_progvers(xprt, low_vers, high_vers) + register SVCXPRT *xprt; + u_long low_vers; + u_long high_vers; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_MISMATCH; + rply.acpted_rply.ar_vers.low = low_vers; + rply.acpted_rply.ar_vers.high = high_vers; + SVC_REPLY(xprt, &rply); +} + +/* ******************* SERVER INPUT STUFF ******************* */ + +/* + * Get server side input from some transport. + * + * Statement of authentication parameters management: + * This function owns and manages all authentication parameters, specifically + * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and + * the "cooked" credentials (rqst->rq_clntcred). + * However, this function does not know the structure of the cooked + * credentials, so it make the following assumptions: + * a) the structure is contiguous (no pointers), and + * b) the cred structure size does not exceed RQCRED_SIZE bytes. + * In all events, all three parameters are freed upon exit from this routine. + * The storage is trivially management on the call stack in user land, but + * is mallocated in kernel land. + */ + +void +svc_getreq(rdfds) + int rdfds; +{ +#ifdef FD_SETSIZE + fd_set readfds; + + FD_ZERO(&readfds); + readfds.fds_bits[0] = rdfds; + svc_getreqset(&readfds); +#else + int readfds = rdfds & svc_fds; + + svc_getreqset(&readfds); +#endif /* def FD_SETSIZE */ +} + +void +svc_getreqset(readfds) +#ifdef FD_SETSIZE + fd_set *readfds; +{ +#else + int *readfds; +{ + int readfds_local = *readfds; +#endif /* def FD_SETSIZE */ + enum xprt_stat stat; + struct rpc_msg msg; + int prog_found; + u_long low_vers; + u_long high_vers; + struct svc_req r; + register SVCXPRT *xprt; + register u_long mask; + register int bit; + register u_long *maskp; + register int setsize; + register int sock; + char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; + msg.rm_call.cb_cred.oa_base = cred_area; + msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); + r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); + + +#ifdef FD_SETSIZE + setsize = _rpc_dtablesize(); + maskp = (u_long *)readfds->fds_bits; + for (sock = 0; sock < setsize; sock += NFDBITS) { + for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { + /* sock has input waiting */ + xprt = xports[sock + bit - 1]; +#else + for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { + if ((readfds_local & 1) != 0) { + /* sock has input waiting */ + xprt = xports[sock]; +#endif /* def FD_SETSIZE */ + /* now receive msgs from xprtprt (support batch calls) */ + do { + if (SVC_RECV(xprt, &msg)) { + + /* now find the exported program and call it */ + register struct svc_callout *s; + enum auth_stat why; + + r.rq_xprt = xprt; + r.rq_prog = msg.rm_call.cb_prog; + r.rq_vers = msg.rm_call.cb_vers; + r.rq_proc = msg.rm_call.cb_proc; + r.rq_cred = msg.rm_call.cb_cred; + /* first authenticate the message */ + if ((why= _authenticate(&r, &msg)) != AUTH_OK) { + svcerr_auth(xprt, why); + goto call_done; + } + /* now match message with a registered service*/ + prog_found = FALSE; + low_vers = 0 - 1; + high_vers = 0; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if (s->sc_prog == r.rq_prog) { + if (s->sc_vers == r.rq_vers) { + (*s->sc_dispatch)(&r, xprt); + goto call_done; + } /* found correct version */ + prog_found = TRUE; + if (s->sc_vers < low_vers) + low_vers = s->sc_vers; + if (s->sc_vers > high_vers) + high_vers = s->sc_vers; + } /* found correct program */ + } + /* + * if we got here, the program or version + * is not served ... + */ + if (prog_found) + svcerr_progvers(xprt, + low_vers, high_vers); + else + svcerr_noprog(xprt); + /* Fall through to ... */ + } + call_done: + if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ + SVC_DESTROY(xprt); + break; + } + } while (stat == XPRT_MOREREQS); + } + } +} diff --git a/sunrpc/svc_auth.c b/sunrpc/svc_auth.c new file mode 100644 index 0000000000..ab7ab69421 --- /dev/null +++ b/sunrpc/svc_auth.c @@ -0,0 +1,114 @@ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc_auth_nodes.c, Server-side rpc authenticator interface, + * *WITHOUT* DES authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> + +/* + * svcauthsw is the bdevsw of server side authentication. + * + * Server side authenticators are called from authenticate by + * using the client auth struct flavor field to index into svcauthsw. + * The server auth flavors must implement a routine that looks + * like: + * + * enum auth_stat + * flavorx_auth(rqst, msg) + * register struct svc_req *rqst; + * register struct rpc_msg *msg; + * + */ + +enum auth_stat _svcauth_null(); /* no authentication */ +enum auth_stat _svcauth_unix(); /* unix style (uid, gids) */ +enum auth_stat _svcauth_short(); /* short hand unix style */ + +static struct { + enum auth_stat (*authenticator)(); +} svcauthsw[] = { + _svcauth_null, /* AUTH_NULL */ + _svcauth_unix, /* AUTH_UNIX */ + _svcauth_short, /* AUTH_SHORT */ +}; +#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */ + + +/* + * The call rpc message, msg has been obtained from the wire. The msg contains + * the raw form of credentials and verifiers. authenticate returns AUTH_OK + * if the msg is successfully authenticated. If AUTH_OK then the routine also + * does the following things: + * set rqst->rq_xprt->verf to the appropriate response verifier; + * sets rqst->rq_client_cred to the "cooked" form of the credentials. + * + * NB: rqst->rq_cxprt->verf must be pre-alloctaed; + * its length is set appropriately. + * + * The caller still owns and is responsible for msg->u.cmb.cred and + * msg->u.cmb.verf. The authentication system retains ownership of + * rqst->rq_client_cred, the cooked credentials. + * + * There is an assumption that any flavour less than AUTH_NULL is + * invalid. + */ +enum auth_stat +_authenticate(rqst, msg) + register struct svc_req *rqst; + struct rpc_msg *msg; +{ + register int cred_flavor; + + rqst->rq_cred = msg->rm_call.cb_cred; + rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; + rqst->rq_xprt->xp_verf.oa_length = 0; + cred_flavor = rqst->rq_cred.oa_flavor; + if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) { + return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg)); + } + + return (AUTH_REJECTEDCRED); +} + +enum auth_stat +_svcauth_null(/*rqst, msg*/) + /*struct svc_req *rqst; + struct rpc_msg *msg;*/ +{ + + return (AUTH_OK); +} diff --git a/sunrpc/svc_authux.c b/sunrpc/svc_authux.c new file mode 100644 index 0000000000..ea00b7895f --- /dev/null +++ b/sunrpc/svc_authux.c @@ -0,0 +1,134 @@ +/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_auth_unix.c + * Handles UNIX flavor authentication parameters on the service side of rpc. + * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. + * _svcauth_unix does full blown unix style uid,gid+gids auth, + * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. + * Note: the shorthand has been gutted for efficiency. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> + +/* + * Unix longhand authenticator + */ +enum auth_stat +_svcauth_unix(rqst, msg) + register struct svc_req *rqst; + register struct rpc_msg *msg; +{ + register enum auth_stat stat; + XDR xdrs; + register struct authunix_parms *aup; + register long *buf; + struct area { + struct authunix_parms area_aup; + char area_machname[MAX_MACHINE_NAME+1]; + int area_gids[NGRPS]; + } *area; + u_int auth_len; + int str_len, gid_len; + register int i; + + area = (struct area *) rqst->rq_clntcred; + aup = &area->area_aup; + aup->aup_machname = area->area_machname; + aup->aup_gids = area->area_gids; + auth_len = (u_int)msg->rm_call.cb_cred.oa_length; + xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); + buf = XDR_INLINE(&xdrs, auth_len); + if (buf != NULL) { + aup->aup_time = IXDR_GET_LONG(buf); + str_len = IXDR_GET_U_LONG(buf); + if (str_len > MAX_MACHINE_NAME) { + stat = AUTH_BADCRED; + goto done; + } + bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len); + aup->aup_machname[str_len] = 0; + str_len = RNDUP(str_len); + buf += str_len / sizeof (long); + aup->aup_uid = IXDR_GET_LONG(buf); + aup->aup_gid = IXDR_GET_LONG(buf); + gid_len = IXDR_GET_U_LONG(buf); + if (gid_len > NGRPS) { + stat = AUTH_BADCRED; + goto done; + } + aup->aup_len = gid_len; + for (i = 0; i < gid_len; i++) { + aup->aup_gids[i] = IXDR_GET_LONG(buf); + } + /* + * five is the smallest unix credentials structure - + * timestamp, hostname len (0), uid, gid, and gids len (0). + */ + if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { + (void) printf("bad auth_len gid %d str %d auth %d\n", + gid_len, str_len, auth_len); + stat = AUTH_BADCRED; + goto done; + } + } else if (! xdr_authunix_parms(&xdrs, aup)) { + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, aup); + stat = AUTH_BADCRED; + goto done; + } + rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; + rqst->rq_xprt->xp_verf.oa_length = 0; + stat = AUTH_OK; +done: + XDR_DESTROY(&xdrs); + return (stat); +} + + +/* + * Shorthand unix authenticator + * Looks up longhand in a cache. + */ +/*ARGSUSED*/ +enum auth_stat +_svcauth_short(rqst, msg) + struct svc_req *rqst; + struct rpc_msg *msg; +{ + return (AUTH_REJECTEDCRED); +} diff --git a/sunrpc/svc_raw.c b/sunrpc/svc_raw.c new file mode 100644 index 0000000000..1170ecec83 --- /dev/null +++ b/sunrpc/svc_raw.c @@ -0,0 +1,166 @@ +/* @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_raw.c, This a toy for simple testing and timing. + * Interface to create an rpc client and server in the same UNIX process. + * This lets us similate rpc and get rpc (round trip) overhead, without + * any interference from the kernal. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> + + +/* + * This is the "network" that we will be moving data over + */ +static struct svcraw_private { + char _raw_buf[UDPMSGSIZE]; + SVCXPRT server; + XDR xdr_stream; + char verf_body[MAX_AUTH_BYTES]; +} *svcraw_private; + +static bool_t svcraw_recv(); +static enum xprt_stat svcraw_stat(); +static bool_t svcraw_getargs(); +static bool_t svcraw_reply(); +static bool_t svcraw_freeargs(); +static void svcraw_destroy(); + +static struct xp_ops server_ops = { + svcraw_recv, + svcraw_stat, + svcraw_getargs, + svcraw_reply, + svcraw_freeargs, + svcraw_destroy +}; + +SVCXPRT * +svcraw_create() +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) { + srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); + if (srp == 0) + return (0); + } + srp->server.xp_sock = 0; + srp->server.xp_port = 0; + srp->server.xp_ops = &server_ops; + srp->server.xp_verf.oa_base = srp->verf_body; + xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); + return (&srp->server); +} + +static enum xprt_stat +svcraw_stat() +{ + + return (XPRT_IDLE); +} + +static bool_t +svcraw_recv(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (0); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + return (TRUE); +} + +static bool_t +svcraw_reply(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_replymsg(xdrs, msg)) + return (FALSE); + (void)XDR_GETPOS(xdrs); /* called just for overhead */ + return (TRUE); +} + +static bool_t +svcraw_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) + return (FALSE); + return ((*xdr_args)(&srp->xdr_stream, args_ptr)); +} + +static bool_t +svcraw_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcraw_destroy() +{ +} diff --git a/sunrpc/svc_run.c b/sunrpc/svc_run.c new file mode 100644 index 0000000000..c1c3e04781 --- /dev/null +++ b/sunrpc/svc_run.c @@ -0,0 +1,72 @@ +/* @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * This is the rpc server side idle loop + * Wait for input, call server program. + */ +#include <rpc/rpc.h> +#include <sys/errno.h> + +void +svc_run() +{ +#ifdef FD_SETSIZE + fd_set readfds; +#else + int readfds; +#endif /* def FD_SETSIZE */ + extern int errno; + + for (;;) { +#ifdef FD_SETSIZE + readfds = svc_fdset; +#else + readfds = svc_fds; +#endif /* def FD_SETSIZE */ + switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0, + (struct timeval *)0)) { + case -1: + if (errno == EINTR) { + continue; + } + perror("svc_run: - select failed"); + return; + case 0: + continue; + default: + svc_getreqset(&readfds); + } + } +} diff --git a/sunrpc/svc_simple.c b/sunrpc/svc_simple.c new file mode 100644 index 0000000000..d6bcbd3c04 --- /dev/null +++ b/sunrpc/svc_simple.c @@ -0,0 +1,143 @@ +/* @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> + +static struct proglst { + char *(*p_progname)(); + int p_prognum; + int p_procnum; + xdrproc_t p_inproc, p_outproc; + struct proglst *p_nxt; +} *proglst; +static void universal(); +static SVCXPRT *transp; +struct proglst *pl; + +registerrpc(prognum, versnum, procnum, progname, inproc, outproc) + char *(*progname)(); + xdrproc_t inproc, outproc; +{ + + if (procnum == NULLPROC) { + (void) fprintf(stderr, + "can't reassign procedure number %d\n", NULLPROC); + return (-1); + } + if (transp == 0) { + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + (void) fprintf(stderr, "couldn't create an rpc server\n"); + return (-1); + } + } + (void) pmap_unset((u_long)prognum, (u_long)versnum); + if (!svc_register(transp, (u_long)prognum, (u_long)versnum, + universal, IPPROTO_UDP)) { + (void) fprintf(stderr, "couldn't register prog %d vers %d\n", + prognum, versnum); + return (-1); + } + pl = (struct proglst *)malloc(sizeof(struct proglst)); + if (pl == NULL) { + (void) fprintf(stderr, "registerrpc: out of memory\n"); + return (-1); + } + pl->p_progname = progname; + pl->p_prognum = prognum; + pl->p_procnum = procnum; + pl->p_inproc = inproc; + pl->p_outproc = outproc; + pl->p_nxt = proglst; + proglst = pl; + return (0); +} + +static void +universal(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + int prog, proc; + char *outdata; + char xdrbuf[UDPMSGSIZE]; + struct proglst *pl; + + /* + * enforce "procnum 0 is echo" convention + */ + if (rqstp->rq_proc == NULLPROC) { + if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) { + (void) fprintf(stderr, "xxx\n"); + exit(1); + } + return; + } + prog = rqstp->rq_prog; + proc = rqstp->rq_proc; + for (pl = proglst; pl != NULL; pl = pl->p_nxt) + if (pl->p_prognum == prog && pl->p_procnum == proc) { + /* decode arguments into a CLEAN buffer */ + bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */ + if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { + svcerr_decode(transp); + return; + } + outdata = (*(pl->p_progname))(xdrbuf); + if (outdata == NULL && pl->p_outproc != xdr_void) + /* there was an error */ + return; + if (!svc_sendreply(transp, pl->p_outproc, outdata)) { + (void) fprintf(stderr, + "trouble replying to prog %d\n", + pl->p_prognum); + exit(1); + } + /* free the decoded arguments */ + (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); + return; + } + (void) fprintf(stderr, "never registered prog %d\n", prog); + exit(1); +} + diff --git a/sunrpc/svc_tcp.c b/sunrpc/svc_tcp.c new file mode 100644 index 0000000000..587e0f0d9b --- /dev/null +++ b/sunrpc/svc_tcp.c @@ -0,0 +1,419 @@ +/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_tcp.c, Server side for TCP/IP based RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Actually implements two flavors of transporter - + * a tcp rendezvouser (a listner and connection establisher) + * and a record/tcp stream. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> +extern bool_t abort(); +extern errno; + +/* + * Ops vector for TCP/IP based rpc service handle + */ +static bool_t svctcp_recv(); +static enum xprt_stat svctcp_stat(); +static bool_t svctcp_getargs(); +static bool_t svctcp_reply(); +static bool_t svctcp_freeargs(); +static void svctcp_destroy(); + +static struct xp_ops svctcp_op = { + svctcp_recv, + svctcp_stat, + svctcp_getargs, + svctcp_reply, + svctcp_freeargs, + svctcp_destroy +}; + +/* + * Ops vector for TCP/IP rendezvous handler + */ +static bool_t rendezvous_request(); +static enum xprt_stat rendezvous_stat(); + +static struct xp_ops svctcp_rendezvous_op = { + rendezvous_request, + rendezvous_stat, + abort, + abort, + abort, + svctcp_destroy +}; + +static int readtcp(), writetcp(); +static SVCXPRT *makefd_xprt(); + +struct tcp_rendezvous { /* kept in xprt->xp_p1 */ + u_int sendsize; + u_int recvsize; +}; + +struct tcp_conn { /* kept in xprt->xp_p1 */ + enum xprt_stat strm_stat; + u_long x_id; + XDR xdrs; + char verf_body[MAX_AUTH_BYTES]; +}; + +/* + * Usage: + * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); + * + * Creates, registers, and returns a (rpc) tcp based transporter. + * Once *xprt is initialized, it is registered as a transporter + * see (svc.h, xprt_register). This routine returns + * a NULL if a problem occurred. + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svctcp_create + * binds it to an arbitrary port. The routine then starts a tcp + * listener on the socket's associated port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * + * Since tcp streams do buffered io similar to stdio, the caller can specify + * how big the send and receive buffers are via the second and third parms; + * 0 => use the system default. + */ +SVCXPRT * +svctcp_create(sock, sendsize, recvsize) + register int sock; + u_int sendsize; + u_int recvsize; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("svctcp_.c - udp socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || + (listen(sock, 2) != 0)) { + perror("svctcp_.c - cannot getsockname or listen"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); + if (r == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + r->sendsize = sendsize; + r->recvsize = recvsize; + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svctcp_rendezvous_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +/* + * Like svtcp_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. + */ +SVCXPRT * +svcfd_create(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + + return (makefd_xprt(fd, sendsize, recvsize)); +} + +static SVCXPRT * +makefd_xprt(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + register SVCXPRT *xprt; + register struct tcp_conn *cd; + + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == (SVCXPRT *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + goto done; + } + cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); + if (cd == (struct tcp_conn *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + mem_free((char *) xprt, sizeof(SVCXPRT)); + xprt = (SVCXPRT *)NULL; + goto done; + } + cd->strm_stat = XPRT_IDLE; + xdrrec_create(&(cd->xdrs), sendsize, recvsize, + (caddr_t)xprt, readtcp, writetcp); + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)cd; + xprt->xp_verf.oa_base = cd->verf_body; + xprt->xp_addrlen = 0; + xprt->xp_ops = &svctcp_op; /* truely deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register(xprt); + done: + return (xprt); +} + +static bool_t +rendezvous_request(xprt) + register SVCXPRT *xprt; +{ + int sock; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len; + + r = (struct tcp_rendezvous *)xprt->xp_p1; + again: + len = sizeof(struct sockaddr_in); + if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, + &len)) < 0) { + if (errno == EINTR) + goto again; + return (FALSE); + } + /* + * make a new transporter (re-uses xprt) + */ + xprt = makefd_xprt(sock, r->sendsize, r->recvsize); + xprt->xp_raddr = addr; + xprt->xp_addrlen = len; + return (FALSE); /* there is never an rpc msg to be processed */ +} + +static enum xprt_stat +rendezvous_stat() +{ + + return (XPRT_IDLE); +} + +static void +svctcp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + if (xprt->xp_port != 0) { + /* a rendezvouser socket */ + xprt->xp_port = 0; + } else { + /* an actual connection socket */ + XDR_DESTROY(&(cd->xdrs)); + } + mem_free((caddr_t)cd, sizeof(struct tcp_conn)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + +/* + * All read operations timeout after 35 seconds. + * A timeout is fatal for the connection. + */ +static struct timeval wait_per_try = { 35, 0 }; + +/* + * reads data from the tcp conection. + * any error is fatal and the connection is closed. + * (And a read of zero bytes is a half closed stream => error.) + */ +static int +readtcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + register int len; +{ + register int sock = xprt->xp_sock; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + register int mask = 1 << sock; + int readfds; +#endif /* def FD_SETSIZE */ + do { + readfds = mask; + if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &wait_per_try) <= 0) { + if (errno == EINTR) { + continue; + } + goto fatal_err; + } +#ifdef FD_SETSIZE + } while (!FD_ISSET(sock, &readfds)); +#else + } while (readfds != mask); +#endif /* def FD_SETSIZE */ + if ((len = read(sock, buf, len)) > 0) { + return (len); + } +fatal_err: + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; + return (-1); +} + +/* + * writes data to the tcp connection. + * Any error is fatal and the connection is closed. + */ +static int +writetcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(xprt->xp_sock, buf, cnt)) < 0) { + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = + XPRT_DIED; + return (-1); + } + } + return (len); +} + +static enum xprt_stat +svctcp_stat(xprt) + SVCXPRT *xprt; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + + if (cd->strm_stat == XPRT_DIED) + return (XPRT_DIED); + if (! xdrrec_eof(&(cd->xdrs))) + return (XPRT_MOREREQS); + return (XPRT_IDLE); +} + +static bool_t +svctcp_recv(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + (void)xdrrec_skiprecord(xdrs); + if (xdr_callmsg(xdrs, msg)) { + cd->x_id = msg->rm_xid; + return (TRUE); + } + return (FALSE); +} + +static bool_t +svctcp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr)); +} + +static bool_t +svctcp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = + &(((struct tcp_conn *)(xprt->xp_p1))->xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static bool_t +svctcp_reply(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + register bool_t stat; + + xdrs->x_op = XDR_ENCODE; + msg->rm_xid = cd->x_id; + stat = xdr_replymsg(xdrs, msg); + (void)xdrrec_endofrecord(xdrs, TRUE); + return (stat); +} diff --git a/sunrpc/svc_udp.c b/sunrpc/svc_udp.c new file mode 100644 index 0000000000..69ef7a1ce3 --- /dev/null +++ b/sunrpc/svc_udp.c @@ -0,0 +1,475 @@ +/* @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_udp.c, + * Server side for UDP/IP based RPC. (Does some caching in the hopes of + * achieving execute-at-most-once semantics.) + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> + + +#define rpc_buffer(xprt) ((xprt)->xp_p1) +#define MAX(a, b) ((a > b) ? a : b) + +static bool_t svcudp_recv(); +static bool_t svcudp_reply(); +static enum xprt_stat svcudp_stat(); +static bool_t svcudp_getargs(); +static bool_t svcudp_freeargs(); +static void svcudp_destroy(); + +static struct xp_ops svcudp_op = { + svcudp_recv, + svcudp_stat, + svcudp_getargs, + svcudp_reply, + svcudp_freeargs, + svcudp_destroy +}; + +extern int errno; + +/* + * kept in xprt->xp_p2 + */ +struct svcudp_data { + u_int su_iosz; /* byte size of send.recv buffer */ + u_long su_xid; /* transaction id */ + XDR su_xdrs; /* XDR handle */ + char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ + char * su_cache; /* cached data, NULL if no cache */ +}; +#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) + +/* + * Usage: + * xprt = svcudp_create(sock); + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svcudp_create + * binds it to an arbitrary port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * Once *xprt is initialized, it is registered as a transporter; + * see (svc.h, xprt_register). + * The routines returns NULL if a problem occurred. + */ +SVCXPRT * +svcudp_bufcreate(sock, sendsz, recvsz) + register int sock; + u_int sendsz, recvsz; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct svcudp_data *su; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("svcudp_create: socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { + perror("svcudp_create - cannot getsockname"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su = (struct svcudp_data *)mem_alloc(sizeof(*su)); + if (su == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; + if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + xdrmem_create( + &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); + su->su_cache = NULL; + xprt->xp_p2 = (caddr_t)su; + xprt->xp_verf.oa_base = su->su_verfbody; + xprt->xp_ops = &svcudp_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +SVCXPRT * +svcudp_create(sock) + int sock; +{ + + return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum xprt_stat +svcudp_stat(xprt) + SVCXPRT *xprt; +{ + + return (XPRT_IDLE); +} + +static bool_t +svcudp_recv(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int rlen; + char *reply; + u_long replylen; + + again: + xprt->xp_addrlen = sizeof(struct sockaddr_in); + rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, + 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); + if (rlen == -1 && errno == EINTR) + goto again; + if (rlen < 4*sizeof(u_long)) + return (FALSE); + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + su->su_xid = msg->rm_xid; + if (su->su_cache != NULL) { + if (cache_get(xprt, msg, &reply, &replylen)) { + (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, + (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); + return (TRUE); + } + } + return (TRUE); +} + +static bool_t +svcudp_reply(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int slen; + register bool_t stat = FALSE; + + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + msg->rm_xid = su->su_xid; + if (xdr_replymsg(xdrs, msg)) { + slen = (int)XDR_GETPOS(xdrs); + if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, + (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) + == slen) { + stat = TRUE; + if (su->su_cache && slen >= 0) { + cache_set(xprt, (u_long) slen); + } + } + } + return (stat); +} + +static bool_t +svcudp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); +} + +static bool_t +svcudp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = &(su_data(xprt)->su_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcudp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct svcudp_data *su = su_data(xprt); + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + XDR_DESTROY(&(su->su_xdrs)); + mem_free(rpc_buffer(xprt), su->su_iosz); + mem_free((caddr_t)su, sizeof(struct svcudp_data)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + + +/***********this could be a separate file*********************/ + +/* + * Fifo cache for udp server + * Copies pointers to reply buffers into fifo cache + * Buffers are sent again if retransmissions are detected. + */ + +#define SPARSENESS 4 /* 75% sparse */ + +#define CACHE_PERROR(msg) \ + (void) fprintf(stderr,"%s\n", msg) + +#define ALLOC(type, size) \ + (type *) mem_alloc((unsigned) (sizeof(type) * (size))) + +#define BZERO(addr, type, size) \ + bzero((char *) addr, sizeof(type) * (int) (size)) + +/* + * An entry in the cache + */ +typedef struct cache_node *cache_ptr; +struct cache_node { + /* + * Index into cache is xid, proc, vers, prog and address + */ + u_long cache_xid; + u_long cache_proc; + u_long cache_vers; + u_long cache_prog; + struct sockaddr_in cache_addr; + /* + * The cached reply and length + */ + char * cache_reply; + u_long cache_replylen; + /* + * Next node on the list, if there is a collision + */ + cache_ptr cache_next; +}; + + + +/* + * The entire cache + */ +struct udp_cache { + u_long uc_size; /* size of cache */ + cache_ptr *uc_entries; /* hash table of entries in cache */ + cache_ptr *uc_fifo; /* fifo list of entries in cache */ + u_long uc_nextvictim; /* points to next victim in fifo list */ + u_long uc_prog; /* saved program number */ + u_long uc_vers; /* saved version number */ + u_long uc_proc; /* saved procedure number */ + struct sockaddr_in uc_addr; /* saved caller's address */ +}; + + +/* + * the hashing function + */ +#define CACHE_LOC(transp, xid) \ + (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) + + +/* + * Enable use of the cache. + * Note: there is no disable. + */ +svcudp_enablecache(transp, size) + SVCXPRT *transp; + u_long size; +{ + struct svcudp_data *su = su_data(transp); + struct udp_cache *uc; + + if (su->su_cache != NULL) { + CACHE_PERROR("enablecache: cache already enabled"); + return(0); + } + uc = ALLOC(struct udp_cache, 1); + if (uc == NULL) { + CACHE_PERROR("enablecache: could not allocate cache"); + return(0); + } + uc->uc_size = size; + uc->uc_nextvictim = 0; + uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); + if (uc->uc_entries == NULL) { + CACHE_PERROR("enablecache: could not allocate cache data"); + return(0); + } + BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); + uc->uc_fifo = ALLOC(cache_ptr, size); + if (uc->uc_fifo == NULL) { + CACHE_PERROR("enablecache: could not allocate cache fifo"); + return(0); + } + BZERO(uc->uc_fifo, cache_ptr, size); + su->su_cache = (char *) uc; + return(1); +} + + +/* + * Set an entry in the cache + */ +static +cache_set(xprt, replylen) + SVCXPRT *xprt; + u_long replylen; +{ + register cache_ptr victim; + register cache_ptr *vicp; + register struct svcudp_data *su = su_data(xprt); + struct udp_cache *uc = (struct udp_cache *) su->su_cache; + u_int loc; + char *newbuf; + + /* + * Find space for the new entry, either by + * reusing an old entry, or by mallocing a new one + */ + victim = uc->uc_fifo[uc->uc_nextvictim]; + if (victim != NULL) { + loc = CACHE_LOC(xprt, victim->cache_xid); + for (vicp = &uc->uc_entries[loc]; + *vicp != NULL && *vicp != victim; + vicp = &(*vicp)->cache_next) + ; + if (*vicp == NULL) { + CACHE_PERROR("cache_set: victim not found"); + return; + } + *vicp = victim->cache_next; /* remote from cache */ + newbuf = victim->cache_reply; + } else { + victim = ALLOC(struct cache_node, 1); + if (victim == NULL) { + CACHE_PERROR("cache_set: victim alloc failed"); + return; + } + newbuf = mem_alloc(su->su_iosz); + if (newbuf == NULL) { + CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); + return; + } + } + + /* + * Store it away + */ + victim->cache_replylen = replylen; + victim->cache_reply = rpc_buffer(xprt); + rpc_buffer(xprt) = newbuf; + xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); + victim->cache_xid = su->su_xid; + victim->cache_proc = uc->uc_proc; + victim->cache_vers = uc->uc_vers; + victim->cache_prog = uc->uc_prog; + victim->cache_addr = uc->uc_addr; + loc = CACHE_LOC(xprt, victim->cache_xid); + victim->cache_next = uc->uc_entries[loc]; + uc->uc_entries[loc] = victim; + uc->uc_fifo[uc->uc_nextvictim++] = victim; + uc->uc_nextvictim %= uc->uc_size; +} + +/* + * Try to get an entry from the cache + * return 1 if found, 0 if not found + */ +static +cache_get(xprt, msg, replyp, replylenp) + SVCXPRT *xprt; + struct rpc_msg *msg; + char **replyp; + u_long *replylenp; +{ + u_int loc; + register cache_ptr ent; + register struct svcudp_data *su = su_data(xprt); + register struct udp_cache *uc = (struct udp_cache *) su->su_cache; + +# define EQADDR(a1, a2) (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) + + loc = CACHE_LOC(xprt, su->su_xid); + for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { + if (ent->cache_xid == su->su_xid && + ent->cache_proc == uc->uc_proc && + ent->cache_vers == uc->uc_vers && + ent->cache_prog == uc->uc_prog && + EQADDR(ent->cache_addr, uc->uc_addr)) { + *replyp = ent->cache_reply; + *replylenp = ent->cache_replylen; + return(1); + } + } + /* + * Failed to find entry + * Remember a few things so we can do a set later + */ + uc->uc_proc = msg->rm_call.cb_proc; + uc->uc_vers = msg->rm_call.cb_vers; + uc->uc_prog = msg->rm_call.cb_prog; + uc->uc_addr = xprt->xp_raddr; + return(0); +} + diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c new file mode 100644 index 0000000000..b8248c20b5 --- /dev/null +++ b/sunrpc/xdr.c @@ -0,0 +1,577 @@ +/* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; +#endif + +/* + * xdr.c, Generic XDR routines implementation. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + * + * These are the "generic" xdr routines used to serialize and de-serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> +char *malloc(); + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * constants specific to the xdr "protocol" + */ +#define XDR_FALSE ((long) 0) +#define XDR_TRUE ((long) 1) +#define LASTUNSIGNED ((u_int) 0-1) + +/* + * for unit alignment + */ +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; + +/* + * Free a data structure using XDR + * Not a filter, but a convenient utility nonetheless + */ +void +xdr_free(proc, objp) + xdrproc_t proc; + char *objp; +{ + XDR x; + + x.x_op = XDR_FREE; + (*proc)(&x, objp); +} + +/* + * XDR nothing + */ +bool_t +xdr_void(/* xdrs, addr */) + /* XDR *xdrs; */ + /* caddr_t addr; */ +{ + + return (TRUE); +} + +/* + * XDR integers + */ +bool_t +xdr_int(xdrs, ip) + XDR *xdrs; + int *ip; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)ip)); + return (xdr_long(xdrs, (long *)ip)); +#else + if (sizeof (int) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ip)); + } else { + return (xdr_short(xdrs, (short *)ip)); + } +#endif +} + +/* + * XDR unsigned integers + */ +bool_t +xdr_u_int(xdrs, up) + XDR *xdrs; + u_int *up; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)up)); + return (xdr_u_long(xdrs, (u_long *)up)); +#else + if (sizeof (u_int) == sizeof (u_long)) { + return (xdr_u_long(xdrs, (u_long *)up)); + } else { + return (xdr_short(xdrs, (short *)up)); + } +#endif +} + +/* + * XDR long integers + * same as xdr_u_long - open coded to save a proc call! + */ +bool_t +xdr_long(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_FREE) + return (TRUE); + + return (FALSE); +} + +/* + * XDR unsigned long integers + * same as xdr_long - open coded to save a proc call! + */ +bool_t +xdr_u_long(xdrs, ulp) + register XDR *xdrs; + u_long *ulp; +{ + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_FREE) + return (TRUE); + return (FALSE); +} + +/* + * XDR short integers + */ +bool_t +xdr_short(xdrs, sp) + register XDR *xdrs; + short *sp; +{ + long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (long) *sp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *sp = (short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short(xdrs, usp) + register XDR *xdrs; + u_short *usp; +{ + u_long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (u_long) *usp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *usp = (u_short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + + +/* + * XDR a char + */ +bool_t +xdr_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + int i; + + i = (*cp); + if (!xdr_int(xdrs, &i)) { + return (FALSE); + } + *cp = i; + return (TRUE); +} + +/* + * XDR an unsigned char + */ +bool_t +xdr_u_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + u_int u; + + u = (*cp); + if (!xdr_u_int(xdrs, &u)) { + return (FALSE); + } + *cp = u; + return (TRUE); +} + +/* + * XDR booleans + */ +bool_t +xdr_bool(xdrs, bp) + register XDR *xdrs; + bool_t *bp; +{ + long lb; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + lb = *bp ? XDR_TRUE : XDR_FALSE; + return (XDR_PUTLONG(xdrs, &lb)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &lb)) { + return (FALSE); + } + *bp = (lb == XDR_FALSE) ? FALSE : TRUE; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR enumerations + */ +bool_t +xdr_enum(xdrs, ep) + XDR *xdrs; + enum_t *ep; +{ +#ifndef lint + enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ + + /* + * enums are treated as ints + */ + if (sizeof (enum sizecheck) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ep)); + } else if (sizeof (enum sizecheck) == sizeof (short)) { + return (xdr_short(xdrs, (short *)ep)); + } else { + return (FALSE); + } +#else + (void) (xdr_short(xdrs, (short *)ep)); + return (xdr_long(xdrs, (long *)ep)); +#endif +} + +/* + * XDR opaque data + * Allows the specification of a fixed size sequence of opaque bytes. + * cp points to the opaque object and cnt gives the byte length. + */ +bool_t +xdr_opaque(xdrs, cp, cnt) + register XDR *xdrs; + caddr_t cp; + register u_int cnt; +{ + register u_int rndup; + static crud[BYTES_PER_XDR_UNIT]; + + /* + * if no data we are done + */ + if (cnt == 0) + return (TRUE); + + /* + * round byte count to full xdr units + */ + rndup = cnt % BYTES_PER_XDR_UNIT; + if (rndup > 0) + rndup = BYTES_PER_XDR_UNIT - rndup; + + if (xdrs->x_op == XDR_DECODE) { + if (!XDR_GETBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_GETBYTES(xdrs, crud, rndup)); + } + + if (xdrs->x_op == XDR_ENCODE) { + if (!XDR_PUTBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); + } + + if (xdrs->x_op == XDR_FREE) { + return (TRUE); + } + + return (FALSE); +} + +/* + * XDR counted bytes + * *cpp is a pointer to the bytes, *sizep is the count. + * If *cpp is NULL maxsize bytes are allocated + */ +bool_t +xdr_bytes(xdrs, cpp, sizep, maxsize) + register XDR *xdrs; + char **cpp; + register u_int *sizep; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + register u_int nodesize; + + /* + * first deal with the length since xdr bytes are counted + */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + nodesize = *sizep; + if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) { + *cpp = sp = (char *)mem_alloc(nodesize); + } + if (sp == NULL) { + (void) fprintf(stderr, "xdr_bytes: out of memory\n"); + return (FALSE); + } + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, nodesize)); + + case XDR_FREE: + if (sp != NULL) { + mem_free(sp, nodesize); + *cpp = NULL; + } + return (TRUE); + } + return (FALSE); +} + +/* + * Implemented here due to commonality of the object. + */ +bool_t +xdr_netobj(xdrs, np) + XDR *xdrs; + struct netobj *np; +{ + + return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); +} + +/* + * XDR a descriminated union + * Support routine for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer. The routine gets + * the discriminant value and then searches the array of xdrdiscrims + * looking for that value. It calls the procedure given in the xdrdiscrim + * to handle the discriminant. If there is no specific routine a default + * routine may be called. + * If there is no specific or default routine an error is returned. + */ +bool_t +xdr_union(xdrs, dscmp, unp, choices, dfault) + register XDR *xdrs; + enum_t *dscmp; /* enum to decide which arm to work on */ + char *unp; /* the union itself */ + struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ + xdrproc_t dfault; /* default xdr routine */ +{ + register enum_t dscm; + + /* + * we deal with the discriminator; it's an enum + */ + if (! xdr_enum(xdrs, dscmp)) { + return (FALSE); + } + dscm = *dscmp; + + /* + * search choices for a value that matches the discriminator. + * if we find one, execute the xdr routine for that value. + */ + for (; choices->proc != NULL_xdrproc_t; choices++) { + if (choices->value == dscm) + return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); + } + + /* + * no match - execute the default xdr routine if there is one + */ + return ((dfault == NULL_xdrproc_t) ? FALSE : + (*dfault)(xdrs, unp, LASTUNSIGNED)); +} + + +/* + * Non-portable xdr primitives. + * Care should be taken when moving these routines to new architectures. + */ + + +/* + * XDR null terminated ASCII strings + * xdr_string deals with "C strings" - arrays of bytes that are + * terminated by a NULL character. The parameter cpp references a + * pointer to storage; If the pointer is null, then the necessary + * storage is allocated. The last parameter is the max allowed length + * of the string as specified by a protocol. + */ +bool_t +xdr_string(xdrs, cpp, maxsize) + register XDR *xdrs; + char **cpp; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + u_int size; + u_int nodesize; + + /* + * first deal with the length since xdr strings are counted-strings + */ + switch (xdrs->x_op) { + case XDR_FREE: + if (sp == NULL) { + return(TRUE); /* already free */ + } + /* fall through... */ + case XDR_ENCODE: + size = strlen(sp); + break; + } + if (! xdr_u_int(xdrs, &size)) { + return (FALSE); + } + if (size > maxsize) { + return (FALSE); + } + nodesize = size + 1; + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) + *cpp = sp = (char *)mem_alloc(nodesize); + if (sp == NULL) { + (void) fprintf(stderr, "xdr_string: out of memory\n"); + return (FALSE); + } + sp[size] = 0; + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, size)); + + case XDR_FREE: + mem_free(sp, nodesize); + *cpp = NULL; + return (TRUE); + } + return (FALSE); +} + +/* + * Wrapper for xdr_string that can be called directly from + * routines like clnt_call + */ +bool_t +xdr_wrapstring(xdrs, cpp) + XDR *xdrs; + char **cpp; +{ + if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { + return (TRUE); + } + return (FALSE); +} diff --git a/sunrpc/xdr_array.c b/sunrpc/xdr_array.c new file mode 100644 index 0000000000..7c2831ccd2 --- /dev/null +++ b/sunrpc/xdr_array.c @@ -0,0 +1,153 @@ +/* @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_array.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * arrays. See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + + +/* + * XDR an array of arbitrary elements + * *addrp is a pointer to the array, *sizep is the number of elements. + * If addrp is NULL (*sizep * elsize) bytes are allocated. + * elsize is the size (in bytes) of each element, and elproc is the + * xdr procedure to call to handle each element of the array. + */ +bool_t +xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc) + register XDR *xdrs; + caddr_t *addrp; /* array pointer */ + u_int *sizep; /* number of elements */ + u_int maxsize; /* max numberof elements */ + u_int elsize; /* size in bytes of each element */ + xdrproc_t elproc; /* xdr routine to handle each element */ +{ + register u_int i; + register caddr_t target = *addrp; + register u_int c; /* the actual element count */ + register bool_t stat = TRUE; + register u_int nodesize; + + /* like strings, arrays are really counted arrays */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + c = *sizep; + if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + nodesize = c * elsize; + + /* + * if we are deserializing, we may need to allocate an array. + * We also save time by checking for a null array if we are freeing. + */ + if (target == NULL) + switch (xdrs->x_op) { + case XDR_DECODE: + if (c == 0) + return (TRUE); + *addrp = target = mem_alloc(nodesize); + if (target == NULL) { + (void) fprintf(stderr, + "xdr_array: out of memory\n"); + return (FALSE); + } + bzero(target, nodesize); + break; + + case XDR_FREE: + return (TRUE); + } + + /* + * now we xdr each element of array + */ + for (i = 0; (i < c) && stat; i++) { + stat = (*elproc)(xdrs, target, LASTUNSIGNED); + target += elsize; + } + + /* + * the array may need freeing + */ + if (xdrs->x_op == XDR_FREE) { + mem_free(*addrp, nodesize); + *addrp = NULL; + } + return (stat); +} + +/* + * xdr_vector(): + * + * XDR a fixed length array. Unlike variable-length arrays, + * the storage of fixed length arrays is static and unfreeable. + * > basep: base of the array + * > size: size of the array + * > elemsize: size of each element + * > xdr_elem: routine to XDR each element + */ +bool_t +xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem) + register XDR *xdrs; + register char *basep; + register u_int nelem; + register u_int elemsize; + register xdrproc_t xdr_elem; +{ + register u_int i; + register char *elptr; + + elptr = basep; + for (i = 0; i < nelem; i++) { + if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { + return(FALSE); + } + elptr += elemsize; + } + return(TRUE); +} + diff --git a/sunrpc/xdr_float.c b/sunrpc/xdr_float.c new file mode 100644 index 0000000000..549f8bd97b --- /dev/null +++ b/sunrpc/xdr_float.c @@ -0,0 +1,267 @@ +/* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_float.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "floating point" xdr routines used to (de)serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * NB: Not portable. + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct ieee_single { + unsigned int mantissa: 23; + unsigned int exp : 8; + unsigned int sign : 1; +}; + +/* Vax single precision floating point */ +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; +}; + +#define VAX_SNG_BIAS 0x81 +#define IEEE_SNG_BIAS 0x7f + +static struct sgl_limits { + struct vax_single s; + struct ieee_single ieee; +} sgl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x0, 0xff, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; +#endif /* vax */ + +bool_t +xdr_float(xdrs, fp) + register XDR *xdrs; + register float *fp; +{ +#ifdef vax + struct ieee_single is; + struct vax_single vs, *vsp; + struct sgl_limits *lim; + int i; +#endif + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifndef vax + return (XDR_PUTLONG(xdrs, (long *)fp)); +#else + vs = *((struct vax_single *)fp); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((vs.mantissa2 == lim->s.mantissa2) && + (vs.exp == lim->s.exp) && + (vs.mantissa1 == lim->s.mantissa1)) { + is = lim->ieee; + goto shipit; + } + } + is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; + shipit: + is.sign = vs.sign; + return (XDR_PUTLONG(xdrs, (long *)&is)); +#endif + + case XDR_DECODE: +#ifndef vax + return (XDR_GETLONG(xdrs, (long *)fp)); +#else + vsp = (struct vax_single *)fp; + if (!XDR_GETLONG(xdrs, (long *)&is)) + return (FALSE); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((is.exp == lim->ieee.exp) && + (is.mantissa == lim->ieee.mantissa)) { + *vsp = lim->s; + goto doneit; + } + } + vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = is.mantissa; + vsp->mantissa1 = (is.mantissa >> 16); + doneit: + vsp->sign = is.sign; + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef vax +/* What IEEE double precision floating point looks like on a Vax */ +struct ieee_double { + unsigned int mantissa1 : 20; + unsigned int exp : 11; + unsigned int sign : 1; + unsigned int mantissa2 : 32; +}; + +/* Vax double precision floating point */ +struct vax_double { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; + unsigned int mantissa3 : 16; + unsigned int mantissa4 : 16; +}; + +#define VAX_DBL_BIAS 0x81 +#define IEEE_DBL_BIAS 0x3ff +#define MASK(nbits) ((1 << nbits) - 1) + +static struct dbl_limits { + struct vax_double d; + struct ieee_double ieee; +} dbl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ + { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; + +#endif /* vax */ + + +bool_t +xdr_double(xdrs, dp) + register XDR *xdrs; + double *dp; +{ + register long *lp; +#ifdef vax + struct ieee_double id; + struct vax_double vd; + register struct dbl_limits *lim; + int i; +#endif + + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifndef vax + lp = (long *)dp; +#else + vd = *((struct vax_double *)dp); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((vd.mantissa4 == lim->d.mantissa4) && + (vd.mantissa3 == lim->d.mantissa3) && + (vd.mantissa2 == lim->d.mantissa2) && + (vd.mantissa1 == lim->d.mantissa1) && + (vd.exp == lim->d.exp)) { + id = lim->ieee; + goto shipit; + } + } + id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); + id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | + (vd.mantissa3 << 13) | + ((vd.mantissa4 >> 3) & MASK(13)); + shipit: + id.sign = vd.sign; + lp = (long *)&id; +#endif + return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); + + case XDR_DECODE: +#ifndef vax + lp = (long *)dp; + return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); +#else + lp = (long *)&id; + if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) + return (FALSE); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((id.mantissa2 == lim->ieee.mantissa2) && + (id.mantissa1 == lim->ieee.mantissa1) && + (id.exp == lim->ieee.exp)) { + vd = lim->d; + goto doneit; + } + } + vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + vd.mantissa1 = (id.mantissa1 >> 13); + vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | + (id.mantissa2 >> 29); + vd.mantissa3 = (id.mantissa2 >> 13); + vd.mantissa4 = (id.mantissa2 << 3); + doneit: + vd.sign = id.sign; + *dp = *((double *)&vd); + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} diff --git a/sunrpc/xdr_mem.c b/sunrpc/xdr_mem.c new file mode 100644 index 0000000000..558d369227 --- /dev/null +++ b/sunrpc/xdr_mem.c @@ -0,0 +1,184 @@ +/* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * If you have some data to be interpreted as external data representation + * or to be converted to external data representation in a memory buffer, + * then this is the package for you. + * + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +static bool_t xdrmem_getlong(); +static bool_t xdrmem_putlong(); +static bool_t xdrmem_getbytes(); +static bool_t xdrmem_putbytes(); +static u_int xdrmem_getpos(); +static bool_t xdrmem_setpos(); +static long * xdrmem_inline(); +static void xdrmem_destroy(); + +static struct xdr_ops xdrmem_ops = { + xdrmem_getlong, + xdrmem_putlong, + xdrmem_getbytes, + xdrmem_putbytes, + xdrmem_getpos, + xdrmem_setpos, + xdrmem_inline, + xdrmem_destroy +}; + +/* + * The procedure xdrmem_create initializes a stream descriptor for a + * memory buffer. + */ +void +xdrmem_create(xdrs, addr, size, op) + register XDR *xdrs; + caddr_t addr; + u_int size; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; + xdrs->x_handy = size; +} + +static void +xdrmem_destroy(/*xdrs*/) + /*XDR *xdrs;*/ +{ +} + +static bool_t +xdrmem_getlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_putlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_getbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +} + +static bool_t +xdrmem_putbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +} + +static u_int +xdrmem_getpos(xdrs) + register XDR *xdrs; +{ + + return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); +} + +static bool_t +xdrmem_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register caddr_t newaddr = xdrs->x_base + pos; + register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + + if ((long)newaddr > (long)lastaddr) + return (FALSE); + xdrs->x_private = newaddr; + xdrs->x_handy = (int)lastaddr - (int)newaddr; + return (TRUE); +} + +static long * +xdrmem_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + long *buf = 0; + + if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (long *) xdrs->x_private; + xdrs->x_private += len; + } + return (buf); +} diff --git a/sunrpc/xdr_rec.c b/sunrpc/xdr_rec.c new file mode 100644 index 0000000000..4d0d4ecfb3 --- /dev/null +++ b/sunrpc/xdr_rec.c @@ -0,0 +1,580 @@ +/* @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" + * layer above tcp (for rpc's use). + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These routines interface XDRSTREAMS to a tcp/ip connection. + * There is a record marking layer between the xdr stream + * and the tcp transport level. A record is composed on one or more + * record fragments. A record fragment is a thirty-two bit header followed + * by n bytes of data, where n is contained in the header. The header + * is represented as a htonl(u_long). Thegh order bit encodes + * whether or not the fragment is the last fragment of the record + * (1 => fragment is last, 0 => more fragments to follow. + * The other 31 bits encode the byte length of the fragment. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +extern long lseek(); + +static u_int fix_buf_size(); + +static bool_t xdrrec_getlong(); +static bool_t xdrrec_putlong(); +static bool_t xdrrec_getbytes(); +static bool_t xdrrec_putbytes(); +static u_int xdrrec_getpos(); +static bool_t xdrrec_setpos(); +static long * xdrrec_inline(); +static void xdrrec_destroy(); + +static struct xdr_ops xdrrec_ops = { + xdrrec_getlong, + xdrrec_putlong, + xdrrec_getbytes, + xdrrec_putbytes, + xdrrec_getpos, + xdrrec_setpos, + xdrrec_inline, + xdrrec_destroy +}; + +/* + * A record is composed of one or more record fragments. + * A record fragment is a two-byte header followed by zero to + * 2**32-1 bytes. The header is treated as a long unsigned and is + * encode/decoded to the network via htonl/ntohl. The low order 31 bits + * are a byte count of the fragment. The highest order bit is a boolean: + * 1 => this fragment is the last fragment of the record, + * 0 => this fragment is followed by more fragment(s). + * + * The fragment/record machinery is not general; it is constructed to + * meet the needs of xdr and rpc based on tcp. + */ + +#define LAST_FRAG ((u_long)(1 << 31)) + +typedef struct rec_strm { + caddr_t tcp_handle; + caddr_t the_buffer; + /* + * out-goung bits + */ + int (*writeit)(); + caddr_t out_base; /* output buffer (points to frag header) */ + caddr_t out_finger; /* next output position */ + caddr_t out_boundry; /* data cannot up to this address */ + u_long *frag_header; /* beginning of curren fragment */ + bool_t frag_sent; /* true if buffer sent in middle of record */ + /* + * in-coming bits + */ + int (*readit)(); + u_long in_size; /* fixed size of the input buffer */ + caddr_t in_base; + caddr_t in_finger; /* location of next byte to be had */ + caddr_t in_boundry; /* can read up to this location */ + long fbtbc; /* fragment bytes to be consumed */ + bool_t last_frag; + u_int sendsize; + u_int recvsize; +} RECSTREAM; + + +/* + * Create an xdr handle for xdrrec + * xdrrec_create fills in xdrs. Sendsize and recvsize are + * send and recv buffer sizes (0 => use default). + * tcp_handle is an opaque handle that is passed as the first parameter to + * the procedures readit and writeit. Readit and writeit are read and + * write respectively. They are like the system + * calls expect that they take an opaque handle rather than an fd. + */ +void +xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) + register XDR *xdrs; + register u_int sendsize; + register u_int recvsize; + caddr_t tcp_handle; + int (*readit)(); /* like read, but pass it a tcp_handle, not sock */ + int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */ +{ + register RECSTREAM *rstrm = + (RECSTREAM *)mem_alloc(sizeof(RECSTREAM)); + + if (rstrm == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + /* + * This is bad. Should rework xdrrec_create to + * return a handle, and in this case return NULL + */ + return; + } + /* + * adjust sizes and allocate buffer quad byte aligned + */ + rstrm->sendsize = sendsize = fix_buf_size(sendsize); + rstrm->recvsize = recvsize = fix_buf_size(recvsize); + rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); + if (rstrm->the_buffer == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + return; + } + for (rstrm->out_base = rstrm->the_buffer; + (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; + rstrm->out_base++); + rstrm->in_base = rstrm->out_base + sendsize; + /* + * now the rest ... + */ + xdrs->x_ops = &xdrrec_ops; + xdrs->x_private = (caddr_t)rstrm; + rstrm->tcp_handle = tcp_handle; + rstrm->readit = readit; + rstrm->writeit = writeit; + rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger += sizeof(u_long); + rstrm->out_boundry += sendsize; + rstrm->frag_sent = FALSE; + rstrm->in_size = recvsize; + rstrm->in_boundry = rstrm->in_base; + rstrm->in_finger = (rstrm->in_boundry += recvsize); + rstrm->fbtbc = 0; + rstrm->last_frag = TRUE; +} + + +/* + * The reoutines defined below are the xdr ops which will go into the + * xdr handle filled in by xdrrec_create. + */ + +static bool_t +xdrrec_getlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *buflp = (long *)(rstrm->in_finger); + long mylong; + + /* first try the inline, fast case */ + if ((rstrm->fbtbc >= sizeof(long)) && + (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) { + *lp = (long)ntohl((u_long)(*buflp)); + rstrm->fbtbc -= sizeof(long); + rstrm->in_finger += sizeof(long); + } else { + if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long))) + return (FALSE); + *lp = (long)ntohl((u_long)mylong); + } + return (TRUE); +} + +static bool_t +xdrrec_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *dest_lp = ((long *)(rstrm->out_finger)); + + if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= sizeof(long); + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + dest_lp = ((long *)(rstrm->out_finger)); + rstrm->out_finger += sizeof(long); + } + *dest_lp = (long)htonl((u_long)(*lp)); + return (TRUE); +} + +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = rstrm->fbtbc; + if (current == 0) { + if (rstrm->last_frag) + return (FALSE); + if (! set_input_fragment(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + if (! get_input_bytes(rstrm, addr, current)) + return (FALSE); + addr += current; + rstrm->fbtbc -= current; + len -= current; + } + return (TRUE); +} + +static bool_t +xdrrec_putbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger; + current = (len < current) ? len : current; + bcopy(addr, rstrm->out_finger, current); + rstrm->out_finger += current; + addr += current; + len -= current; + if (rstrm->out_finger == rstrm->out_boundry) { + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + } + } + return (TRUE); +} + +static u_int +xdrrec_getpos(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + register long pos; + + pos = lseek((int)rstrm->tcp_handle, (long) 0, 1); + if (pos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + pos += rstrm->out_finger - rstrm->out_base; + break; + + case XDR_DECODE: + pos -= rstrm->in_boundry - rstrm->in_finger; + break; + + default: + pos = (u_int) -1; + break; + } + return ((u_int) pos); +} + +static bool_t +xdrrec_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + u_int currpos = xdrrec_getpos(xdrs); + int delta = currpos - pos; + caddr_t newpos; + + if ((int)currpos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + newpos = rstrm->out_finger - delta; + if ((newpos > (caddr_t)(rstrm->frag_header)) && + (newpos < rstrm->out_boundry)) { + rstrm->out_finger = newpos; + return (TRUE); + } + break; + + case XDR_DECODE: + newpos = rstrm->in_finger - delta; + if ((delta < (int)(rstrm->fbtbc)) && + (newpos <= rstrm->in_boundry) && + (newpos >= rstrm->in_base)) { + rstrm->in_finger = newpos; + rstrm->fbtbc -= delta; + return (TRUE); + } + break; + } + return (FALSE); +} + +static long * +xdrrec_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + long * buf = NULL; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + if ((rstrm->out_finger + len) <= rstrm->out_boundry) { + buf = (long *) rstrm->out_finger; + rstrm->out_finger += len; + } + break; + + case XDR_DECODE: + if ((len <= rstrm->fbtbc) && + ((rstrm->in_finger + len) <= rstrm->in_boundry)) { + buf = (long *) rstrm->in_finger; + rstrm->fbtbc -= len; + rstrm->in_finger += len; + } + break; + } + return (buf); +} + +static void +xdrrec_destroy(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + + mem_free(rstrm->the_buffer, + rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); +} + + +/* + * Exported routines to manage xdr records + */ + +/* + * Before reading (deserializing from the stream, one should always call + * this procedure to guarantee proper record alignment. + */ +bool_t +xdrrec_skiprecord(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (FALSE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (FALSE); + } + rstrm->last_frag = FALSE; + return (TRUE); +} + +/* + * Look ahead fuction. + * Returns TRUE iff there is no more input in the buffer + * after consuming the rest of the current record. + */ +bool_t +xdrrec_eof(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (TRUE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (TRUE); + } + if (rstrm->in_finger == rstrm->in_boundry) + return (TRUE); + return (FALSE); +} + +/* + * The client must tell the package when an end-of-record has occurred. + * The second paraemters tells whether the record should be flushed to the + * (output) tcp stream. (This let's the package support batched or + * pipelined procedure calls.) TRUE => immmediate flush to tcp connection. + */ +bool_t +xdrrec_endofrecord(xdrs, sendnow) + XDR *xdrs; + bool_t sendnow; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register u_long len; /* fragment length */ + + if (sendnow || rstrm->frag_sent || + ((u_long)rstrm->out_finger + sizeof(u_long) >= + (u_long)rstrm->out_boundry)) { + rstrm->frag_sent = FALSE; + return (flush_out(rstrm, TRUE)); + } + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - + sizeof(u_long); + *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG); + rstrm->frag_header = (u_long *)rstrm->out_finger; + rstrm->out_finger += sizeof(u_long); + return (TRUE); +} + + +/* + * Internal useful routines + */ +static bool_t +flush_out(rstrm, eor) + register RECSTREAM *rstrm; + bool_t eor; +{ + register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; + register u_long len = (u_long)(rstrm->out_finger) - + (u_long)(rstrm->frag_header) - sizeof(u_long); + + *(rstrm->frag_header) = htonl(len | eormask); + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); + if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) + != (int)len) + return (FALSE); + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long); + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +fill_input_buf(rstrm) + register RECSTREAM *rstrm; +{ + register caddr_t where; + u_int i; + register int len; + + where = rstrm->in_base; + i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT; + where += i; + len = rstrm->in_size - i; + if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) + return (FALSE); + rstrm->in_finger = where; + where += len; + rstrm->in_boundry = where; + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +get_input_bytes(rstrm, addr, len) + register RECSTREAM *rstrm; + register caddr_t addr; + register int len; +{ + register int current; + + while (len > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + bcopy(rstrm->in_finger, addr, current); + rstrm->in_finger += current; + addr += current; + len -= current; + } + return (TRUE); +} + +static bool_t /* next two bytes of the input stream are treated as a header */ +set_input_fragment(rstrm) + register RECSTREAM *rstrm; +{ + u_long header; + + if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) + return (FALSE); + header = (long)ntohl(header); + rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; + rstrm->fbtbc = header & (~LAST_FRAG); + return (TRUE); +} + +static bool_t /* consumes input bytes; knows nothing about records! */ +skip_input_bytes(rstrm, cnt) + register RECSTREAM *rstrm; + long cnt; +{ + register int current; + + while (cnt > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (cnt < current) ? cnt : current; + rstrm->in_finger += current; + cnt -= current; + } + return (TRUE); +} + +static u_int +fix_buf_size(s) + register u_int s; +{ + + if (s < 100) + s = 4000; + return (RNDUP(s)); +} diff --git a/sunrpc/xdr_ref.c b/sunrpc/xdr_ref.c new file mode 100644 index 0000000000..32d91d9999 --- /dev/null +++ b/sunrpc/xdr_ref.c @@ -0,0 +1,132 @@ +/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; +#endif + +/* + * xdr_reference.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1987, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * "pointers". See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + +/* + * XDR an indirect pointer + * xdr_reference is for recursively translating a structure that is + * referenced by a pointer inside the structure that is currently being + * translated. pp references a pointer to storage. If *pp is null + * the necessary storage is allocated. + * size is the sizeof the referneced structure. + * proc is the routine to handle the referenced structure. + */ +bool_t +xdr_reference(xdrs, pp, size, proc) + register XDR *xdrs; + caddr_t *pp; /* the pointer to work on */ + u_int size; /* size of the object pointed to */ + xdrproc_t proc; /* xdr routine to handle the object */ +{ + register caddr_t loc = *pp; + register bool_t stat; + + if (loc == NULL) + switch (xdrs->x_op) { + case XDR_FREE: + return (TRUE); + + case XDR_DECODE: + *pp = loc = (caddr_t) mem_alloc(size); + if (loc == NULL) { + (void) fprintf(stderr, + "xdr_reference: out of memory\n"); + return (FALSE); + } + bzero(loc, (int)size); + break; + } + + stat = (*proc)(xdrs, loc, LASTUNSIGNED); + + if (xdrs->x_op == XDR_FREE) { + mem_free(loc, size); + *pp = NULL; + } + return (stat); +} + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + * What's sent is actually a union: + * + * union object_pointer switch (boolean b) { + * case TRUE: object_data data; + * case FALSE: void nothing; + * } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) + register XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; +{ + + bool_t more_data; + + more_data = (*objpp != NULL); + if (! xdr_bool(xdrs,&more_data)) { + return (FALSE); + } + if (! more_data) { + *objpp = NULL; + return (TRUE); + } + return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} diff --git a/sunrpc/xdr_stdio.c b/sunrpc/xdr_stdio.c new file mode 100644 index 0000000000..694774f6f6 --- /dev/null +++ b/sunrpc/xdr_stdio.c @@ -0,0 +1,189 @@ +/* @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_stdio.c, XDR implementation on standard i/o file. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements a XDR on a stdio stream. + * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes + * from the stream. + */ + +#include <rpc/types.h> +#include <stdio.h> +#include <rpc/xdr.h> + +static bool_t xdrstdio_getlong(); +static bool_t xdrstdio_putlong(); +static bool_t xdrstdio_getbytes(); +static bool_t xdrstdio_putbytes(); +static u_int xdrstdio_getpos(); +static bool_t xdrstdio_setpos(); +static long * xdrstdio_inline(); +static void xdrstdio_destroy(); + +/* + * Ops vector for stdio type XDR + */ +static struct xdr_ops xdrstdio_ops = { + xdrstdio_getlong, /* deseraialize a long int */ + xdrstdio_putlong, /* seraialize a long int */ + xdrstdio_getbytes, /* deserialize counted bytes */ + xdrstdio_putbytes, /* serialize counted bytes */ + xdrstdio_getpos, /* get offset in the stream */ + xdrstdio_setpos, /* set offset in the stream */ + xdrstdio_inline, /* prime stream for inline macros */ + xdrstdio_destroy /* destroy stream */ +}; + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +void +xdrstdio_create(xdrs, file, op) + register XDR *xdrs; + FILE *file; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrstdio_ops; + xdrs->x_private = (caddr_t)file; + xdrs->x_handy = 0; + xdrs->x_base = 0; +} + +/* + * Destroy a stdio xdr stream. + * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. + */ +static void +xdrstdio_destroy(xdrs) + register XDR *xdrs; +{ + (void)fflush((FILE *)xdrs->x_private); + /* xx should we close the file ?? */ +}; + +static bool_t +xdrstdio_getlong(xdrs, lp) + XDR *xdrs; + register long *lp; +{ + + if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); +#ifndef mc68000 + *lp = ntohl(*lp); +#endif + return (TRUE); +} + +static bool_t +xdrstdio_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + +#ifndef mc68000 + long mycopy = htonl(*lp); + lp = &mycopy; +#endif + if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_getbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_putbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static u_int +xdrstdio_getpos(xdrs) + XDR *xdrs; +{ + + return ((u_int) ftell((FILE *)xdrs->x_private)); +} + +static bool_t +xdrstdio_setpos(xdrs, pos) + XDR *xdrs; + u_int pos; +{ + + return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? + FALSE : TRUE); +} + +static long * +xdrstdio_inline(xdrs, len) + XDR *xdrs; + u_int len; +{ + + /* + * Must do some work to implement this: must insure + * enough data in the underlying stdio buffer, + * that the buffer is aligned so that we can indirect through a + * long *, and stuff this pointer in xdrs->x_buf. Doing + * a fread or fwrite to a scratch buffer would defeat + * most of the gains to be had here and require storage + * management on this buffer, so we don't do this. + */ + return (NULL); +} diff --git a/sys/bitypes.h b/sys/bitypes.h new file mode 100644 index 0000000000..137945172d --- /dev/null +++ b/sys/bitypes.h @@ -0,0 +1 @@ +#include <resolv/sys/bitypes.h> diff --git a/sys/cdefs.h b/sys/cdefs.h new file mode 100644 index 0000000000..200abb4f02 --- /dev/null +++ b/sys/cdefs.h @@ -0,0 +1 @@ +#include <misc/sys/cdefs.h> diff --git a/sys/dir.h b/sys/dir.h new file mode 100644 index 0000000000..5453e743fc --- /dev/null +++ b/sys/dir.h @@ -0,0 +1 @@ +#include <misc/sys/dir.h> diff --git a/sys/errno.h b/sys/errno.h new file mode 100644 index 0000000000..339f4fc10c --- /dev/null +++ b/sys/errno.h @@ -0,0 +1 @@ +#include <errno.h> diff --git a/sys/fcntl.h b/sys/fcntl.h new file mode 100644 index 0000000000..dec2157be6 --- /dev/null +++ b/sys/fcntl.h @@ -0,0 +1 @@ +#include <io/sys/fcntl.h> diff --git a/sys/file.h b/sys/file.h new file mode 100644 index 0000000000..fb3cd7544e --- /dev/null +++ b/sys/file.h @@ -0,0 +1 @@ +#include <misc/sys/file.h> diff --git a/sys/ioctl.h b/sys/ioctl.h new file mode 100644 index 0000000000..8cc77757f6 --- /dev/null +++ b/sys/ioctl.h @@ -0,0 +1 @@ +#include <misc/sys/ioctl.h> diff --git a/sys/poll.h b/sys/poll.h new file mode 100644 index 0000000000..5231e6845e --- /dev/null +++ b/sys/poll.h @@ -0,0 +1 @@ +#include <io/sys/poll.h> diff --git a/sys/ptrace.h b/sys/ptrace.h new file mode 100644 index 0000000000..f099a4e912 --- /dev/null +++ b/sys/ptrace.h @@ -0,0 +1 @@ +#include <misc/sys/ptrace.h> diff --git a/sys/resource.h b/sys/resource.h new file mode 100644 index 0000000000..33e6f4de9e --- /dev/null +++ b/sys/resource.h @@ -0,0 +1 @@ +#include <resource/sys/resource.h> diff --git a/sys/signal.h b/sys/signal.h new file mode 100644 index 0000000000..b2110df1ae --- /dev/null +++ b/sys/signal.h @@ -0,0 +1 @@ +#include <signal/sys/signal.h> diff --git a/sys/socket.h b/sys/socket.h new file mode 100644 index 0000000000..999a683016 --- /dev/null +++ b/sys/socket.h @@ -0,0 +1 @@ +#include <socket/sys/socket.h> diff --git a/sys/stat.h b/sys/stat.h new file mode 100644 index 0000000000..37a526069f --- /dev/null +++ b/sys/stat.h @@ -0,0 +1 @@ +#include <io/sys/stat.h> diff --git a/sys/syslog.h b/sys/syslog.h new file mode 100644 index 0000000000..247528b430 --- /dev/null +++ b/sys/syslog.h @@ -0,0 +1 @@ +#include <misc/sys/syslog.h> diff --git a/sys/termios.h b/sys/termios.h new file mode 100644 index 0000000000..27e4de5f4b --- /dev/null +++ b/sys/termios.h @@ -0,0 +1 @@ +#include <termios/sys/termios.h> diff --git a/sys/time.h b/sys/time.h new file mode 100644 index 0000000000..5595a957a0 --- /dev/null +++ b/sys/time.h @@ -0,0 +1 @@ +#include <time/sys/time.h> diff --git a/sys/timeb.h b/sys/timeb.h new file mode 100644 index 0000000000..9f4509c35e --- /dev/null +++ b/sys/timeb.h @@ -0,0 +1 @@ +#include <time/sys/timeb.h> diff --git a/sys/times.h b/sys/times.h new file mode 100644 index 0000000000..16ca91138a --- /dev/null +++ b/sys/times.h @@ -0,0 +1 @@ +#include <posix/sys/times.h> diff --git a/sys/ttydefaults.h b/sys/ttydefaults.h new file mode 100644 index 0000000000..9cf7f1b6b9 --- /dev/null +++ b/sys/ttydefaults.h @@ -0,0 +1 @@ +#include <termios/sys/ttydefaults.h> diff --git a/sys/types.h b/sys/types.h new file mode 100644 index 0000000000..716732f4d4 --- /dev/null +++ b/sys/types.h @@ -0,0 +1 @@ +#include <posix/sys/types.h> diff --git a/sys/uio.h b/sys/uio.h new file mode 100644 index 0000000000..03afd84b87 --- /dev/null +++ b/sys/uio.h @@ -0,0 +1 @@ +#include <misc/sys/uio.h> diff --git a/sys/un.h b/sys/un.h new file mode 100644 index 0000000000..bdbee99980 --- /dev/null +++ b/sys/un.h @@ -0,0 +1 @@ +#include <socket/sys/un.h> diff --git a/sys/unistd.h b/sys/unistd.h new file mode 100644 index 0000000000..8ca19e5516 --- /dev/null +++ b/sys/unistd.h @@ -0,0 +1 @@ +#include <posix/sys/unistd.h> diff --git a/sys/utsname.h b/sys/utsname.h new file mode 100644 index 0000000000..ff81bdf48e --- /dev/null +++ b/sys/utsname.h @@ -0,0 +1 @@ +#include <posix/sys/utsname.h> diff --git a/sys/vlimit.h b/sys/vlimit.h new file mode 100644 index 0000000000..8a76d2fd00 --- /dev/null +++ b/sys/vlimit.h @@ -0,0 +1 @@ +#include <resource/sys/vlimit.h> diff --git a/sys/vtimes.h b/sys/vtimes.h new file mode 100644 index 0000000000..dd666ca443 --- /dev/null +++ b/sys/vtimes.h @@ -0,0 +1 @@ +#include <resource/sys/vtimes.h> diff --git a/sys/wait.h b/sys/wait.h new file mode 100644 index 0000000000..379d5cc7a5 --- /dev/null +++ b/sys/wait.h @@ -0,0 +1 @@ +#include <posix/sys/wait.h> diff --git a/sysdeps/alpha/DEFS.h b/sysdeps/alpha/DEFS.h new file mode 100644 index 0000000000..c2a4fc88ae --- /dev/null +++ b/sysdeps/alpha/DEFS.h @@ -0,0 +1,27 @@ +#ifdef __STDC__ +#define FUNC__(name) \ + .align 3; \ + .globl __##name; \ + .ent __##name; \ + __##name: \ + lda sp, -16(sp); \ + .frame sp, 16, t9, 0; \ + .prologue 0 +#else +#define FUNC__(name) \ + .align 3; \ + .globl __/**/name; \ + .ent __/**/name,0; \ + __/**/name: \ + lda sp, -16(sp); \ + .frame sp, 16, t9, 0; \ + .prologue 0 +#endif + +#ifdef __STDC__ +#define NAME__(name) \ + __##name +#else +#define NAME__(name) \ + __/**/name +#endif diff --git a/sysdeps/alpha/Dist b/sysdeps/alpha/Dist new file mode 100644 index 0000000000..c4ea856629 --- /dev/null +++ b/sysdeps/alpha/Dist @@ -0,0 +1,4 @@ +setjmp_aux.c +DEFS.h +divrem.m4 macros.m4 +divl.S divlu.S divq.S divqu.S reml.S remlu.S remq.S remqu.S diff --git a/sysdeps/alpha/Implies b/sysdeps/alpha/Implies new file mode 100644 index 0000000000..93234096f0 --- /dev/null +++ b/sysdeps/alpha/Implies @@ -0,0 +1,2 @@ +# Alpha uses IEEE 754 floating point. +ieee754 diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile new file mode 100644 index 0000000000..06621b824d --- /dev/null +++ b/sysdeps/alpha/Makefile @@ -0,0 +1,94 @@ +# Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +# Contributed by Brendan Kehoe (brendan@zen.org). + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),setjmp) +sysdep_routines := $(sysdep_routines) setjmp_aux +endif + +ifeq ($(subdir),gnulib) +routines = $(divrem) +endif # gnulib + +# We distribute these files, even though they are generated, +# so as to avoid the need for a functioning m4 to build the library. +divrem := divl divlu divq divqu reml remlu remq remqu + ++divrem-NAME-divl := divl ++divrem-NAME-divlu := divlu ++divrem-NAME-divq := divq ++divrem-NAME-divqu := divqu ++divrem-NAME-reml := reml ++divrem-NAME-remlu := remlu ++divrem-NAME-remq := remq ++divrem-NAME-remqu := remqu ++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@))) + ++divrem-OP-divl := divl ++divrem-OP-divlu := divlu ++divrem-OP-divq := divq ++divrem-OP-divqu := divqu ++divrem-OP-reml := reml ++divrem-OP-remlu := remlu ++divrem-OP-remq := remq ++divrem-OP-remqu := remqu ++divrem-BASEOP-divl := div ++divrem-BASEOP-divlu := div ++divrem-BASEOP-divq := div ++divrem-BASEOP-divqu := div ++divrem-BASEOP-reml := rem ++divrem-BASEOP-remlu := rem ++divrem-BASEOP-remq := rem ++divrem-BASEOP-remqu := rem ++divrem-S-divl := true ++divrem-S-divlu := false ++divrem-S-divq := true ++divrem-S-divqu := false ++divrem-S-reml := true ++divrem-S-remlu := false ++divrem-S-remq := true ++divrem-S-remqu := false ++divrem-SIZE-divl := l ++divrem-SIZE-divlu := l ++divrem-SIZE-divq := q ++divrem-SIZE-divqu := q ++divrem-SIZE-reml := l ++divrem-SIZE-remlu := l ++divrem-SIZE-remq := q ++divrem-SIZE-remqu := q ++divrem-MODE-divl := l ++divrem-MODE-divlu := lu ++divrem-MODE-divq := q ++divrem-MODE-divqu := qu ++divrem-MODE-reml := l ++divrem-MODE-remlu := lu ++divrem-MODE-remq := q ++divrem-MODE-remqu := qu + +$(divrem:%=$(sysdep_dir)/alpha/%.S): $(sysdep_dir)/alpha/divrem.m4 $(sysdep_dir)/alpha/DEFS.h $(sysdep_dir)/alpha/macros.m4 + (echo "define(OP,\`$(+divrem-NAME)')\ + define(BASEOP,\`$(+divrem-BASEOP-$(+divrem-NAME))')\ + define(MODE,\`$(+divrem-MODE-$(+divrem-NAME))')\ + define(SIZE,\`$(+divrem-SIZE-$(+divrem-NAME))')\ + define(SIGNED,\`$(+divrem-S-$(+divrem-NAME))')\ + define(SYSDEP_DIR, \`$(sysdep_dir)/alpha')\ + /* This file is generated from divrem.m4; DO NOT EDIT! */"; \ + cat $<) | $(M4) > $@-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $@-tmp + mv -f $@-tmp $@ + test -d CVS && cvs commit -m'Regenerated from $<' $@ diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c new file mode 100644 index 0000000000..19a2e26696 --- /dev/null +++ b/sysdeps/alpha/__longjmp.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Global register vars must come before any function defn. */ + +register long int + r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"), + r13 asm ("$13"), r14 asm ("$14"); + +register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26"); + +#if 1 /* XXX */ +register double + f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"), + f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9"); +#endif + +#include <setjmp.h> + + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +__NORETURN +void +__longjmp (const __jmp_buf env, int val) +{ + /* Restore the integer registers. */ + r9 = env[0].__9; + r10 = env[0].__10; + r11 = env[0].__11; + r12 = env[0].__12; + r13 = env[0].__13; + r14 = env[0].__14; + +#if 1 /* XXX */ + /* Restore the floating point registers. */ + f2 = env[0].__f2; + f3 = env[0].__f3; + f4 = env[0].__f4; + f5 = env[0].__f5; + f6 = env[0].__f6; + f7 = env[0].__f7; + f8 = env[0].__f8; + f9 = env[0].__f9; +#endif + + /* Set the return PC to that of setjmp's caller. */ + retpc = env[0].__pc; + + /* Restore the FP and SP of setjmp's caller. */ + fp = env[0].__fp; + sp = env[0].__sp; + + /* Return VAL (or 1 if VAL is zero) to setjmp's caller. + + We use an asm here rather than a normal C return statement + just in case the compiler wanted to do some stack frobnication + in the function epilogue. Since we have already restored + precisely the FP and SP the desired environment needs, + we must avoid the compiler doing anything with the stack. */ + + while (1) + { + /* The loop is just to avoid `volatile function does return' warnings. + The instruction will only be executed once. */ + + register long int retval asm ("$0"); + + asm volatile + ("cmoveq %1, 1, %0\n\t" /* $0 = val ?: 1; */ + "ret $31, (%2), 1" /* return $0 */ + : "=r" (retval) + /* The "0" constraint should force VAL into $0. */ + : "0" (val), "r" (retpc)); + } +} diff --git a/sysdeps/alpha/__math.h b/sysdeps/alpha/__math.h new file mode 100644 index 0000000000..b06f716c50 --- /dev/null +++ b/sysdeps/alpha/__math.h @@ -0,0 +1,35 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#if defined (__GNUC__) && !defined (__NO_MATH_INLINES) + +extern __inline __CONSTVALUE double +__copysign (double __x, double __y) +{ + __asm ("cpys %1, %2, %0" : "=f" (__x) : "f" (__y), "f" (__x)); + return __x; +} + +extern __inline double +fabs (double __x) +{ + __asm ("cpys $f31, %1, %0" : "=f" (__x) : "f" (__x)); + return __x; +} + +#endif diff --git a/sysdeps/alpha/bsd-_setjmp.S b/sysdeps/alpha/bsd-_setjmp.S new file mode 100644 index 0000000000..9947d8f45a --- /dev/null +++ b/sysdeps/alpha/bsd-_setjmp.S @@ -0,0 +1,30 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + lda $27, __sigsetjmp /* Load address to jump to. */ + bis $31, $31, $17 /* Pass a second argument of zero. */ + jmp $31, ($27), __sigsetjmp /* Call __sigsetjmp. */ + .end setjmp diff --git a/sysdeps/alpha/bsd-setjmp.S b/sysdeps/alpha/bsd-setjmp.S new file mode 100644 index 0000000000..470f7bc47d --- /dev/null +++ b/sysdeps/alpha/bsd-setjmp.S @@ -0,0 +1,30 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + lda $27, __sigsetjmp /* Load address to jump to. */ + bis $31, 1, $17 /* Pass a second argument of one. */ + jmp $31, ($27), __sigsetjmp /* Call __sigsetjmp. */ + .end setjmp diff --git a/sysdeps/alpha/bytesex.h b/sysdeps/alpha/bytesex.h new file mode 100644 index 0000000000..e873d2123c --- /dev/null +++ b/sysdeps/alpha/bytesex.h @@ -0,0 +1,3 @@ +/* Alpha is little-endian. */ + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/sysdeps/alpha/copysign.c b/sysdeps/alpha/copysign.c new file mode 100644 index 0000000000..69544b01fb --- /dev/null +++ b/sysdeps/alpha/copysign.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define __NO_MATH_INLINES + +#include <math.h> + +/* Return X with its sign changed to Y's. */ +__inline double +__copysign (double __x, double __y) +{ + __asm ("cpys %1, %2, %0" : "=f" (__x) : "f" (__y), "f" (__x)); + return __x; +} + +weak_alias (__copysign, copysign) diff --git a/sysdeps/alpha/divl.S b/sysdeps/alpha/divl.S new file mode 100644 index 0000000000..7ae3e0cc13 --- /dev/null +++ b/sysdeps/alpha/divl.S @@ -0,0 +1,54 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(divl) + /* First set up the dividend. */ + sextl t10, t10 + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + sextl t11, t11 + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + sextl t12, t12 + + + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(divl) diff --git a/sysdeps/alpha/divlu.S b/sysdeps/alpha/divlu.S new file mode 100644 index 0000000000..9ae5950c53 --- /dev/null +++ b/sysdeps/alpha/divlu.S @@ -0,0 +1,54 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(divlu) + /* First set up the dividend. */ + zapnot t10, 0xf, t10 + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + zapnot t11, 0xf, t11 + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + sextl t12, t12 + + + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(divlu) diff --git a/sysdeps/alpha/divq.S b/sysdeps/alpha/divq.S new file mode 100644 index 0000000000..79ff6ca7c5 --- /dev/null +++ b/sysdeps/alpha/divq.S @@ -0,0 +1,51 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(divq) + /* First set up the dividend. */ + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + + + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(divq) diff --git a/sysdeps/alpha/divqu.S b/sysdeps/alpha/divqu.S new file mode 100644 index 0000000000..7908b9f77d --- /dev/null +++ b/sysdeps/alpha/divqu.S @@ -0,0 +1,57 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(divqu) + /* First set up the dividend. */ + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + ldit $f26, 18446744073709551616.0 + addt $f26, $f10, $f26 + fcmovlt $f10, $f26, $f10 + + + /* Then set up the divisor. */ + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + ldit $f26, 18446744073709551616.0 + addt $f26, $f1, $f26 + fcmovlt $f1, $f26, $f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + + + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(divqu) diff --git a/sysdeps/alpha/divrem.m4 b/sysdeps/alpha/divrem.m4 new file mode 100644 index 0000000000..5942cf447f --- /dev/null +++ b/sysdeps/alpha/divrem.m4 @@ -0,0 +1,48 @@ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + +define(path, `SYSDEP_DIR/macros.m4')dnl +include(path) + +FUNC__(OP) + /* First set up the dividend. */ + EXTEND(t10) + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + ADJQU($f10) + + /* Then set up the divisor. */ + EXTEND(t11) + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + ADJQU($f1) + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + FULLEXTEND(t12) + + DOREM + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(OP) diff --git a/sysdeps/alpha/fabs.c b/sysdeps/alpha/fabs.c new file mode 100644 index 0000000000..321df0d1e1 --- /dev/null +++ b/sysdeps/alpha/fabs.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define __NO_MATH_INLINES + +#include <math.h> + +__inline double +fabs (double __x) +{ + __asm ("cpys $f31, %1, %0" : "=f" (__x) : "f" (__x)); + return __x; +} diff --git a/sysdeps/alpha/gmp-mparam.h b/sysdeps/alpha/gmp-mparam.h new file mode 100644 index 0000000000..05c893f790 --- /dev/null +++ b/sysdeps/alpha/gmp-mparam.h @@ -0,0 +1,26 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define BITS_PER_MP_LIMB 64 +#define BYTES_PER_MP_LIMB 8 +#define BITS_PER_LONGINT 64 +#define BITS_PER_INT 32 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 diff --git a/sysdeps/alpha/jmp_buf.h b/sysdeps/alpha/jmp_buf.h new file mode 100644 index 0000000000..6e6f6b4727 --- /dev/null +++ b/sysdeps/alpha/jmp_buf.h @@ -0,0 +1,46 @@ +/* Define the machine-dependent type `jmp_buf'. Alpha version. +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +typedef struct + { + /* Integer registers: + $0 is the return value; + $1-$8, $22-$25, $28 are call-used; + $9-$14 we save here; + $15 is the FP and we save it here; + $16-$21 are input arguments (call-used); + $26 is the return PC and we save it here; + $27 is the procedure value (i.e., the address of __setjmp); + $29 is the global pointer, which the caller will reconstruct + from the return address restored in $26; + $30 is the stack pointer and we save it here; + $31 is always zero. */ + long int __9, __10, __11, __12, __13, __14; + long int *__pc, *__fp, *__sp; + +#if 1 /* XXX need predefine for TARGET_FPREGS */ + /* Floating-point registers: + $f0 is the floating return value; + $f1, $f10-$f15, $f22-$f30 are call-used; + $f2-$f9 we save here; + $f16-$21 are input args (call-used); + $f31 is always zero. */ + double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9; +#endif /* Have FP regs. */ + } __jmp_buf[1]; diff --git a/sysdeps/alpha/macros.m4 b/sysdeps/alpha/macros.m4 new file mode 100644 index 0000000000..f8c1fe9662 --- /dev/null +++ b/sysdeps/alpha/macros.m4 @@ -0,0 +1,34 @@ +dnl NOTE: The $1 below is the argument to EXTEND, not register $1. +define(EXTEND, +`ifelse(SIZE, `l', +`ifelse(SIGNED, `true', +` sextl $1, $1 +',dnl +` zapnot $1, 0xf, $1 +')')')dnl + +dnl FULLEXTEND -- extend the register named in the first argument +define(FULLEXTEND, +`ifelse(SIZE, `l', +` sextl $1, $1 +')')dnl + +dnl This is used by divqu. +define(ADJQU, +`ifelse(MODE, `qu', +` ldit $f26, 18446744073709551616.0 + addt $f26, $1, $f26 + fcmovlt $1, $f26, $1 +')')dnl + +define(DOREM, +`ifelse(BASEOP, `rem', +` /* Compute the remainder. */ +ifelse(SIZE, `l', +` mull t11, t12, t11 + subl t10, t11, t12 +',dnl Note mulq/subq were only really used in remq, but we will find out +dnl if assuming they apply to remqu as well is wrong or not. +` mulq t11, t12, t11 + subq t10, t11, t12 +')')')dnl diff --git a/sysdeps/alpha/memchr.c b/sysdeps/alpha/memchr.c new file mode 100644 index 0000000000..11ff542f25 --- /dev/null +++ b/sysdeps/alpha/memchr.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Search no more than N bytes of S for C. */ + +void * +memchr (const void *s, int c, size_t n) +{ + const char *char_ptr; + const unsigned long int *longword_ptr; + unsigned long int charmask; + size_t x; + + c = (unsigned char) c; + + /* Handle the first few characters by reading one character at a time. + Do this until STR is aligned on a 8-byte border. */ + for (char_ptr = s; n > 0 && ((unsigned long int) char_ptr & 7) != 0; + --n, ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + if (n == (size_t)0) + return NULL; + + x = n; + + longword_ptr = (unsigned long int *) char_ptr; + + /* Set up a longword, each of whose bytes is C. */ + charmask = c | (c << 8); + charmask |= charmask << 16; + charmask |= charmask << 32; + + for (;;) + { + const unsigned long int longword = *longword_ptr++; + int ge, le; + + if (x < 4) + x = (size_t) 0; + else + x -= 4; + + /* Set bits in GE if bytes in CHARMASK are >= bytes in LONGWORD. */ + asm ("cmpbge %1, %2, %0" : "=r" (ge) : "r" (charmask), "r" (longword)); + + /* Set bits in LE if bytes in CHARMASK are <= bytes in LONGWORD. */ + asm ("cmpbge %2, %1, %0" : "=r" (le) : "r" (charmask), "r" (longword)); + + /* Bytes that are both <= and >= are == to C. */ + if (ge & le) + { + /* Which of the bytes was the C? */ + + unsigned char *cp = (unsigned char *) (longword_ptr - 1); + int i; + + for (i = 0; i < 6; i++) + if (cp[i] == c) + return &cp[i]; + return &cp[7]; + } + + if (x == (size_t)0) + break; + } + + return NULL; +} diff --git a/sysdeps/alpha/reml.S b/sysdeps/alpha/reml.S new file mode 100644 index 0000000000..2ece297f09 --- /dev/null +++ b/sysdeps/alpha/reml.S @@ -0,0 +1,57 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(reml) + /* First set up the dividend. */ + sextl t10, t10 + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + sextl t11, t11 + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + sextl t12, t12 + + + /* Compute the remainder. */ + mull t11, t12, t11 + subl t10, t11, t12 + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(reml) diff --git a/sysdeps/alpha/remlu.S b/sysdeps/alpha/remlu.S new file mode 100644 index 0000000000..d7700e6595 --- /dev/null +++ b/sysdeps/alpha/remlu.S @@ -0,0 +1,57 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(remlu) + /* First set up the dividend. */ + zapnot t10, 0xf, t10 + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + zapnot t11, 0xf, t11 + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + sextl t12, t12 + + + /* Compute the remainder. */ + mull t11, t12, t11 + subl t10, t11, t12 + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(remlu) diff --git a/sysdeps/alpha/remq.S b/sysdeps/alpha/remq.S new file mode 100644 index 0000000000..47510cbc8e --- /dev/null +++ b/sysdeps/alpha/remq.S @@ -0,0 +1,54 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(remq) + /* First set up the dividend. */ + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + + + /* Then set up the divisor. */ + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + + + /* Compute the remainder. */ + mulq t11, t12, t11 + subq t10, t11, t12 + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(remq) diff --git a/sysdeps/alpha/remqu.S b/sysdeps/alpha/remqu.S new file mode 100644 index 0000000000..ec9572dd62 --- /dev/null +++ b/sysdeps/alpha/remqu.S @@ -0,0 +1,60 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* For each N divided by D, we do: + result = (double) N / (double) D + Then, for each N mod D, we do: + result = N - (D * divMODE (N, D)) + + FIXME: + The q and qu versions won't deal with operands > 50 bits. We also + don't check for divide by zero. */ + +#include "DEFS.h" +#if 0 +/* We do not handle div by zero yet. */ +#include <machine/pal.h> +#endif +#include <sysdep.h> + + + + + + +FUNC__(remqu) + /* First set up the dividend. */ + + stq t10,0(sp) + ldt $f10,0(sp) + cvtqt $f10,$f10 + ldit $f26, 18446744073709551616.0 + addt $f26, $f10, $f26 + fcmovlt $f10, $f26, $f10 + + + /* Then set up the divisor. */ + + stq t11,0(sp) + ldt $f1,0(sp) + cvtqt $f1,$f1 + ldit $f26, 18446744073709551616.0 + addt $f26, $f1, $f26 + fcmovlt $f1, $f26, $f1 + + + /* Do the division. */ + divt $f10,$f1,$f10 + cvttqc $f10,$f10 + + /* Put the result in t12. */ + stt $f10,0(sp) + ldq t12,0(sp) + + + /* Compute the remainder. */ + mulq t11, t12, t11 + subq t10, t11, t12 + + + lda sp,16(sp) + ret zero,(t9),1 + .end NAME__(remqu) diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S new file mode 100644 index 0000000000..08932ccd1a --- /dev/null +++ b/sysdeps/alpha/setjmp.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* The function __sigsetjmp_aux saves all the registers, but it can't + reliably access the stack or frame pointers, so we pass them in as + extra arguments. */ +ENTRY (__sigsetjmp) + lda $27, __sigsetjmp_aux/* Load address to jump to. */ + bis $15, $15, $18 /* Pass FP as 3rd arg. */ + bis $30, $30, $19 /* Pass SP as 4th arg. */ + jmp $31, ($27), __sigsetjmp_aux /* Call __sigsetjmp_aux. */ + .end __sigsetjmp diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c new file mode 100644 index 0000000000..f92517be92 --- /dev/null +++ b/sysdeps/alpha/setjmp_aux.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Global register decls must come before any function defn. */ + +register long int + r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"), + r13 asm ("$13"), r14 asm ("$14"); + +register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26"); + +#if 1 /* XXX */ +register double + f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"), + f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9"); +#endif + + +#include <setjmp.h> + + +/* Save the current program position in ENV and return 0. */ +int +__sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp) +{ + /* Save the integer registers. */ + env[0].__jmpbuf[0].__9 = r9; + env[0].__jmpbuf[0].__10 = r10; + env[0].__jmpbuf[0].__11 = r11; + env[0].__jmpbuf[0].__12 = r12; + env[0].__jmpbuf[0].__13 = r13; + env[0].__jmpbuf[0].__14 = r14; + +#if 1 /* XXX */ + /* Save the floating point registers. */ + env[0].__jmpbuf[0].__f2 = f2; + env[0].__jmpbuf[0].__f3 = f3; + env[0].__jmpbuf[0].__f4 = f4; + env[0].__jmpbuf[0].__f5 = f5; + env[0].__jmpbuf[0].__f6 = f6; + env[0].__jmpbuf[0].__f7 = f7; + env[0].__jmpbuf[0].__f8 = f8; + env[0].__jmpbuf[0].__f9 = f9; +#endif + + /* Save the return address of our caller, where longjmp will jump to. */ + env[0].__jmpbuf[0].__pc = retpc; + + /* Save the FP and SP of our caller. The __sigsetjmp entry point + simply puts these in the argument registers for us to fetch. */ + env[0].__jmpbuf[0].__fp = fp; + env[0].__jmpbuf[0].__sp = sp; + + /* Save the signal mask if requested. */ + __sigjmp_save (env, savemask); + + /* Return to the original caller of __sigsetjmp. */ + return 0; +} diff --git a/sysdeps/alpha/strchr.c b/sysdeps/alpha/strchr.c new file mode 100644 index 0000000000..69afa4b87f --- /dev/null +++ b/sysdeps/alpha/strchr.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Return the length of the null-terminated string STR. Scan for + the null terminator quickly by testing eight bytes at a time. */ + +char * +strchr (const char *str, int c) +{ + const char *char_ptr; + const unsigned long int *longword_ptr; + unsigned long int charmask; + + c = (unsigned char) c; + + /* Handle the first few characters by reading one character at a time. + Do this until STR is aligned on a 8-byte border. */ + for (char_ptr = str; ((unsigned long int) char_ptr & 7) != 0; ++char_ptr) + if (*char_ptr == c) + return (char *) char_ptr; + else if (*char_ptr == '\0') + return NULL; + + longword_ptr = (unsigned long int *) char_ptr; + + /* Set up a longword, each of whose bytes is C. */ + charmask = c | (c << 8); + charmask |= charmask << 16; + charmask |= charmask << 32; + + for (;;) + { + const unsigned long int longword = *longword_ptr++; + int ge, le, zero; + + /* Set bits in ZERO if bytes in LONGWORD are zero. */ + asm ("cmpbge $31, %1, %0" : "=r" (zero) : "r" (longword)); + + /* Set bits in GE if bytes in CHARMASK are >= bytes in LONGWORD. */ + asm ("cmpbge %1, %2, %0" : "=r" (ge) : "r" (charmask), "r" (longword)); + + /* Set bits in LE if bytes in CHARMASK are <= bytes in LONGWORD. */ + asm ("cmpbge %2, %1, %0" : "=r" (le) : "r" (charmask), "r" (longword)); + + /* Bytes that are both <= and >= are == to C. */ + if (zero || (ge & le)) + { + /* Which of the bytes was the C? */ + + char *cp = (char *) (longword_ptr - 1); + int i; + + for (i = 0; i < 8; i++) + { + if (cp[i] == c) + return &cp[i]; + if (cp[i] == 0) + return NULL; + } + return NULL; + } + } +} + +#ifdef weak_alias +#undef index +weak_alias (strchr, index) +#endif diff --git a/sysdeps/alpha/strlen.c b/sysdeps/alpha/strlen.c new file mode 100644 index 0000000000..d7744476ad --- /dev/null +++ b/sysdeps/alpha/strlen.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Return the length of the null-terminated string STR. Scan for + the null terminator quickly by testing eight bytes at a time. */ + +size_t +strlen (const char *str) +{ + const char *char_ptr; + const unsigned long int *longword_ptr; + + /* Handle the first few characters by reading one character at a time. + Do this until STR is aligned on a 8-byte border. */ + for (char_ptr = str; ((unsigned long int) char_ptr & 7) != 0; ++char_ptr) + if (*char_ptr == '\0') + return char_ptr - str; + + longword_ptr = (unsigned long int *) char_ptr; + + for (;;) + { + int mask; + asm ("cmpbge %1, %2, %0" : "=r" (mask) : "r" (0), "r" (*longword_ptr++)); + if (mask) + { + /* Which of the bytes was the zero? */ + + const char *cp = (const char *) (longword_ptr - 1); + int i; + + for (i = 0; i < 6; i++) + if (cp[i] == 0) + return cp - str + i; + return cp - str + 7; + } + } +} diff --git a/sysdeps/alpha/udiv_qrnnd.S b/sysdeps/alpha/udiv_qrnnd.S new file mode 100644 index 0000000000..942d7a884b --- /dev/null +++ b/sysdeps/alpha/udiv_qrnnd.S @@ -0,0 +1,152 @@ + # Alpha 21064 __udiv_qrnnd + + # Copyright (C) 1992, 1994 Free Software Foundation, Inc. + + # This file is part of the GNU MP Library. + + # The GNU MP Library is free software; you can redistribute it and/or modify + # it under the terms of the GNU Library General Public License as published by + # the Free Software Foundation; either version 2 of the License, or (at your + # option) any later version. + + # The GNU MP Library is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + # License for more details. + + # You should have received a copy of the GNU Library General Public License + # along with the GNU MP Library; see the file COPYING.LIB. If not, write to + # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + .set noreorder + .set noat + +.text + .align 3 + .globl __udiv_qrnnd + .ent __udiv_qrnnd 0 +__udiv_qrnnd: +__udiv_qrnnd..ng: + .frame $30,0,$26,0 + .prologue 0 +#define cnt $2 +#define tmp $3 +#define rem_ptr $16 +#define n1 $17 +#define n0 $18 +#define d $19 +#define qb $20 + + ldiq cnt,16 + blt d,Largedivisor + +Loop1: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,Loop1 + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +Largedivisor: + and n0,1,$4 + + srl n0,1,n0 + sll n1,63,tmp + or tmp,n0,n0 + srl n1,1,n1 + + and d,1,$6 + srl d,1,$5 + addq $5,$6,$5 + +Loop2: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,Loop2 + + addq n1,n1,n1 + addq $4,n1,n1 + bne $6,Odd + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +Odd: + /* q' in n0. r' in n1. */ + addq n1,n0,n1 + cmpult n1,n0,tmp # tmp := carry from addq + beq tmp,LLp6 + addq n0,1,n0 + subq n1,d,n1 +LLp6: cmpult n1,d,tmp + bne tmp,LLp7 + addq n0,1,n0 + subq n1,d,n1 +LLp7: + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + + .end __udiv_qrnnd diff --git a/sysdeps/am29k/ffs.c b/sysdeps/am29k/ffs.c new file mode 100644 index 0000000000..0f38f8795c --- /dev/null +++ b/sysdeps/am29k/ffs.c @@ -0,0 +1,40 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For Amd 290x0. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <bstring.h> + +#undef ffs + +#ifdef __GNUC__ + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + + asm ("clz %0,%1" : "=r" (cnt) : "r" (x & -x)); + + return 32 - cnt; +} + +#else +#include <sysdeps/generic/ffs.c> +#endif diff --git a/sysdeps/generic/Dist b/sysdeps/generic/Dist new file mode 100644 index 0000000000..2431f7b272 --- /dev/null +++ b/sysdeps/generic/Dist @@ -0,0 +1,8 @@ +make_siglist.c signame.c signame.h +det_endian.c +mathimpl.h +trig.h +sincos.c +asincos.c +exp__E.c +log__L.c diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile new file mode 100644 index 0000000000..b80b073d0c --- /dev/null +++ b/sysdeps/generic/Makefile @@ -0,0 +1,60 @@ +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),math) +ifndef math-twiddled + +elided-routines := $(elided-routines) acos asin cos sin hypot +sysdep_routines := $(sysdep_routines) sincos asincos exp__E log__L + +math-twiddled := t +endif + +endif + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/bytesex.h)))))) + +$(common-objpfx)bytesex.h: $(common-objpfx)det_endian + $(dir $<)$(notdir $<) > $@-tmp + mv $@-tmp $@ + +$(common-objpfx)det_endian: $(sysdep_dir)/generic/det_endian.c + $(native-compile) + +before-compile := $(before-compile) $(common-objpfx)bytesex.h +common-generated := $(common-generated) bytesex.h det_endian + +endif + +ifeq ($(subdir),stdio) + +ifeq "$(filter $(objpfx)siglist.c,$(before-compile))" "" +before-compile := $(before-compile) $(objpfx)siglist.c +$(objpfx)siglist.c: $(objpfx)make_siglist + @rm -f $@ + $(dir $<)$(notdir $<) > $@-tmp + mv $@-tmp $@ + +$(objpfx)make_siglist: $(sysdep_dir)/generic/make_siglist.c + $(native-compile) + +generated := $(generated) make_siglist siglist.c +endif + +endif diff --git a/sysdeps/generic/_strerror.c b/sysdeps/generic/_strerror.c new file mode 100644 index 0000000000..455c8ff0a7 --- /dev/null +++ b/sysdeps/generic/_strerror.c @@ -0,0 +1,43 @@ +/* Copyright (C) 19911993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + +#ifndef HAVE_GNU_LD +#define _sys_errlist sys_errlist +#define _sys_nerr sys_nerr +#endif + +/* Return a string describing the errno code in ERRNUM. */ +char * +DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024]) +{ + if (errnum < 0 || errnum > _sys_nerr) + { + static char fmt[] = "Unknown error %d"; + size_t len = sprintf (buf, fmt, errnum); + if (len < sizeof(fmt) - 2) + return NULL; + buf[len - 1] = '\0'; + return buf; + } + + return (char *) _sys_errlist[errnum]; +} diff --git a/sysdeps/generic/abort.c b/sysdeps/generic/abort.c new file mode 100644 index 0000000000..1a27c4946b --- /dev/null +++ b/sysdeps/generic/abort.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> + +/* Cause an abnormal program termination with core-dump. */ +void +DEFUN_VOID(abort) +{ + sigset_t sigs; + + if (__sigemptyset(&sigs) == 0 && + __sigaddset(&sigs, SIGABRT) == 0) + (void) __sigprocmask(SIG_UNBLOCK, &sigs, (sigset_t *) NULL); + + while (1) + if (raise (SIGABRT)) + /* If we can't signal ourselves, exit. */ + _exit (127); + /* If we signal ourselves and are still alive, + or can't exit, loop forever. */ +} diff --git a/sysdeps/generic/acos.c b/sysdeps/generic/acos.c new file mode 100644 index 0000000000..c77c9faf1f --- /dev/null +++ b/sysdeps/generic/acos.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the inverse cosine of X. */ +double +DEFUN(acos, (x), double x) +{ + double t; + + if (__isnan(x)) + { + errno = EDOM; + return x; + } + + if (x == -1.0) + /* If X is -1, the general formula blows up (zero divided by zero loses), + but we know that acos(-1) = pi. */ + t = atan2(1.0, 0.0); + else + t = atan2(sqrt((1.0 - x) / (1.0 + x)), 1.0); + return t + t; +} diff --git a/sysdeps/generic/acosh.c b/sysdeps/generic/acosh.c new file mode 100644 index 0000000000..bc16cc7b46 --- /dev/null +++ b/sysdeps/generic/acosh.c @@ -0,0 +1,102 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)acosh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ACOSH(X) + * RETURN THE INVERSE HYPERBOLIC COSINE OF X + * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 2/16/85; + * REVISED BY K.C. NG on 3/6/85, 3/24/85, 4/16/85, 8/17/85. + * + * Required system supported functions : + * sqrt(x) + * + * Required kernel function: + * log1p(x) ...return log(1+x) + * + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log1p(x)+ln2, if (x > 1.0E20); else + * acosh(x) := log1p( sqrt(x-1) * (sqrt(x-1) + sqrt(x+1)) ) . + * These formulae avoid the over/underflow complication. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + * + * Accuracy: + * acosh(x) returns the exact inverse hyperbolic cosine of x nearly + * rounded. In a test run with 512,000 random arguments on a VAX, the + * maximum observed error was 3.30 ulps (units of the last place) at + * x=1.0070493753568216 . + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) + +ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76) + +#ifdef vccast +#define ln2hi vccast(ln2hi) +#define ln2lo vccast(ln2lo) +#endif + +double acosh(x) +double x; +{ + double t,big=1.E20; /* big+1==big */ + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + + /* return log1p(x) + log(2) if x is large */ + if(x>big) {t=log1p(x)+ln2lo; return(t+ln2hi);} + + t=sqrt(x-1.0); + return(log1p(t*(t+sqrt(x+1.0)))); +} diff --git a/sysdeps/generic/add_1.c b/sysdeps/generic/add_1.c new file mode 100644 index 0000000000..7b1c697a67 --- /dev/null +++ b/sysdeps/generic/add_1.c @@ -0,0 +1,61 @@ +/* mpn_add_1 -- + +Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define __mpn_add_1 __noname +#include "gmp.h" +#undef __mpn_add_1 + +#include "gmp-impl.h" + +mp_limb +__mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb s2_limb; +{ + register mp_limb x; + + x = *s1_ptr++; + s2_limb = x + s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb < x) + { + while (--s1_size != 0) + { + x = *s1_ptr++ + 1; + *res_ptr++ = x; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + + return 0; +} diff --git a/sysdeps/generic/add_n.c b/sysdeps/generic/add_n.c new file mode 100644 index 0000000000..6989ab0628 --- /dev/null +++ b/sysdeps/generic/add_n.c @@ -0,0 +1,61 @@ +/* __mpn_add_n -- Add two limb vectors of equal, non-zero length. + +Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +mp_limb +#if __STDC__ +__mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size) +#else +__mpn_add_n (res_ptr, s1_ptr, s2_ptr, size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_srcptr s2_ptr; + mp_size_t size; +#endif +{ + register mp_limb x, y, cy; + register mp_size_t j; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -size; + + /* Offset the base pointers to compensate for the negative indices. */ + s1_ptr -= j; + s2_ptr -= j; + res_ptr -= j; + + cy = 0; + do + { + y = s2_ptr[j]; + x = s1_ptr[j]; + y += cy; /* add previous carry to one addend */ + cy = (y < cy); /* get out carry from that addition */ + y = x + y; /* add other addend */ + cy = (y < x) + cy; /* get out carry from that add, combine */ + res_ptr[j] = y; + } + while (++j != 0); + + return cy; +} diff --git a/sysdeps/generic/addmul_1.c b/sysdeps/generic/addmul_1.c new file mode 100644 index 0000000000..fdf3541561 --- /dev/null +++ b/sysdeps/generic/addmul_1.c @@ -0,0 +1,64 @@ +/* __mpn_addmul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR + by S2_LIMB, add the S1_SIZE least significant limbs of the product to the + limb vector pointed to by RES_PTR. Return the most significant limb of + the product, adjusted for carry-out from the addition. + +Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +mp_limb +__mpn_addmul_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + mp_size_t s1_size; + register mp_limb s2_limb; +{ + register mp_limb cy_limb; + register mp_size_t j; + register mp_limb prod_high, prod_low; + register mp_limb x; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -s1_size; + + /* Offset the base pointers to compensate for the negative indices. */ + res_ptr -= j; + s1_ptr -= j; + + cy_limb = 0; + do + { + umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); + + prod_low += cy_limb; + cy_limb = (prod_low < cy_limb) + prod_high; + + x = res_ptr[j]; + prod_low = x + prod_low; + cy_limb += (prod_low < x); + res_ptr[j] = prod_low; + } + while (++j != 0); + + return cy_limb; +} diff --git a/sysdeps/generic/asin.c b/sysdeps/generic/asin.c new file mode 100644 index 0000000000..e75ee3d87e --- /dev/null +++ b/sysdeps/generic/asin.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the inverse sine of X. */ +double +DEFUN(asin, (x), double x) +{ + double abs_x; + + if (__isnan(x)) + { + errno = EDOM; + return x; + } + + abs_x = fabs(x); + + if (abs_x <= 0.5) + return atan2(x, sqrt(1.0 - (x * x))); + else + { + double t = 1.0 - abs_x; + return atan2(x, sqrt((t + t) - (t * t))); + } +} diff --git a/sysdeps/generic/asincos.c b/sysdeps/generic/asincos.c new file mode 100644 index 0000000000..c746b1652a --- /dev/null +++ b/sysdeps/generic/asincos.c @@ -0,0 +1,169 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)asincos.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ASIN(X) + * RETURNS ARC SINE OF X + * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) + * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. + * + * Required system supported functions: + * copysign(x,y) + * sqrt(x) + * + * Required kernel function: + * atan2(y,x) + * + * Method : + * asin(x) = atan2(x,sqrt(1-x*x)); for better accuracy, 1-x*x is + * computed as follows + * 1-x*x if x < 0.5, + * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5. + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN. + * + * Accuracy: + * 1) If atan2() uses machine PI, then + * + * asin(x) returns (PI/pi) * (the exact arc sine of x) nearly rounded; + * and PI is the exact pi rounded to machine precision (see atan2 for + * details): + * + * in decimal: + * pi = 3.141592653589793 23846264338327 ..... + * 53 bits PI = 3.141592653589793 115997963 ..... , + * 56 bits PI = 3.141592653589793 227020265 ..... , + * + * in hexadecimal: + * pi = 3.243F6A8885A308D313198A2E.... + * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps + * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps + * + * In a test run with more than 200,000 random arguments on a VAX, the + * maximum observed error in ulps (units in the last place) was + * 2.06 ulps. (comparing against (PI/pi)*(exact asin(x))); + * + * 2) If atan2() uses true pi, then + * + * asin(x) returns the exact asin(x) with error below about 2 ulps. + * + * In a test run with more than 1,024,000 random arguments on a VAX, the + * maximum observed error in ulps (units in the last place) was + * 1.99 ulps. + */ + +double asin(x) +double x; +{ + double s,t,copysign(),atan2(),sqrt(),one=1.0; +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + s=copysign(x,one); + if(s <= 0.5) + return(atan2(x,sqrt(one-x*x))); + else + { t=one-s; s=t+t; return(atan2(x,sqrt(s-t*t))); } + +} + +/* ACOS(X) + * RETURNS ARC COS OF X + * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) + * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. + * + * Required system supported functions: + * copysign(x,y) + * sqrt(x) + * + * Required kernel function: + * atan2(y,x) + * + * Method : + * ________ + * / 1 - x + * acos(x) = 2*atan2( / -------- , 1 ) . + * \/ 1 + x + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN. + * + * Accuracy: + * 1) If atan2() uses machine PI, then + * + * acos(x) returns (PI/pi) * (the exact arc cosine of x) nearly rounded; + * and PI is the exact pi rounded to machine precision (see atan2 for + * details): + * + * in decimal: + * pi = 3.141592653589793 23846264338327 ..... + * 53 bits PI = 3.141592653589793 115997963 ..... , + * 56 bits PI = 3.141592653589793 227020265 ..... , + * + * in hexadecimal: + * pi = 3.243F6A8885A308D313198A2E.... + * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps + * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps + * + * In a test run with more than 200,000 random arguments on a VAX, the + * maximum observed error in ulps (units in the last place) was + * 2.07 ulps. (comparing against (PI/pi)*(exact acos(x))); + * + * 2) If atan2() uses true pi, then + * + * acos(x) returns the exact acos(x) with error below about 2 ulps. + * + * In a test run with more than 1,024,000 random arguments on a VAX, the + * maximum observed error in ulps (units in the last place) was + * 2.15 ulps. + */ + +double acos(x) +double x; +{ + double t,copysign(),atan2(),sqrt(),one=1.0; +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); +#endif /* !defined(vax)&&!defined(tahoe) */ + if( x != -1.0) + t=atan2(sqrt((one-x)/(one+x)),one); + else + t=atan2(one,0.0); /* t = PI/2 */ + return(t+t); +} diff --git a/sysdeps/generic/asinh.c b/sysdeps/generic/asinh.c new file mode 100644 index 0000000000..5db8d2ddf7 --- /dev/null +++ b/sysdeps/generic/asinh.c @@ -0,0 +1,101 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)asinh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ASINH(X) + * RETURN THE INVERSE HYPERBOLIC SINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 2/16/85; + * REVISED BY K.C. NG on 3/7/85, 3/24/85, 4/16/85. + * + * Required system supported functions : + * copysign(x,y) + * sqrt(x) + * + * Required kernel function: + * log1p(x) ...return log(1+x) + * + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log1p(x)+ln2)) if sqrt(1+x*x)=x, else + * := sign(x)*log1p(|x| + |x|/(1/|x| + sqrt(1+(1/|x|)^2)) ) + * + * Accuracy: + * asinh(x) returns the exact inverse hyperbolic sine of x nearly rounded. + * In a test run with 52,000 random arguments on a VAX, the maximum + * observed error was 1.58 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) + +ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76) + +#ifdef vccast +#define ln2hi vccast(ln2hi) +#define ln2lo vccast(ln2lo) +#endif + +double asinh(x) +double x; +{ + double t,s; + const static double small=1.0E-10, /* fl(1+small*small) == 1 */ + big =1.0E20, /* fl(1+big) == big */ + one =1.0 ; + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + if((t=copysign(x,one))>small) + if(t<big) { + s=one/t; return(copysign(log1p(t+t/(s+sqrt(one+s*s))),x)); } + else /* if |x| > big */ + {s=log1p(t)+ln2lo; return(copysign(s+ln2hi,x));} + else /* if |x| < small */ + return(x); +} diff --git a/sysdeps/generic/atan.c b/sysdeps/generic/atan.c new file mode 100644 index 0000000000..f2cc693924 --- /dev/null +++ b/sysdeps/generic/atan.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return the inverse tangent of X. */ +double +DEFUN(atan, (x), register double x) +{ + return atan2(x, 1.0); +} diff --git a/sysdeps/generic/atan2.c b/sysdeps/generic/atan2.c new file mode 100644 index 0000000000..958a154726 --- /dev/null +++ b/sysdeps/generic/atan2.c @@ -0,0 +1,281 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)atan2.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ATAN2(Y,X) + * RETURN ARG (X+iY) + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 2/7/85, 2/13/85, 3/7/85, 3/30/85, 6/29/85. + * + * Required system supported functions : + * copysign(x,y) + * scalb(x,y) + * logb(x) + * + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * 3. According to the integer k=4t+0.25 truncated , t=y/x, the argument + * is further reduced to one of the following intervals and the + * arctangent of y/x is evaluated by the corresponding formula: + * + * [0,7/16] atan(y/x) = t - t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(y/x) = atan(1/2) + atan( (y-x/2)/(x+y/2) ) + * [11/16.19/16] atan(y/x) = atan( 1 ) + atan( (y-x)/(x+y) ) + * [19/16,39/16] atan(y/x) = atan(3/2) + atan( (y-1.5x)/(x+1.5y) ) + * [39/16,INF] atan(y/x) = atan(INF) + atan( -x/y ) + * + * Special cases: + * Notations: atan2(y,x) == ARG (x+iy) == ARG(x,y). + * + * ARG( NAN , (anything) ) is NaN; + * ARG( (anything), NaN ) is NaN; + * ARG(+(anything but NaN), +-0) is +-0 ; + * ARG(-(anything but NaN), +-0) is +-PI ; + * ARG( 0, +-(anything but 0 and NaN) ) is +-PI/2; + * ARG( +INF,+-(anything but INF and NaN) ) is +-0 ; + * ARG( -INF,+-(anything but INF and NaN) ) is +-PI; + * ARG( +INF,+-INF ) is +-PI/4 ; + * ARG( -INF,+-INF ) is +-3PI/4; + * ARG( (anything but,0,NaN, and INF),+-INF ) is +-PI/2; + * + * Accuracy: + * atan2(y,x) returns (PI/pi) * the exact ARG (x+iy) nearly rounded, + * where + * + * in decimal: + * pi = 3.141592653589793 23846264338327 ..... + * 53 bits PI = 3.141592653589793 115997963 ..... , + * 56 bits PI = 3.141592653589793 227020265 ..... , + * + * in hexadecimal: + * pi = 3.243F6A8885A308D313198A2E.... + * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps + * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps + * + * In a test run with 356,000 random argument on [-1,1] * [-1,1] on a + * VAX, the maximum observed error was 1.41 ulps (units of the last place) + * compared with (PI/pi)*(the exact ARG(x+iy)). + * + * Note: + * We use machine PI (the true pi rounded) in place of the actual + * value of pi for all the trig and inverse trig functions. In general, + * if trig is one of sin, cos, tan, then computed trig(y) returns the + * exact trig(y*pi/PI) nearly rounded; correspondingly, computed arctrig + * returns the exact arctrig(y)*PI/pi nearly rounded. These guarantee the + * trig functions have period PI, and trig(arctrig(x)) returns x for + * all critical values x. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(athfhi, 4.6364760900080611433E-1 ,6338,3fed,da7b,2b0d, -1, .ED63382B0DDA7B) +vc(athflo, 1.9338828231967579916E-19 ,5005,2164,92c0,9cfe, -62, .E450059CFE92C0) +vc(PIo4, 7.8539816339744830676E-1 ,0fda,4049,68c2,a221, 0, .C90FDAA22168C2) +vc(at1fhi, 9.8279372324732906796E-1 ,985e,407b,b4d9,940f, 0, .FB985E940FB4D9) +vc(at1flo,-3.5540295636764633916E-18 ,1edc,a383,eaea,34d6, -57,-.831EDC34D6EAEA) +vc(PIo2, 1.5707963267948966135E0 ,0fda,40c9,68c2,a221, 1, .C90FDAA22168C2) +vc(PI, 3.1415926535897932270E0 ,0fda,4149,68c2,a221, 2, .C90FDAA22168C2) +vc(a1, 3.3333333333333473730E-1 ,aaaa,3faa,ab75,aaaa, -1, .AAAAAAAAAAAB75) +vc(a2, -2.0000000000017730678E-1 ,cccc,bf4c,946e,cccd, -2,-.CCCCCCCCCD946E) +vc(a3, 1.4285714286694640301E-1 ,4924,3f12,4262,9274, -2, .92492492744262) +vc(a4, -1.1111111135032672795E-1 ,8e38,bee3,6292,ebc6, -3,-.E38E38EBC66292) +vc(a5, 9.0909091380563043783E-2 ,2e8b,3eba,d70c,b31b, -3, .BA2E8BB31BD70C) +vc(a6, -7.6922954286089459397E-2 ,89c8,be9d,7f18,27c3, -3,-.9D89C827C37F18) +vc(a7, 6.6663180891693915586E-2 ,86b4,3e88,9e58,ae37, -3, .8886B4AE379E58) +vc(a8, -5.8772703698290408927E-2 ,bba5,be70,a942,8481, -4,-.F0BBA58481A942) +vc(a9, 5.2170707402812969804E-2 ,b0f3,3e55,13ab,a1ab, -4, .D5B0F3A1AB13AB) +vc(a10, -4.4895863157820361210E-2 ,e4b9,be37,048f,7fd1, -4,-.B7E4B97FD1048F) +vc(a11, 3.3006147437343875094E-2 ,3174,3e07,2d87,3cf7, -4, .8731743CF72D87) +vc(a12, -1.4614844866464185439E-2 ,731a,bd6f,76d9,2f34, -6,-.EF731A2F3476D9) + +ic(athfhi, 4.6364760900080609352E-1 , -2, 1.DAC670561BB4F) +ic(athflo, 4.6249969567426939759E-18 , -58, 1.5543B8F253271) +ic(PIo4, 7.8539816339744827900E-1 , -1, 1.921FB54442D18) +ic(at1fhi, 9.8279372324732905408E-1 , -1, 1.F730BD281F69B) +ic(at1flo,-2.4407677060164810007E-17 , -56, -1.C23DFEFEAE6B5) +ic(PIo2, 1.5707963267948965580E0 , 0, 1.921FB54442D18) +ic(PI, 3.1415926535897931160E0 , 1, 1.921FB54442D18) +ic(a1, 3.3333333333333942106E-1 , -2, 1.55555555555C3) +ic(a2, -1.9999999999979536924E-1 , -3, -1.9999999997CCD) +ic(a3, 1.4285714278004377209E-1 , -3, 1.24924921EC1D7) +ic(a4, -1.1111110579344973814E-1 , -4, -1.C71C7059AF280) +ic(a5, 9.0908906105474668324E-2 , -4, 1.745CE5AA35DB2) +ic(a6, -7.6919217767468239799E-2 , -4, -1.3B0FA54BEC400) +ic(a7, 6.6614695906082474486E-2 , -4, 1.10DA924597FFF) +ic(a8, -5.8358371008508623523E-2 , -5, -1.DE125FDDBD793) +ic(a9, 4.9850617156082015213E-2 , -5, 1.9860524BDD807) +ic(a10, -3.6700606902093604877E-2 , -5, -1.2CA6C04C6937A) +ic(a11, 1.6438029044759730479E-2 , -6, 1.0D52174A1BB54) + +#ifdef vccast +#define athfhi vccast(athfhi) +#define athflo vccast(athflo) +#define PIo4 vccast(PIo4) +#define at1fhi vccast(at1fhi) +#define at1flo vccast(at1flo) +#define PIo2 vccast(PIo2) +#define PI vccast(PI) +#define a1 vccast(a1) +#define a2 vccast(a2) +#define a3 vccast(a3) +#define a4 vccast(a4) +#define a5 vccast(a5) +#define a6 vccast(a6) +#define a7 vccast(a7) +#define a8 vccast(a8) +#define a9 vccast(a9) +#define a10 vccast(a10) +#define a11 vccast(a11) +#define a12 vccast(a12) +#endif + +double atan2(y,x) +double y,x; +{ + static const double zero=0, one=1, small=1.0E-9, big=1.0E18; + double t,z,signy,signx,hi,lo; + int k,m; + +#if !defined(vax)&&!defined(tahoe) + /* if x or y is NAN */ + if(x!=x) return(x); if(y!=y) return(y); +#endif /* !defined(vax)&&!defined(tahoe) */ + + /* copy down the sign of y and x */ + signy = copysign(one,y) ; + signx = copysign(one,x) ; + + /* if x is 1.0, goto begin */ + if(x==1) { y=copysign(y,one); t=y; if(finite(t)) goto begin;} + + /* when y = 0 */ + if(y==zero) return((signx==one)?y:copysign(PI,signy)); + + /* when x = 0 */ + if(x==zero) return(copysign(PIo2,signy)); + + /* when x is INF */ + if(!finite(x)) + if(!finite(y)) + return(copysign((signx==one)?PIo4:3*PIo4,signy)); + else + return(copysign((signx==one)?zero:PI,signy)); + + /* when y is INF */ + if(!finite(y)) return(copysign(PIo2,signy)); + + /* compute y/x */ + x=copysign(x,one); + y=copysign(y,one); + if((m=(k=logb(y))-logb(x)) > 60) t=big+big; + else if(m < -80 ) t=y/x; + else { t = y/x ; y = scalb(y,-k); x=scalb(x,-k); } + + /* begin argument reduction */ +begin: + if (t < 2.4375) { + + /* truncate 4(t+1/16) to integer for branching */ + k = 4 * (t+0.0625); + switch (k) { + + /* t is in [0,7/16] */ + case 0: + case 1: + if (t < small) + { big + small ; /* raise inexact flag */ + return (copysign((signx>zero)?t:PI-t,signy)); } + + hi = zero; lo = zero; break; + + /* t is in [7/16,11/16] */ + case 2: + hi = athfhi; lo = athflo; + z = x+x; + t = ( (y+y) - x ) / ( z + y ); break; + + /* t is in [11/16,19/16] */ + case 3: + case 4: + hi = PIo4; lo = zero; + t = ( y - x ) / ( x + y ); break; + + /* t is in [19/16,39/16] */ + default: + hi = at1fhi; lo = at1flo; + z = y-x; y=y+y+y; t = x+x; + t = ( (z+z)-x ) / ( t + y ); break; + } + } + /* end of if (t < 2.4375) */ + + else + { + hi = PIo2; lo = zero; + + /* t is in [2.4375, big] */ + if (t <= big) t = - x / y; + + /* t is in [big, INF] */ + else + { big+small; /* raise inexact flag */ + t = zero; } + } + /* end of argument reduction */ + + /* compute atan(t) for t in [-.4375, .4375] */ + z = t*t; +#if defined(vax)||defined(tahoe) + z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+ + z*(a9+z*(a10+z*(a11+z*a12)))))))))))); +#else /* defined(vax)||defined(tahoe) */ + z = t*(z*(a1+z*(a2+z*(a3+z*(a4+z*(a5+z*(a6+z*(a7+z*(a8+ + z*(a9+z*(a10+z*a11))))))))))); +#endif /* defined(vax)||defined(tahoe) */ + z = lo - z; z += t; z += hi; + + return(copysign((signx>zero)?z:PI-z,signy)); +} diff --git a/sysdeps/generic/atanh.c b/sysdeps/generic/atanh.c new file mode 100644 index 0000000000..89cb61cca2 --- /dev/null +++ b/sysdeps/generic/atanh.c @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)atanh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* ATANH(X) + * RETURN THE HYPERBOLIC ARC TANGENT OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85. + * + * Required kernel function: + * log1p(x) ...return log(1+x) + * + * Method : + * Return + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * Special cases: + * atanh(x) is NaN if |x| > 1 with signal; + * atanh(NaN) is that NaN with no signal; + * atanh(+-1) is +-INF with signal. + * + * Accuracy: + * atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded. + * In a test run with 512,000 random arguments on a VAX, the maximum + * observed error was 1.87 ulps (units in the last place) at + * x= -3.8962076028810414000e-03. + */ +#include "mathimpl.h" + +#if defined(vax)||defined(tahoe) +#include <errno.h> +#endif /* defined(vax)||defined(tahoe) */ + +double atanh(x) +double x; +{ + double z; + z = copysign(0.5,x); + x = copysign(x,1.0); +#if defined(vax)||defined(tahoe) + if (x == 1.0) { + return(copysign(1.0,z)*infnan(ERANGE)); /* sign(x)*INF */ + } +#endif /* defined(vax)||defined(tahoe) */ + x = x/(1.0-x); + return( z*log1p(x+x) ); +} diff --git a/sysdeps/generic/bcopy.c b/sysdeps/generic/bcopy.c new file mode 100644 index 0000000000..51de492877 --- /dev/null +++ b/sysdeps/generic/bcopy.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +#define memmove bcopy +#define rettype void +#define RETURN(s) return +#define a1 src +#define a1const CONST +#define a2 dest +#define a2const + +#include <memmove.c> diff --git a/sysdeps/generic/bzero.c b/sysdeps/generic/bzero.c new file mode 100644 index 0000000000..7ebdcfe7e3 --- /dev/null +++ b/sysdeps/generic/bzero.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +/* Set N bytes of S to 0. */ +void +DEFUN(bzero, (s, n), PTR s AND size_t len) +{ + long int dstp = (long int) s; + CONST op_t zero = 0; + + if (len >= 8) + { + size_t xlen; + + /* There are at least some bytes to zero. No need to test + for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((byte *) dstp)[0] = 0; + dstp += 1; + len -= 1; + } + + /* Write 8 op_t per iteration until less than 8 op_t remain. */ + xlen = len / (OPSIZ * 8); + while (xlen != 0) + { + ((op_t *) dstp)[0] = zero; + ((op_t *) dstp)[1] = zero; + ((op_t *) dstp)[2] = zero; + ((op_t *) dstp)[3] = zero; + ((op_t *) dstp)[4] = zero; + ((op_t *) dstp)[5] = zero; + ((op_t *) dstp)[6] = zero; + ((op_t *) dstp)[7] = zero; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 op_t per iteration until less than op_t remain. */ + xlen = len / OPSIZ; + while (xlen != 0) + { + ((op_t *) dstp)[0] = zero; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len != 0) + { + ((byte *) dstp)[0] = 0; + dstp += 1; + len -= 1; + } +} + diff --git a/sysdeps/generic/cabs.c b/sysdeps/generic/cabs.c new file mode 100644 index 0000000000..6f4e1cd211 --- /dev/null +++ b/sysdeps/generic/cabs.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +double +DEFUN(cabs, (z), struct __cabs_complex z) +{ + return hypot (z.__x, z.__y); +} diff --git a/sysdeps/generic/ceil.c b/sysdeps/generic/ceil.c new file mode 100644 index 0000000000..6b7fad3ca8 --- /dev/null +++ b/sysdeps/generic/ceil.c @@ -0,0 +1,68 @@ +/* snarfed from BSD common_source/floor.c: + * Copyright (c) 1985 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)floor.c 5.7 (Berkeley) 10/9/90"; +#endif /* not lint */ + +#include "mathimpl.h" + +vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ + +ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ + +#ifdef vccast +#define L vccast(L) +#endif + +double +ceil(x) +double x; +{ + double y; + + if ( +#if !defined(vax)&&!defined(tahoe) + x != x || /* NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + x >= L) /* already an even integer */ + return x; + else if (x < (double)0) + return -floor(-x); + else { /* now 0 <= x < L */ + y = L+x; /* destructive store must be forced */ + y -= L; /* an integer, and |x-y| < 1 */ + return x > y ? y+(double)1 : y; + } +} + diff --git a/sysdeps/generic/cmp.c b/sysdeps/generic/cmp.c new file mode 100644 index 0000000000..144c88588f --- /dev/null +++ b/sysdeps/generic/cmp.c @@ -0,0 +1,55 @@ +/* __mpn_cmp -- Compare two low-level natural-number integers. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE. + There are no restrictions on the relative sizes of + the two arguments. + Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. */ + +int +#if __STDC__ +__mpn_cmp (mp_srcptr op1_ptr, mp_srcptr op2_ptr, mp_size_t size) +#else +__mpn_cmp (op1_ptr, op2_ptr, size) + mp_srcptr op1_ptr; + mp_srcptr op2_ptr; + mp_size_t size; +#endif +{ + mp_size_t i; + mp_limb op1_word, op2_word; + + for (i = size - 1; i >= 0; i--) + { + op1_word = op1_ptr[i]; + op2_word = op2_ptr[i]; + if (op1_word != op2_word) + goto diff; + } + return 0; + diff: + /* This can *not* be simplified to + op2_word - op2_word + since that expression might give signed overflow. */ + return (op1_word > op2_word) ? 1 : -1; +} diff --git a/sysdeps/generic/configure b/sysdeps/generic/configure new file mode 100755 index 0000000000..c89b679eb9 --- /dev/null +++ b/sysdeps/generic/configure @@ -0,0 +1,52 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + + +if [ ! "$inhibit_glue" ]; then + +# For signame.c, used in make_siglist. +for ac_func in psignal +do +ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'` +echo "checking for ${ac_func}" 1>&4 +if eval "test \"`echo '${'ac_cv_func_${ac_func}'+set}'`\" = set"; then + echo " using cached value for ac_cv_func_${ac_func}" 1>&5 +else + cat > conftest.${ac_ext} <<EOF +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_${ac_func}) || defined (__stub___${ac_func}) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char ${ac_func}(); ${ac_func}(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + eval "ac_cv_func_${ac_func}=yes" +else + rm -rf conftest* + eval "ac_cv_func_${ac_func}=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'${ac_func}`\" = yes"; then + +{ +test "$verbose" = yes && \ +echo " defining ${ac_tr_func}" +echo "#define" ${ac_tr_func} "1" >> confdefs.h +DEFS="$DEFS -D${ac_tr_func}=1" +} + +fi +done + +fi diff --git a/sysdeps/generic/configure.in b/sysdeps/generic/configure.in new file mode 100644 index 0000000000..50209f3bf5 --- /dev/null +++ b/sysdeps/generic/configure.in @@ -0,0 +1,7 @@ +sinclude(./aclocal.m4)dnl +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +if test -z "$inhibit_glue"; then +# For signame.c, used in make_siglist. +AC_CHECK_FUNCS(psignal) +fi diff --git a/sysdeps/generic/confname.h b/sysdeps/generic/confname.h new file mode 100644 index 0000000000..3a0305a0b4 --- /dev/null +++ b/sysdeps/generic/confname.h @@ -0,0 +1,76 @@ +/* `sysconf', `pathconf', and `confstr' NAME values. Generic version. +Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum + { + _PC_LINK_MAX, + _PC_MAX_CANON, + _PC_MAX_INPUT, + _PC_NAME_MAX, + _PC_PATH_MAX, + _PC_PIPE_BUF, + _PC_CHOWN_RESTRICTED, + _PC_NO_TRUNC, + _PC_VDISABLE + }; + +/* Values for the argument to `sysconf'. */ +enum + { + _SC_ARG_MAX, + _SC_CHILD_MAX, + _SC_CLK_TCK, + _SC_NGROUPS_MAX, + _SC_OPEN_MAX, + _SC_STREAM_MAX, + _SC_TZNAME_MAX, + _SC_JOB_CONTROL, + _SC_SAVED_IDS, + _SC_VERSION, + _SC_PAGESIZE, + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, + _SC_BC_DIM_MAX, + _SC_BC_SCALE_MAX, + _SC_BC_STRING_MAX, + _SC_COLL_WEIGHTS_MAX, + _SC_EQUIV_CLASS_MAX, + _SC_EXPR_NEST_MAX, + _SC_LINE_MAX, + _SC_RE_DUP_MAX, + + _SC_2_VERSION, + _SC_2_C_BIND, + _SC_2_C_DEV, + _SC_2_FORT_DEV, + _SC_2_FORT_RUN, + _SC_2_SW_DEV, + _SC_2_LOCALEDEF + }; + +#ifdef __USE_POSIX2 +/* Values for the NAME argument to `confstr'. */ +enum + { + _CS_PATH /* The default search path. */ + }; +#endif diff --git a/sysdeps/generic/copysign.c b/sysdeps/generic/copysign.c new file mode 100644 index 0000000000..0bd3ed9360 --- /dev/null +++ b/sysdeps/generic/copysign.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return X with its signed changed to Y's. */ +double +DEFUN(__copysign, (x, y), double x AND double y) +{ + x = fabs (x); + return y < 0 ? - x : x; +} + +weak_alias (__copysign, copysign) diff --git a/sysdeps/generic/cosh.c b/sysdeps/generic/cosh.c new file mode 100644 index 0000000000..e2b30731b8 --- /dev/null +++ b/sysdeps/generic/cosh.c @@ -0,0 +1,133 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)cosh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* COSH(X) + * RETURN THE HYPERBOLIC COSINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 2/8/85, 2/23/85, 3/7/85, 3/29/85, 4/16/85. + * + * Required system supported functions : + * copysign(x,y) + * scalb(x,N) + * + * Required kernel function: + * exp(x) + * exp__E(x,c) ...return exp(x+c)-1-x for |x|<0.3465 + * + * Method : + * 1. Replace x by |x|. + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= 0.3465 : cosh(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * 0.3465 <= x <= 22 : cosh(x) := ------------------- + * 2 + * 22 <= x <= lnovfl : cosh(x) := exp(x)/2 + * lnovfl <= x <= lnovfl+log(2) + * : cosh(x) := exp(x)/2 (avoid overflow) + * log(2)+lnovfl < x < INF: overflow to INF + * + * Note: .3465 is a number near one half of ln2. + * + * Special cases: + * cosh(x) is x if x is +INF, -INF, or NaN. + * only cosh(0)=1 is exact for finite x. + * + * Accuracy: + * cosh(x) returns the exact hyperbolic cosine of x nearly rounded. + * In a test run with 768,000 random arguments on a VAX, the maximum + * observed error was 1.23 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(mln2hi, 8.8029691931113054792E1 ,0f33,43b0,2bdb,c7e2, 7, .B00F33C7E22BDB) +vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A) +vc(lnovfl, 8.8029691931113053016E1 ,0f33,43b0,2bda,c7e2, 7, .B00F33C7E22BDA) + +ic(mln2hi, 7.0978271289338397310E2, 10, 1.62E42FEFA39EF) +ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F) +ic(lnovfl, 7.0978271289338397310E2, 9, 1.62E42FEFA39EF) + +#ifdef vccast +#define mln2hi vccast(mln2hi) +#define mln2lo vccast(mln2lo) +#define lnovfl vccast(lnovfl) +#endif + +#if defined(vax)||defined(tahoe) +static max = 126 ; +#else /* defined(vax)||defined(tahoe) */ +static max = 1023 ; +#endif /* defined(vax)||defined(tahoe) */ + +double cosh(x) +double x; +{ + static const double half=1.0/2.0, + one=1.0, small=1.0E-18; /* fl(1+small)==1 */ + double t; + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + if((x=copysign(x,one)) <= 22) + if(x<0.3465) + if(x<small) return(one+x); + else {t=x+__exp__E(x,0.0);x=t+t; return(one+t*t/(2.0+x)); } + + else /* for x lies in [0.3465,22] */ + { t=exp(x); return((t+one/t)*half); } + + if( lnovfl <= x && x <= (lnovfl+0.7)) + /* for x lies in [lnovfl, lnovfl+ln2], decrease x by ln(2^(max+1)) + * and return 2^max*exp(x) to avoid unnecessary overflow + */ + return(scalb(exp((x-mln2hi)-mln2lo), max)); + + else + return(exp(x)*half); /* for large x, cosh(x)=exp(x)/2 */ +} diff --git a/sysdeps/generic/det_endian.c b/sysdeps/generic/det_endian.c new file mode 100644 index 0000000000..50b5bdc5bf --- /dev/null +++ b/sysdeps/generic/det_endian.c @@ -0,0 +1,34 @@ +/* Determine the "endianness" of the CPU. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdio.h> + +main () +{ + unsigned long int i; + + if (sizeof (i) != 4) + puts ("#error \"Not a 32-bit machine!\""); + + i = (((((('4' << 8) + '3') << 8) + '2') << 8) + '1'); + + printf ("#define __BYTE_ORDER %.4s\n", (char *) &i); + + exit (0); +} diff --git a/sysdeps/generic/divmod.c b/sysdeps/generic/divmod.c new file mode 100644 index 0000000000..76b9bcae6b --- /dev/null +++ b/sysdeps/generic/divmod.c @@ -0,0 +1,234 @@ +/* __mpn_divmod -- Divide natural numbers, producing both remainder and + quotient. + +Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +/* Divide num (NUM_PTR/NUM_SIZE) by den (DEN_PTR/DEN_SIZE) and write + the NUM_SIZE-DEN_SIZE least significant quotient limbs at QUOT_PTR + and the DEN_SIZE long remainder at NUM_PTR. + Return the most significant limb of the quotient, this is always 0 or 1. + + Argument constraints: + 1. The most significant bit of the divisor must be set. + 2. QUOT_PTR must either not overlap with the input operands at all, or + QUOT_PTR + DEN_SIZE >= NUM_PTR must hold true. (This means that it's + possible to put the quotient in the high part of NUM, right after the + remainder in NUM. */ + +mp_limb +#if __STDC__ +__mpn_divmod (mp_ptr quot_ptr, + mp_ptr num_ptr, mp_size_t num_size, + mp_srcptr den_ptr, mp_size_t den_size) +#else +__mpn_divmod (quot_ptr, num_ptr, num_size, den_ptr, den_size) + mp_ptr quot_ptr; + mp_ptr num_ptr; + mp_size_t num_size; + mp_srcptr den_ptr; + mp_size_t den_size; +#endif +{ + mp_limb most_significant_q_limb = 0; + + switch (den_size) + { + case 0: + /* We are asked to divide by zero, so go ahead and do it! (To make + the compiler not remove this statement, return the value.) */ + return 1 / den_size; + + case 1: + { + mp_size_t i; + mp_limb n1, n0; + mp_limb d; + + d = den_ptr[0]; + n1 = num_ptr[num_size - 1]; + + if (n1 >= d) + { + most_significant_q_limb = 1; + n1 -= d; + } + + for (i = num_size - 2; i >= 0; i--) + { + n0 = num_ptr[i]; + udiv_qrnnd (quot_ptr[i], n1, n1, n0, d); + } + + num_ptr[0] = n1; + } + break; + + case 2: + { + mp_size_t i; + mp_limb n1, n0, n2; + mp_limb d1, d0; + + num_ptr += num_size - 2; + d1 = den_ptr[1]; + d0 = den_ptr[0]; + n1 = num_ptr[1]; + n0 = num_ptr[0]; + + if (n1 >= d1 && (n1 > d1 || n0 >= d0)) + { + most_significant_q_limb = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + + for (i = num_size - den_size - 1; i >= 0; i--) + { + mp_limb q; + mp_limb r; + + num_ptr--; + if (n1 == d1) + { + /* Q should be either 111..111 or 111..110. Need special + treatment of this rare case as normal division would + give overflow. */ + q = ~(mp_limb) 0; + + r = n0 + d1; + if (r < d1) /* Carry in the addition? */ + { + add_ssaaaa (n1, n0, r - d0, num_ptr[0], 0, d0); + quot_ptr[i] = q; + continue; + } + n1 = d0 - (d0 != 0); + n0 = -d0; + } + else + { + udiv_qrnnd (q, r, n1, n0, d1); + umul_ppmm (n1, n0, d0, q); + } + + n2 = num_ptr[0]; + q_test: + if (n1 > r || (n1 == r && n0 > n2)) + { + /* The estimated Q was too large. */ + q--; + + sub_ddmmss (n1, n0, n1, n0, 0, d0); + r += d1; + if (r >= d1) /* If not carry, test Q again. */ + goto q_test; + } + + quot_ptr[i] = q; + sub_ddmmss (n1, n0, r, n2, n1, n0); + } + num_ptr[1] = n1; + num_ptr[0] = n0; + } + break; + + default: + { + mp_size_t i; + mp_limb dX, d1, n0; + + num_ptr += num_size; + den_ptr += den_size; + dX = den_ptr[-1]; + d1 = den_ptr[-2]; + n0 = num_ptr[-1]; + + if (n0 >= dX) + { + if (n0 > dX + || __mpn_cmp (num_ptr - den_size, den_ptr - den_size, + den_size - 1) >= 0) + { + __mpn_sub_n (num_ptr - den_size, + num_ptr - den_size, den_ptr - den_size, + den_size); + most_significant_q_limb = 1; + } + + n0 = num_ptr[-1]; + } + + for (i = num_size - den_size - 1; i >= 0; i--) + { + mp_limb q; + mp_limb n1; + mp_limb cy_limb; + + num_ptr--; + if (n0 == dX) + /* This might over-estimate q, but it's probably not worth + the extra code here to find out. */ + q = ~(mp_limb) 0; + else + { + mp_limb r; + + udiv_qrnnd (q, r, n0, num_ptr[-1], dX); + umul_ppmm (n1, n0, d1, q); + + while (n1 > r || (n1 == r && n0 > num_ptr[-2])) + { + q--; + r += dX; + if (r < dX) /* I.e. "carry in previous addition?" */ + break; + n1 -= n0 < d1; + n0 -= d1; + } + } + + /* Possible optimization: We already have (q * n0) and (1 * n1) + after the calculation of q. Taking advantage of that, we + could make this loop make two iterations less. */ + + cy_limb = __mpn_submul_1 (num_ptr - den_size, + den_ptr - den_size, den_size, q); + + if (num_ptr[0] != cy_limb) + { + mp_limb cy; + cy = __mpn_add_n (num_ptr - den_size, + num_ptr - den_size, + den_ptr - den_size, den_size); + if (cy == 0) + abort (); + q--; + } + + quot_ptr[i] = q; + n0 = num_ptr[-1]; + } + } + } + + return most_significant_q_limb; +} diff --git a/sysdeps/generic/divmod_1.c b/sysdeps/generic/divmod_1.c new file mode 100644 index 0000000000..d156eeb00d --- /dev/null +++ b/sysdeps/generic/divmod_1.c @@ -0,0 +1,209 @@ +/* __mpn_divmod_1(quot_ptr, dividend_ptr, dividend_size, divisor_limb) -- + Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. + Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR. + Return the single-limb remainder. + There are no constraints on the value of the divisor. + + QUOT_PTR and DIVIDEND_PTR might point to the same limb. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +#ifndef UMUL_TIME +#define UMUL_TIME 1 +#endif + +#ifndef UDIV_TIME +#define UDIV_TIME UMUL_TIME +#endif + +/* FIXME: We should be using invert_limb (or invert_normalized_limb) + here (not udiv_qrnnd). */ + +mp_limb +#if __STDC__ +__mpn_divmod_1 (mp_ptr quot_ptr, + mp_srcptr dividend_ptr, mp_size_t dividend_size, + mp_limb divisor_limb) +#else +__mpn_divmod_1 (quot_ptr, dividend_ptr, dividend_size, divisor_limb) + mp_ptr quot_ptr; + mp_srcptr dividend_ptr; + mp_size_t dividend_size; + mp_limb divisor_limb; +#endif +{ + mp_size_t i; + mp_limb n1, n0, r; + int dummy; + + /* ??? Should this be handled at all? Rely on callers? */ + if (dividend_size == 0) + return 0; + + /* If multiplication is much faster than division, and the + dividend is large, pre-invert the divisor, and use + only multiplications in the inner loop. */ + + /* This test should be read: + Does it ever help to use udiv_qrnnd_preinv? + && Does what we save compensate for the inversion overhead? */ + if (UDIV_TIME > (2 * UMUL_TIME + 6) + && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + mp_limb divisor_limb_inverted; + + divisor_limb <<= normalization_steps; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + +#if 0 /* This can't happen when normalization_steps != 0 */ + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb) 0; + else +#endif + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (quot_ptr[i + 1], r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb, divisor_limb_inverted); + n1 = n0; + } + udiv_qrnnd_preinv (quot_ptr[0], r, r, + n1 << normalization_steps, + divisor_limb, divisor_limb_inverted); + return r >> normalization_steps; + } + else + { + mp_limb divisor_limb_inverted; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb) 0; + else + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + { + quot_ptr[i] = 0; + i--; + } + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (quot_ptr[i], r, r, + n0, divisor_limb, divisor_limb_inverted); + } + return r; + } + } + else + { + if (UDIV_NEEDS_NORMALIZATION) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + divisor_limb <<= normalization_steps; + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (quot_ptr[i + 1], r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb); + n1 = n0; + } + udiv_qrnnd (quot_ptr[0], r, r, + n1 << normalization_steps, + divisor_limb); + return r >> normalization_steps; + } + } + /* No normalization needed, either because udiv_qrnnd doesn't require + it, or because DIVISOR_LIMB is already normalized. */ + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + { + quot_ptr[i] = 0; + i--; + } + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (quot_ptr[i], r, r, n0, divisor_limb); + } + return r; + } +} diff --git a/sysdeps/generic/exp.c b/sysdeps/generic/exp.c new file mode 100644 index 0000000000..9b4f045f82 --- /dev/null +++ b/sysdeps/generic/exp.c @@ -0,0 +1,203 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* EXP(X) + * RETURN THE EXPONENTIAL OF X + * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) + * CODED IN C BY K.C. NG, 1/19/85; + * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86. + * + * Required system supported functions: + * scalb(x,n) + * copysign(x,y) + * finite(x) + * + * Method: + * 1. Argument Reduction: given the input x, find r and integer k such + * that + * x = k*ln2 + r, |r| <= 0.5*ln2 . + * r will be represented as r := z+c for better accuracy. + * + * 2. Compute exp(r) by + * + * exp(r) = 1 + r + r*R1/(2-R1), + * where + * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))). + * + * 3. exp(x) = 2^k * exp(r) . + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF)= 0; + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * exp(x) returns the exponential of x nearly rounded. In a test run + * with 1,156,000 random arguments on a VAX, the maximum observed + * error was 0.869 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010) +vc(lntiny,-9.5654310917272452386E1 ,4f01,c3bf,33af,d72e, 7,-.BF4F01D72E33AF) +vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1) +vc(p1, 1.6666666666666602251E-1 ,aaaa,3f2a,a9f1,aaaa, -2, .AAAAAAAAAAA9F1) +vc(p2, -2.7777777777015591216E-3 ,0b60,bc36,ec94,b5f5, -8,-.B60B60B5F5EC94) +vc(p3, 6.6137563214379341918E-5 ,b355,398a,f15f,792e, -13, .8AB355792EF15F) +vc(p4, -1.6533902205465250480E-6 ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84) +vc(p5, 4.1381367970572387085E-8 ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683) + +#ifdef vccast +#define ln2hi vccast(ln2hi) +#define ln2lo vccast(ln2lo) +#define lnhuge vccast(lnhuge) +#define lntiny vccast(lntiny) +#define invln2 vccast(invln2) +#define p1 vccast(p1) +#define p2 vccast(p2) +#define p3 vccast(p3) +#define p4 vccast(p4) +#define p5 vccast(p5) +#endif + +ic(p1, 1.6666666666666601904E-1, -3, 1.555555555553E) +ic(p2, -2.7777777777015593384E-3, -9, -1.6C16C16BEBD93) +ic(p3, 6.6137563214379343612E-5, -14, 1.1566AAF25DE2C) +ic(p4, -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1) +ic(p5, 4.1381367970572384604E-8, -25, 1.6376972BEA4D0) +ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76) +ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2) +ic(lntiny,-7.5137154372698068983E2, 9, -1.77AF8EBEAE354) +ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE) + +double exp(x) +double x; +{ + double z,hi,lo,c; + int k; + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + if( x <= lnhuge ) { + if( x >= lntiny ) { + + /* argument reduction : x --> x - k*ln2 */ + + k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */ + + /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */ + + hi=x-k*ln2hi; + x=hi-(lo=k*ln2lo); + + /* return 2^k*[1+x+x*c/(2+c)] */ + z=x*x; + c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); + return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k); + + } + /* end of x > lntiny */ + + else + /* exp(-big#) underflows to zero */ + if(finite(x)) return(scalb(1.0,-5000)); + + /* exp(-INF) is zero */ + else return(0.0); + } + /* end of x < lnhuge */ + + else + /* exp(INF) is INF, exp(+big#) overflows to INF */ + return( finite(x) ? scalb(1.0,5000) : x); +} + +/* returns exp(r = x + c) for |c| < |x| with no overlap. */ + +double __exp__D(x, c) +double x, c; +{ + double z,hi,lo, t; + int k; + +#if !defined(vax)&&!defined(tahoe) + if (x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + if ( x <= lnhuge ) { + if ( x >= lntiny ) { + + /* argument reduction : x --> x - k*ln2 */ + z = invln2*x; + k = z + copysign(.5, x); + + /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */ + + hi=(x-k*ln2hi); /* Exact. */ + x= hi - (lo = k*ln2lo-c); + /* return 2^k*[1+x+x*c/(2+c)] */ + z=x*x; + c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); + c = (x*c)/(2.0-c); + + return scalb(1.+(hi-(lo - c)), k); + } + /* end of x > lntiny */ + + else + /* exp(-big#) underflows to zero */ + if(finite(x)) return(scalb(1.0,-5000)); + + /* exp(-INF) is zero */ + else return(0.0); + } + /* end of x < lnhuge */ + + else + /* exp(INF) is INF, exp(+big#) overflows to INF */ + return( finite(x) ? scalb(1.0,5000) : x); +} diff --git a/sysdeps/generic/exp__E.c b/sysdeps/generic/exp__E.c new file mode 100644 index 0000000000..ab972477a0 --- /dev/null +++ b/sysdeps/generic/exp__E.c @@ -0,0 +1,136 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)exp__E.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* exp__E(x,c) + * ASSUMPTION: c << x SO THAT fl(x+c)=x. + * (c is the correction term for x) + * exp__E RETURNS + * + * / exp(x+c) - 1 - x , 1E-19 < |x| < .3465736 + * exp__E(x,c) = | + * \ 0 , |x| < 1E-19. + * + * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) + * KERNEL FUNCTION OF EXP, EXPM1, POW FUNCTIONS + * CODED IN C BY K.C. NG, 1/31/85; + * REVISED BY K.C. NG on 3/16/85, 4/16/85. + * + * Required system supported function: + * copysign(x,y) + * + * Method: + * 1. Rational approximation. Let r=x+c. + * Based on + * 2 * sinh(r/2) + * exp(r) - 1 = ---------------------- , + * cosh(r/2) - sinh(r/2) + * exp__E(r) is computed using + * x*x (x/2)*W - ( Q - ( 2*P + x*P ) ) + * --- + (c + x*[---------------------------------- + c ]) + * 2 1 - W + * where P := p1*x^2 + p2*x^4, + * Q := q1*x^2 + q2*x^4 (for 56 bits precision, add q3*x^6) + * W := x/2-(Q-x*P), + * + * (See the listing below for the values of p1,p2,q1,q2,q3. The poly- + * nomials P and Q may be regarded as the approximations to sinh + * and cosh : + * sinh(r/2) = r/2 + r * P , cosh(r/2) = 1 + Q . ) + * + * The coefficients were obtained by a special Remez algorithm. + * + * Approximation error: + * + * | exp(x) - 1 | 2**(-57), (IEEE double) + * | ------------ - (exp__E(x,0)+x)/x | <= + * | x | 2**(-69). (VAX D) + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(p1, 1.5150724356786683059E-2 ,3abe,3d78,066a,67e1, -6, .F83ABE67E1066A) +vc(p2, 6.3112487873718332688E-5 ,5b42,3984,0173,48cd, -13, .845B4248CD0173) +vc(q1, 1.1363478204690669916E-1 ,b95a,3ee8,ec45,44a2, -3, .E8B95A44A2EC45) +vc(q2, 1.2624568129896839182E-3 ,7905,3ba5,f5e7,72e4, -9, .A5790572E4F5E7) +vc(q3, 1.5021856115869022674E-6 ,9eb4,36c9,c395,604a, -19, .C99EB4604AC395) + +ic(p1, 1.3887401997267371720E-2, -7, 1.C70FF8B3CC2CF) +ic(p2, 3.3044019718331897649E-5, -15, 1.15317DF4526C4) +ic(q1, 1.1110813732786649355E-1, -4, 1.C719538248597) +ic(q2, 9.9176615021572857300E-4, -10, 1.03FC4CB8C98E8) + +#ifdef vccast +#define p1 vccast(p1) +#define p2 vccast(p2) +#define q1 vccast(q1) +#define q2 vccast(q2) +#define q3 vccast(q3) +#endif + +double __exp__E(x,c) +double x,c; +{ + const static double zero=0.0, one=1.0, half=1.0/2.0, small=1.0E-19; + double z,p,q,xp,xh,w; + if(copysign(x,one)>small) { + z = x*x ; + p = z*( p1 +z* p2 ); +#if defined(vax)||defined(tahoe) + q = z*( q1 +z*( q2 +z* q3 )); +#else /* defined(vax)||defined(tahoe) */ + q = z*( q1 +z* q2 ); +#endif /* defined(vax)||defined(tahoe) */ + xp= x*p ; + xh= x*half ; + w = xh-(q-xp) ; + p = p+p; + c += x*((xh*w-(q-(p+xp)))/(one-w)+c); + return(z*half+c); + } + /* end of |x| > small */ + + else { + if(x!=zero) one+small; /* raise the inexact flag */ + return(copysign(zero,x)); + } +} diff --git a/sysdeps/generic/expm1.c b/sysdeps/generic/expm1.c new file mode 100644 index 0000000000..a738d124c8 --- /dev/null +++ b/sysdeps/generic/expm1.c @@ -0,0 +1,169 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)expm1.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* EXPM1(X) + * RETURN THE EXPONENTIAL OF X MINUS ONE + * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS) + * CODED IN C BY K.C. NG, 1/19/85; + * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85. + * + * Required system supported functions: + * scalb(x,n) + * copysign(x,y) + * finite(x) + * + * Kernel function: + * exp__E(x,c) + * + * Method: + * 1. Argument Reduction: given the input x, find r and integer k such + * that + * x = k*ln2 + r, |r| <= 0.5*ln2 . + * r will be represented as r := z+c for better accuracy. + * + * 2. Compute EXPM1(r)=exp(r)-1 by + * + * EXPM1(r=z+c) := z + exp__E(z,c) + * + * 3. EXPM1(x) = 2^k * ( EXPM1(r) + 1-2^-k ). + * + * Remarks: + * 1. When k=1 and z < -0.25, we use the following formula for + * better accuracy: + * EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) ) + * 2. To avoid rounding error in 1-2^-k where k is large, we use + * EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 } + * when k>56. + * + * Special cases: + * EXPM1(INF) is INF, EXPM1(NaN) is NaN; + * EXPM1(-INF)= -1; + * for finite argument, only EXPM1(0)=0 is exact. + * + * Accuracy: + * EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with + * 1,166,000 random arguments on a VAX, the maximum observed error was + * .872 ulps (units of the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010) +vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1) + +ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76) +ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2) +ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE) + +#ifdef vccast +#define ln2hi vccast(ln2hi) +#define ln2lo vccast(ln2lo) +#define lnhuge vccast(lnhuge) +#define invln2 vccast(invln2) +#endif + +double expm1(x) +double x; +{ + const static double one=1.0, half=1.0/2.0; + double z,hi,lo,c; + int k; +#if defined(vax)||defined(tahoe) + static prec=56; +#else /* defined(vax)||defined(tahoe) */ + static prec=53; +#endif /* defined(vax)||defined(tahoe) */ + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + + if( x <= lnhuge ) { + if( x >= -40.0 ) { + + /* argument reduction : x - k*ln2 */ + k= invln2 *x+copysign(0.5,x); /* k=NINT(x/ln2) */ + hi=x-k*ln2hi ; + z=hi-(lo=k*ln2lo); + c=(hi-z)-lo; + + if(k==0) return(z+__exp__E(z,c)); + if(k==1) + if(z< -0.25) + {x=z+half;x +=__exp__E(z,c); return(x+x);} + else + {z+=__exp__E(z,c); x=half+z; return(x+x);} + /* end of k=1 */ + + else { + if(k<=prec) + { x=one-scalb(one,-k); z += __exp__E(z,c);} + else if(k<100) + { x = __exp__E(z,c)-scalb(one,-k); x+=z; z=one;} + else + { x = __exp__E(z,c)+z; z=one;} + + return (scalb(x+z,k)); + } + } + /* end of x > lnunfl */ + + else + /* expm1(-big#) rounded to -1 (inexact) */ + if(finite(x)) + { ln2hi+ln2lo; return(-one);} + + /* expm1(-INF) is -1 */ + else return(-one); + } + /* end of x < lnhuge */ + + else + /* expm1(INF) is INF, expm1(+big#) overflows to INF */ + return( finite(x) ? scalb(one,5000) : x); +} + +weak_alias (__expm1, expm1) diff --git a/sysdeps/generic/fabs.c b/sysdeps/generic/fabs.c new file mode 100644 index 0000000000..cf8fa18e50 --- /dev/null +++ b/sysdeps/generic/fabs.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return the absolute value of X. */ +double +DEFUN(fabs, (x), register double x) +{ + return x < 0.0 ? -x : x; +} diff --git a/sysdeps/generic/ffs.c b/sysdeps/generic/ffs.c new file mode 100644 index 0000000000..016f0336e9 --- /dev/null +++ b/sysdeps/generic/ffs.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <limits.h> +#include <string.h> + +#undef ffs + + +/* Find the first bit set in I. */ +int +DEFUN(ffs, (i), int i) +{ + static CONST unsigned char table[] = + { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + unsigned long int a; + unsigned long int x = i & -i; + + a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24); + + return table[x >> a] + a; +} diff --git a/sysdeps/generic/floor.c b/sysdeps/generic/floor.c new file mode 100644 index 0000000000..a57d79a4f7 --- /dev/null +++ b/sysdeps/generic/floor.c @@ -0,0 +1,74 @@ +/* snarfed from BSD common_source/floor.c: + * Copyright (c) 1985 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)floor.c 5.7 (Berkeley) 10/9/90"; +#endif /* not lint */ + +#include "mathimpl.h" + +vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ + +ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ + +#ifdef vccast +#define L vccast(L) +#endif + +/* + * floor(x) := the largest integer no larger than x; + * ceil(x) := -floor(-x), for all real x. + * + * Note: Inexact will be signaled if x is not an integer, as is + * customary for IEEE 754. No other signal can be emitted. + */ +double +floor(x) +double x; +{ + double y; + + if ( +#if !defined(vax)&&!defined(tahoe) + x != x || /* NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + x >= L) /* already an even integer */ + return x; + else if (x < (double)0) + return -ceil(-x); + else { /* now 0 <= x < L */ + y = L+x; /* destructive store must be forced */ + y -= L; /* an integer, and |x-y| < 1 */ + return x < y ? y-(double)1 : y; + } +} diff --git a/sysdeps/generic/fmod.c b/sysdeps/generic/fmod.c new file mode 100644 index 0000000000..09a31b29b3 --- /dev/null +++ b/sysdeps/generic/fmod.c @@ -0,0 +1,155 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)fmod.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* fmod.c + * + * SYNOPSIS + * + * #include <math.h> + * double fmod(double x, double y) + * + * DESCRIPTION + * + * The fmod function computes the floating-point remainder of x/y. + * + * RETURNS + * + * The fmod function returns the value x-i*y, for some integer i + * such that, if y is nonzero, the result has the same sign as x and + * magnitude less than the magnitude of y. + * + * On a VAX or CCI, + * + * fmod(x,0) traps/faults on floating-point divided-by-zero. + * + * On IEEE-754 conforming machines with "isnan()" primitive, + * + * fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned. + * + */ +#if !defined(vax) && !defined(tahoe) +extern int isnan(),finite(); +#endif /* !defined(vax) && !defined(tahoe) */ +extern double frexp(),ldexp(),fabs(); + +#ifdef TEST_FMOD +static double +_fmod(x,y) +#else /* TEST_FMOD */ +double +fmod(x,y) +#endif /* TEST_FMOD */ +double x,y; +{ + int ir,iy; + double r,w; + + if (y == (double)0 +#if !defined(vax) && !defined(tahoe) /* per "fmod" manual entry, SunOS 4.0 */ + || isnan(y) || !finite(x) +#endif /* !defined(vax) && !defined(tahoe) */ + ) + return (x*y)/(x*y); + + r = fabs(x); + y = fabs(y); + (void)frexp(y,&iy); + while (r >= y) { + (void)frexp(r,&ir); + w = ldexp(y,ir-iy); + r -= w <= r ? w : w*(double)0.5; + } + return x >= (double)0 ? r : -r; +} + +#ifdef TEST_FMOD +extern long random(); +extern double fmod(); + +#define NTEST 10000 +#define NCASES 3 + +static int nfail = 0; + +static void +doit(x,y) +double x,y; +{ + double ro = fmod(x,y),rn = _fmod(x,y); + if (ro != rn) { + (void)printf(" x = 0x%08.8x %08.8x (%24.16e)\n",x,x); + (void)printf(" y = 0x%08.8x %08.8x (%24.16e)\n",y,y); + (void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro); + (void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn); + (void)printf("\n"); + } +} + +main() +{ + register int i,cases; + double x,y; + + srandom(12345); + for (i = 0; i < NTEST; i++) { + x = (double)random(); + y = (double)random(); + for (cases = 0; cases < NCASES; cases++) { + switch (cases) { + case 0: + break; + case 1: + y = (double)1/y; break; + case 2: + x = (double)1/x; break; + default: + abort(); break; + } + doit(x,y); + doit(x,-y); + doit(-x,y); + doit(-x,-y); + } + } + if (nfail) + (void)printf("Number of failures: %d (out of a total of %d)\n", + nfail,NTEST*NCASES*4); + else + (void)printf("No discrepancies were found\n"); + exit(0); +} +#endif /* TEST_FMOD */ diff --git a/sysdeps/generic/frexp.c b/sysdeps/generic/frexp.c new file mode 100644 index 0000000000..b2705bdf52 --- /dev/null +++ b/sysdeps/generic/frexp.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Break VALUE into a normalized fraction and an integral power of 2. */ +double +DEFUN(frexp, (value, exp), double value AND int *exp) +{ +#ifdef NAN + if (__isinf (value)) + { + errno = EDOM; + *exp = 0; + return __copysign (NAN, value); + } +#endif + + if (__isnan (value)) + { + errno = EDOM; + *exp = 0; + return value; + } + + if (value == 0) + { + *exp = 0; + return value; + } + + /* Add one to the exponent of the number, + so we have one digit before the binary point. */ + *exp = (int) __logb (value) + 1; + return ldexp (value, - *exp); +} diff --git a/sysdeps/generic/ftime.c b/sysdeps/generic/ftime.c new file mode 100644 index 0000000000..76e9276483 --- /dev/null +++ b/sysdeps/generic/ftime.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/timeb.h> +#include <sys/time.h> +#include <errno.h> + +int +ftime (timebuf) + struct timeb *timebuf; +{ + int save = errno; + struct tm *tp; + + errno = 0; + if (time (&timebuf->time) == (time_t) -1 && errno != 0) + return -1; + timebuf->millitm = 0; + + tp = localtime (&timebuf->time); + if (tp == NULL) + return -1; + + timebuf->timezone = tp->tm_gmtoff / 60; + timebuf->dstflag = tp->tm_isdst; + + errno = save; + return 0; +} diff --git a/sysdeps/generic/get_str.c b/sysdeps/generic/get_str.c new file mode 100644 index 0000000000..182815ee18 --- /dev/null +++ b/sysdeps/generic/get_str.c @@ -0,0 +1,213 @@ +/* __mpn_get_str -- Convert a MSIZE long limb vector pointed to by MPTR + to a printable string in STR in base BASE. + +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + + +This file is part of the GNU C Library. Its master source is NOT part of +the C library, however. This file is in fact copied from the GNU MP +Library and its source lives there. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Convert the limb vector pointed to by MPTR and MSIZE long to a + char array, using base BASE for the result array. Store the + result in the character array STR. STR must point to an array with + space for the largest possible number represented by a MSIZE long + limb vector + 1 extra character. + + The result is NOT in Ascii, to convert it to printable format, add + '0' or 'A' depending on the base and range. + + Return the number of digits in the result string. + This may include some leading zeros. + + The limb vector pointed to by MPTR is clobbered. */ + +size_t +__mpn_get_str (str, base, mptr, msize) + unsigned char *str; + int base; + mp_ptr mptr; + mp_size_t msize; +{ + mp_limb big_base; +#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME + int normalization_steps; +#endif +#if UDIV_TIME > 2 * UMUL_TIME + mp_limb big_base_inverted; +#endif + unsigned int dig_per_u; + mp_size_t out_len; + register unsigned char *s; + + big_base = __mp_bases[base].big_base; + + s = str; + + /* Special case zero, as the code below doesn't handle it. */ + if (msize == 0) + { + s[0] = 0; + return 1; + } + + if ((base & (base - 1)) == 0) + { + /* The base is a power of 2. Make conversion from most + significant side. */ + mp_limb n1, n0; + register int bits_per_digit = big_base; + register int x; + register int bit_pos; + register int i; + + n1 = mptr[msize - 1]; + count_leading_zeros (x, n1); + + /* BIT_POS should be R when input ends in least sign. nibble, + R + bits_per_digit * n when input ends in n:th least significant + nibble. */ + + { + int bits; + + bits = BITS_PER_MP_LIMB * msize - x; + x = bits % bits_per_digit; + if (x != 0) + bits += bits_per_digit - x; + bit_pos = bits - (msize - 1) * BITS_PER_MP_LIMB; + } + + /* Fast loop for bit output. */ + i = msize - 1; + for (;;) + { + bit_pos -= bits_per_digit; + while (bit_pos >= 0) + { + *s++ = (n1 >> bit_pos) & ((1 << bits_per_digit) - 1); + bit_pos -= bits_per_digit; + } + i--; + if (i < 0) + break; + n0 = (n1 << -bit_pos) & ((1 << bits_per_digit) - 1); + n1 = mptr[i]; + bit_pos += BITS_PER_MP_LIMB; + *s++ = n0 | (n1 >> bit_pos); + } + + *s = 0; + + return s - str; + } + else + { + /* General case. The base is not a power of 2. Make conversion + from least significant end. */ + + /* If udiv_qrnnd only handles divisors with the most significant bit + set, prepare BIG_BASE for being a divisor by shifting it to the + left exactly enough to set the most significant bit. */ +#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME + count_leading_zeros (normalization_steps, big_base); + big_base <<= normalization_steps; +#if UDIV_TIME > 2 * UMUL_TIME + /* Get the fixed-point approximation to 1/(BIG_BASE << NORMALIZATION_STEPS). */ + big_base_inverted = __mp_bases[base].big_base_inverted; +#endif +#endif + + dig_per_u = __mp_bases[base].chars_per_limb; + out_len = ((size_t) msize * BITS_PER_MP_LIMB + * __mp_bases[base].chars_per_bit_exactly) + 1; + s += out_len; + + while (msize != 0) + { + int i; + mp_limb n0, n1; + +#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME + /* If we shifted BIG_BASE above, shift the dividend too, to get + the right quotient. We need to do this every loop, + since the intermediate quotients are OK, but the quotient from + one turn in the loop is going to be the dividend in the + next turn, and the dividend needs to be up-shifted. */ + if (normalization_steps != 0) + { + n0 = __mpn_lshift (mptr, mptr, msize, normalization_steps); + + /* If the shifting gave a carry out limb, store it and + increase the length. */ + if (n0 != 0) + { + mptr[msize] = n0; + msize++; + } + } +#endif + + /* Divide the number at TP with BIG_BASE to get a quotient and a + remainder. The remainder is our new digit in base BIG_BASE. */ + i = msize - 1; + n1 = mptr[i]; + + if (n1 >= big_base) + n1 = 0; + else + { + msize--; + i--; + } + + for (; i >= 0; i--) + { + n0 = mptr[i]; +#if UDIV_TIME > 2 * UMUL_TIME + udiv_qrnnd_preinv (mptr[i], n1, n1, n0, big_base, big_base_inverted); +#else + udiv_qrnnd (mptr[i], n1, n1, n0, big_base); +#endif + } + +#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME + /* If we shifted above (at previous UDIV_NEEDS_NORMALIZATION tests) + the remainder will be up-shifted here. Compensate. */ + n1 >>= normalization_steps; +#endif + + /* Convert N1 from BIG_BASE to a string of digits in BASE + using single precision operations. */ + for (i = dig_per_u - 1; i >= 0; i--) + { + *--s = n1 % base; + n1 /= base; + if (n1 == 0 && msize == 0) + break; + } + } + + while (s != str) + *--s = 0; + return out_len; + } +} diff --git a/sysdeps/generic/getenv.c b/sysdeps/generic/getenv.c new file mode 100644 index 0000000000..d4099a9733 --- /dev/null +++ b/sysdeps/generic/getenv.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +/* Return the value of the environment variable NAME. */ +char * +DEFUN(getenv, (name), register CONST char *name) +{ + register CONST size_t len = strlen(name); + register char **ep; + + if (__environ == NULL) + return NULL; + + for (ep = __environ; *ep != NULL; ++ep) + if (!strncmp(*ep, name, len) && (*ep)[len] == '=') + return &(*ep)[len + 1]; + + return NULL; +} diff --git a/sysdeps/generic/getpgrp.c b/sysdeps/generic/getpgrp.c new file mode 100644 index 0000000000..d745b0fbf2 --- /dev/null +++ b/sysdeps/generic/getpgrp.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Get the process group ID of the calling process. */ +int +DEFUN_VOID(getpgrp) +{ + return __getpgid (0); +} diff --git a/sysdeps/generic/gmp-mparam.h b/sysdeps/generic/gmp-mparam.h new file mode 100644 index 0000000000..4286ebf03b --- /dev/null +++ b/sysdeps/generic/gmp-mparam.h @@ -0,0 +1,26 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define BITS_PER_MP_LIMB 32 +#define BYTES_PER_MP_LIMB 4 +#define BITS_PER_LONGINT 32 +#define BITS_PER_INT 32 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 diff --git a/sysdeps/generic/htonl.c b/sysdeps/generic/htonl.c new file mode 100644 index 0000000000..724ef54639 --- /dev/null +++ b/sysdeps/generic/htonl.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <netinet/in.h> + +#undef htonl + +unsigned long int +DEFUN(htonl, (x), unsigned long int x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); +#endif + + return x; +} diff --git a/sysdeps/generic/htons.c b/sysdeps/generic/htons.c new file mode 100644 index 0000000000..e3209f3e68 --- /dev/null +++ b/sysdeps/generic/htons.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <netinet/in.h> + +#undef htons + +unsigned short int +DEFUN(htons, (x), unsigned short int x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + x = (x << 8) | (x >> 8); +#endif + + return x; +} diff --git a/sysdeps/generic/hypot.c b/sysdeps/generic/hypot.c new file mode 100644 index 0000000000..a0ea8e11ea --- /dev/null +++ b/sysdeps/generic/hypot.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return `sqrt(x*x + y*y)'. */ +__CONSTVALUE double +DEFUN(hypot, (x, y), double x AND double y) +{ + return sqrt(x*x + y*y); +} diff --git a/sysdeps/generic/infnan.c b/sysdeps/generic/infnan.c new file mode 100644 index 0000000000..1102a5392d --- /dev/null +++ b/sysdeps/generic/infnan.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Deal with an infinite or NaN result. + If ERROR is ERANGE, result is +Inf; + if ERROR is - ERANGE, result is -Inf; + otherwise result is NaN. + This will set `errno' to either ERANGE or EDOM, + and may return an infinity or NaN, or may do something else. */ +double +DEFUN(__infnan, (error), int error) +{ + switch (error) + { + case ERANGE: + errno = ERANGE; + return HUGE_VAL; + + case - ERANGE: + errno = ERANGE; + return - HUGE_VAL; + + default: + errno = EDOM; + return 0.0; + } +} + +weak_alias (__infnan, infnan) diff --git a/sysdeps/generic/isnan.c b/sysdeps/generic/isnan.c new file mode 100644 index 0000000000..79b2d10567 --- /dev/null +++ b/sysdeps/generic/isnan.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return nonzero if VALUE is not a number. */ +int +DEFUN(__isnan, (value), double value) +{ + return value != value; +} + +weak_alias (__isnan, isnan) diff --git a/sysdeps/generic/ldexp.c b/sysdeps/generic/ldexp.c new file mode 100644 index 0000000000..ac5b019cc6 --- /dev/null +++ b/sysdeps/generic/ldexp.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return X times (two to the EXP power). */ +double +DEFUN(ldexp, (x, exp), register double x AND register int exp) +{ + return x * pow(2.0, (double) exp); +} diff --git a/sysdeps/generic/log.c b/sysdeps/generic/log.c new file mode 100644 index 0000000000..ae186722f8 --- /dev/null +++ b/sysdeps/generic/log.c @@ -0,0 +1,486 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)log.c 8.2 (Berkeley) 11/30/93"; +#endif /* not lint */ + +#include <math.h> +#include <errno.h> + +#include "mathimpl.h" + +/* Table-driven natural logarithm. + * + * This code was derived, with minor modifications, from: + * Peter Tang, "Table-Driven Implementation of the + * Logarithm in IEEE Floating-Point arithmetic." ACM Trans. + * Math Software, vol 16. no 4, pp 378-400, Dec 1990). + * + * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256, + * where F = j/128 for j an integer in [0, 128]. + * + * log(2^m) = log2_hi*m + log2_tail*m + * since m is an integer, the dominant term is exact. + * m has at most 10 digits (for subnormal numbers), + * and log2_hi has 11 trailing zero bits. + * + * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h + * logF_hi[] + 512 is exact. + * + * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ... + * the leading term is calculated to extra precision in two + * parts, the larger of which adds exactly to the dominant + * m and F terms. + * There are two cases: + * 1. when m, j are non-zero (m | j), use absolute + * precision for the leading term. + * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1). + * In this case, use a relative precision of 24 bits. + * (This is done differently in the original paper) + * + * Special cases: + * 0 return signalling -Inf + * neg return signalling NaN + * +Inf return +Inf +*/ + +#if defined(vax) || defined(tahoe) +#define _IEEE 0 +#define TRUNC(x) x = (double) (float) (x) +#else +#define _IEEE 1 +#define endian (((*(int *) &one)) ? 1 : 0) +#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000 +#define infnan(x) 0.0 +#endif + +#define N 128 + +/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. + * Used for generation of extend precision logarithms. + * The constant 35184372088832 is 2^45, so the divide is exact. + * It ensures correct reading of logF_head, even for inaccurate + * decimal-to-binary conversion routines. (Everybody gets the + * right answer for integers less than 2^53.) + * Values for log(F) were generated using error < 10^-57 absolute + * with the bc -l package. +*/ +static double A1 = .08333333333333178827; +static double A2 = .01250000000377174923; +static double A3 = .002232139987919447809; +static double A4 = .0004348877777076145742; + +static double logF_head[N+1] = { + 0., + .007782140442060381246, + .015504186535963526694, + .023167059281547608406, + .030771658666765233647, + .038318864302141264488, + .045809536031242714670, + .053244514518837604555, + .060624621816486978786, + .067950661908525944454, + .075223421237524235039, + .082443669210988446138, + .089612158689760690322, + .096729626458454731618, + .103796793681567578460, + .110814366340264314203, + .117783035656430001836, + .124703478501032805070, + .131576357788617315236, + .138402322859292326029, + .145182009844575077295, + .151916042025732167530, + .158605030176659056451, + .165249572895390883786, + .171850256926518341060, + .178407657472689606947, + .184922338493834104156, + .191394852999565046047, + .197825743329758552135, + .204215541428766300668, + .210564769107350002741, + .216873938300523150246, + .223143551314024080056, + .229374101064877322642, + .235566071312860003672, + .241719936886966024758, + .247836163904594286577, + .253915209980732470285, + .259957524436686071567, + .265963548496984003577, + .271933715484010463114, + .277868451003087102435, + .283768173130738432519, + .289633292582948342896, + .295464212893421063199, + .301261330578199704177, + .307025035294827830512, + .312755710004239517729, + .318453731118097493890, + .324119468654316733591, + .329753286372579168528, + .335355541920762334484, + .340926586970454081892, + .346466767346100823488, + .351976423156884266063, + .357455888922231679316, + .362905493689140712376, + .368325561158599157352, + .373716409793814818840, + .379078352934811846353, + .384411698910298582632, + .389716751140440464951, + .394993808240542421117, + .400243164127459749579, + .405465108107819105498, + .410659924985338875558, + .415827895143593195825, + .420969294644237379543, + .426084395310681429691, + .431173464818130014464, + .436236766774527495726, + .441274560805140936281, + .446287102628048160113, + .451274644139630254358, + .456237433481874177232, + .461175715122408291790, + .466089729924533457960, + .470979715219073113985, + .475845904869856894947, + .480688529345570714212, + .485507815781602403149, + .490303988045525329653, + .495077266798034543171, + .499827869556611403822, + .504556010751912253908, + .509261901790523552335, + .513945751101346104405, + .518607764208354637958, + .523248143765158602036, + .527867089620485785417, + .532464798869114019908, + .537041465897345915436, + .541597282432121573947, + .546132437597407260909, + .550647117952394182793, + .555141507540611200965, + .559615787935399566777, + .564070138285387656651, + .568504735352689749561, + .572919753562018740922, + .577315365035246941260, + .581691739635061821900, + .586049045003164792433, + .590387446602107957005, + .594707107746216934174, + .599008189645246602594, + .603290851438941899687, + .607555250224322662688, + .611801541106615331955, + .616029877215623855590, + .620240409751204424537, + .624433288012369303032, + .628608659422752680256, + .632766669570628437213, + .636907462236194987781, + .641031179420679109171, + .645137961373620782978, + .649227946625615004450, + .653301272011958644725, + .657358072709030238911, + .661398482245203922502, + .665422632544505177065, + .669430653942981734871, + .673422675212350441142, + .677398823590920073911, + .681359224807238206267, + .685304003098281100392, + .689233281238557538017, + .693147180560117703862 +}; + +static double logF_tail[N+1] = { + 0., + -.00000000000000543229938420049, + .00000000000000172745674997061, + -.00000000000001323017818229233, + -.00000000000001154527628289872, + -.00000000000000466529469958300, + .00000000000005148849572685810, + -.00000000000002532168943117445, + -.00000000000005213620639136504, + -.00000000000001819506003016881, + .00000000000006329065958724544, + .00000000000008614512936087814, + -.00000000000007355770219435028, + .00000000000009638067658552277, + .00000000000007598636597194141, + .00000000000002579999128306990, + -.00000000000004654729747598444, + -.00000000000007556920687451336, + .00000000000010195735223708472, + -.00000000000017319034406422306, + -.00000000000007718001336828098, + .00000000000010980754099855238, + -.00000000000002047235780046195, + -.00000000000008372091099235912, + .00000000000014088127937111135, + .00000000000012869017157588257, + .00000000000017788850778198106, + .00000000000006440856150696891, + .00000000000016132822667240822, + -.00000000000007540916511956188, + -.00000000000000036507188831790, + .00000000000009120937249914984, + .00000000000018567570959796010, + -.00000000000003149265065191483, + -.00000000000009309459495196889, + .00000000000017914338601329117, + -.00000000000001302979717330866, + .00000000000023097385217586939, + .00000000000023999540484211737, + .00000000000015393776174455408, + -.00000000000036870428315837678, + .00000000000036920375082080089, + -.00000000000009383417223663699, + .00000000000009433398189512690, + .00000000000041481318704258568, + -.00000000000003792316480209314, + .00000000000008403156304792424, + -.00000000000034262934348285429, + .00000000000043712191957429145, + -.00000000000010475750058776541, + -.00000000000011118671389559323, + .00000000000037549577257259853, + .00000000000013912841212197565, + .00000000000010775743037572640, + .00000000000029391859187648000, + -.00000000000042790509060060774, + .00000000000022774076114039555, + .00000000000010849569622967912, + -.00000000000023073801945705758, + .00000000000015761203773969435, + .00000000000003345710269544082, + -.00000000000041525158063436123, + .00000000000032655698896907146, + -.00000000000044704265010452446, + .00000000000034527647952039772, + -.00000000000007048962392109746, + .00000000000011776978751369214, + -.00000000000010774341461609578, + .00000000000021863343293215910, + .00000000000024132639491333131, + .00000000000039057462209830700, + -.00000000000026570679203560751, + .00000000000037135141919592021, + -.00000000000017166921336082431, + -.00000000000028658285157914353, + -.00000000000023812542263446809, + .00000000000006576659768580062, + -.00000000000028210143846181267, + .00000000000010701931762114254, + .00000000000018119346366441110, + .00000000000009840465278232627, + -.00000000000033149150282752542, + -.00000000000018302857356041668, + -.00000000000016207400156744949, + .00000000000048303314949553201, + -.00000000000071560553172382115, + .00000000000088821239518571855, + -.00000000000030900580513238244, + -.00000000000061076551972851496, + .00000000000035659969663347830, + .00000000000035782396591276383, + -.00000000000046226087001544578, + .00000000000062279762917225156, + .00000000000072838947272065741, + .00000000000026809646615211673, + -.00000000000010960825046059278, + .00000000000002311949383800537, + -.00000000000058469058005299247, + -.00000000000002103748251144494, + -.00000000000023323182945587408, + -.00000000000042333694288141916, + -.00000000000043933937969737844, + .00000000000041341647073835565, + .00000000000006841763641591466, + .00000000000047585534004430641, + .00000000000083679678674757695, + -.00000000000085763734646658640, + .00000000000021913281229340092, + -.00000000000062242842536431148, + -.00000000000010983594325438430, + .00000000000065310431377633651, + -.00000000000047580199021710769, + -.00000000000037854251265457040, + .00000000000040939233218678664, + .00000000000087424383914858291, + .00000000000025218188456842882, + -.00000000000003608131360422557, + -.00000000000050518555924280902, + .00000000000078699403323355317, + -.00000000000067020876961949060, + .00000000000016108575753932458, + .00000000000058527188436251509, + -.00000000000035246757297904791, + -.00000000000018372084495629058, + .00000000000088606689813494916, + .00000000000066486268071468700, + .00000000000063831615170646519, + .00000000000025144230728376072, + -.00000000000017239444525614834 +}; + +double +#ifdef _ANSI_SOURCE +log(double x) +#else +log(x) double x; +#endif +{ + int m, j; + double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0; + volatile double u1; + + /* Catch special cases */ + if (x <= 0) + if (_IEEE && x == zero) /* log(0) = -Inf */ + return (-one/zero); + else if (_IEEE) /* log(neg) = NaN */ + return (zero/zero); + else if (x == zero) /* NOT REACHED IF _IEEE */ + return (infnan(-ERANGE)); + else + return (infnan(EDOM)); + else if (!finite(x)) + if (_IEEE) /* x = NaN, Inf */ + return (x+x); + else + return (infnan(ERANGE)); + + /* Argument reduction: 1 <= g < 2; x/2^m = g; */ + /* y = F*(1 + f/F) for |f| <= 2^-8 */ + + m = logb(x); + g = ldexp(x, -m); + if (_IEEE && m == -1022) { + j = logb(g), m += j; + g = ldexp(g, -j); + } + j = N*(g-1) + .5; + F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */ + f = g - F; + + /* Approximate expansion for log(1+f/F) ~= u + q */ + g = 1/(2*F+f); + u = 2*f*g; + v = u*u; + q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); + + /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8, + * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits. + * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750 + */ + if (m | j) + u1 = u + 513, u1 -= 513; + + /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero; + * u1 = u to 24 bits. + */ + else + u1 = u, TRUNC(u1); + u2 = (2.0*(f - F*u1) - u1*f) * g; + /* u1 + u2 = 2f/(2F+f) to extra precision. */ + + /* log(x) = log(2^m*F*(1+f/F)) = */ + /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */ + /* (exact) + (tiny) */ + + u1 += m*logF_head[N] + logF_head[j]; /* exact */ + u2 = (u2 + logF_tail[j]) + q; /* tiny */ + u2 += logF_tail[N]*m; + return (u1 + u2); +} + +/* + * Extra precision variant, returning struct {double a, b;}; + * log(x) = a+b to 63 bits, with a is rounded to 26 bits. + */ +struct Double +#ifdef _ANSI_SOURCE +__log__D(double x) +#else +__log__D(x) double x; +#endif +{ + int m, j; + double F, f, g, q, u, v, u2, one = 1.0; + volatile double u1; + struct Double r; + + /* Argument reduction: 1 <= g < 2; x/2^m = g; */ + /* y = F*(1 + f/F) for |f| <= 2^-8 */ + + m = logb(x); + g = ldexp(x, -m); + if (_IEEE && m == -1022) { + j = logb(g), m += j; + g = ldexp(g, -j); + } + j = N*(g-1) + .5; + F = (1.0/N) * j + 1; + f = g - F; + + g = 1/(2*F+f); + u = 2*f*g; + v = u*u; + q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); + if (m | j) + u1 = u + 513, u1 -= 513; + else + u1 = u, TRUNC(u1); + u2 = (2.0*(f - F*u1) - u1*f) * g; + + u1 += m*logF_head[N] + logF_head[j]; + + u2 += logF_tail[j]; u2 += q; + u2 += logF_tail[N]*m; + r.a = u1 + u2; /* Only difference is here */ + TRUNC(r.a); + r.b = (u1 - r.a) + u2; + return (r); +} diff --git a/sysdeps/generic/log10.c b/sysdeps/generic/log10.c new file mode 100644 index 0000000000..df52d542be --- /dev/null +++ b/sysdeps/generic/log10.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +#ifndef LN10 +#define LN10 log(10.0) +#endif + +/* Return the base-ten logarithm of X. */ +double +DEFUN(log10, (x), double x) +{ + static double ln10 = 0.0; + + if (ln10 == 0.0) + ln10 = LN10; + + return log(x) / ln10; +} diff --git a/sysdeps/generic/log1p.c b/sysdeps/generic/log1p.c new file mode 100644 index 0000000000..cbf9fcd895 --- /dev/null +++ b/sysdeps/generic/log1p.c @@ -0,0 +1,170 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)log1p.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* LOG1P(x) + * RETURN THE LOGARITHM OF 1+x + * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/19/85; + * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85. + * + * Required system supported functions: + * scalb(x,n) + * copysign(x,y) + * logb(x) + * finite(x) + * + * Required kernel function: + * log__L(z) + * + * Method : + * 1. Argument Reduction: find k and f such that + * 1+x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * log(1+f) is computed by + * + * log(1+f) = 2s + s*log__L(s*s) + * where + * log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...))) + * + * See log__L() for the values of the coefficients. + * + * 3. Finally, log(1+x) = k*ln2 + log(1+f). + * + * Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers + * n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last + * 20 bits (for VAX D format), or the last 21 bits ( for IEEE + * double) is 0. This ensures n*ln2hi is exactly representable. + * 2. In step 1, f may not be representable. A correction term c + * for f is computed. It follows that the correction term for + * f - t (the leading term of log(1+f) in step 2) is c-c*x. We + * add this correction term to n*ln2lo to attenuate the error. + * + * + * Special cases: + * log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal; + * log1p(INF) is +INF; log1p(-1) is -INF with signal; + * only log1p(0)=0 is exact for finite argument. + * + * Accuracy: + * log1p(x) returns the exact log(1+x) nearly rounded. In a test run + * with 1,536,000 random arguments on a VAX, the maximum observed + * error was .846 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include <errno.h> +#include "mathimpl.h" + +vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000) +vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC) +vc(sqrt2, 1.4142135623730950622E0 ,04f3,40b5,de65,33f9, 1, .B504F333F9DE65) + +ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000) +ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76) +ic(sqrt2, 1.4142135623730951455E0, 0, 1.6A09E667F3BCD) + +#ifdef vccast +#define ln2hi vccast(ln2hi) +#define ln2lo vccast(ln2lo) +#define sqrt2 vccast(sqrt2) +#endif + +double log1p(x) +double x; +{ + const static double zero=0.0, negone= -1.0, one=1.0, + half=1.0/2.0, small=1.0E-20; /* 1+small == 1 */ + double z,s,t,c; + int k; + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + + if(finite(x)) { + if( x > negone ) { + + /* argument reduction */ + if(copysign(x,one)<small) return(x); + k=logb(one+x); z=scalb(x,-k); t=scalb(one,-k); + if(z+t >= sqrt2 ) + { k += 1 ; z *= half; t *= half; } + t += negone; x = z + t; + c = (t-x)+z ; /* correction term for x */ + + /* compute log(1+x) */ + s = x/(2+x); t = x*x*half; + c += (k*ln2lo-c*x); + z = c+s*(t+__log__L(s*s)); + x += (z - t) ; + + return(k*ln2hi+x); + } + /* end of if (x > negone) */ + + else { +#if defined(vax)||defined(tahoe) + if ( x == negone ) + return (infnan(-ERANGE)); /* -INF */ + else + return (infnan(EDOM)); /* NaN */ +#else /* defined(vax)||defined(tahoe) */ + /* x = -1, return -INF with signal */ + if ( x == negone ) return( negone/zero ); + + /* negative argument for log, return NaN with signal */ + else return ( zero / zero ); +#endif /* defined(vax)||defined(tahoe) */ + } + } + /* end of if (finite(x)) */ + + /* log(-INF) is NaN */ + else if(x<0) + return(zero/zero); + + /* log(+INF) is INF */ + else return(x); +} diff --git a/sysdeps/generic/log__L.c b/sysdeps/generic/log__L.c new file mode 100644 index 0000000000..c00158fa51 --- /dev/null +++ b/sysdeps/generic/log__L.c @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)log__L.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* log__L(Z) + * LOG(1+X) - 2S X + * RETURN --------------- WHERE Z = S*S, S = ------- , 0 <= Z <= .0294... + * S 2 + X + * + * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS) + * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS + * CODED IN C BY K.C. NG, 1/19/85; + * REVISED BY K.C. Ng, 2/3/85, 4/16/85. + * + * Method : + * 1. Polynomial approximation: let s = x/(2+x). + * Based on log(1+x) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * + * (log(1+x) - 2s)/s is computed by + * + * z*(L1 + z*(L2 + z*(... (L7 + z*L8)...))) + * + * where z=s*s. (See the listing below for Lk's values.) The + * coefficients are obtained by a special Remez algorithm. + * + * Accuracy: + * Assuming no rounding error, the maximum magnitude of the approximation + * error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63) + * for VAX D format. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(L1, 6.6666666666666703212E-1 ,aaaa,402a,aac5,aaaa, 0, .AAAAAAAAAAAAC5) +vc(L2, 3.9999999999970461961E-1 ,cccc,3fcc,2684,cccc, -1, .CCCCCCCCCC2684) +vc(L3, 2.8571428579395698188E-1 ,4924,3f92,5782,92f8, -1, .92492492F85782) +vc(L4, 2.2222221233634724402E-1 ,8e38,3f63,af2c,39b7, -2, .E38E3839B7AF2C) +vc(L5, 1.8181879517064680057E-1 ,2eb4,3f3a,655e,cc39, -2, .BA2EB4CC39655E) +vc(L6, 1.5382888777946145467E-1 ,8551,3f1d,781d,e8c5, -2, .9D8551E8C5781D) +vc(L7, 1.3338356561139403517E-1 ,95b3,3f08,cd92,907f, -2, .8895B3907FCD92) +vc(L8, 1.2500000000000000000E-1 ,0000,3f00,0000,0000, -2, .80000000000000) + +ic(L1, 6.6666666666667340202E-1, -1, 1.5555555555592) +ic(L2, 3.9999999999416702146E-1, -2, 1.999999997FF24) +ic(L3, 2.8571428742008753154E-1, -2, 1.24924941E07B4) +ic(L4, 2.2222198607186277597E-1, -3, 1.C71C52150BEA6) +ic(L5, 1.8183562745289935658E-1, -3, 1.74663CC94342F) +ic(L6, 1.5314087275331442206E-1, -3, 1.39A1EC014045B) +ic(L7, 1.4795612545334174692E-1, -3, 1.2F039F0085122) + +#ifdef vccast +#define L1 vccast(L1) +#define L2 vccast(L2) +#define L3 vccast(L3) +#define L4 vccast(L4) +#define L5 vccast(L5) +#define L6 vccast(L6) +#define L7 vccast(L7) +#define L8 vccast(L8) +#endif + +double __log__L(z) +double z; +{ +#if defined(vax)||defined(tahoe) + return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*(L7+z*L8)))))))); +#else /* defined(vax)||defined(tahoe) */ + return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*L7))))))); +#endif /* defined(vax)||defined(tahoe) */ +} diff --git a/sysdeps/generic/lshift.c b/sysdeps/generic/lshift.c new file mode 100644 index 0000000000..1ba09038dd --- /dev/null +++ b/sysdeps/generic/lshift.c @@ -0,0 +1,86 @@ +/* __mpn_lshift -- Shift left low level. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left + and store the USIZE least significant digits of the result at WP. + Return the bits shifted out from the most significant digit. + + Argument constraints: + 1. 0 < CNT < BITS_PER_MP_LIMB + 2. If the result is to be written over the input, WP must be >= UP. +*/ + +mp_limb +#if __STDC__ +__mpn_lshift (register mp_ptr wp, + register mp_srcptr up, mp_size_t usize, + register unsigned int cnt) +#else +__mpn_lshift (wp, up, usize, cnt) + register mp_ptr wp; + register mp_srcptr up; + mp_size_t usize; + register unsigned int cnt; +#endif +{ + register mp_limb high_limb, low_limb; + register unsigned sh_1, sh_2; + register mp_size_t i; + mp_limb retval; + +#ifdef DEBUG + if (usize == 0 || cnt == 0) + abort (); +#endif + + sh_1 = cnt; +#if 0 + if (sh_1 == 0) + { + if (wp != up) + { + /* Copy from high end to low end, to allow specified input/output + overlapping. */ + for (i = usize - 1; i >= 0; i--) + wp[i] = up[i]; + } + return 0; + } +#endif + + wp += 1; + sh_2 = BITS_PER_MP_LIMB - sh_1; + i = usize - 1; + low_limb = up[i]; + retval = low_limb >> sh_2; + high_limb = low_limb; + while (--i >= 0) + { + low_limb = up[i]; + wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); + high_limb = low_limb; + } + wp[i] = high_limb << sh_1; + + return retval; +} diff --git a/sysdeps/generic/lstat.c b/sysdeps/generic/lstat.c new file mode 100644 index 0000000000..44fafa6f4d --- /dev/null +++ b/sysdeps/generic/lstat.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +int +DEFUN(__lstat, (file, buf), + CONST char *file AND struct stat *buf) +{ + return __stat (file, buf); +} + +weak_alias (__lstat, lstat) diff --git a/sysdeps/generic/make_siglist.c b/sysdeps/generic/make_siglist.c new file mode 100644 index 0000000000..34abf80513 --- /dev/null +++ b/sysdeps/generic/make_siglist.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <signal.h> +#include <stdio.h> + + +/* Make a definition for sys_siglist. */ + + +#undef HAVE_SYS_SIGLIST +#define sys_siglist my_siglist /* Avoid clash with signal.h. */ + +#include "signame.c" + + +int +main() +{ + register int i; + + signame_init (); + + puts ("#include \"ansidecl.h\"\n#include <stddef.h>\n"); + + puts ("\n/* This is a list of all known signal numbers. */"); + + puts ("\nCONST char *CONST _sys_siglist[] =\n {"); + + for (i = 0; i < NSIG; ++i) + printf (" \"%s\",\n", sys_siglist[i]); + + puts (" NULL\n };\n"); + + puts ("weak_alias (_sys_siglist, sys_siglist)"); + exit (0); +} diff --git a/sysdeps/generic/mathimpl.h b/sysdeps/generic/mathimpl.h new file mode 100644 index 0000000000..a2c963d288 --- /dev/null +++ b/sysdeps/generic/mathimpl.h @@ -0,0 +1,127 @@ +/* This part here added by roland@prep.ai.mit.edu for the GNU C library. */ + +#include <math.h> /* Done first so we can #undef. */ +#include <endian.h> +#if __BYTE_ORDER == __LITTLE_ENDIAN +#undef national +#define national +#endif + +#undef isinf +#define isinf __isinf +#undef isnan +#define isnan __isnan +#undef infnan +#define infnan __infnan +#undef copysign +#define copysign __copysign +#undef scalb +#define scalb __scalb +#undef drem +#define drem __drem +#undef logb +#define logb __logb +#undef __finite +#undef finite +#define finite __finite +#undef expm1 +#define expm1 __expm1 + +/* + * 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. + * + * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93 + */ + +#include <sys/cdefs.h> +#include <math.h> + +#if defined(vax)||defined(tahoe) + +/* Deal with different ways to concatenate in cpp */ +# ifdef __STDC__ +# define cat3(a,b,c) a ## b ## c +# else +# define cat3(a,b,c) a/**/b/**/c +# endif + +/* Deal with vax/tahoe byte order issues */ +# ifdef vax +# define cat3t(a,b,c) cat3(a,b,c) +# else +# define cat3t(a,b,c) cat3(a,c,b) +# endif + +# define vccast(name) (*(const double *)(cat3(name,,x))) + + /* + * Define a constant to high precision on a Vax or Tahoe. + * + * Args are the name to define, the decimal floating point value, + * four 16-bit chunks of the float value in hex + * (because the vax and tahoe differ in float format!), the power + * of 2 of the hex-float exponent, and the hex-float mantissa. + * Most of these arguments are not used at compile time; they are + * used in a post-check to make sure the constants were compiled + * correctly. + * + * People who want to use the constant will have to do their own + * #define foo vccast(foo) + * since CPP cannot do this for them from inside another macro (sigh). + * We define "vccast" if this needs doing. + */ +# define vc(name, value, x1,x2,x3,x4, bexp, xval) \ + const static long cat3(name,,x)[] = {cat3t(0x,x1,x2), cat3t(0x,x3,x4)}; + +# define ic(name, value, bexp, xval) ; + +#else /* vax or tahoe */ + + /* Hooray, we have an IEEE machine */ +# undef vccast +# define vc(name, value, x1,x2,x3,x4, bexp, xval) ; + +# define ic(name, value, bexp, xval) \ + const static double name = value; + +#endif /* defined(vax)||defined(tahoe) */ + + +/* + * Functions internal to the math package, yet not static. + */ +extern double __exp__E(); +extern double __log__L(); + +struct Double {double a, b;}; +double __exp__D __P((double, double)); +struct Double __log__D __P((double)); diff --git a/sysdeps/generic/memccpy.c b/sysdeps/generic/memccpy.c new file mode 100644 index 0000000000..b905952527 --- /dev/null +++ b/sysdeps/generic/memccpy.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> /* For size_t and NULL. */ + + +/* + * Copy no more than N bytes of SRC to DEST, stopping when C is found. + * Return the position in DEST one byte past where C was copied, + * or NULL if C was not found in the first N bytes of SRC. + */ +PTR +DEFUN(__memccpy, (dest, src, c, n), + PTR dest AND CONST PTR src AND int c AND size_t n) +{ + register CONST char *s = src; + register char *d = dest; + register CONST int x = (unsigned char) c; + register size_t i = n; + + while (i-- > 0) + if ((*d++ = *s++) == x) + return d; + + return NULL; +} + +weak_alias (__memccpy, memccpy) diff --git a/sysdeps/generic/memchr.c b/sysdeps/generic/memchr.c new file mode 100644 index 0000000000..d17f9c649e --- /dev/null +++ b/sysdeps/generic/memchr.c @@ -0,0 +1,168 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Based on strlen implemention by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Search no more than N bytes of S for C. */ + +PTR +DEFUN(memchr, (s, c, n), CONST PTR s AND int c AND size_t n) +{ + CONST unsigned char *char_ptr; + CONST unsigned long int *longword_ptr; + unsigned long int longword, magic_bits, charmask; + + c = (unsigned char) c; + + /* Handle the first few characters by reading one character at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = s; n > 0 && ((unsigned long int) char_ptr + & (sizeof (longword) - 1)) != 0; + --n, ++char_ptr) + if (*char_ptr == c) + return (PTR) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to 8-byte longwords. */ + + longword_ptr = (unsigned long int *) char_ptr; + + /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits + the "holes." Note that there is a hole just to the left of + each byte, with an extra at the end: + + bits: 01111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD + + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ + switch (sizeof (longword)) + { + case 4: magic_bits = 0x7efefeffL; break; + case 8: magic_bits = (0x7efefefeL << 32) | 0xfefefeffL; break; + default: + abort (); + } + + /* Set up a longword, each of whose bytes is C. */ + charmask = c | (c << 8); + charmask |= charmask << 16; + if (sizeof (longword) > 4) + charmask |= charmask << 32; + if (sizeof (longword) > 8) + abort (); + + /* Instead of the traditional loop which tests each character, + we will test a longword at a time. The tricky part is testing + if *any of the four* bytes in the longword in question are zero. */ + while (n >= sizeof (longword)) + { + /* We tentatively exit the loop if adding MAGIC_BITS to + LONGWORD fails to change any of the hole bits of LONGWORD. + + 1) Is this safe? Will it catch all the zero bytes? + Suppose there is a byte with all zeros. Any carry bits + propagating from its left will fall into the hole at its + least significant bit and stop. Since there will be no + carry from its most significant bit, the LSB of the + byte to the left will be unchanged, and the zero will be + detected. + + 2) Is this worthwhile? Will it ignore everything except + zero bytes? Suppose every byte of LONGWORD has a bit set + somewhere. There will be a carry into bit 8. If bit 8 + is set, this will carry into bit 16. If bit 8 is clear, + one of bits 9-15 must be set, so there will be a carry + into bit 16. Similarly, there will be a carry into bit + 24. If one of bits 24-30 is set, there will be a carry + into bit 31, so all of the hole bits will be changed. + + The one misfire occurs when bits 24-30 are clear and bit + 31 is set; in this case, the hole at bit 31 is not + changed. If we had access to the processor carry flag, + we could close this loophole by putting the fourth hole + at bit 32! + + So it ignores everything except 128's, when they're aligned + properly. + + 3) But wait! Aren't we looking for C, not zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + + longword = *longword_ptr++ ^ charmask; + + /* Add MAGIC_BITS to LONGWORD. */ + if ((((longword + magic_bits) + + /* Set those bits that were unchanged by the addition. */ + ^ ~longword) + + /* Look at only the hole bits. If any of the hole bits + are unchanged, most likely one of the bytes was a + zero. */ + & ~magic_bits) != 0) + { + /* Which of the bytes was C? If none of them were, it was + a misfire; continue the search. */ + + CONST unsigned char *cp = (CONST unsigned char *) (longword_ptr - 1); + + if (cp[0] == c) + return (PTR) cp; + if (cp[1] == c) + return (PTR) &cp[1]; + if (cp[2] == c) + return (PTR) &cp[2]; + if (cp[3] == c) + return (PTR) &cp[3]; + if (sizeof (longword) > 4) + { + if (cp[4] == c) + return (PTR) &cp[4]; + if (cp[5] == c) + return (PTR) &cp[5]; + if (cp[6] == c) + return (PTR) &cp[6]; + if (cp[7] == c) + return (PTR) &cp[7]; + } + } + + n -= sizeof (longword); + } + + char_ptr = (CONST unsigned char *) longword_ptr; + + while (n-- > 0) + { + if (*char_ptr == c) + return (PTR) char_ptr; + else + ++char_ptr; + } + + return NULL; +} diff --git a/sysdeps/generic/memcmp.c b/sysdeps/generic/memcmp.c new file mode 100644 index 0000000000..8f5eca0b6b --- /dev/null +++ b/sysdeps/generic/memcmp.c @@ -0,0 +1,369 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#undef __ptr_t +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#define __ptr_t void * +#else /* Not C++ or ANSI C. */ +#undef const +#define const +#define __ptr_t char * +#endif /* C++ or ANSI C. */ + +#if defined (HAVE_STRING_H) || defined (_LIBC) +#include <string.h> +#endif + +#ifdef _LIBC + +#include <memcopy.h> + +#else /* Not in the GNU C library. */ + +#include <sys/types.h> + +/* Type to use for aligned memory operations. + This should normally be the biggest type supported by a single load + and store. Must be an unsigned type. */ +#define op_t unsigned long int +#define OPSIZ (sizeof(op_t)) + +/* Threshold value for when to enter the unrolled loops. */ +#define OP_T_THRES 16 + +/* Type to use for unaligned operations. */ +typedef unsigned char byte; + +#ifndef WORDS_BIGENDIAN +#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2))) +#else +#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2))) +#endif + +#endif /* In the GNU C library. */ + +#ifdef WORDS_BIGENDIAN +#define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1) +#else +#define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b)) +#endif + +/* BE VERY CAREFUL IF YOU CHANGE THIS CODE! */ + +/* The strategy of this memcmp is: + + 1. Compare bytes until one of the block pointers is aligned. + + 2. Compare using memcmp_common_alignment or + memcmp_not_common_alignment, regarding the alignment of the other + block after the initial byte operations. The maximum number of + full words (of type op_t) are compared in this way. + + 3. Compare the few remaining bytes. */ + +#ifndef WORDS_BIGENDIAN +/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine. + A and B are known to be different. + This is needed only on little-endian machines. */ +#ifdef __GNUC__ +__inline +#endif +static int +memcmp_bytes (a, b) + op_t a, b; +{ + long int srcp1 = (long int) &a; + long int srcp2 = (long int) &b; + op_t a0, b0; + + do + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + } + while (a0 == b0); + return a0 - b0; +} +#endif + +/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t' + objects (not LEN bytes!). Both SRCP1 and SRCP2 should be aligned for + memory operations on `op_t's. */ +#ifdef __GNUC__ +__inline +#endif +static int +memcmp_common_alignment (srcp1, srcp2, len) + long int srcp1; + long int srcp2; + size_t len; +{ + op_t a0, a1; + op_t b0, b1; + + switch (len % 4) + { + case 2: + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + srcp1 -= 2 * OPSIZ; + srcp2 -= 2 * OPSIZ; + len += 2; + goto do1; + case 3: + a1 = ((op_t *) srcp1)[0]; + b1 = ((op_t *) srcp2)[0]; + srcp1 -= OPSIZ; + srcp2 -= OPSIZ; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return 0; + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + goto do3; + case 1: + a1 = ((op_t *) srcp1)[0]; + b1 = ((op_t *) srcp2)[0]; + srcp1 += OPSIZ; + srcp2 += OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + /* Fall through. */ + } + + do + { + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + + do3: + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[1]; + if (a0 != b0) + return CMP_LT_OR_GT (a0, b0); + + do2: + a0 = ((op_t *) srcp1)[2]; + b0 = ((op_t *) srcp2)[2]; + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + + do1: + a1 = ((op_t *) srcp1)[3]; + b1 = ((op_t *) srcp2)[3]; + if (a0 != b0) + return CMP_LT_OR_GT (a0, b0); + + srcp1 += 4 * OPSIZ; + srcp2 += 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + if (a1 != b1) + return CMP_LT_OR_GT (a1, b1); + return 0; +} + +/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN + `op_t' objects (not LEN bytes!). SRCP2 should be aligned for memory + operations on `op_t', but SRCP1 *should be unaligned*. */ +#ifdef __GNUC__ +__inline +#endif +static int +memcmp_not_common_alignment (srcp1, srcp2, len) + long int srcp1; + long int srcp2; + size_t len; +{ + op_t a0, a1, a2, a3; + op_t b0, b1, b2, b3; + op_t x; + int shl, shr; + + /* Calculate how to shift a word read at the memory operation + aligned srcp1 to make it aligned for comparison. */ + + shl = 8 * (srcp1 % OPSIZ); + shr = 8 * OPSIZ - shl; + + /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t' + it points in the middle of. */ + srcp1 &= -OPSIZ; + + switch (len % 4) + { + case 2: + a1 = ((op_t *) srcp1)[0]; + a2 = ((op_t *) srcp1)[1]; + b2 = ((op_t *) srcp2)[0]; + srcp1 -= 1 * OPSIZ; + srcp2 -= 2 * OPSIZ; + len += 2; + goto do1; + case 3: + a0 = ((op_t *) srcp1)[0]; + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[0]; + srcp2 -= 1 * OPSIZ; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return 0; + a3 = ((op_t *) srcp1)[0]; + a0 = ((op_t *) srcp1)[1]; + b0 = ((op_t *) srcp2)[0]; + srcp1 += 1 * OPSIZ; + goto do3; + case 1: + a2 = ((op_t *) srcp1)[0]; + a3 = ((op_t *) srcp1)[1]; + b3 = ((op_t *) srcp2)[0]; + srcp1 += 2 * OPSIZ; + srcp2 += 1 * OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + /* Fall through. */ + } + + do + { + a0 = ((op_t *) srcp1)[0]; + b0 = ((op_t *) srcp2)[0]; + x = MERGE(a2, shl, a3, shr); + if (x != b3) + return CMP_LT_OR_GT (x, b3); + + do3: + a1 = ((op_t *) srcp1)[1]; + b1 = ((op_t *) srcp2)[1]; + x = MERGE(a3, shl, a0, shr); + if (x != b0) + return CMP_LT_OR_GT (x, b0); + + do2: + a2 = ((op_t *) srcp1)[2]; + b2 = ((op_t *) srcp2)[2]; + x = MERGE(a0, shl, a1, shr); + if (x != b1) + return CMP_LT_OR_GT (x, b1); + + do1: + a3 = ((op_t *) srcp1)[3]; + b3 = ((op_t *) srcp2)[3]; + x = MERGE(a1, shl, a2, shr); + if (x != b2) + return CMP_LT_OR_GT (x, b2); + + srcp1 += 4 * OPSIZ; + srcp2 += 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + x = MERGE(a2, shl, a3, shr); + if (x != b3) + return CMP_LT_OR_GT (x, b3); + return 0; +} + +int +memcmp (s1, s2, len) + const __ptr_t s1; + const __ptr_t s2; + size_t len; +{ + op_t a0; + op_t b0; + long int srcp1 = (long int) s1; + long int srcp2 = (long int) s2; + op_t res; + + if (len >= OP_T_THRES) + { + /* There are at least some bytes to compare. No need to test + for LEN == 0 in this alignment loop. */ + while (srcp2 % OPSIZ != 0) + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + res = a0 - b0; + if (res != 0) + return res; + len -= 1; + } + + /* SRCP2 is now aligned for memory operations on `op_t'. + SRCP1 alignment determines if we can do a simple, + aligned compare or need to shuffle bits. */ + + if (srcp1 % OPSIZ == 0) + res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ); + else + res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ); + if (res != 0) + return res; + + /* Number of bytes remaining in the interval [0..OPSIZ-1]. */ + srcp1 += len & -OPSIZ; + srcp2 += len & -OPSIZ; + len %= OPSIZ; + } + + /* There are just a few bytes to compare. Use byte memory operations. */ + while (len != 0) + { + a0 = ((byte *) srcp1)[0]; + b0 = ((byte *) srcp2)[0]; + srcp1 += 1; + srcp2 += 1; + res = a0 - b0; + if (res != 0) + return res; + len -= 1; + } + + return 0; +} + +#ifdef weak_alias +#undef bcmp +weak_alias (memcmp, bcmp) +#endif diff --git a/sysdeps/generic/memcopy.h b/sysdeps/generic/memcopy.h new file mode 100644 index 0000000000..262b8aae4c --- /dev/null +++ b/sysdeps/generic/memcopy.h @@ -0,0 +1,149 @@ +/* memcopy.h -- definitions for memory copy functions. Generic C version. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* The strategy of the memory functions is: + + 1. Copy bytes until the destination pointer is aligned. + + 2. Copy words in unrolled loops. If the source and destination + are not aligned in the same way, use word memory operations, + but shift and merge two read words before writing. + + 3. Copy the few remaining bytes. + + This is fast on processors that have at least 10 registers for + allocation by GCC, and that can access memory at reg+const in one + instruction. + + I made an "exhaustive" test of this memmove when I wrote it, + exhaustive in the sense that I tried all alignment and length + combinations, with and without overlap. */ + +#include <sys/cdefs.h> +#include <endian.h> + +/* The macros defined in this file are: + + BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy) + + BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy) + + WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy) + + WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy) + + MERGE(old_word, sh_1, new_word, sh_2) + [I fail to understand. I feel stupid. --roland] +*/ + +/* Type to use for aligned memory operations. + This should normally be the biggest type supported by a single load + and store. */ +#define op_t unsigned long int +#define OPSIZ (sizeof(op_t)) + +/* Type to use for unaligned operations. */ +typedef unsigned char byte; + +/* Optimal type for storing bytes in registers. */ +#define reg_char char + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2))) +#endif +#if __BYTE_ORDER == __BIG_ENDIAN +#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2))) +#endif + +/* Copy exactly NBYTES bytes from SRC_BP to DST_BP, + without any assumptions about alignment of the pointers. */ +#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \ + do \ + { \ + size_t __nbytes = (nbytes); \ + while (__nbytes > 0) \ + { \ + byte __x = ((byte *) src_bp)[0]; \ + src_bp += 1; \ + __nbytes -= 1; \ + ((byte *) dst_bp)[0] = __x; \ + dst_bp += 1; \ + } \ + } while (0) + +/* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR, + beginning at the bytes right before the pointers and continuing towards + smaller addresses. Don't assume anything about alignment of the + pointers. */ +#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \ + do \ + { \ + size_t __nbytes = (nbytes); \ + while (__nbytes > 0) \ + { \ + byte __x; \ + src_ep -= 1; \ + __x = ((byte *) src_ep)[0]; \ + dst_ep -= 1; \ + __nbytes -= 1; \ + ((byte *) dst_ep)[0] = __x; \ + } \ + } while (0) + +/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with + the assumption that DST_BP is aligned on an OPSIZ multiple. If + not all bytes could be easily copied, store remaining number of bytes + in NBYTES_LEFT, otherwise store 0. */ +extern void _wordcopy_fwd_aligned __P ((long int, long int, size_t)); +extern void _wordcopy_fwd_dest_aligned __P ((long int, long int, size_t)); +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + if (src_bp % OPSIZ == 0) \ + _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \ + else \ + _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \ + src_bp += (nbytes) & -OPSIZ; \ + dst_bp += (nbytes) & -OPSIZ; \ + (nbytes_left) = (nbytes) % OPSIZ; \ + } while (0) + +/* Copy *up to* NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR, + beginning at the words (of type op_t) right before the pointers and + continuing towards smaller addresses. May take advantage of that + DST_END_PTR is aligned on an OPSIZ multiple. If not all bytes could be + easily copied, store remaining number of bytes in NBYTES_REMAINING, + otherwise store 0. */ +extern void _wordcopy_bwd_aligned __P ((long int, long int, size_t)); +extern void _wordcopy_bwd_dest_aligned __P ((long int, long int, size_t)); +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + if (src_ep % OPSIZ == 0) \ + _wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \ + else \ + _wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \ + src_ep -= (nbytes) & -OPSIZ; \ + dst_ep -= (nbytes) & -OPSIZ; \ + (nbytes_left) = (nbytes) % OPSIZ; \ + } while (0) + + +/* Threshold value for when to enter the unrolled loops. */ +#define OP_T_THRES 16 diff --git a/sysdeps/generic/memcpy.c b/sysdeps/generic/memcpy.c new file mode 100644 index 0000000000..222d358224 --- /dev/null +++ b/sysdeps/generic/memcpy.c @@ -0,0 +1,55 @@ +/* memcpy -- copy memory to memory until the specified number of bytes + has been copied. Overlap is NOT handled correctly. + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +PTR +DEFUN(memcpy, (dstpp, srcpp, len), + PTR dstpp AND CONST PTR srcpp AND size_t len) +{ + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; + + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); + + /* Copy from SRCP to DSTP taking advantage of the known + alignment of DSTP. Number of bytes remaining is put + in the third argumnet, i.e. in LEN. This number may + vary from machine to machine. */ + + WORD_COPY_FWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD (dstp, srcp, len); + + return dstpp; +} diff --git a/sysdeps/generic/memmem.c b/sysdeps/generic/memmem.c new file mode 100644 index 0000000000..79b4544db5 --- /dev/null +++ b/sysdeps/generic/memmem.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <string.h> + + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +PTR +DEFUN(memmem, (haystack, haystack_len, + needle, needle_len), + CONST PTRCONST haystack AND CONST size_t haystack_len AND + CONST PTRCONST needle AND CONST size_t needle_len) +{ + register CONST char *begin; + register CONST char *CONST last_possible + = (CONST char *) haystack + haystack_len - needle_len; + + if (needle_len == 0) + return (PTR) &((CONST char *) haystack)[needle_len - 1]; + + for (begin = (CONST char *) haystack; begin <= last_possible; ++begin) + if (begin[0] == ((CONST char *) needle)[0] && + !memcmp ((CONST PTR) &begin[1], + (CONST PTR) ((CONST char *) needle + 1), + needle_len - 1)) + return (PTR) begin; + + return NULL; +} diff --git a/sysdeps/generic/memmove.c b/sysdeps/generic/memmove.c new file mode 100644 index 0000000000..e3016819d9 --- /dev/null +++ b/sysdeps/generic/memmove.c @@ -0,0 +1,99 @@ +/* memmove -- copy memory to memory until the specified number of bytes + has been copied. Overlap is handled correctly. + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +/* All this is so that bcopy.c can #include + this file after defining some things. */ +#ifndef a1 +#define a1 dest /* First arg is DEST. */ +#define a1const +#define a2 src /* Second arg is SRC. */ +#define a2const CONST +#endif +#if !defined(RETURN) || !defined(rettype) +#define RETURN(s) return (s) /* Return DEST. */ +#define rettype PTR +#endif + +rettype +DEFUN(memmove, (a1, a2, len), + a1const PTR a1 AND a2const PTR a2 AND size_t len) +{ + unsigned long int dstp = (long int) dest; + unsigned long int srcp = (long int) src; + + /* This test makes the forward copying code be used whenever possible. + Reduces the working set. */ + if (dstp - srcp >= len) /* *Unsigned* compare! */ + { + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); + + /* Copy from SRCP to DSTP taking advantage of the known + alignment of DSTP. Number of bytes remaining is put + in the third argumnet, i.e. in LEN. This number may + vary from machine to machine. */ + + WORD_COPY_FWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD (dstp, srcp, len); + } + else + { + /* Copy from the end to the beginning. */ + srcp += len; + dstp += len; + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) + { + /* Copy just a few bytes to make DSTP aligned. */ + len -= dstp % OPSIZ; + BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ); + + /* Copy from SRCP to DSTP taking advantage of the known + alignment of DSTP. Number of bytes remaining is put + in the third argumnet, i.e. in LEN. This number may + vary from machine to machine. */ + + WORD_COPY_BWD (dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_BWD (dstp, srcp, len); + } + + RETURN(dest); +} diff --git a/sysdeps/generic/memset.c b/sysdeps/generic/memset.c new file mode 100644 index 0000000000..6dee4e279e --- /dev/null +++ b/sysdeps/generic/memset.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +PTR +DEFUN(memset, (dstpp, c, len), PTR dstpp AND int c AND size_t len) +{ + long int dstp = (long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + cccc |= cccc << 32; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((byte *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((byte *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} diff --git a/sysdeps/generic/mig-reply.c b/sysdeps/generic/mig-reply.c new file mode 100644 index 0000000000..54712a85fc --- /dev/null +++ b/sysdeps/generic/mig-reply.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> + +/* These functions are called by MiG-generated code. */ + +static mach_port_t reply_port; + +/* Called by MiG to get a reply port. */ +mach_port_t +__mig_get_reply_port (void) +{ + if (reply_port == MACH_PORT_NULL) + reply_port = __mach_reply_port (); + + return reply_port; +} + +/* Called by MiG to deallocate the reply port. */ +void +__mig_dealloc_reply_port (void) +{ + mach_port_t port = reply_port; + reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */ + __mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_RECEIVE, -1); +} + + +/* Called at startup with CPROC == NULL. cthreads has a different version + of this function that is sometimes called with a `cproc_t' pointer. */ +void +__mig_init (void *cproc) +{ + if (cproc == 0) + reply_port = MACH_PORT_NULL; +} diff --git a/sysdeps/generic/mod_1.c b/sysdeps/generic/mod_1.c new file mode 100644 index 0000000000..ae4ed0914f --- /dev/null +++ b/sysdeps/generic/mod_1.c @@ -0,0 +1,198 @@ +/* __mpn_mod_1(dividend_ptr, dividend_size, divisor_limb) -- + Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. + Return the single-limb remainder. + There are no constraints on the value of the divisor. + + QUOT_PTR and DIVIDEND_PTR might point to the same limb. + +Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +#ifndef UMUL_TIME +#define UMUL_TIME 1 +#endif + +#ifndef UDIV_TIME +#define UDIV_TIME UMUL_TIME +#endif + +/* FIXME: We should be using invert_limb (or invert_normalized_limb) + here (not udiv_qrnnd). */ + +mp_limb +#if __STDC__ +__mpn_mod_1 (mp_srcptr dividend_ptr, mp_size_t dividend_size, + mp_limb divisor_limb) +#else +__mpn_mod_1 (dividend_ptr, dividend_size, divisor_limb) + mp_srcptr dividend_ptr; + mp_size_t dividend_size; + mp_limb divisor_limb; +#endif +{ + mp_size_t i; + mp_limb n1, n0, r; + int dummy; + + /* Botch: Should this be handled at all? Rely on callers? */ + if (dividend_size == 0) + return 0; + + /* If multiplication is much faster than division, and the + dividend is large, pre-invert the divisor, and use + only multiplications in the inner loop. */ + + /* This test should be read: + Does it ever help to use udiv_qrnnd_preinv? + && Does what we save compensate for the inversion overhead? */ + if (UDIV_TIME > (2 * UMUL_TIME + 6) + && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + mp_limb divisor_limb_inverted; + + divisor_limb <<= normalization_steps; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb) 0; + else + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (dummy, r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb, divisor_limb_inverted); + n1 = n0; + } + udiv_qrnnd_preinv (dummy, r, r, + n1 << normalization_steps, + divisor_limb, divisor_limb_inverted); + return r >> normalization_steps; + } + else + { + mp_limb divisor_limb_inverted; + + /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The + result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the + most significant bit (with weight 2**N) implicit. */ + + /* Special case for DIVISOR_LIMB == 100...000. */ + if (divisor_limb << 1 == 0) + divisor_limb_inverted = ~(mp_limb) 0; + else + udiv_qrnnd (divisor_limb_inverted, dummy, + -divisor_limb, 0, divisor_limb); + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + i--; + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd_preinv (dummy, r, r, + n0, divisor_limb, divisor_limb_inverted); + } + return r; + } + } + else + { + if (UDIV_NEEDS_NORMALIZATION) + { + int normalization_steps; + + count_leading_zeros (normalization_steps, divisor_limb); + if (normalization_steps != 0) + { + divisor_limb <<= normalization_steps; + + n1 = dividend_ptr[dividend_size - 1]; + r = n1 >> (BITS_PER_MP_LIMB - normalization_steps); + + /* Possible optimization: + if (r == 0 + && divisor_limb > ((n1 << normalization_steps) + | (dividend_ptr[dividend_size - 2] >> ...))) + ...one division less... */ + + for (i = dividend_size - 2; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (dummy, r, r, + ((n1 << normalization_steps) + | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))), + divisor_limb); + n1 = n0; + } + udiv_qrnnd (dummy, r, r, + n1 << normalization_steps, + divisor_limb); + return r >> normalization_steps; + } + } + /* No normalization needed, either because udiv_qrnnd doesn't require + it, or because DIVISOR_LIMB is already normalized. */ + + i = dividend_size - 1; + r = dividend_ptr[i]; + + if (r >= divisor_limb) + r = 0; + else + i--; + + for (; i >= 0; i--) + { + n0 = dividend_ptr[i]; + udiv_qrnnd (dummy, r, r, n0, divisor_limb); + } + return r; + } +} diff --git a/sysdeps/generic/modf.c b/sysdeps/generic/modf.c new file mode 100644 index 0000000000..5305caf71c --- /dev/null +++ b/sysdeps/generic/modf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +#undef modf + +/* Break VALUE into integral and fractional parts. */ +double +DEFUN(modf, (value, iptr), double value AND double *iptr) +{ + register double ipart = floor(value); + *iptr = ipart; + return value - ipart; +} diff --git a/sysdeps/generic/morecore.c b/sysdeps/generic/morecore.c new file mode 100644 index 0000000000..7c83e4aae5 --- /dev/null +++ b/sysdeps/generic/morecore.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _MALLOC_INTERNAL +#define _MALLOC_INTERNAL +#include <malloc.h> +#endif + +#ifndef __GNU_LIBRARY__ +#define __sbrk sbrk +#endif + +#ifdef __GNU_LIBRARY__ +/* It is best not to declare this and cast its result on foreign operating + systems with potentially hostile include files. */ +extern __ptr_t __sbrk __P ((int increment)); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Allocate INCREMENT more bytes of data space, + and return the start of data space, or NULL on errors. + If INCREMENT is negative, shrink data space. */ +__ptr_t +__default_morecore (increment) + __malloc_ptrdiff_t increment; +{ + __ptr_t result = (__ptr_t) __sbrk (increment); + if (result == (__ptr_t) -1) + return NULL; + return result; +} diff --git a/sysdeps/generic/mul.c b/sysdeps/generic/mul.c new file mode 100644 index 0000000000..cd2acb5127 --- /dev/null +++ b/sysdeps/generic/mul.c @@ -0,0 +1,147 @@ +/* __mpn_mul -- Multiply two natural numbers. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs) + and v (pointed to by VP, with VSIZE limbs), and store the result at + PRODP. USIZE + VSIZE limbs are always stored, but if the input + operands are normalized. Return the most significant limb of the + result. + + NOTE: The space pointed to by PRODP is overwritten before finished + with U and V, so overlap is an error. + + Argument constraints: + 1. USIZE >= VSIZE. + 2. PRODP != UP and PRODP != VP, i.e. the destination + must be distinct from the multiplier and the multiplicand. */ + +/* If KARATSUBA_THRESHOLD is not already defined, define it to a + value which is good on most machines. */ +#ifndef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 32 +#endif + +mp_limb +#if __STDC__ +__mpn_mul (mp_ptr prodp, + mp_srcptr up, mp_size_t usize, + mp_srcptr vp, mp_size_t vsize) +#else +__mpn_mul (prodp, up, usize, vp, vsize) + mp_ptr prodp; + mp_srcptr up; + mp_size_t usize; + mp_srcptr vp; + mp_size_t vsize; +#endif +{ + mp_ptr prod_endp = prodp + usize + vsize - 1; + mp_limb cy; + mp_ptr tspace; + + if (vsize < KARATSUBA_THRESHOLD) + { + /* Handle simple cases with traditional multiplication. + + This is the most critical code of the entire function. All + multiplies rely on this, both small and huge. Small ones arrive + here immediately. Huge ones arrive here as this is the base case + for Karatsuba's recursive algorithm below. */ + mp_size_t i; + mp_limb cy_limb; + mp_limb v_limb; + + if (vsize == 0) + return 0; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = vp[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, usize); + else + MPN_ZERO (prodp, usize); + cy_limb = 0; + } + else + cy_limb = __mpn_mul_1 (prodp, up, usize, v_limb); + + prodp[usize] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < vsize; i++) + { + v_limb = vp[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = __mpn_add_n (prodp, prodp, up, usize); + } + else + cy_limb = __mpn_addmul_1 (prodp, up, usize, v_limb); + + prodp[usize] = cy_limb; + prodp++; + } + return cy_limb; + } + + tspace = (mp_ptr) alloca (2 * vsize * BYTES_PER_MP_LIMB); + MPN_MUL_N_RECURSE (prodp, up, vp, vsize, tspace); + + prodp += vsize; + up += vsize; + usize -= vsize; + if (usize >= vsize) + { + mp_ptr tp = (mp_ptr) alloca (2 * vsize * BYTES_PER_MP_LIMB); + do + { + MPN_MUL_N_RECURSE (tp, up, vp, vsize, tspace); + cy = __mpn_add_n (prodp, prodp, tp, vsize); + __mpn_add_1 (prodp + vsize, tp + vsize, vsize, cy); + prodp += vsize; + up += vsize; + usize -= vsize; + } + while (usize >= vsize); + } + + /* True: usize < vsize. */ + + /* Make life simple: Recurse. */ + + if (usize != 0) + { + __mpn_mul (tspace, vp, vsize, up, usize); + cy = __mpn_add_n (prodp, prodp, tspace, vsize); + __mpn_add_1 (prodp + vsize, tspace + vsize, usize, cy); + } + + return *prod_endp; +} diff --git a/sysdeps/generic/mul_1.c b/sysdeps/generic/mul_1.c new file mode 100644 index 0000000000..37dbc33031 --- /dev/null +++ b/sysdeps/generic/mul_1.c @@ -0,0 +1,58 @@ +/* __mpn_mul_1 -- Multiply a limb vector with a single limb and + store the product in a second limb vector. + +Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +mp_limb +__mpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + mp_size_t s1_size; + register mp_limb s2_limb; +{ + register mp_limb cy_limb; + register mp_size_t j; + register mp_limb prod_high, prod_low; + + /* The loop counter and index J goes from -S1_SIZE to -1. This way + the loop becomes faster. */ + j = -s1_size; + + /* Offset the base pointers to compensate for the negative indices. */ + s1_ptr -= j; + res_ptr -= j; + + cy_limb = 0; + do + { + umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); + + prod_low += cy_limb; + cy_limb = (prod_low < cy_limb) + prod_high; + + res_ptr[j] = prod_low; + } + while (++j != 0); + + return cy_limb; +} diff --git a/sysdeps/generic/mul_n.c b/sysdeps/generic/mul_n.c new file mode 100644 index 0000000000..7900988143 --- /dev/null +++ b/sysdeps/generic/mul_n.c @@ -0,0 +1,420 @@ +/* __mpn_mul_n -- Multiply two natural numbers of length n. + +Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP), + both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are + always stored. Return the most significant limb. + + Argument constraints: + 1. PRODP != UP and PRODP != VP, i.e. the destination + must be distinct from the multiplier and the multiplicand. */ + +/* If KARATSUBA_THRESHOLD is not already defined, define it to a + value which is good on most machines. */ +#ifndef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 32 +#endif + +/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ +#if KARATSUBA_THRESHOLD < 2 +#undef KARATSUBA_THRESHOLD +#define KARATSUBA_THRESHOLD 2 +#endif + +void +#if __STDC__ +____mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr); +#else +____mpn_mul_n (); +#endif + +/* Handle simple cases with traditional multiplication. + + This is the most critical code of multiplication. All multiplies rely + on this, both small and huge. Small ones arrive here immediately. Huge + ones arrive here as this is the base case for Karatsuba's recursive + algorithm below. */ + +void +#if __STDC__ +____mpn_mul_n_basecase (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size) +#else +____mpn_mul_n_basecase (prodp, up, vp, size) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; +#endif +{ + mp_size_t i; + mp_limb cy_limb; + mp_limb v_limb; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = vp[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, size); + else + MPN_ZERO (prodp, size); + cy_limb = 0; + } + else + cy_limb = __mpn_mul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < size; i++) + { + v_limb = vp[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = __mpn_add_n (prodp, prodp, up, size); + } + else + cy_limb = __mpn_addmul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + } +} + +void +#if __STDC__ +____mpn_mul_n (mp_ptr prodp, + mp_srcptr up, mp_srcptr vp, mp_size_t size, mp_ptr tspace) +#else +____mpn_mul_n (prodp, up, vp, size, tspace) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; + mp_ptr tspace; +#endif +{ + if ((size & 1) != 0) + { + /* The size is odd, the code code below doesn't handle that. + Multiply the least significant (size - 1) limbs with a recursive + call, and handle the most significant limb of S1 and S2 + separately. */ + /* A slightly faster way to do this would be to make the Karatsuba + code below behave as if the size were even, and let it check for + odd size in the end. I.e., in essence move this code to the end. + Doing so would save us a recursive call, and potentially make the + stack grow a lot less. */ + + mp_size_t esize = size - 1; /* even size */ + mp_limb cy_limb; + + MPN_MUL_N_RECURSE (prodp, up, vp, esize, tspace); + cy_limb = __mpn_addmul_1 (prodp + esize, up, esize, vp[esize]); + prodp[esize + esize] = cy_limb; + cy_limb = __mpn_addmul_1 (prodp + esize, vp, size, up[esize]); + + prodp[esize + size] = cy_limb; + } + else + { + /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm. + + Split U in two pieces, U1 and U0, such that + U = U0 + U1*(B**n), + and V in V1 and V0, such that + V = V0 + V1*(B**n). + + UV is then computed recursively using the identity + + 2n n n n + UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V + 1 1 1 0 0 1 0 0 + + Where B = 2**BITS_PER_MP_LIMB. */ + + mp_size_t hsize = size >> 1; + mp_limb cy; + int negflg; + + /*** Product H. ________________ ________________ + |_____U1 x V1____||____U0 x V0_____| */ + /* Put result in upper part of PROD and pass low part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (prodp + size, up + hsize, vp + hsize, hsize, tspace); + + /*** Product M. ________________ + |_(U1-U0)(V0-V1)_| */ + if (__mpn_cmp (up + hsize, up, hsize) >= 0) + { + __mpn_sub_n (prodp, up + hsize, up, hsize); + negflg = 0; + } + else + { + __mpn_sub_n (prodp, up, up + hsize, hsize); + negflg = 1; + } + if (__mpn_cmp (vp + hsize, vp, hsize) >= 0) + { + __mpn_sub_n (prodp + hsize, vp + hsize, vp, hsize); + negflg ^= 1; + } + else + { + __mpn_sub_n (prodp + hsize, vp, vp + hsize, hsize); + /* No change of NEGFLG. */ + } + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (tspace, prodp, prodp + hsize, hsize, tspace + size); + + /*** Add/copy product H. */ + MPN_COPY (prodp + hsize, prodp + size, hsize); + cy = __mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize); + + /*** Add product M (if NEGFLG M is a negative number). */ + if (negflg) + cy -= __mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size); + else + cy += __mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + + /*** Product L. ________________ ________________ + |________________||____U0 x V0_____| */ + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_MUL_N_RECURSE (tspace, up, vp, hsize, tspace + size); + + /*** Add/copy Product L (twice). */ + + cy += __mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + if (cy) + { + if (cy > 0) + __mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + else + { + __mpn_sub_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + abort (); + } + } + + MPN_COPY (prodp, tspace, hsize); + cy = __mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); + if (cy) + __mpn_add_1 (prodp + size, prodp + size, size, 1); + } +} + +void +#if __STDC__ +____mpn_sqr_n_basecase (mp_ptr prodp, mp_srcptr up, mp_size_t size) +#else +____mpn_sqr_n_basecase (prodp, up, size) + mp_ptr prodp; + mp_srcptr up; + mp_size_t size; +#endif +{ + mp_size_t i; + mp_limb cy_limb; + mp_limb v_limb; + + /* Multiply by the first limb in V separately, as the result can be + stored (not added) to PROD. We also avoid a loop for zeroing. */ + v_limb = up[0]; + if (v_limb <= 1) + { + if (v_limb == 1) + MPN_COPY (prodp, up, size); + else + MPN_ZERO (prodp, size); + cy_limb = 0; + } + else + cy_limb = __mpn_mul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + + /* For each iteration in the outer loop, multiply one limb from + U with one limb from V, and add it to PROD. */ + for (i = 1; i < size; i++) + { + v_limb = up[i]; + if (v_limb <= 1) + { + cy_limb = 0; + if (v_limb == 1) + cy_limb = __mpn_add_n (prodp, prodp, up, size); + } + else + cy_limb = __mpn_addmul_1 (prodp, up, size, v_limb); + + prodp[size] = cy_limb; + prodp++; + } +} + +void +#if __STDC__ +____mpn_sqr_n (mp_ptr prodp, + mp_srcptr up, mp_size_t size, mp_ptr tspace) +#else +____mpn_sqr_n (prodp, up, size, tspace) + mp_ptr prodp; + mp_srcptr up; + mp_size_t size; + mp_ptr tspace; +#endif +{ + if ((size & 1) != 0) + { + /* The size is odd, the code code below doesn't handle that. + Multiply the least significant (size - 1) limbs with a recursive + call, and handle the most significant limb of S1 and S2 + separately. */ + /* A slightly faster way to do this would be to make the Karatsuba + code below behave as if the size were even, and let it check for + odd size in the end. I.e., in essence move this code to the end. + Doing so would save us a recursive call, and potentially make the + stack grow a lot less. */ + + mp_size_t esize = size - 1; /* even size */ + mp_limb cy_limb; + + MPN_SQR_N_RECURSE (prodp, up, esize, tspace); + cy_limb = __mpn_addmul_1 (prodp + esize, up, esize, up[esize]); + prodp[esize + esize] = cy_limb; + cy_limb = __mpn_addmul_1 (prodp + esize, up, size, up[esize]); + + prodp[esize + size] = cy_limb; + } + else + { + mp_size_t hsize = size >> 1; + mp_limb cy; + + /*** Product H. ________________ ________________ + |_____U1 x U1____||____U0 x U0_____| */ + /* Put result in upper part of PROD and pass low part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (prodp + size, up + hsize, hsize, tspace); + + /*** Product M. ________________ + |_(U1-U0)(U0-U1)_| */ + if (__mpn_cmp (up + hsize, up, hsize) >= 0) + { + __mpn_sub_n (prodp, up + hsize, up, hsize); + } + else + { + __mpn_sub_n (prodp, up, up + hsize, hsize); + } + + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (tspace, prodp, hsize, tspace + size); + + /*** Add/copy product H. */ + MPN_COPY (prodp + hsize, prodp + size, hsize); + cy = __mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize); + + /*** Add product M (if NEGFLG M is a negative number). */ + cy -= __mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size); + + /*** Product L. ________________ ________________ + |________________||____U0 x U0_____| */ + /* Read temporary operands from low part of PROD. + Put result in low part of TSPACE using upper part of TSPACE + as new TSPACE. */ + MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size); + + /*** Add/copy Product L (twice). */ + + cy += __mpn_add_n (prodp + hsize, prodp + hsize, tspace, size); + if (cy) + { + if (cy > 0) + __mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + else + { + __mpn_sub_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy); + abort (); + } + } + + MPN_COPY (prodp, tspace, hsize); + cy = __mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); + if (cy) + __mpn_add_1 (prodp + size, prodp + size, size, 1); + } +} + +/* This should be made into an inline function in gmp.h. */ +inline void +#if __STDC__ +__mpn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size) +#else +__mpn_mul_n (prodp, up, vp, size) + mp_ptr prodp; + mp_srcptr up; + mp_srcptr vp; + mp_size_t size; +#endif +{ + if (up == vp) + { + if (size < KARATSUBA_THRESHOLD) + { + ____mpn_sqr_n_basecase (prodp, up, size); + } + else + { + mp_ptr tspace; + tspace = (mp_ptr) alloca (2 * size * BYTES_PER_MP_LIMB); + ____mpn_sqr_n (prodp, up, size, tspace); + } + } + else + { + if (size < KARATSUBA_THRESHOLD) + { + ____mpn_mul_n_basecase (prodp, up, vp, size); + } + else + { + mp_ptr tspace; + tspace = (mp_ptr) alloca (2 * size * BYTES_PER_MP_LIMB); + ____mpn_mul_n (prodp, up, vp, size, tspace); + } + } +} diff --git a/sysdeps/generic/ntohl.c b/sysdeps/generic/ntohl.c new file mode 100644 index 0000000000..389cc9ffc0 --- /dev/null +++ b/sysdeps/generic/ntohl.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <netinet/in.h> + +#undef ntohl + +unsigned long int +DEFUN(ntohl, (x), unsigned long int x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); +#endif + + return x; +} diff --git a/sysdeps/generic/ntohs.c b/sysdeps/generic/ntohs.c new file mode 100644 index 0000000000..1ac462a6d2 --- /dev/null +++ b/sysdeps/generic/ntohs.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <netinet/in.h> + +#undef ntohs + +unsigned short int +DEFUN(ntohs, (x), unsigned short int x) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + x = (x << 8) | (x >> 8); +#endif + + return x; +} diff --git a/sysdeps/generic/pow.c b/sysdeps/generic/pow.c new file mode 100644 index 0000000000..5121f30464 --- /dev/null +++ b/sysdeps/generic/pow.c @@ -0,0 +1,215 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)pow.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* POW(X,Y) + * RETURN X**Y + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 7/10/85. + * KERNEL pow_P() REPLACED BY P. McILROY 7/22/92. + * Required system supported functions: + * scalb(x,n) + * logb(x) + * copysign(x,y) + * finite(x) + * drem(x,y) + * + * Required kernel functions: + * exp__D(a,c) exp(a + c) for |a| << |c| + * struct d_double dlog(x) r.a + r.b, |r.b| < |r.a| + * + * Method + * 1. Compute and return log(x) in three pieces: + * log(x) = n*ln2 + hi + lo, + * where n is an integer. + * 2. Perform y*log(x) by simulating muti-precision arithmetic and + * return the answer in three pieces: + * y*log(x) = m*ln2 + hi + lo, + * where m is an integer. + * 3. Return x**y = exp(y*log(x)) + * = 2^m * ( exp(hi+lo) ). + * + * Special cases: + * (anything) ** 0 is 1 ; + * (anything) ** 1 is itself; + * (anything) ** NaN is NaN; + * NaN ** (anything except 0) is NaN; + * +(anything > 1) ** +INF is +INF; + * -(anything > 1) ** +INF is NaN; + * +-(anything > 1) ** -INF is +0; + * +-(anything < 1) ** +INF is +0; + * +(anything < 1) ** -INF is +INF; + * -(anything < 1) ** -INF is NaN; + * +-1 ** +-INF is NaN and signal INVALID; + * +0 ** +(anything except 0, NaN) is +0; + * -0 ** +(anything except 0, NaN, odd integer) is +0; + * +0 ** -(anything except 0, NaN) is +INF and signal DIV-BY-ZERO; + * -0 ** -(anything except 0, NaN, odd integer) is +INF with signal; + * -0 ** (odd integer) = -( +0 ** (odd integer) ); + * +INF ** +(anything except 0,NaN) is +INF; + * +INF ** -(anything except 0,NaN) is +0; + * -INF ** (odd integer) = -( +INF ** (odd integer) ); + * -INF ** (even integer) = ( +INF ** (even integer) ); + * -INF ** -(anything except integer,NaN) is NaN with signal; + * -(x=anything) ** (k=integer) is (-1)**k * (x ** k); + * -(anything except 0) ** (non-integer) is NaN with signal; + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular, on a SUN, a VAX, + * and a Zilog Z8000, + * pow(integer,integer) + * always returns the correct integer provided it is representable. + * In a test run with 100,000 random arguments with 0 < x, y < 20.0 + * on a VAX, the maximum observed error was 1.79 ulps (units in the + * last place). + * + * Constants : + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include <errno.h> +#include <math.h> + +#include "mathimpl.h" + +#if (defined(vax) || defined(tahoe)) +#define TRUNC(x) x = (double) (float) x +#define _IEEE 0 +#else +#define _IEEE 1 +#define endian (((*(int *) &one)) ? 1 : 0) +#define TRUNC(x) *(((int *) &x)+endian) &= 0xf8000000 +#define infnan(x) 0.0 +#endif /* vax or tahoe */ + +const static double zero=0.0, one=1.0, two=2.0, negone= -1.0; + +static double pow_P __P((double, double)); + +double pow(x,y) +double x,y; +{ + double t; + if (y==zero) + return (one); + else if (y==one || (_IEEE && x != x)) + return (x); /* if x is NaN or y=1 */ + else if (_IEEE && y!=y) /* if y is NaN */ + return (y); + else if (!finite(y)) /* if y is INF */ + if ((t=fabs(x))==one) /* +-1 ** +-INF is NaN */ + return (y - y); + else if (t>one) + return ((y<0)? zero : ((x<zero)? y-y : y)); + else + return ((y>0)? zero : ((x<0)? y-y : -y)); + else if (y==two) + return (x*x); + else if (y==negone) + return (one/x); + /* x > 0, x == +0 */ + else if (copysign(one, x) == one) + return (pow_P(x, y)); + + /* sign(x)= -1 */ + /* if y is an even integer */ + else if ( (t=drem(y,two)) == zero) + return (pow_P(-x, y)); + + /* if y is an odd integer */ + else if (copysign(t,one) == one) + return (-pow_P(-x, y)); + + /* Henceforth y is not an integer */ + else if (x==zero) /* x is -0 */ + return ((y>zero)? -x : one/(-x)); + else if (_IEEE) + return (zero/zero); + else + return (infnan(EDOM)); +} +/* kernel function for x >= 0 */ +static double +#ifdef _ANSI_SOURCE +pow_P(double x, double y) +#else +pow_P(x, y) double x, y; +#endif +{ + struct Double s, t, __log__D(); + double __exp__D(), huge = 1e300, tiny = 1e-300; + + if (x == zero) + if (y > zero) + return (zero); + else if (_IEEE) + return (huge*huge); + else + return (infnan(ERANGE)); + if (x == one) + return (one); + if (!finite(x)) + if (y < zero) + return (zero); + else if (_IEEE) + return (huge*huge); + else + return (infnan(ERANGE)); + if (y >= 7e18) /* infinity */ + if (x < 1) + return(tiny*tiny); + else if (_IEEE) + return (huge*huge); + else + return (infnan(ERANGE)); + + /* Return exp(y*log(x)), using simulated extended */ + /* precision for the log and the multiply. */ + + s = __log__D(x); + t.a = y; + TRUNC(t.a); + t.b = y - t.a; + t.b = s.b*y + t.b*s.a; + t.a *= s.a; + s.a = t.a + t.b; + s.b = (t.a - s.a) + t.b; + return (__exp__D(s.a, s.b)); +} diff --git a/sysdeps/generic/putenv.c b/sysdeps/generic/putenv.c new file mode 100644 index 0000000000..77a8393f43 --- /dev/null +++ b/sysdeps/generic/putenv.c @@ -0,0 +1,101 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#if defined (__GNU_LIBRARY__) || defined (HAVE_STDLIB_H) +#include <stdlib.h> +#endif +#if defined (__GNU_LIBRARY__) || defined (HAVE_STRING_H) +#include <string.h> +#endif +#if defined (__GNU_LIBRARY__) || defined (HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#if !defined (__GNU_LIBRARY__) && !defined (HAVE_STRCHR) +#define strchr index +#endif +#if !defined (__GNU_LIBRARY__) && !defined (HAVE_MEMCPY) +#define memcpy(d,s,n) bcopy ((s), (d), (n)) +#endif + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + + +/* Put STRING, which is of the form "NAME=VALUE", in the environment. */ +int +putenv (string) + const char *string; +{ + const char *const name_end = strchr (string, '='); + register size_t size; + register char **ep; + + if (name_end == NULL) + { + /* Remove the variable from the environment. */ + size = strlen (string); + for (ep = __environ; *ep != NULL; ++ep) + if (!strncmp (*ep, string, size) && (*ep)[size] == '=') + { + while (ep[1] != NULL) + { + ep[0] = ep[1]; + ++ep; + } + *ep = NULL; + return 0; + } + } + + size = 0; + for (ep = __environ; *ep != NULL; ++ep) + if (!strncmp (*ep, string, name_end - string) && + (*ep)[name_end - string] == '=') + break; + else + ++size; + + if (*ep == NULL) + { + static char **last_environ = NULL; + char **new_environ = (char **) malloc ((size + 2) * sizeof (char *)); + if (new_environ == NULL) + return -1; + (void) memcpy ((void *) new_environ, (void *) __environ, + size * sizeof (char *)); + new_environ[size] = (char *) string; + new_environ[size + 1] = NULL; + if (last_environ != NULL) + free ((void *) last_environ); + last_environ = new_environ; + __environ = new_environ; + } + else + *ep = (char *) string; + + return 0; +} diff --git a/sysdeps/generic/resourcebits.h b/sysdeps/generic/resourcebits.h new file mode 100644 index 0000000000..e343b300cc --- /dev/null +++ b/sysdeps/generic/resourcebits.h @@ -0,0 +1,53 @@ +/* Bit values for resource limits. 4.4 BSD/generic GNU version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These are the values for 4.4 BSD and GNU. Earlier BSD systems have a + subset of these kinds of resource limit. In systems where `getrlimit' + and `setrlimit' are not system calls, these are the values used by the C + library to emulate them. */ + +/* Kinds of resource limit. */ +enum __rlimit_resource + { + /* Per-process CPU limit, in seconds. */ + RLIMIT_CPU, + /* Largest file that can be created, in bytes. */ + RLIMIT_FSIZE, + /* Maximum size of data segment, in bytes. */ + RLIMIT_DATA, + /* Maximum size of stack segment, in bytes. */ + RLIMIT_STACK, + /* Largest core file that can be created, in bytes. */ + RLIMIT_CORE, + /* Largest resident set size, in bytes. + This affects swapping; processes that are exceeding their + resident set size will be more likely to have physical memory + taken from them. */ + RLIMIT_RSS, + /* Locked-in-memory address space. */ + RLIMIT_MEMLOCK, + /* Number of processes. */ + RLIMIT_NPROC, + /* Number of open files. */ + RLIMIT_OFILE, + RLIMIT_NOFILE = RLIMIT_OFILE, /* Another name for the same thing. */ + + RLIMIT_NLIMITS, /* Number of limit flavors. */ + RLIM_NLIMITS = RLIMIT_NLIMITS /* Traditional name for same. */ + }; diff --git a/sysdeps/generic/rint.c b/sysdeps/generic/rint.c new file mode 100644 index 0000000000..a26fd09620 --- /dev/null +++ b/sysdeps/generic/rint.c @@ -0,0 +1,87 @@ +/* snarfed from BSD common_source/floor.c: + * Copyright (c) 1985, 1995 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)floor.c 5.7 (Berkeley) 10/9/90"; +#endif /* not lint */ + +#include "mathimpl.h" + +vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ + +ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ + +#ifdef vccast +#define L vccast(L) +#endif + +/* + * algorithm for rint(x) in pseudo-pascal form ... + * + * real rint(x): real x; + * ... delivers integer nearest x in direction of prevailing rounding + * ... mode + * const L = (last consecutive integer)/2 + * = 2**55; for VAX D + * = 2**52; for IEEE 754 Double + * real s,t; + * begin + * if x != x then return x; ... NaN + * if |x| >= L then return x; ... already an integer + * s := copysign(L,x); + * t := x + s; ... = (x+s) rounded to integer + * return t - s + * end; + * + * Note: Inexact will be signaled if x is not an integer, as is + * customary for IEEE 754. No other signal can be emitted. + */ +double +__rint(x) +double x; +{ + double s,t; + const double one = 1.0; + +#if !defined(vax)&&!defined(tahoe) + if (x != x) /* NaN */ + return (x); +#endif /* !defined(vax)&&!defined(tahoe) */ + if (copysign(x,one) >= L) /* already an integer */ + return (x); + s = copysign(L,x); + t = x + s; /* x+s rounded to integer */ + return (t - s); +} + +weak_alias (__rint, rint) diff --git a/sysdeps/generic/rshift.c b/sysdeps/generic/rshift.c new file mode 100644 index 0000000000..966cc7bcad --- /dev/null +++ b/sysdeps/generic/rshift.c @@ -0,0 +1,87 @@ +/* __mpn_rshift -- Shift right a low-level natural-number integer. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right + and store the USIZE least significant limbs of the result at WP. + The bits shifted out to the right are returned. + + Argument constraints: + 1. 0 < CNT < BITS_PER_MP_LIMB + 2. If the result is to be written over the input, WP must be <= UP. +*/ + +mp_limb +#if __STDC__ +__mpn_rshift (register mp_ptr wp, + register mp_srcptr up, mp_size_t usize, + register unsigned int cnt) +#else +__mpn_rshift (wp, up, usize, cnt) + register mp_ptr wp; + register mp_srcptr up; + mp_size_t usize; + register unsigned int cnt; +#endif +{ + register mp_limb high_limb, low_limb; + register unsigned sh_1, sh_2; + register mp_size_t i; + mp_limb retval; + +#ifdef DEBUG + if (usize == 0 || cnt == 0) + abort (); +#endif + + sh_1 = cnt; + +#if 0 + if (sh_1 == 0) + { + if (wp != up) + { + /* Copy from low end to high end, to allow specified input/output + overlapping. */ + for (i = 0; i < usize; i++) + wp[i] = up[i]; + } + return usize; + } +#endif + + wp -= 1; + sh_2 = BITS_PER_MP_LIMB - sh_1; + high_limb = up[0]; + retval = high_limb << sh_2; + low_limb = high_limb; + + for (i = 1; i < usize; i++) + { + high_limb = up[i]; + wp[i] = (low_limb >> sh_1) | (high_limb << sh_2); + low_limb = high_limb; + } + wp[i] = low_limb >> sh_1; + + return retval; +} diff --git a/sysdeps/generic/sbrk.c b/sysdeps/generic/sbrk.c new file mode 100644 index 0000000000..28beab62d5 --- /dev/null +++ b/sysdeps/generic/sbrk.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +/* Defined in brk.c. */ +extern PTR __curbrk; +extern int EXFUN(__brk, (PTR addr)); + +/* Extend the process's data space by INCREMENT. + If INCREMENT is negative, shrink data space by - INCREMENT. + Return start of new space allocated, or -1 for errors. */ +PTR +DEFUN(__sbrk, (increment), int increment) +{ + char *oldbrk; + + if (increment == 0) + return __curbrk; + + oldbrk = __curbrk; + if (__brk(oldbrk + increment) < 0) + return (PTR) -1; + + return oldbrk; +} + +weak_alias (__sbrk, sbrk) diff --git a/sysdeps/generic/setenv.c b/sysdeps/generic/setenv.c new file mode 100644 index 0000000000..a27f02e50a --- /dev/null +++ b/sysdeps/generic/setenv.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +int +DEFUN(setenv, (name, value, replace), + CONST char *name AND CONST char *value AND int replace) +{ + register char **ep; + register size_t size; + CONST size_t namelen = strlen (name); + CONST size_t vallen = strlen (value); + + size = 0; + for (ep = __environ; *ep != NULL; ++ep) + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + + if (*ep == NULL) + { + static char **last_environ = NULL; + char **new_environ = (char **) malloc((size + 2) * sizeof(char *)); + if (new_environ == NULL) + return -1; + (void) memcpy((PTR) new_environ, (PTR) __environ, size * sizeof(char *)); + + new_environ[size] = malloc (namelen + 1 + vallen + 1); + if (new_environ[size] == NULL) + { + free (new_environ); + errno = ENOMEM; + return -1; + } + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen + 1); + + new_environ[size + 1] = NULL; + + if (last_environ != NULL) + free ((PTR) last_environ); + last_environ = new_environ; + __environ = new_environ; + } + else if (replace) + { + size_t len = strlen (*ep); + if (len < namelen + 1 + vallen) + { + char *new = malloc (namelen + 1 + vallen); + if (new == NULL) + return -1; + *ep = new; + } + memcpy (*ep, name, namelen); + (*ep)[namelen] = '='; + memcpy (&(*ep)[namelen + 1], value, vallen + 1); + } + + return 0; +} diff --git a/sysdeps/generic/sigaction.h b/sysdeps/generic/sigaction.h new file mode 100644 index 0000000000..31ce45c705 --- /dev/null +++ b/sysdeps/generic/sigaction.h @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These definitions match those used by the 4.4 BSD kernel. + If the operating system has a `sigaction' system call that correctly + implements the POSIX.1 behavior, there should be a system-dependent + version of this file that defines `struct sigaction' and the `SA_*' + constants appropriately. */ + +/* Structure describing the action to be taken when a signal arrives. */ +struct sigaction + { + /* Signal handler. */ + __sighandler_t sa_handler; + + /* Additional set of signals to be blocked. */ + __sigset_t sa_mask; + + /* Special flags. */ + int sa_flags; + }; + +/* Bits in `sa_flags'. */ +#ifdef __USE_BSD +#define SA_ONSTACK 0x1 /* Take signal on signal stack. */ +#define SA_RESTART 0x2 /* Don't restart syscall on signal return. */ +#define SA_DISABLE 0x4 /* Disable alternate signal stack. */ +#endif +#define SA_NOCLDSTOP 0x8 /* Don't send SIGCHLD when children stop. */ + + +/* Values for the HOW argument to `sigprocmask'. */ +#define SIG_BLOCK 1 /* Block signals. */ +#define SIG_UNBLOCK 2 /* Unblock signals. */ +#define SIG_SETMASK 3 /* Set the set of blocked signals. */ diff --git a/sysdeps/generic/signame.c b/sysdeps/generic/signame.c new file mode 100644 index 0000000000..5f8deab3ad --- /dev/null +++ b/sysdeps/generic/signame.c @@ -0,0 +1,275 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <sys/types.h> /* Some systems need this for <signal.h>. */ +#include <signal.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* Some systems do not define NSIG in <signal.h>. */ +#ifndef NSIG +#ifdef _NSIG +#define NSIG _NSIG +#else +#define NSIG 32 +#endif +#endif + +#if !__STDC__ +#define const +#endif + +#include "signame.h" + +#ifndef HAVE_SYS_SIGLIST +/* There is too much variation in Sys V signal numbers and names, so + we must initialize them at runtime. */ + +static const char undoc[] = "unknown signal"; + +const char *sys_siglist[NSIG]; + +#else /* HAVE_SYS_SIGLIST. */ + +#ifndef SYS_SIGLIST_DECLARED +extern char *sys_siglist[]; +#endif /* Not SYS_SIGLIST_DECLARED. */ + +#endif /* Not HAVE_SYS_SIGLIST. */ + +/* Table of abbreviations for signals. Note: A given number can + appear more than once with different abbreviations. */ +typedef struct + { + int number; + const char *abbrev; + } num_abbrev; +static num_abbrev sig_table[NSIG*2]; +/* Number of elements of sig_table used. */ +static int sig_table_nelts = 0; + +/* Enter signal number NUMBER into the tables with ABBREV and NAME. */ + +static void +init_sig (number, abbrev, name) + int number; + const char *abbrev; + const char *name; +{ +#ifndef HAVE_SYS_SIGLIST + sys_siglist[number] = name; +#endif + sig_table[sig_table_nelts].number = number; + sig_table[sig_table_nelts++].abbrev = abbrev; +} + +void +signame_init () +{ +#ifndef HAVE_SYS_SIGLIST + int i; + /* Initialize signal names. */ + for (i = 0; i < NSIG; i++) + sys_siglist[i] = undoc; +#endif /* !HAVE_SYS_SIGLIST */ + + /* Initialize signal names. */ +#if defined (SIGHUP) + init_sig (SIGHUP, "HUP", "Hangup"); +#endif +#if defined (SIGINT) + init_sig (SIGINT, "INT", "Interrupt"); +#endif +#if defined (SIGQUIT) + init_sig (SIGQUIT, "QUIT", "Quit"); +#endif +#if defined (SIGILL) + init_sig (SIGILL, "ILL", "Illegal Instruction"); +#endif +#if defined (SIGTRAP) + init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap"); +#endif + /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because + SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */ +#if defined (SIGABRT) + init_sig (SIGABRT, "ABRT", "Aborted"); +#endif +#if defined (SIGIOT) + init_sig (SIGIOT, "IOT", "IOT trap"); +#endif +#if defined (SIGEMT) + init_sig (SIGEMT, "EMT", "EMT trap"); +#endif +#if defined (SIGFPE) + init_sig (SIGFPE, "FPE", "Floating point exception"); +#endif +#if defined (SIGKILL) + init_sig (SIGKILL, "KILL", "Killed"); +#endif +#if defined (SIGBUS) + init_sig (SIGBUS, "BUS", "Bus error"); +#endif +#if defined (SIGSEGV) + init_sig (SIGSEGV, "SEGV", "Segmentation fault"); +#endif +#if defined (SIGSYS) + init_sig (SIGSYS, "SYS", "Bad system call"); +#endif +#if defined (SIGPIPE) + init_sig (SIGPIPE, "PIPE", "Broken pipe"); +#endif +#if defined (SIGALRM) + init_sig (SIGALRM, "ALRM", "Alarm clock"); +#endif +#if defined (SIGTERM) + init_sig (SIGTERM, "TERM", "Terminated"); +#endif +#if defined (SIGUSR1) + init_sig (SIGUSR1, "USR1", "User defined signal 1"); +#endif +#if defined (SIGUSR2) + init_sig (SIGUSR2, "USR2", "User defined signal 2"); +#endif + /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that + is what is in POSIX.1. */ +#if defined (SIGCHLD) + init_sig (SIGCHLD, "CHLD", "Child exited"); +#endif +#if defined (SIGCLD) + init_sig (SIGCLD, "CLD", "Child exited"); +#endif +#if defined (SIGPWR) + init_sig (SIGPWR, "PWR", "Power failure"); +#endif +#if defined (SIGTSTP) + init_sig (SIGTSTP, "TSTP", "Stopped"); +#endif +#if defined (SIGTTIN) + init_sig (SIGTTIN, "TTIN", "Stopped (tty input)"); +#endif +#if defined (SIGTTOU) + init_sig (SIGTTOU, "TTOU", "Stopped (tty output)"); +#endif +#if defined (SIGSTOP) + init_sig (SIGSTOP, "STOP", "Stopped (signal)"); +#endif +#if defined (SIGXCPU) + init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded"); +#endif +#if defined (SIGXFSZ) + init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded"); +#endif +#if defined (SIGVTALRM) + init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired"); +#endif +#if defined (SIGPROF) + init_sig (SIGPROF, "PROF", "Profiling timer expired"); +#endif +#if defined (SIGWINCH) + /* "Window size changed" might be more accurate, but even if that + is all that it means now, perhaps in the future it will be + extended to cover other kinds of window changes. */ + init_sig (SIGWINCH, "WINCH", "Window changed"); +#endif +#if defined (SIGCONT) + init_sig (SIGCONT, "CONT", "Continued"); +#endif +#if defined (SIGURG) + init_sig (SIGURG, "URG", "Urgent I/O condition"); +#endif +#if defined (SIGIO) + /* "I/O pending" has also been suggested. A disadvantage is + that signal only happens when the process has + asked for it, not everytime I/O is pending. Another disadvantage + is the confusion from giving it a different name than under Unix. */ + init_sig (SIGIO, "IO", "I/O possible"); +#endif +#if defined (SIGWIND) + init_sig (SIGWIND, "WIND", "SIGWIND"); +#endif +#if defined (SIGPHONE) + init_sig (SIGPHONE, "PHONE", "SIGPHONE"); +#endif +#if defined (SIGPOLL) + init_sig (SIGPOLL, "POLL", "I/O possible"); +#endif +#if defined (SIGLOST) + init_sig (SIGLOST, "LOST", "Resource lost"); +#endif +#if defined (SIGDANGER) + init_sig (SIGDANGER, "DANGER", "Danger signal"); +#endif +} + +/* Return the abbreviation for signal NUMBER. */ + +char * +sig_abbrev (number) + int number; +{ + int i; + + if (sig_table_nelts == 0) + signame_init (); + + for (i = 0; i < sig_table_nelts; i++) + if (sig_table[i].number == number) + return (char *)sig_table[i].abbrev; + return NULL; +} + +/* Return the signal number for an ABBREV, or -1 if there is no + signal by that name. */ + +int +sig_number (abbrev) + const char *abbrev; +{ + int i; + + if (sig_table_nelts == 0) + signame_init (); + + /* Skip over "SIG" if present. */ + if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G') + abbrev += 3; + + for (i = 0; i < sig_table_nelts; i++) + if (abbrev[0] == sig_table[i].abbrev[0] + && strcmp (abbrev, sig_table[i].abbrev) == 0) + return sig_table[i].number; + return -1; +} + +#ifndef HAVE_PSIGNAL +/* Print to standard error the name of SIGNAL, preceded by MESSAGE and + a colon, and followed by a newline. */ + +void +psignal (signal, message) + int signal; + const char *message; +{ + if (signal <= 0 || signal >= NSIG) + fprintf (stderr, "%s: unknown signal", message); + else + fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]); +} +#endif diff --git a/sysdeps/generic/signame.h b/sysdeps/generic/signame.h new file mode 100644 index 0000000000..2bd1637cfc --- /dev/null +++ b/sysdeps/generic/signame.h @@ -0,0 +1,57 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if defined (__STDC__) && __STDC__ + +/* Initialize `sys_siglist'. */ +void signame_init (void); + +/* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER. + Do not return this as a const char *. The caller might want to + assign it to a char *. */ +char *sig_abbrev (int number); + +/* Return the signal number for an ABBREV, or -1 if there is no + signal by that name. */ +int sig_number (const char *abbrev); + +/* Avoid conflicts with a system header file that might define these two. */ + +#ifndef HAVE_PSIGNAL +/* Print to standard error the name of SIGNAL, preceded by MESSAGE and + a colon, and followed by a newline. */ +void psignal (int signal, const char *message); +#endif + +#if !defined (HAVE_SYS_SIGLIST) +/* Names for signals from 0 to NSIG-1. */ +extern const char *sys_siglist[]; +#endif + +#else + +void signame_init (); +char *sig_abbrev (); +int sig_number (); +#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_PSIGNAL) +void psignal (); +#endif +#if !defined (HAVE_SYS_SIGLIST) +extern char *sys_siglist[]; +#endif + +#endif diff --git a/sysdeps/generic/sigset.h b/sysdeps/generic/sigset.h new file mode 100644 index 0000000000..bc56d96daf --- /dev/null +++ b/sysdeps/generic/sigset.h @@ -0,0 +1,79 @@ +/* __sig_atomic_t, __sigset_t, and related definitions. Generic/BSD version. +Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SIGSET_H_types +#define _SIGSET_H_types 1 + +typedef int __sig_atomic_t; + +/* A `sigset_t' has a bit for each signal. */ +typedef unsigned long int __sigset_t; + +#endif + + +/* We only want to define these functions if <signal.h> was actually + included; otherwise we were included just to define the types. Since we + are namespace-clean, it wouldn't hurt to define extra macros. But + trouble can be caused by functions being defined (e.g., any global + register vars declared later will cause compilation errors). */ + +#if !defined (_SIGSET_H_fns) && defined (_SIGNAL_H) +#define _SIGSET_H_fns 1 + +/* Return a mask that includes SIG only. The cast to `sigset_t' avoids + overflow if `sigset_t' is wider than `int'. */ +#define __sigmask(sig) (((__sigset_t) 1) << ((sig) - 1)) + +#define __sigemptyset(set) ((*(set) = (__sigset_t) 0), 0) +#define __sigfillset(set) ((*(set) = ~(__sigset_t) 0), 0) + +/* These functions must check for a bogus signal number. We detect it by a + zero sigmask, since a number too low or too high will have shifted the 1 + off the high end of the mask. If we find an error, we punt to a random + call we know fails with EINVAL (kludge city!), so as to avoid referring + to `errno' in this file (sigh). */ + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif +#define __SIGSETFN(NAME, BODY, CONST) \ + _EXTERN_INLINE int \ + __##NAME (CONST __sigset_t *__set, int __sig) \ + { \ + if (__sig < 1 || __sig > sizeof (__sigset_t) * 8) \ + { \ + extern int raise (int); \ + return raise (-1); \ + } \ + else \ + { \ + __sigset_t __mask = __sigmask (__sig); \ + return BODY; \ + } \ + } + +__SIGSETFN (sigismember, (*__set & __mask) ? 1 : 0, __const) +__SIGSETFN (sigaddset, ((*__set |= __mask), 0), ) +__SIGSETFN (sigdelset, ((*__set &= ~__mask), 0), ) + +#undef __SIGSETFN + + +#endif /* ! _SIGSET_H_fns. */ diff --git a/sysdeps/generic/sincos.c b/sysdeps/generic/sincos.c new file mode 100644 index 0000000000..ab885607cf --- /dev/null +++ b/sysdeps/generic/sincos.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)sincos.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include "trig.h" +double +sin(x) +double x; +{ + double a,c,z; + + if(!finite(x)) /* sin(NaN) and sin(INF) must be NaN */ + return x-x; + x=drem(x,PI2); /* reduce x into [-PI,PI] */ + a=copysign(x,one); + if (a >= PIo4) { + if(a >= PI3o4) /* ... in [3PI/4,PI] */ + x = copysign((a = PI-a),x); + else { /* ... in [PI/4,3PI/4] */ + a = PIo2-a; /* rtn. sign(x)*C(PI/2-|x|) */ + z = a*a; + c = cos__C(z); + z *= half; + a = (z >= thresh ? half-((z-half)-c) : one-(z-c)); + return copysign(a,x); + } + } + + if (a < small) { /* rtn. S(x) */ + big+a; + return x; + } + return x+x*sin__S(x*x); +} + +double +cos(x) +double x; +{ + double a,c,z,s = 1.0; + + if(!finite(x)) /* cos(NaN) and cos(INF) must be NaN */ + return x-x; + x=drem(x,PI2); /* reduce x into [-PI,PI] */ + a=copysign(x,one); + if (a >= PIo4) { + if (a >= PI3o4) { /* ... in [3PI/4,PI] */ + a = PI-a; + s = negone; + } + else { /* ... in [PI/4,3PI/4] */ + a = PIo2-a; + return a+a*sin__S(a*a); /* rtn. S(PI/2-|x|) */ + } + } + if (a < small) { + big+a; + return s; /* rtn. s*C(a) */ + } + z = a*a; + c = cos__C(z); + z *= half; + a = (z >= thresh ? half-((z-half)-c) : one-(z-c)); + return copysign(a,s); +} diff --git a/sysdeps/generic/sinh.c b/sysdeps/generic/sinh.c new file mode 100644 index 0000000000..0516849cff --- /dev/null +++ b/sysdeps/generic/sinh.c @@ -0,0 +1,121 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)sinh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* SINH(X) + * RETURN THE HYPERBOLIC SINE OF X + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 2/8/85, 3/7/85, 3/24/85, 4/16/85. + * + * Required system supported functions : + * copysign(x,y) + * scalb(x,N) + * + * Required kernel functions: + * expm1(x) ...return exp(x)-1 + * + * Method : + * 1. reduce x to non-negative by sinh(-x) = - sinh(x). + * 2. + * + * expm1(x) + expm1(x)/(expm1(x)+1) + * 0 <= x <= lnovfl : sinh(x) := -------------------------------- + * 2 + * lnovfl <= x <= lnovfl+ln2 : sinh(x) := expm1(x)/2 (avoid overflow) + * lnovfl+ln2 < x < INF : overflow to INF + * + * + * Special cases: + * sinh(x) is x if x is +INF, -INF, or NaN. + * only sinh(0)=0 is exact for finite argument. + * + * Accuracy: + * sinh(x) returns the exact hyperbolic sine of x nearly rounded. In + * a test run with 1,024,000 random arguments on a VAX, the maximum + * observed error was 1.93 ulps (units in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "mathimpl.h" + +vc(mln2hi, 8.8029691931113054792E1 ,0f33,43b0,2bdb,c7e2, 7, .B00F33C7E22BDB) +vc(mln2lo,-4.9650192275318476525E-16 ,1b60,a70f,582a,279e, -50,-.8F1B60279E582A) +vc(lnovfl, 8.8029691931113053016E1 ,0f33,43b0,2bda,c7e2, 7, .B00F33C7E22BDA) + +ic(mln2hi, 7.0978271289338397310E2, 10, 1.62E42FEFA39EF) +ic(mln2lo, 2.3747039373786107478E-14, -45, 1.ABC9E3B39803F) +ic(lnovfl, 7.0978271289338397310E2, 9, 1.62E42FEFA39EF) + +#ifdef vccast +#define mln2hi vccast(mln2hi) +#define mln2lo vccast(mln2lo) +#define lnovfl vccast(lnovfl) +#endif + +#if defined(vax)||defined(tahoe) +static max = 126 ; +#else /* defined(vax)||defined(tahoe) */ +static max = 1023 ; +#endif /* defined(vax)||defined(tahoe) */ + + +double sinh(x) +double x; +{ + static const double one=1.0, half=1.0/2.0 ; + double t, sign; +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + sign=copysign(one,x); + x=copysign(x,one); + if(x<lnovfl) + {t=expm1(x); return(copysign((t+t/(one+t))*half,sign));} + + else if(x <= lnovfl+0.7) + /* subtract x by ln(2^(max+1)) and return 2^max*exp(x) + to avoid unnecessary overflow */ + return(copysign(scalb(one+expm1((x-mln2hi)-mln2lo),max),sign)); + + else /* sinh(+-INF) = +-INF, sinh(+-big no.) overflow to +-INF */ + return( expm1(x)*sign ); +} diff --git a/sysdeps/generic/sockaddrcom.h b/sysdeps/generic/sockaddrcom.h new file mode 100644 index 0000000000..1aac49c5cd --- /dev/null +++ b/sysdeps/generic/sockaddrcom.h @@ -0,0 +1,34 @@ +/* Definition of `struct sockaddr_*' common members. Generic/4.2 BSD version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SOCKADDRCOM_H +#define _SOCKADDRCOM_H 1 + + +/* This macro is used to declare the initial common members + of the data types used for socket addresses, `struct sockaddr', + `struct sockaddr_in', `struct sockaddr_un', etc. */ + +#define __SOCKADDR_COMMON(sa_prefix) \ + unsigned short int sa_prefix##family + +#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int)) + + +#endif /* sockaddrcom.h */ diff --git a/sysdeps/generic/speed.c b/sysdeps/generic/speed.c new file mode 100644 index 0000000000..1f5a3eeacc --- /dev/null +++ b/sysdeps/generic/speed.c @@ -0,0 +1,67 @@ +/* `struct termios' speed frobnication functions. 4.4 BSD/generic GNU version. +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <termios.h> + +/* Return the output baud rate stored in *TERMIOS_P. */ +speed_t +DEFUN(cfgetospeed, (termios_p), CONST struct termios *termios_p) +{ + return termios_p->__ospeed; +} + +/* Return the input baud rate stored in *TERMIOS_P. */ +speed_t +DEFUN(cfgetispeed, (termios_p), CONST struct termios *termios_p) +{ + return termios_p->__ispeed; +} + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +int +DEFUN(cfsetospeed, (termios_p, speed), + struct termios *termios_p AND speed_t speed) +{ + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + termios_p->__ospeed = speed; + return 0; +} + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. */ +int +DEFUN(cfsetispeed, (termios_p, speed), + struct termios *termios_p AND speed_t speed) +{ + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + termios_p->__ispeed = speed; + return 0; +} diff --git a/sysdeps/generic/stpcpy.c b/sysdeps/generic/stpcpy.c new file mode 100644 index 0000000000..dd96948c40 --- /dev/null +++ b/sysdeps/generic/stpcpy.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +char * +DEFUN(stpcpy, (dest, src), char *dest AND CONST char *src) +{ + register char *d = dest; + register CONST char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} diff --git a/sysdeps/generic/stpncpy.c b/sysdeps/generic/stpncpy.c new file mode 100644 index 0000000000..40c9173477 --- /dev/null +++ b/sysdeps/generic/stpncpy.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + + +/* Copy no more than N characters of SRC to DEST, returning the address of + the last character written into DEST. */ +char * +DEFUN(__stpncpy, (dest, src, n), char *dest AND CONST char *src AND size_t n) +{ + reg_char c; + char *s = dest; + + --dest; + + if (n >= 4) + { + size_t n4 = n >> 2; + + for (;;) + { + c = *src++; + *++dest = c; + if (c == '\0') + break; + c = *src++; + *++dest = c; + if (c == '\0') + break; + c = *src++; + *++dest = c; + if (c == '\0') + break; + c = *src++; + *++dest = c; + if (c == '\0') + break; + if (--n4 == 0) + goto last_chars; + } + n = n - (dest - s) - 1; + if (n == 0) + return dest; + goto zero_fill; + } + + last_chars: + n &= 3; + if (n == 0) + return s; + + do + { + c = *src++; + *++dest = c; + if (--n == 0) + return dest; + } + while (c != '\0'); + + zero_fill: + do + *++dest = '\0'; + while (--n > 0); + + return dest; +} + +weak_alias (__stpncpy, stpncpy) diff --git a/sysdeps/generic/strcasecmp.c b/sysdeps/generic/strcasecmp.c new file mode 100644 index 0000000000..7ccfe5c0c5 --- /dev/null +++ b/sysdeps/generic/strcasecmp.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <ctype.h> + +/* Compare S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexiographically less than, + equal to or greater than S2. */ +int +DEFUN(strcasecmp, (s1, s2), CONST char *s1 AND CONST char *s2) +{ + register CONST unsigned char *p1 = (CONST unsigned char *) s1; + register CONST unsigned char *p2 = (CONST unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = tolower (*p1++); + c2 = tolower (*p2++); + if (c1 == '\0') + break; + } + while (c1 == c2); + + return c1 - c2; +} diff --git a/sysdeps/generic/strcat.c b/sysdeps/generic/strcat.c new file mode 100644 index 0000000000..b4b5536971 --- /dev/null +++ b/sysdeps/generic/strcat.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +/* Append SRC on the end of DEST. */ +char * +DEFUN(strcat, (dest, src), char *dest AND CONST char *src) +{ + register char *s1 = dest; + register CONST char *s2 = src; + reg_char c; + + /* Find the end of the string. */ + do + c = *s1++; + while (c != '\0'); + + /* Make S1 point before the next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + s1 -= 2; + + do + { + c = *s2++; + *++s1 = c; + } + while (c != '\0'); + + return dest; +} diff --git a/sysdeps/generic/strchr.c b/sysdeps/generic/strchr.c new file mode 100644 index 0000000000..b9c8393f8e --- /dev/null +++ b/sysdeps/generic/strchr.c @@ -0,0 +1,183 @@ +/* Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. + Based on strlen implemention by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + bug fix and commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Find the first ocurrence of C in S. */ + +char * +DEFUN(strchr, (s, c), CONST char *s AND int c) +{ + CONST unsigned char *char_ptr; + CONST unsigned long int *longword_ptr; + unsigned long int longword, magic_bits, charmask; + + c = (unsigned char) c; + + /* Handle the first few characters by reading one character at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = s; ((unsigned long int) char_ptr + & (sizeof (longword) - 1)) != 0; + ++char_ptr) + if (*char_ptr == c) + return (PTR) char_ptr; + else if (*char_ptr == '\0') + return NULL; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to 8-byte longwords. */ + + longword_ptr = (unsigned long int *) char_ptr; + + /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits + the "holes." Note that there is a hole just to the left of + each byte, with an extra at the end: + + bits: 01111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD + + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ + switch (sizeof (longword)) + { + case 4: magic_bits = 0x7efefeffL; break; + case 8: magic_bits = (0x7efefefeL << 32) | 0xfefefeffL; break; + default: + abort (); + } + + /* Set up a longword, each of whose bytes is C. */ + charmask = c | (c << 8); + charmask |= charmask << 16; + if (sizeof (longword) > 4) + charmask |= charmask << 32; + if (sizeof (longword) > 8) + abort (); + + /* Instead of the traditional loop which tests each character, + we will test a longword at a time. The tricky part is testing + if *any of the four* bytes in the longword in question are zero. */ + for (;;) + { + /* We tentatively exit the loop if adding MAGIC_BITS to + LONGWORD fails to change any of the hole bits of LONGWORD. + + 1) Is this safe? Will it catch all the zero bytes? + Suppose there is a byte with all zeros. Any carry bits + propagating from its left will fall into the hole at its + least significant bit and stop. Since there will be no + carry from its most significant bit, the LSB of the + byte to the left will be unchanged, and the zero will be + detected. + + 2) Is this worthwhile? Will it ignore everything except + zero bytes? Suppose every byte of LONGWORD has a bit set + somewhere. There will be a carry into bit 8. If bit 8 + is set, this will carry into bit 16. If bit 8 is clear, + one of bits 9-15 must be set, so there will be a carry + into bit 16. Similarly, there will be a carry into bit + 24. If one of bits 24-30 is set, there will be a carry + into bit 31, so all of the hole bits will be changed. + + The one misfire occurs when bits 24-30 are clear and bit + 31 is set; in this case, the hole at bit 31 is not + changed. If we had access to the processor carry flag, + we could close this loophole by putting the fourth hole + at bit 32! + + So it ignores everything except 128's, when they're aligned + properly. + + 3) But wait! Aren't we looking for C as well as zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + + longword = *longword_ptr++; + + /* Add MAGIC_BITS to LONGWORD. */ + if ((((longword + magic_bits) + + /* Set those bits that were unchanged by the addition. */ + ^ ~longword) + + /* Look at only the hole bits. If any of the hole bits + are unchanged, most likely one of the bytes was a + zero. */ + & ~magic_bits) != 0 || + + /* That caught zeroes. Now test for C. */ + ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask)) + & ~magic_bits) != 0) + { + /* Which of the bytes was C or zero? + If none of them were, it was a misfire; continue the search. */ + + CONST unsigned char *cp = (CONST unsigned char *) (longword_ptr - 1); + + if (*cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (sizeof (longword) > 4) + { + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + if (*++cp == c) + return (char *) cp; + else if (*cp == '\0') + return NULL; + } + } + } + + return NULL; +} + +#ifdef weak_alias +#undef index +weak_alias (strchr, index) +#endif diff --git a/sysdeps/generic/strcmp.c b/sysdeps/generic/strcmp.c new file mode 100644 index 0000000000..ec0c1e6b00 --- /dev/null +++ b/sysdeps/generic/strcmp.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +/* Compare S1 and S2, returning less than, equal to or + greater than zero if S1 is lexiographically less than, + equal to or greater than S2. */ +int +DEFUN(strcmp, (p1, p2), CONST char *p1 AND CONST char *p2) +{ + register CONST unsigned char *s1 = (CONST unsigned char *) p1; + register CONST unsigned char *s2 = (CONST unsigned char *) p2; + unsigned reg_char c1, c2; + + do + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0') + return c1 - c2; + } + while (c1 == c2); + + return c1 - c2; +} diff --git a/sysdeps/generic/strcpy.c b/sysdeps/generic/strcpy.c new file mode 100644 index 0000000000..0a7c2a88f7 --- /dev/null +++ b/sysdeps/generic/strcpy.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <string.h> +#include <memcopy.h> + +/* Copy SRC to DEST. */ +char * +DEFUN(strcpy, (dest, src), char *dest AND CONST char *src) +{ + reg_char c; + char *s = (char *) src; + CONST ptrdiff_t off = dest - src - 1; + + do + { + c = *s++; + s[off] = c; + } + while (c != '\0'); + + return dest; +} + diff --git a/sysdeps/generic/strcspn.c b/sysdeps/generic/strcspn.c new file mode 100644 index 0000000000..915faa77c0 --- /dev/null +++ b/sysdeps/generic/strcspn.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Return the length of the maximum inital segment of S + which contains no characters from REJECT. */ +size_t +strcspn (s, reject) + register const char *s; + register const char *reject; +{ + register size_t count = 0; + + while (*s != '\0') + if (strchr (reject, *s++) == NULL) + ++count; + else + return count; + + return count; +} diff --git a/sysdeps/generic/strlen.c b/sysdeps/generic/strlen.c new file mode 100644 index 0000000000..5e8d360c9a --- /dev/null +++ b/sysdeps/generic/strlen.c @@ -0,0 +1,149 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. + Written by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se); + commentary by Jim Blandy (jimb@ai.mit.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Return the length of the null-terminated string STR. Scan for + the null terminator quickly by testing four bytes at a time. */ + +size_t +DEFUN(strlen, (str), CONST char *str) +{ + CONST char *char_ptr; + CONST unsigned long int *longword_ptr; + unsigned long int longword, magic_bits, himagic, lomagic; + + /* Handle the first few characters by reading one character at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = str; ((unsigned long int) char_ptr + & (sizeof (longword) - 1)) != 0; + ++char_ptr) + if (*char_ptr == '\0') + return char_ptr - str; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to 8-byte longwords. */ + + longword_ptr = (unsigned long int *) char_ptr; + + /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits + the "holes." Note that there is a hole just to the left of + each byte, with an extra at the end: + + bits: 01111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD + + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ + magic_bits = 0x7efefeffL; + himagic = 0x80808080L; + lomagic = 0x01010101L; + if (sizeof (longword) > 4) + { + /* 64-bit version of the magic. */ + magic_bits = (0x7efefefeL << 32) | 0xfefefeffL; + himagic = (himagic << 32) | himagic; + lomagic = (lomagic << 32) | lomagic; + } + if (sizeof (longword) > 8) + abort (); + + /* Instead of the traditional loop which tests each character, + we will test a longword at a time. The tricky part is testing + if *any of the four* bytes in the longword in question are zero. */ + for (;;) + { + /* We tentatively exit the loop if adding MAGIC_BITS to + LONGWORD fails to change any of the hole bits of LONGWORD. + + 1) Is this safe? Will it catch all the zero bytes? + Suppose there is a byte with all zeros. Any carry bits + propagating from its left will fall into the hole at its + least significant bit and stop. Since there will be no + carry from its most significant bit, the LSB of the + byte to the left will be unchanged, and the zero will be + detected. + + 2) Is this worthwhile? Will it ignore everything except + zero bytes? Suppose every byte of LONGWORD has a bit set + somewhere. There will be a carry into bit 8. If bit 8 + is set, this will carry into bit 16. If bit 8 is clear, + one of bits 9-15 must be set, so there will be a carry + into bit 16. Similarly, there will be a carry into bit + 24. If one of bits 24-30 is set, there will be a carry + into bit 31, so all of the hole bits will be changed. + + The one misfire occurs when bits 24-30 are clear and bit + 31 is set; in this case, the hole at bit 31 is not + changed. If we had access to the processor carry flag, + we could close this loophole by putting the fourth hole + at bit 32! + + So it ignores everything except 128's, when they're aligned + properly. */ + + longword = *longword_ptr++; + + if ( +#if 0 + /* Add MAGIC_BITS to LONGWORD. */ + (((longword + magic_bits) + + /* Set those bits that were unchanged by the addition. */ + ^ ~longword) + + /* Look at only the hole bits. If any of the hole bits + are unchanged, most likely one of the bytes was a + zero. */ + & ~magic_bits) +#else + ((longword - lomagic) & himagic) +#endif + != 0) + { + /* Which of the bytes was the zero? If none of them were, it was + a misfire; continue the search. */ + + CONST char *cp = (CONST char *) (longword_ptr - 1); + + if (cp[0] == 0) + return cp - str; + if (cp[1] == 0) + return cp - str + 1; + if (cp[2] == 0) + return cp - str + 2; + if (cp[3] == 0) + return cp - str + 3; + if (sizeof (longword) > 4) + { + if (cp[4] == 0) + return cp - str + 4; + if (cp[5] == 0) + return cp - str + 5; + if (cp[6] == 0) + return cp - str + 6; + if (cp[7] == 0) + return cp - str + 7; + } + } + } +} diff --git a/sysdeps/generic/strncase.c b/sysdeps/generic/strncase.c new file mode 100644 index 0000000000..f589937fac --- /dev/null +++ b/sysdeps/generic/strncase.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <ctype.h> + +/* Compare no more than N characters of S1 and S2, + ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less + than, equal to or greater than S2. */ +int +DEFUN(strncasecmp, (s1, s2, n), + CONST char *s1 AND CONST char *s2 AND size_t n) +{ + register CONST unsigned char *p1 = (CONST unsigned char *) s1; + register CONST unsigned char *p2 = (CONST unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = tolower (*p1++); + c2 = tolower (*p2++); + if (c1 == '\0' || c1 != c2) + return c1 - c2; + } while (--n > 0); + + return c1 - c2; +} diff --git a/sysdeps/generic/strncat.c b/sysdeps/generic/strncat.c new file mode 100644 index 0000000000..09463b36b8 --- /dev/null +++ b/sysdeps/generic/strncat.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +char * +DEFUN(strncat, (s1, s2, n), char *s1 AND CONST char *s2 AND size_t n) +{ + reg_char c; + char *s = s1; + + /* Find the end of S1. */ + do + c = *s1++; + while (c != '\0'); + + /* Make S1 point before next character, so we can increment + it while memory is read (wins on pipelined cpus). */ + s1 -= 2; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + c = *s2++; + *++s1 = c; + if (c == '\0') + return s; + n--; + } + + if (c != '\0') + *++s1 = '\0'; + + return s; +} diff --git a/sysdeps/generic/strncmp.c b/sysdeps/generic/strncmp.c new file mode 100644 index 0000000000..623d9c5714 --- /dev/null +++ b/sysdeps/generic/strncmp.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +/* Compare no more than N characters of S1 and S2, + returning less than, equal to or greater than zero + if S1 is lexiographically less than, equal to or + greater than S2. */ +int +DEFUN(strncmp, (s1, s2, n), + CONST char *s1 AND CONST char *s2 AND size_t n) +{ + unsigned reg_char c1 = '\0'; + unsigned reg_char c2 = '\0'; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + n--; + } + + return c1 - c2; +} diff --git a/sysdeps/generic/strncpy.c b/sysdeps/generic/strncpy.c new file mode 100644 index 0000000000..460e0baca4 --- /dev/null +++ b/sysdeps/generic/strncpy.c @@ -0,0 +1,82 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +char * +DEFUN(strncpy, (s1, s2, n), char *s1 AND CONST char *s2 AND size_t n) +{ + reg_char c; + char *s = s1; + + --s1; + + if (n >= 4) + { + size_t n4 = n >> 2; + + for (;;) + { + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + c = *s2++; + *++s1 = c; + if (c == '\0') + break; + if (--n4 == 0) + goto last_chars; + } + n = n - (s1 - s) - 1; + if (n == 0) + return s; + goto zero_fill; + } + + last_chars: + n &= 3; + if (n == 0) + return s; + + do + { + c = *s2++; + *++s1 = c; + if (--n == 0) + return s; + } + while (c != '\0'); + + zero_fill: + do + *++s1 = '\0'; + while (--n > 0); + + return s; +} diff --git a/sysdeps/generic/strpbrk.c b/sysdeps/generic/strpbrk.c new file mode 100644 index 0000000000..73339ba762 --- /dev/null +++ b/sysdeps/generic/strpbrk.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Find the first ocurrence in S of any character in ACCEPT. */ +char * +DEFUN(strpbrk, (s, accept), + register CONST char *s AND register CONST char *accept) +{ + while (*s != '\0') + { + const char *a = accept; + while (*a != '\0') + if (*a++ == *s) + return (char *) s; + ++s; + } + + return NULL; +} diff --git a/sysdeps/generic/strrchr.c b/sysdeps/generic/strrchr.c new file mode 100644 index 0000000000..29402f086c --- /dev/null +++ b/sysdeps/generic/strrchr.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Find the last ocurrence of C in S. */ +char * +DEFUN(strrchr, (s, c), CONST char *s AND int c) +{ + register CONST char *found, *p; + + c = (unsigned char) c; + + /* Since strchr is fast, we use it rather than the obvious loop. */ + + if (c == '\0') + return strchr(s, '\0'); + + found = NULL; + while ((p = strchr(s, c)) != NULL) + { + found = p; + s = p + 1; + } + + return (char *) found; +} + +#ifdef weak_alias +#undef rindex +weak_alias (strrchr, rindex) +#endif diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c new file mode 100644 index 0000000000..bb4d68bd6e --- /dev/null +++ b/sysdeps/generic/strsep.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +char * +DEFUN(strsep, (stringp, delim), + char **stringp AND CONST char *delim) +{ + char *begin, *end; + + begin = *stringp + strspn (*stringp, delim); + end = *stringp + strcspn (*stringp, delim); + + if (end == *stringp) + return NULL; + + if (*end != '\0') + *end++ = '\0'; + *stringp = end; + + return begin; +} diff --git a/sysdeps/generic/strspn.c b/sysdeps/generic/strspn.c new file mode 100644 index 0000000000..89b45ad300 --- /dev/null +++ b/sysdeps/generic/strspn.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Return the length of the maximum initial segment + of S which contains only characters in ACCEPT. */ +size_t +DEFUN(strspn, (s, accept), CONST char *s AND CONST char *accept) +{ + register CONST char *p; + register CONST char *a; + register size_t count = 0; + + for (p = s; *p != '\0'; ++p) + { + for (a = accept; *a != '\0'; ++a) + if (*p == *a) + break; + if (*a == '\0') + return count; + else + ++count; + } + + return count; +} diff --git a/sysdeps/generic/strstr.c b/sysdeps/generic/strstr.c new file mode 100644 index 0000000000..06681de931 --- /dev/null +++ b/sysdeps/generic/strstr.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <string.h> + +/* Return the first ocurrence of NEEDLE in HAYSTACK. */ +char * +DEFUN(strstr, (haystack, needle), + CONST char *CONST haystack AND + CONST char *CONST needle) +{ + register CONST char *CONST needle_end = strchr(needle, '\0'); + register CONST char *CONST haystack_end = strchr(haystack, '\0'); + register CONST size_t needle_len = needle_end - needle; + register CONST size_t needle_last = needle_len - 1; + register CONST char *begin; + + if (needle_len == 0) + return (char *) haystack; /* ANSI 4.11.5.7, line 25. */ + if ((size_t) (haystack_end - haystack) < needle_len) + return NULL; + + for (begin = &haystack[needle_last]; begin < haystack_end; ++begin) + { + register CONST char *n = &needle[needle_last]; + register CONST char *h = begin; + + do + if (*h != *n) + goto loop; /* continue for loop */ + while (--n >= needle && --h >= haystack); + + return (char *) h; + + loop:; + } + + return NULL; +} diff --git a/sysdeps/generic/sub_n.c b/sysdeps/generic/sub_n.c new file mode 100644 index 0000000000..6b33e6696f --- /dev/null +++ b/sysdeps/generic/sub_n.c @@ -0,0 +1,61 @@ +/* __mpn_sub_n -- Subtract two limb vectors of equal, non-zero length. + +Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +mp_limb +#if __STDC__ +__mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size) +#else +__mpn_sub_n (res_ptr, s1_ptr, s2_ptr, size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_srcptr s2_ptr; + mp_size_t size; +#endif +{ + register mp_limb x, y, cy; + register mp_size_t j; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -size; + + /* Offset the base pointers to compensate for the negative indices. */ + s1_ptr -= j; + s2_ptr -= j; + res_ptr -= j; + + cy = 0; + do + { + y = s2_ptr[j]; + x = s1_ptr[j]; + y += cy; /* add previous carry to subtrahend */ + cy = (y < cy); /* get out carry from that addition */ + y = x - y; /* main subtract */ + cy = (y > x) + cy; /* get out carry from the subtract, combine */ + res_ptr[j] = y; + } + while (++j != 0); + + return cy; +} diff --git a/sysdeps/generic/submul_1.c b/sysdeps/generic/submul_1.c new file mode 100644 index 0000000000..855dd3feaf --- /dev/null +++ b/sysdeps/generic/submul_1.c @@ -0,0 +1,64 @@ +/* __mpn_submul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR + by S2_LIMB, subtract the S1_SIZE least significant limbs of the product + from the limb vector pointed to by RES_PTR. Return the most significant + limb of the product, adjusted for carry-out from the subtraction. + +Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" + +mp_limb +__mpn_submul_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + mp_size_t s1_size; + register mp_limb s2_limb; +{ + register mp_limb cy_limb; + register mp_size_t j; + register mp_limb prod_high, prod_low; + register mp_limb x; + + /* The loop counter and index J goes from -SIZE to -1. This way + the loop becomes faster. */ + j = -s1_size; + + /* Offset the base pointers to compensate for the negative indices. */ + res_ptr -= j; + s1_ptr -= j; + + cy_limb = 0; + do + { + umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); + + prod_low += cy_limb; + cy_limb = (prod_low < cy_limb) + prod_high; + + x = res_ptr[j]; + prod_low = x - prod_low; + cy_limb += (prod_low > x); + res_ptr[j] = prod_low; + } + while (++j != 0); + + return cy_limb; +} diff --git a/sysdeps/generic/sys/mman.h b/sysdeps/generic/sys/mman.h new file mode 100644 index 0000000000..3575eeb3b4 --- /dev/null +++ b/sysdeps/generic/sys/mman.h @@ -0,0 +1,106 @@ +/* Definitions for BSD-style memory management. Generic/4.4 BSD version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These are the bits used by 4.4 BSD and its derivatives. On systems + (such as GNU) where these facilities are not system services but can be + emulated in the C library, these are the definitions we emulate. */ + +#ifndef _SYS_MMAN_H + +#define _SYS_MMAN_H 1 +#include <features.h> + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x04 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x01 /* Pages can be executed. */ + + +/* Flags contain mapping type, sharing type and options. */ + +/* Mapping type (must choose one and only one of these). */ +#define MAP_FILE 0x0001 /* Mapped from a file or device. */ +#define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */ +#define MAP_TYPE 0x000f /* Mask for type field. */ + +/* Sharing types (must choose one and only one of these). */ +#define MAP_COPY 0x0020 /* Virtual copy of region at mapping time. */ +#define MAP_SHARED 0x0010 /* Share changes. */ +#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */ + +/* Other flags. */ +#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */ +#define MAP_NOEXTEND 0x0200 /* For MAP_FILE, don't change file size. */ +#define MAP_HASSEMPHORE 0x0400 /* Region may contain semaphores. */ +#define MAP_INHERIT 0x0800 /* Region is retained after exec. */ + +/* Advice to `madvise'. */ +#define MADV_NORMAL 0 /* No further special treatment. */ +#define MADV_RANDOM 1 /* Expect random page references. */ +#define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define MADV_WILLNEED 3 /* Will need these pages. */ +#define MADV_DONTNEED 4 /* Don't need these pages. */ + +#include <sys/cdefs.h> + +__BEGIN_DECLS +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__caddr_t mmap __P ((__caddr_t __addr, size_t __len, + int __prot, int __flags, int __fd, off_t __offset)); + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ +int munmap __P ((__caddr_t __addr, size_t __len)); + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ +int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ +int msync __P ((__caddr_t __addr, size_t __len)); + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ +int madvise __P ((__caddr_t __addr, size_t __len, int __advice)); + +__END_DECLS + + +#endif /* sys/mman.h */ diff --git a/sysdeps/generic/sysd-stdio.c b/sysdeps/generic/sysd-stdio.c new file mode 100644 index 0000000000..fef0ed4d9a --- /dev/null +++ b/sysdeps/generic/sysd-stdio.c @@ -0,0 +1,189 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +/* Read N bytes into BUF from COOKIE. */ +int +DEFUN(__stdio_read, (cookie, buf, n), + PTR cookie AND register char *buf AND register size_t n) +{ + CONST int fd = (int) cookie; +#if defined (EINTR) && defined (EINTR_REPEAT) + int save = errno; + int nread; + + try:; + errno = 0; + nread = __read (fd, buf, (int) n); + if (nread < 0) + { + if (errno == EINTR) + goto try; + return -1; + } + errno = save; + return nread; + +#else /* No EINTR. */ + return __read (fd, buf, n); +#endif +} + + +/* Write N bytes from BUF to COOKIE. */ +int +DEFUN(__stdio_write, (cookie, buf, n), + PTR cookie AND register CONST char *buf AND register size_t n) +{ + CONST int fd = (int) cookie; + register size_t written = 0; + + while (n > 0) + { + int count = __write (fd, buf, (int) n); + if (count > 0) + { + buf += count; + written += count; + n -= count; + } + else if (count < 0 +#if defined (EINTR) && defined (EINTR_REPEAT) + && errno != EINTR +#endif + ) + /* Write error. */ + return -1; + } + + return (int) written; +} + + +/* Move COOKIE's file position *POS bytes, according to WHENCE. + The new file position is stored in *POS. + Returns zero if successful, nonzero if not. */ +int +DEFUN(__stdio_seek, (cookie, pos, whence), + PTR cookie AND fpos_t *pos AND int whence) +{ + off_t new; + new = __lseek ((int) cookie, (off_t) *pos, whence); + if (new < 0) + return 1; + *pos = (fpos_t) new; + return 0; +} + + +/* Close COOKIE. */ +int +DEFUN(__stdio_close, (cookie), PTR cookie) +{ + return __close ((int) cookie); +} + +/* Return the POSIX.1 file descriptor associated with COOKIE, + or -1 for errors. If COOKIE does not relate to any POSIX.1 file + descriptor, this should return -1 with errno set to EOPNOTSUPP. */ +int +DEFUN(__stdio_fileno, (cookie), PTR cookie) +{ + return (int) cookie; +} + + +/* Open the given file with the mode given in the __io_mode argument. */ +int +DEFUN(__stdio_open, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND PTR *cookieptr) +{ + int fd; + int mode; + + if (m.__read && m.__write) + mode = O_RDWR; + else + mode = m.__read ? O_RDONLY : O_WRONLY; + + if (m.__append) + mode |= O_APPEND; + if (m.__exclusive) + mode |= O_EXCL; + if (m.__truncate) + mode |= O_TRUNC; + + if (m.__create) + fd = __open (filename, mode | O_CREAT, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + else + fd = __open (filename, mode); + + if (fd < 0) + return -1; + + *cookieptr = (PTR) fd; + return 0; +} + + +/* Open FILENAME with the mode in M. Use the same magic cookie + already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */ +int +DEFUN(__stdio_reopen, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND + PTR *cookieptr AND __io_close_fn closefn) +{ + PTR newcookie; + + /* We leave the old descriptor open while we open the file. + That way ``freopen ("/dev/stdin", "r", stdin)'' works. */ + + if (__stdio_open (filename, m, &newcookie)) + { + if (errno == ENFILE || errno == EMFILE) + { + /* We are out of file descriptors. Try closing the old one and + retrying the open. */ + (void) (*closefn) (*cookieptr); + if (__stdio_open (filename, m, &newcookie)) + return -1; + } + } + + if (newcookie != *cookieptr) + { + if (closefn != __stdio_close || + /* Try to move the descriptor to the desired one. */ + __dup2 ((int) newcookie, (int) *cookieptr) < 0) + /* Didn't work. Give the caller the new cookie. */ + *cookieptr = newcookie; + } + + return 0; +} diff --git a/sysdeps/generic/tan.c b/sysdeps/generic/tan.c new file mode 100644 index 0000000000..61ed5c55c7 --- /dev/null +++ b/sysdeps/generic/tan.c @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)tan.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include "trig.h" +double +tan(x) +double x; +{ + double a,z,ss,cc,c; + int k; + + if(!finite(x)) /* tan(NaN) and tan(INF) must be NaN */ + return x-x; + x = drem(x,PI); /* reduce x into [-PI/2, PI/2] */ + a = copysign(x,one); /* ... = abs(x) */ + if (a >= PIo4) { + k = 1; + x = copysign(PIo2-a,x); + } + else { + k = 0; + if (a < small) { + big+a; + return x; + } + } + z = x*x; + cc = cos__C(z); + ss = sin__S(z); + z *= half; /* Next get c = cos(x) accurately */ + c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc)); + if (k == 0) + return x+(x*(z-(cc-ss)))/c; /* ... sin/cos */ +#ifdef national + else if (x == zero) + return copysign(fmax,x); /* no inf on 32k */ +#endif /* national */ + else + return c/(x+x*ss); /* ... cos/sin */ +} diff --git a/sysdeps/generic/tanh.c b/sysdeps/generic/tanh.c new file mode 100644 index 0000000000..d4923b3418 --- /dev/null +++ b/sysdeps/generic/tanh.c @@ -0,0 +1,99 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)tanh.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* TANH(X) + * RETURN THE HYPERBOLIC TANGENT OF X + * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 1/8/85; + * REVISED BY K.C. NG on 2/8/85, 2/11/85, 3/7/85, 3/24/85. + * + * Required system supported functions : + * copysign(x,y) + * finite(x) + * + * Required kernel function: + * expm1(x) ...exp(x)-1 + * + * Method : + * 1. reduce x to non-negative by tanh(-x) = - tanh(x). + * 2. + * 0 < x <= 1.e-10 : tanh(x) := x + * -expm1(-2x) + * 1.e-10 < x <= 1 : tanh(x) := -------------- + * expm1(-2x) + 2 + * 2 + * 1 <= x <= 22.0 : tanh(x) := 1 - --------------- + * expm1(2x) + 2 + * 22.0 < x <= INF : tanh(x) := 1. + * + * Note: 22 was chosen so that fl(1.0+2/(expm1(2*22)+2)) == 1. + * + * Special cases: + * tanh(NaN) is NaN; + * only tanh(0)=0 is exact for finite argument. + * + * Accuracy: + * tanh(x) returns the exact hyperbolic tangent of x nealy rounded. + * In a test run with 1,024,000 random arguments on a VAX, the maximum + * observed error was 2.22 ulps (units in the last place). + */ + +double tanh(x) +double x; +{ + static double one=1.0, two=2.0, small = 1.0e-10, big = 1.0e10; + double expm1(), t, copysign(), sign; + int finite(); + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + + sign=copysign(one,x); + x=copysign(x,one); + if(x < 22.0) + if( x > one ) + return(copysign(one-two/(expm1(x+x)+two),sign)); + else if ( x > small ) + {t= -expm1(-(x+x)); return(copysign(t/(two-t),sign));} + else /* raise the INEXACT flag for non-zero x */ + {big+x; return(copysign(x,sign));} + else if(finite(x)) + return (sign+1.0E-37); /* raise the INEXACT flag */ + else + return(sign); /* x is +- INF */ +} diff --git a/sysdeps/generic/termbits.h b/sysdeps/generic/termbits.h new file mode 100644 index 0000000000..542f915d97 --- /dev/null +++ b/sysdeps/generic/termbits.h @@ -0,0 +1,202 @@ +/* termios type and macro definitions. 4.4 BSD/generic GNU version. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These definitions match those used by the 4.4 BSD kernel. + If the operating system has termios system calls or ioctls that + correctly implement the POSIX.1 behavior, there should be a + system-dependent version of this file that defines `struct termios', + `tcflag_t', `cc_t', `speed_t' and the `TC*' constants appropriately. */ + +/* Type of terminal control flag masks. */ +typedef unsigned long int tcflag_t; + +/* Type of control characters. */ +typedef unsigned char cc_t; + +/* Type of baud rate specifiers. */ +typedef long int speed_t; + +/* Terminal control structure. */ +struct termios +{ + /* Input modes. */ + tcflag_t c_iflag; +#define IGNBRK (1 << 0) /* Ignore break condition. */ +#define BRKINT (1 << 1) /* Signal interrupt on break. */ +#define IGNPAR (1 << 2) /* Ignore characters with parity errors. */ +#define PARMRK (1 << 3) /* Mark parity and framing errors. */ +#define INPCK (1 << 4) /* Enable input parity check. */ +#define ISTRIP (1 << 5) /* Strip 8th bit off characters. */ +#define INLCR (1 << 6) /* Map NL to CR on input. */ +#define IGNCR (1 << 7) /* Ignore CR. */ +#define ICRNL (1 << 8) /* Map CR to NL on input. */ +#define IXON (1 << 9) /* Enable start/stop output control. */ +#define IXOFF (1 << 10) /* Enable start/stop input control. */ +#ifdef __USE_BSD +#define IXANY (1 << 11) /* Any character will restart after stop. */ +#define IMAXBEL (1 << 13) /* Ring bell when input queue is full. */ +#endif + + /* Output modes. */ + tcflag_t c_oflag; +#define OPOST (1 << 0) /* Perform output processing. */ +#ifdef __USE_BSD +#define ONLCR (1 << 1) /* Map NL to CR-NL on output. */ +#define OXTABS (1 << 2) /* Expand tabs to spaces. */ +#define ONOEOT (1 << 8) /* Discard EOT (^D) on output. */ +#endif + + /* Control modes. */ + tcflag_t c_cflag; +#ifdef __USE_BSD +#define CIGNORE (1 << 0) /* Ignore these control flags. */ +#endif +#define CSIZE (CS5|CS6|CS7|CS8) /* Number of bits per byte (mask). */ +#define CS5 0 /* 5 bits per byte. */ +#define CS6 (1 << 8) /* 6 bits per byte. */ +#define CS7 (1 << 9) /* 7 bits per byte. */ +#define CS8 (CS6|CS7) /* 8 bits per byte. */ +#define CSTOPB (1 << 10) /* Two stop bits instead of one. */ +#define CREAD (1 << 11) /* Enable receiver. */ +#define PARENB (1 << 12) /* Parity enable. */ +#define PARODD (1 << 13) /* Odd parity instead of even. */ +#define HUPCL (1 << 14) /* Hang up on last close. */ +#define CLOCAL (1 << 15) /* Ignore modem status lines. */ +#ifdef __USE_BSD +#define CCTS_OFLOW (1 << 16) /* CTS flow control of output. */ +#define CRTS_IFLOW (1 << 17) /* RTS flow control of input. */ +#define MDMBUF (1 << 20) /* Carrier flow control of output. */ +#endif + + /* Local modes. */ + tcflag_t c_lflag; +#ifdef __USE_BSD +#define ECHOKE (1 << 0) /* Visual erase for KILL. */ +#endif +#define _ECHOE (1 << 1) /* Visual erase for ERASE. */ +#define ECHOE _ECHOE +#define _ECHOK (1 << 2) /* Echo NL after KILL. */ +#define ECHOK _ECHOK +#define _ECHO (1 << 3) /* Enable echo. */ +#define ECHO _ECHO +#define _ECHONL (1 << 4) /* Echo NL even if ECHO is off. */ +#define ECHONL _ECHONL +#ifdef __USE_BSD +#define ECHOPRT (1 << 5) /* Hardcopy visual erase. */ +#define ECHOCTL (1 << 6) /* Echo control characters as ^X. */ +#endif +#define _ISIG (1 << 7) /* Enable signals. */ +#define ISIG _ISIG +#define _ICANON (1 << 8) /* Do erase and kill processing. */ +#define ICANON _ICANON +#ifdef __USE_BSD +#define ALTWERASE (1 << 9) /* Alternate WERASE algorithm. */ +#endif +#define _IEXTEN (1 << 10) /* Enable DISCARD and LNEXT. */ +#define IEXTEN _IEXTEN +#define EXTPROC (1 << 11) /* External processing. */ +#define _TOSTOP (1 << 22) /* Send SIGTTOU for background output. */ +#define TOSTOP _TOSTOP +#ifdef __USE_BSD +#define FLUSHO (1 << 23) /* Output being flushed (state). */ +#define NOKERNINFO (1 << 25) /* Disable VSTATUS. */ +#define PENDIN (1 << 29) /* Retype pending input (state). */ +#endif +#define _NOFLSH (1 << 31) /* Disable flush after interrupt. */ +#define NOFLSH _NOFLSH + + /* Control characters. */ +#define VEOF 0 /* End-of-file character [ICANON]. */ +#define VEOL 1 /* End-of-line character [ICANON]. */ +#ifdef __USE_BSD +#define VEOL2 2 /* Second EOL character [ICANON]. */ +#endif +#define VERASE 3 /* Erase character [ICANON]. */ +#ifdef __USE_BSD +#define VWERASE 4 /* Word-erase character [ICANON]. */ +#endif +#define VKILL 5 /* Kill-line character [ICANON]. */ +#ifdef __USE_BSD +#define VREPRINT 6 /* Reprint-line character [ICANON]. */ +#endif +#define VINTR 8 /* Interrupt character [ISIG]. */ +#define VQUIT 9 /* Quit character [ISIG]. */ +#define VSUSP 10 /* Suspend character [ISIG]. */ +#ifdef __USE_BSD +#define VDSUSP 11 /* Delayed suspend character [ISIG]. */ +#endif +#define VSTART 12 /* Start (X-ON) character [IXON, IXOFF]. */ +#define VSTOP 13 /* Stop (X-OFF) character [IXON, IXOFF]. */ +#ifdef __USE_BSD +#define VLNEXT 14 /* Literal-next character [IEXTEN]. */ +#define VDISCARD 15 /* Discard character [IEXTEN]. */ +#endif +#define VMIN 16 /* Minimum number of bytes read at once [!ICANON]. */ +#define VTIME 17 /* Time-out value (tenths of a second) [!ICANON]. */ +#ifdef __USE_BSD +#define VSTATUS 18 /* Status character [ICANON]. */ +#endif +#define NCCS 20 /* Value duplicated in <hurd/tioctl.defs>. */ + cc_t c_cc[NCCS]; + + /* Input and output baud rates. */ + speed_t __ispeed, __ospeed; +#define B0 0 /* Hang up. */ +#define B50 50 /* 50 baud. */ +#define B75 75 /* 75 baud. */ +#define B110 110 /* 110 baud. */ +#define B134 134 /* 134.5 baud. */ +#define B150 150 /* 150 baud. */ +#define B200 200 /* 200 baud. */ +#define B300 300 /* 300 baud. */ +#define B600 600 /* 600 baud. */ +#define B1200 1200 /* 1200 baud. */ +#define B1800 1800 /* 1800 baud. */ +#define B2400 2400 /* 2400 baud. */ +#define B4800 4800 /* 4800 baud. */ +#define B9600 9600 /* 9600 baud. */ +#define B19200 19200 /* 19200 baud. */ +#define B38400 38400 /* 38400 baud. */ +#ifdef __USE_BSD +#define EXTA 19200 +#define EXTB 38400 +#endif +}; + +#define _IOT_termios /* Hurd ioctl type field. */ \ + _IOT (_IOTS (tcflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2) + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 /* Change immediately. */ +#define TCSADRAIN 1 /* Change when pending output is written. */ +#define TCSAFLUSH 2 /* Flush pending input before changing. */ +#ifdef __USE_BSD +#define TCSASOFT 0x10 /* Flag: Don't alter hardware state. */ +#endif + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 1 /* Discard data received but not yet read. */ +#define TCOFLUSH 2 /* Discard data written but not yet sent. */ +#define TCIOFLUSH 3 /* Discard all pending data. */ + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 1 /* Suspend output. */ +#define TCOON 2 /* Restart suspended output. */ +#define TCIOFF 3 /* Send a STOP character. */ +#define TCION 4 /* Send a START character. */ diff --git a/sysdeps/generic/trig.h b/sysdeps/generic/trig.h new file mode 100644 index 0000000000..9e05b0ea0d --- /dev/null +++ b/sysdeps/generic/trig.h @@ -0,0 +1,215 @@ +/* + * 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. + * + * @(#)trig.h 8.1 (Berkeley) 6/4/93 + */ + +#include "mathimpl.h" + +vc(thresh, 2.6117239648121182150E-1 ,b863,3f85,6ea0,6b02, -1, .85B8636B026EA0) +vc(PIo4, 7.8539816339744830676E-1 ,0fda,4049,68c2,a221, 0, .C90FDAA22168C2) +vc(PIo2, 1.5707963267948966135E0 ,0fda,40c9,68c2,a221, 1, .C90FDAA22168C2) +vc(PI3o4, 2.3561944901923449203E0 ,cbe3,4116,0e92,f999, 2, .96CBE3F9990E92) +vc(PI, 3.1415926535897932270E0 ,0fda,4149,68c2,a221, 2, .C90FDAA22168C2) +vc(PI2, 6.2831853071795864540E0 ,0fda,41c9,68c2,a221, 3, .C90FDAA22168C2) + +ic(thresh, 2.6117239648121182150E-1 , -2, 1.0B70C6D604DD4) +ic(PIo4, 7.8539816339744827900E-1 , -1, 1.921FB54442D18) +ic(PIo2, 1.5707963267948965580E0 , 0, 1.921FB54442D18) +ic(PI3o4, 2.3561944901923448370E0 , 1, 1.2D97C7F3321D2) +ic(PI, 3.1415926535897931160E0 , 1, 1.921FB54442D18) +ic(PI2, 6.2831853071795862320E0 , 2, 1.921FB54442D18) + +#ifdef vccast +#define thresh vccast(thresh) +#define PIo4 vccast(PIo4) +#define PIo2 vccast(PIo2) +#define PI3o4 vccast(PI3o4) +#define PI vccast(PI) +#define PI2 vccast(PI2) +#endif + +#ifdef national +static long fmaxx[] = { 0xffffffff, 0x7fefffff}; +#define fmax (*(double*)fmaxx) +#endif /* national */ + +static const double + zero = 0, + one = 1, + negone = -1, + half = 1.0/2.0, + small = 1E-10, /* 1+small**2 == 1; better values for small: + * small = 1.5E-9 for VAX D + * = 1.2E-8 for IEEE Double + * = 2.8E-10 for IEEE Extended + */ + big = 1E20; /* big := 1/(small**2) */ + +/* sin__S(x*x) ... re-implemented as a macro + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * STATIC KERNEL FUNCTION OF SIN(X), COS(X), AND TAN(X) + * CODED IN C BY K.C. NG, 1/21/85; + * REVISED BY K.C. NG on 8/13/85. + * + * sin(x*k) - x + * RETURN --------------- on [-PI/4,PI/4] , where k=pi/PI, PI is the rounded + * x + * value of pi in machine precision: + * + * Decimal: + * pi = 3.141592653589793 23846264338327 ..... + * 53 bits PI = 3.141592653589793 115997963 ..... , + * 56 bits PI = 3.141592653589793 227020265 ..... , + * + * Hexadecimal: + * pi = 3.243F6A8885A308D313198A2E.... + * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 + * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 + * + * Method: + * 1. Let z=x*x. Create a polynomial approximation to + * (sin(k*x)-x)/x = z*(S0 + S1*z^1 + ... + S5*z^5). + * Then + * sin__S(x*x) = z*(S0 + S1*z^1 + ... + S5*z^5) + * + * The coefficient S's are obtained by a special Remez algorithm. + * + * Accuracy: + * In the absence of rounding error, the approximation has absolute error + * less than 2**(-61.11) for VAX D FORMAT, 2**(-57.45) for IEEE DOUBLE. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + * + */ + +vc(S0, -1.6666666666666646660E-1 ,aaaa,bf2a,aa71,aaaa, -2, -.AAAAAAAAAAAA71) +vc(S1, 8.3333333333297230413E-3 ,8888,3d08,477f,8888, -6, .8888888888477F) +vc(S2, -1.9841269838362403710E-4 ,0d00,ba50,1057,cf8a, -12, -.D00D00CF8A1057) +vc(S3, 2.7557318019967078930E-6 ,ef1c,3738,bedc,a326, -18, .B8EF1CA326BEDC) +vc(S4, -2.5051841873876551398E-8 ,3195,b3d7,e1d3,374c, -25, -.D73195374CE1D3) +vc(S5, 1.6028995389845827653E-10 ,3d9c,3030,cccc,6d26, -32, .B03D9C6D26CCCC) +vc(S6, -6.2723499671769283121E-13 ,8d0b,ac30,ea82,7561, -40, -.B08D0B7561EA82) + +ic(S0, -1.6666666666666463126E-1 , -3, -1.555555555550C) +ic(S1, 8.3333333332992771264E-3 , -7, 1.111111110C461) +ic(S2, -1.9841269816180999116E-4 , -13, -1.A01A019746345) +ic(S3, 2.7557309793219876880E-6 , -19, 1.71DE3209CDCD9) +ic(S4, -2.5050225177523807003E-8 , -26, -1.AE5C0E319A4EF) +ic(S5, 1.5868926979889205164E-10 , -33, 1.5CF61DF672B13) + +#ifdef vccast +#define S0 vccast(S0) +#define S1 vccast(S1) +#define S2 vccast(S2) +#define S3 vccast(S3) +#define S4 vccast(S4) +#define S5 vccast(S5) +#define S6 vccast(S6) +#endif + +#if defined(vax)||defined(tahoe) +# define sin__S(z) (z*(S0+z*(S1+z*(S2+z*(S3+z*(S4+z*(S5+z*S6))))))) +#else /* defined(vax)||defined(tahoe) */ +# define sin__S(z) (z*(S0+z*(S1+z*(S2+z*(S3+z*(S4+z*S5)))))) +#endif /* defined(vax)||defined(tahoe) */ + +/* cos__C(x*x) ... re-implemented as a macro + * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS) + * STATIC KERNEL FUNCTION OF SIN(X), COS(X), AND TAN(X) + * CODED IN C BY K.C. NG, 1/21/85; + * REVISED BY K.C. NG on 8/13/85. + * + * x*x + * RETURN cos(k*x) - 1 + ----- on [-PI/4,PI/4], where k = pi/PI, + * 2 + * PI is the rounded value of pi in machine precision : + * + * Decimal: + * pi = 3.141592653589793 23846264338327 ..... + * 53 bits PI = 3.141592653589793 115997963 ..... , + * 56 bits PI = 3.141592653589793 227020265 ..... , + * + * Hexadecimal: + * pi = 3.243F6A8885A308D313198A2E.... + * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 + * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 + * + * + * Method: + * 1. Let z=x*x. Create a polynomial approximation to + * cos(k*x)-1+z/2 = z*z*(C0 + C1*z^1 + ... + C5*z^5) + * then + * cos__C(z) = z*z*(C0 + C1*z^1 + ... + C5*z^5) + * + * The coefficient C's are obtained by a special Remez algorithm. + * + * Accuracy: + * In the absence of rounding error, the approximation has absolute error + * less than 2**(-64) for VAX D FORMAT, 2**(-58.3) for IEEE DOUBLE. + * + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +vc(C0, 4.1666666666666504759E-2 ,aaaa,3e2a,a9f0,aaaa, -4, .AAAAAAAAAAA9F0) +vc(C1, -1.3888888888865302059E-3 ,0b60,bbb6,0cca,b60a, -9, -.B60B60B60A0CCA) +vc(C2, 2.4801587285601038265E-5 ,0d00,38d0,098f,cdcd, -15, .D00D00CDCD098F) +vc(C3, -2.7557313470902390219E-7 ,f27b,b593,e805,b593, -21, -.93F27BB593E805) +vc(C4, 2.0875623401082232009E-9 ,74c8,320f,3ff0,fa1e, -28, .8F74C8FA1E3FF0) +vc(C5, -1.1355178117642986178E-11 ,c32d,ae47,5a63,0a5c, -36, -.C7C32D0A5C5A63) + +ic(C0, 4.1666666666666504759E-2 , -5, 1.555555555553E) +ic(C1, -1.3888888888865301516E-3 , -10, -1.6C16C16C14199) +ic(C2, 2.4801587269650015769E-5 , -16, 1.A01A01971CAEB) +ic(C3, -2.7557304623183959811E-7 , -22, -1.27E4F1314AD1A) +ic(C4, 2.0873958177697780076E-9 , -29, 1.1EE3B60DDDC8C) +ic(C5, -1.1250289076471311557E-11 , -37, -1.8BD5986B2A52E) + +#ifdef vccast +#define C0 vccast(C0) +#define C1 vccast(C1) +#define C2 vccast(C2) +#define C3 vccast(C3) +#define C4 vccast(C4) +#define C5 vccast(C5) +#endif + +#define cos__C(z) (z*z*(C0+z*(C1+z*(C2+z*(C3+z*(C4+z*C5)))))) diff --git a/sysdeps/generic/uname.c b/sysdeps/generic/uname.c new file mode 100644 index 0000000000..b3ecf70ad7 --- /dev/null +++ b/sysdeps/generic/uname.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <string.h> +#include <sys/utsname.h> +#include <unistd.h> + +/* This file is created by the configuration process, and defines UNAME_*. */ +#include <config-name.h> + +/* Put information about the system in NAME. */ +int +DEFUN(uname, (name), struct utsname *name) +{ + int save; + + if (name == NULL) + { + errno = EINVAL; + return -1; + } + + save = errno; + if (__gethostname (name->nodename, sizeof (name->nodename)) < 0) + { + if (errno == ENOSYS) + { + /* Hostname is meaningless for this machine. */ + name->nodename[0] = '\0'; + errno = save; + } +#ifdef ENAMETOOLONG + else if (errno == ENAMETOOLONG) + /* The name was truncated. */ + errno = save; +#endif + else + return -1; + } + strncpy (name->sysname, UNAME_SYSNAME, sizeof (name->sysname)); + strncpy (name->release, UNAME_RELEASE, sizeof (name->release)); + strncpy (name->version, UNAME_VERSION, sizeof (name->version)); + strncpy (name->machine, UNAME_MACHINE, sizeof (name->machine)); + + return 0; +} diff --git a/sysdeps/generic/utsnamelen.h b/sysdeps/generic/utsnamelen.h new file mode 100644 index 0000000000..5594bcc4da --- /dev/null +++ b/sysdeps/generic/utsnamelen.h @@ -0,0 +1,3 @@ +/* The size of the character arrays used to hold the information + in a `struct utsname'. Enlarge this as necessary. */ +#define _UTSNAME_LENGTH 1024 diff --git a/sysdeps/generic/varargs.h b/sysdeps/generic/varargs.h new file mode 100644 index 0000000000..3500480f73 --- /dev/null +++ b/sysdeps/generic/varargs.h @@ -0,0 +1,61 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _VARARGS_H + +#define _VARARGS_H 1 +#include <features.h> + +#ifdef __GNUC__ + +#define va_alist __builtin_va_alist +#define va_dcl int __builtin_va_alist; +#define va_list char * + +#ifdef __sparc__ +#define va_start(AP) \ + (__builtin_saveregs (), \ + AP = ((void *) &__builtin_va_alist)) +#else +#define va_start(AP) AP=(char *) &__builtin_va_alist +#endif +#define va_end(AP) + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#define va_arg(AP, TYPE) \ + (*((TYPE *) (AP += __va_rounded_size (TYPE), \ + AP - __va_rounded_size (TYPE)))) + +#else /* Not GCC. */ + +/* Implement varargs on top of our stdarg implementation. */ + +#include <stdarg.h> + +#define va_alist __va_fakearg +#define va_dcl int __va_fakearg; + +#undef va_start +#define va_start(ap) (__va_start((ap), __va_fakearg), \ + (ap) -= sizeof(__va_fakearg)) + +#endif /* GCC. */ + +#endif /* varargs.h */ diff --git a/sysdeps/generic/vfork.c b/sysdeps/generic/vfork.c new file mode 100644 index 0000000000..f5d2e840bf --- /dev/null +++ b/sysdeps/generic/vfork.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* If we don't have vfork, fork is close enough. */ + +__pid_t +__vfork __P ((void)) +{ + return __fork (); +} + +weak_alias (__vfork, vfork) diff --git a/sysdeps/generic/vlimit.c b/sysdeps/generic/vlimit.c new file mode 100644 index 0000000000..56f1199ab3 --- /dev/null +++ b/sysdeps/generic/vlimit.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This is generic in the sense that it will work with the BSD, SYSV, + or stub versions of getrlimit. Separate versions could be written + for efficiency, but it's probably not worth it. */ + +#include <ansidecl.h> +#include <sys/vlimit.h> +#include <sys/resource.h> +#include <errno.h> + +/* Set the soft limit for RESOURCE to be VALUE. + Returns 0 for success, -1 for failure. */ +int +DEFUN(vlimit, (resource, value), + enum __vlimit_resource resource AND int value) +{ + if (resource >= LIM_CPU && resource <= LIM_MAXRSS) + { + /* The rlimit codes happen to each be one less + than the corresponding vlimit codes. */ + enum __rlimit_resource rlimit_res = + (enum __rlimit_resource) ((int) resource - 1); + struct rlimit lims; + + if (getrlimit(rlimit_res, &lims) < 0) + return -1; + + lims.rlim_cur = value; + return setrlimit(rlimit_res, &lims); + } + + errno = EINVAL; + return -1; +} diff --git a/sysdeps/generic/vtimes.c b/sysdeps/generic/vtimes.c new file mode 100644 index 0000000000..faa053ff79 --- /dev/null +++ b/sysdeps/generic/vtimes.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <sys/vtimes.h> +#include <sys/resource.h> + +/* Return the number of 1/VTIMES_UNITS_PER_SECOND-second + units in the `struct timeval' TV. */ +#define TIMEVAL_TO_VTIMES(tv) \ + ((tv.tv_sec * VTIMES_UNITS_PER_SECOND) + \ + (tv.tv_usec * VTIMES_UNITS_PER_SECOND / 1000000)) + +/* If VT is not NULL, write statistics for WHO into *VT. + Return 0 for success, -1 for failure. */ +static int +DEFUN(vtimes_one, (vt, who), + struct vtimes *vt AND enum __rusage_who who) +{ + if (vt != NULL) + { + struct rusage usage; + + if (getrusage(who, &usage) < 0) + return -1; + + vt->vm_utime = TIMEVAL_TO_VTIMES(usage.ru_utime); + vt->vm_stime = TIMEVAL_TO_VTIMES(usage.ru_stime); + vt->vm_idsrss = usage.ru_idrss + usage.ru_isrss; + vt->vm_majflt = usage.ru_majflt; + vt->vm_minflt = usage.ru_minflt; + vt->vm_nswap = usage.ru_nswap; + vt->vm_inblk = usage.ru_inblock; + vt->vm_oublk = usage.ru_oublock; + } + return 0; +} + +/* If CURRENT is not NULL, write statistics for the current process into + *CURRENT. If CHILD is not NULL, write statistics for all terminated child + processes into *CHILD. Returns 0 for success, -1 for failure. */ +int +DEFUN(vtimes, (current, child), + struct vtimes *current AND struct vtimes *child) +{ + if (vtimes_one(current, RUSAGE_SELF) < 0 || + vtimes_one(child, RUSAGE_CHILDREN) < 0) + return -1; + return 0; +} diff --git a/sysdeps/generic/waitstatus.h b/sysdeps/generic/waitstatus.h new file mode 100644 index 0000000000..fdb40db7ef --- /dev/null +++ b/sysdeps/generic/waitstatus.h @@ -0,0 +1,103 @@ +/* Definitions of status bits for `wait' et al. +Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Everything extant so far uses these same bits. */ + +#ifndef _WAITSTATUS_H +#define _WAITSTATUS_H + +/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ +#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) + +/* If WIFSIGNALED(STATUS), the terminating signal. */ +#define __WTERMSIG(status) ((status) & 0x7f) + +/* If WIFSTOPPED(STATUS), the signal that stopped the child. */ +#define __WSTOPSIG(status) __WEXITSTATUS(status) + +/* Nonzero if STATUS indicates normal termination. */ +#define __WIFEXITED(status) (__WTERMSIG(status) == 0) + +/* Nonzero if STATUS indicates termination by a signal. */ +#ifdef __GNUC__ +#define __WIFSIGNALED(status) \ + (__extension__ ({ int __stat = (status); \ + !__WIFSTOPPED(__stat) && !__WIFEXITED(__stat); })) +#else /* Not GCC. */ +#define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status)) +#endif /* GCC. */ + +/* Nonzero if STATUS indicates the child is stopped. */ +#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f) + +/* Nonzero if STATUS indicates the child dumped core. */ +#define __WCOREDUMP(status) ((status) & __WCOREFLAG) + +/* Macros for constructing status values. */ +#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) +#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f) +#define __WCOREFLAG 0x80 + + +#ifdef __USE_BSD + +#include <endian.h> + +union wait + { + struct + { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int __w_termsig:7; /* Terminating signal. */ + unsigned int __w_coredump:1; /* Set if dumped core. */ + unsigned int __w_retcode:8; /* Return code if exited normally. */ + unsigned int:16; +#endif /* Little endian. */ +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int:16; + unsigned int __w_retcode:8; + unsigned int __w_coredump:1; + unsigned int __w_termsig:7; +#endif /* Big endian. */ + } __wait_terminated; + struct + { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int __w_stopval:8; /* W_STOPPED if stopped. */ + unsigned int __w_stopsig:8; /* Stopping signal. */ + unsigned int:16; +#endif /* Little endian. */ +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int:16; + unsigned int __w_stopsig:8; /* Stopping signal. */ + unsigned int __w_stopval:8; /* W_STOPPED if stopped. */ +#endif /* Big endian. */ + } __wait_stopped; + }; + +#define w_termsig __wait_terminated.__w_termsig +#define w_coredump __wait_terminated.__w_coredump +#define w_retcode __wait_terminated.__w_retcode +#define w_stopsig __wait_stopped.__w_stopsig +#define w_stopval __wait_stopped.__w_stopval + +#endif /* Use BSD. */ + + +#endif /* waitstatus.h */ diff --git a/sysdeps/generic/wordcopy.c b/sysdeps/generic/wordcopy.c new file mode 100644 index 0000000000..44dabf6e00 --- /dev/null +++ b/sysdeps/generic/wordcopy.c @@ -0,0 +1,405 @@ +/* _memcopy.c -- subroutines for memory copy functions. + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */ + +#include <ansidecl.h> +#include <stddef.h> +#include <memcopy.h> + +/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to + block beginning at DSTP with LEN `op_t' words (not LEN bytes!). + Both SRCP and DSTP should be aligned for memory operations on `op_t's. */ + +void +DEFUN(_wordcopy_fwd_aligned, (dstp, srcp, len), + long int dstp AND long int srcp AND size_t len) +{ + op_t a0, a1; + + switch (len % 8) + { + case 2: + a0 = ((op_t *) srcp)[0]; + srcp -= 6 * OPSIZ; + dstp -= 7 * OPSIZ; + len += 6; + goto do1; + case 3: + a1 = ((op_t *) srcp)[0]; + srcp -= 5 * OPSIZ; + dstp -= 6 * OPSIZ; + len += 5; + goto do2; + case 4: + a0 = ((op_t *) srcp)[0]; + srcp -= 4 * OPSIZ; + dstp -= 5 * OPSIZ; + len += 4; + goto do3; + case 5: + a1 = ((op_t *) srcp)[0]; + srcp -= 3 * OPSIZ; + dstp -= 4 * OPSIZ; + len += 3; + goto do4; + case 6: + a0 = ((op_t *) srcp)[0]; + srcp -= 2 * OPSIZ; + dstp -= 3 * OPSIZ; + len += 2; + goto do5; + case 7: + a1 = ((op_t *) srcp)[0]; + srcp -= 1 * OPSIZ; + dstp -= 2 * OPSIZ; + len += 1; + goto do6; + + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return; + a0 = ((op_t *) srcp)[0]; + srcp -= 0 * OPSIZ; + dstp -= 1 * OPSIZ; + goto do7; + case 1: + a1 = ((op_t *) srcp)[0]; + srcp -=-1 * OPSIZ; + dstp -= 0 * OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + goto do8; /* No-op. */ + } + + do + { + do8: + a0 = ((op_t *) srcp)[0]; + ((op_t *) dstp)[0] = a1; + do7: + a1 = ((op_t *) srcp)[1]; + ((op_t *) dstp)[1] = a0; + do6: + a0 = ((op_t *) srcp)[2]; + ((op_t *) dstp)[2] = a1; + do5: + a1 = ((op_t *) srcp)[3]; + ((op_t *) dstp)[3] = a0; + do4: + a0 = ((op_t *) srcp)[4]; + ((op_t *) dstp)[4] = a1; + do3: + a1 = ((op_t *) srcp)[5]; + ((op_t *) dstp)[5] = a0; + do2: + a0 = ((op_t *) srcp)[6]; + ((op_t *) dstp)[6] = a1; + do1: + a1 = ((op_t *) srcp)[7]; + ((op_t *) dstp)[7] = a0; + + srcp += 8 * OPSIZ; + dstp += 8 * OPSIZ; + len -= 8; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + ((op_t *) dstp)[0] = a1; +} + +/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to + block beginning at DSTP with LEN `op_t' words (not LEN bytes!). + DSTP should be aligned for memory operations on `op_t's, but SRCP must + *not* be aligned. */ + +void +DEFUN(_wordcopy_fwd_dest_aligned, (dstp, srcp, len), + long int dstp AND long int srcp AND size_t len) +{ + op_t a0, a1, a2, a3; + int sh_1, sh_2; + + /* Calculate how to shift a word read at the memory operation + aligned srcp to make it aligned for copy. */ + + sh_1 = 8 * (srcp % OPSIZ); + sh_2 = 8 * OPSIZ - sh_1; + + /* Make SRCP aligned by rounding it down to the beginning of the `op_t' + it points in the middle of. */ + srcp &= -OPSIZ; + + switch (len % 4) + { + case 2: + a1 = ((op_t *) srcp)[0]; + a2 = ((op_t *) srcp)[1]; + srcp -= 1 * OPSIZ; + dstp -= 3 * OPSIZ; + len += 2; + goto do1; + case 3: + a0 = ((op_t *) srcp)[0]; + a1 = ((op_t *) srcp)[1]; + srcp -= 0 * OPSIZ; + dstp -= 2 * OPSIZ; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return; + a3 = ((op_t *) srcp)[0]; + a0 = ((op_t *) srcp)[1]; + srcp -=-1 * OPSIZ; + dstp -= 1 * OPSIZ; + len += 0; + goto do3; + case 1: + a2 = ((op_t *) srcp)[0]; + a3 = ((op_t *) srcp)[1]; + srcp -=-2 * OPSIZ; + dstp -= 0 * OPSIZ; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + goto do4; /* No-op. */ + } + + do + { + do4: + a0 = ((op_t *) srcp)[0]; + ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2); + do3: + a1 = ((op_t *) srcp)[1]; + ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2); + do2: + a2 = ((op_t *) srcp)[2]; + ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2); + do1: + a3 = ((op_t *) srcp)[3]; + ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2); + + srcp += 4 * OPSIZ; + dstp += 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2); +} + +/* _wordcopy_bwd_aligned -- Copy block finishing right before + SRCP to block finishing right before DSTP with LEN `op_t' words + (not LEN bytes!). Both SRCP and DSTP should be aligned for memory + operations on `op_t's. */ + +void +DEFUN(_wordcopy_bwd_aligned, (dstp, srcp, len), + long int dstp AND long int srcp AND size_t len) +{ + op_t a0, a1; + + switch (len % 8) + { + case 2: + srcp -= 2 * OPSIZ; + dstp -= 1 * OPSIZ; + a0 = ((op_t *) srcp)[1]; + len += 6; + goto do1; + case 3: + srcp -= 3 * OPSIZ; + dstp -= 2 * OPSIZ; + a1 = ((op_t *) srcp)[2]; + len += 5; + goto do2; + case 4: + srcp -= 4 * OPSIZ; + dstp -= 3 * OPSIZ; + a0 = ((op_t *) srcp)[3]; + len += 4; + goto do3; + case 5: + srcp -= 5 * OPSIZ; + dstp -= 4 * OPSIZ; + a1 = ((op_t *) srcp)[4]; + len += 3; + goto do4; + case 6: + srcp -= 6 * OPSIZ; + dstp -= 5 * OPSIZ; + a0 = ((op_t *) srcp)[5]; + len += 2; + goto do5; + case 7: + srcp -= 7 * OPSIZ; + dstp -= 6 * OPSIZ; + a1 = ((op_t *) srcp)[6]; + len += 1; + goto do6; + + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return; + srcp -= 8 * OPSIZ; + dstp -= 7 * OPSIZ; + a0 = ((op_t *) srcp)[7]; + goto do7; + case 1: + srcp -= 9 * OPSIZ; + dstp -= 8 * OPSIZ; + a1 = ((op_t *) srcp)[8]; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + goto do8; /* No-op. */ + } + + do + { + do8: + a0 = ((op_t *) srcp)[7]; + ((op_t *) dstp)[7] = a1; + do7: + a1 = ((op_t *) srcp)[6]; + ((op_t *) dstp)[6] = a0; + do6: + a0 = ((op_t *) srcp)[5]; + ((op_t *) dstp)[5] = a1; + do5: + a1 = ((op_t *) srcp)[4]; + ((op_t *) dstp)[4] = a0; + do4: + a0 = ((op_t *) srcp)[3]; + ((op_t *) dstp)[3] = a1; + do3: + a1 = ((op_t *) srcp)[2]; + ((op_t *) dstp)[2] = a0; + do2: + a0 = ((op_t *) srcp)[1]; + ((op_t *) dstp)[1] = a1; + do1: + a1 = ((op_t *) srcp)[0]; + ((op_t *) dstp)[0] = a0; + + srcp -= 8 * OPSIZ; + dstp -= 8 * OPSIZ; + len -= 8; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + ((op_t *) dstp)[7] = a1; +} + +/* _wordcopy_bwd_dest_aligned -- Copy block finishing right + before SRCP to block finishing right before DSTP with LEN `op_t' + words (not LEN bytes!). DSTP should be aligned for memory + operations on `op_t', but SRCP must *not* be aligned. */ + +void +DEFUN(_wordcopy_bwd_dest_aligned, (dstp, srcp, len), + long int dstp AND long int srcp AND size_t len) +{ + op_t a0, a1, a2, a3; + int sh_1, sh_2; + + /* Calculate how to shift a word read at the memory operation + aligned srcp to make it aligned for copy. */ + + sh_1 = 8 * (srcp % OPSIZ); + sh_2 = 8 * OPSIZ - sh_1; + + /* Make srcp aligned by rounding it down to the beginning of the op_t + it points in the middle of. */ + srcp &= -OPSIZ; + srcp += OPSIZ; + + switch (len % 4) + { + case 2: + srcp -= 3 * OPSIZ; + dstp -= 1 * OPSIZ; + a2 = ((op_t *) srcp)[2]; + a1 = ((op_t *) srcp)[1]; + len += 2; + goto do1; + case 3: + srcp -= 4 * OPSIZ; + dstp -= 2 * OPSIZ; + a3 = ((op_t *) srcp)[3]; + a2 = ((op_t *) srcp)[2]; + len += 1; + goto do2; + case 0: + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + return; + srcp -= 5 * OPSIZ; + dstp -= 3 * OPSIZ; + a0 = ((op_t *) srcp)[4]; + a3 = ((op_t *) srcp)[3]; + goto do3; + case 1: + srcp -= 6 * OPSIZ; + dstp -= 4 * OPSIZ; + a1 = ((op_t *) srcp)[5]; + a0 = ((op_t *) srcp)[4]; + len -= 1; + if (OP_T_THRES <= 3 * OPSIZ && len == 0) + goto do0; + goto do4; /* No-op. */ + } + + do + { + do4: + a3 = ((op_t *) srcp)[3]; + ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2); + do3: + a2 = ((op_t *) srcp)[2]; + ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2); + do2: + a1 = ((op_t *) srcp)[1]; + ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2); + do1: + a0 = ((op_t *) srcp)[0]; + ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2); + + srcp -= 4 * OPSIZ; + dstp -= 4 * OPSIZ; + len -= 4; + } + while (len != 0); + + /* This is the right position for do0. Please don't move + it into the loop. */ + do0: + ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2); +} diff --git a/sysdeps/i386/Implies b/sysdeps/i386/Implies new file mode 100644 index 0000000000..1610bfdc5b --- /dev/null +++ b/sysdeps/i386/Implies @@ -0,0 +1 @@ +ieee754 diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile new file mode 100644 index 0000000000..29676784a2 --- /dev/null +++ b/sysdeps/i386/Makefile @@ -0,0 +1,3 @@ +# The mpn functions need a #define for asm syntax flavor. +# Every i386 port in use uses gas syntax (I think). +asm-CPPFLAGS := $(asm-CPPFLAGS) -DGAS_SYNTAX diff --git a/sysdeps/i386/__longjmp.c b/sysdeps/i386/__longjmp.c new file mode 100644 index 0000000000..65d6ec18ec --- /dev/null +++ b/sysdeps/i386/__longjmp.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* Put these global register declarations first, because we get an error if + they come after any function definition, including inlines which might + be in some header. */ + +#define REGS \ + REG (bx);\ + REG (si);\ + REG (di);\ + REG (bp);\ + REG (sp) + +#define REG(xx) register long int xx asm (#xx) +REGS; +#undef REG + +#include <ansidecl.h> +#include <errno.h> +#include <setjmp.h> +#include <stdlib.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +void +DEFUN(__longjmp, (env, val), + __jmp_buf env AND int val) +{ + /* We specify explicit registers because, when not optimizing, + the compiler will generate code that uses the frame pointer + after it's been munged. */ + + register CONST __typeof (env[0]) *e asm ("cx"); + register int v asm ("ax"); + + e = env; + v = val == 0 ? 1 : val; + +#define REG(xx) xx = (long int) e->__##xx + REGS; + + asm volatile ("jmp %*%0" : : "g" (e->__pc), "a" (v)); + + /* NOTREACHED */ + abort (); +} diff --git a/sysdeps/i386/abort.c b/sysdeps/i386/abort.c new file mode 100644 index 0000000000..28513fd1ec --- /dev/null +++ b/sysdeps/i386/abort.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +/* Cause an abnormal program termination with core-dump. */ +void +DEFUN_VOID(abort) +{ + while (1) + asm ("hlt"); +} diff --git a/sysdeps/i386/add_n.S b/sysdeps/i386/add_n.S new file mode 100644 index 0000000000..f528976866 --- /dev/null +++ b/sysdeps/i386/add_n.S @@ -0,0 +1,94 @@ +/* i80386 __mpn_add_n -- Add two limb vectors of the same length > 0 and store +sum in a third limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 12) + size (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +.text + ALIGN (3) + .globl C_SYMBOL_NAME(__mpn_add_n) +C_SYMBOL_NAME(__mpn_add_n:) + pushl %edi + pushl %esi + + movl 12(%esp),%edi /* res_ptr */ + movl 16(%esp),%esi /* s1_ptr */ + movl 20(%esp),%edx /* s2_ptr */ + movl 24(%esp),%ecx /* size */ + + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax + andl $7,%eax /* get index where to start loop */ + jz Loop /* necessary special case for 0 */ + incl %ecx /* adjust loop count */ + shll $2,%eax /* adjustment for pointers... */ + subl %eax,%edi /* ... since they are offset ... */ + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ + leal (Loop - 3)(%eax,%eax,8),%eax /* calc start addr in loop */ + jmp *%eax /* jump into loop */ + ALIGN (3) +Loop: movl (%esi),%eax + adcl (%edx),%eax + movl %eax,(%edi) + movl 4(%esi),%eax + adcl 4(%edx),%eax + movl %eax,4(%edi) + movl 8(%esi),%eax + adcl 8(%edx),%eax + movl %eax,8(%edi) + movl 12(%esi),%eax + adcl 12(%edx),%eax + movl %eax,12(%edi) + movl 16(%esi),%eax + adcl 16(%edx),%eax + movl %eax,16(%edi) + movl 20(%esi),%eax + adcl 20(%edx),%eax + movl %eax,20(%edi) + movl 24(%esi),%eax + adcl 24(%edx),%eax + movl %eax,24(%edi) + movl 28(%esi),%eax + adcl 28(%edx),%eax + movl %eax,28(%edi) + leal 32(%edi),%edi + leal 32(%esi),%esi + leal 32(%edx),%edx + decl %ecx + jnz Loop + + sbbl %eax,%eax + negl %eax + + popl %esi + popl %edi + ret diff --git a/sysdeps/i386/addmul_1.S b/sysdeps/i386/addmul_1.S new file mode 100644 index 0000000000..3e166ec38b --- /dev/null +++ b/sysdeps/i386/addmul_1.S @@ -0,0 +1,75 @@ +/* i80386 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebp + + TEXT + ALIGN (3) + GLOBL C_SYMBOL_NAME(__mpn_addmul_1) +C_SYMBOL_NAME(__mpn_addmul_1:) + + INSN1(push,l ,R(edi)) + INSN1(push,l ,R(esi)) + INSN1(push,l ,R(ebx)) + INSN1(push,l ,R(ebp)) + + INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) + INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) + INSN2(mov,l ,R(size),MEM_DISP(esp,28)) + INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) + + INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) + INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) + INSN1(neg,l ,R(size)) + INSN2(xor,l ,R(ebx),R(ebx)) + ALIGN (3) +Loop: + INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) + INSN1(mul,l ,R(s2_limb)) + INSN2(add,l ,R(eax),R(ebx)) + INSN2(adc,l ,R(edx),$0) + INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax)) + INSN2(adc,l ,R(edx),$0) + INSN2(mov,l ,R(ebx),R(edx)) + + INSN1(inc,l ,R(size)) + INSN1(jnz, ,Loop) + INSN2(mov,l ,R(eax),R(ebx)) + + INSN1(pop,l ,R(ebp)) + INSN1(pop,l ,R(ebx)) + INSN1(pop,l ,R(esi)) + INSN1(pop,l ,R(edi)) + ret diff --git a/sysdeps/i386/asm-syntax.h b/sysdeps/i386/asm-syntax.h new file mode 100644 index 0000000000..6e287764dc --- /dev/null +++ b/sysdeps/i386/asm-syntax.h @@ -0,0 +1,64 @@ +/* asm.h -- Definitions for x86 syntax variations. + +Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#undef ALIGN + +#ifdef GAS_SYNTAX +#define R(r) %r +#define MEM(base)(base) +#define MEM_DISP(base,displacement)displacement(R(base)) +#define MEM_INDEX(base,index,size)(R(base),R(index),size) +#ifdef __STDC__ +#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst +#else +#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst +#endif +#define TEXT .text +#define ALIGN(log) .align log +#define GLOBL .globl +#endif + +#ifdef INTEL_SYNTAX +#define R(r) r +#define MEM(base)[base] +#define MEM_DISP(base,displacement)[base+(displacement)] +#define MEM_INDEX(base,index,size)[base+index*size] +#define INSN1(mnemonic,size_suffix,dst)mnemonic dst +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src +#define TEXT .text +#define ALIGN(log) .align log +#define GLOBL .globl +#endif + +#ifdef BROKEN_ALIGN +#undef ALIGN +#define ALIGN(log) .align log,0x90 +#endif + +#if !defined (NOLOG_ALIGN) && defined (HAVE_ELF) +#define NOLOG_ALIGN +#endif + +#ifdef NOLOG_ALIGN +#undef ALIGN +#define ALIGN(log) .align 1<<log +#endif diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S new file mode 100644 index 0000000000..372fc242b2 --- /dev/null +++ b/sysdeps/i386/bsd-_setjmp.S @@ -0,0 +1,32 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + popl %eax /* Pop return PC. */ + popl %ecx /* Pop jmp_buf argument. */ + pushl $0 /* Push second argument of zero. */ + pushl %ecx /* Push back first argument. */ + pushl %eax /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S new file mode 100644 index 0000000000..238f0307ad --- /dev/null +++ b/sysdeps/i386/bsd-setjmp.S @@ -0,0 +1,32 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + popl %eax /* Pop return PC. */ + popl %ecx /* Pop jmp_buf argument. */ + pushl $1 /* Push second argument of one. */ + pushl %ecx /* Push back first argument. */ + pushl %eax /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/i386/bytesex.h b/sysdeps/i386/bytesex.h new file mode 100644 index 0000000000..a5d6c5ea92 --- /dev/null +++ b/sysdeps/i386/bytesex.h @@ -0,0 +1,3 @@ +/* i386 is little-endian. */ + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/sysdeps/i386/bzero.c b/sysdeps/i386/bzero.c new file mode 100644 index 0000000000..659e54df22 --- /dev/null +++ b/sysdeps/i386/bzero.c @@ -0,0 +1,81 @@ +/* bzero -- set a block of memory to zero. + For Intel 80x86, x>=3. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +#undef bzero + +#ifdef __GNUC__ + +void +DEFUN(bzero, (dstpp, len), + PTR dstpp AND size_t len) +{ + /* N.B.: This code is almost verbatim from memset.c. */ + + unsigned long int dstp = (unsigned long int) dstpp; + + /* This explicit register allocation + improves code very much indeed. */ + register op_t x asm("ax"); + + x = 0; + + /* Clear the direction flag, so filling will move forward. */ + asm volatile("cld"); + + /* This threshold value is optimal. */ + if (len >= 12) + { + /* Adjust LEN for the bytes handled in the first loop. */ + len -= (-dstp) % OPSIZ; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + + /* Fill bytes until DSTP is aligned on a longword boundary. */ + asm volatile("rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" ((-dstp) % OPSIZ), "a" (x) : + "cx"); + + /* Fill longwords. */ + asm volatile("rep\n" + "stosl" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" (len / OPSIZ), "a" (x) : + "cx"); + len %= OPSIZ; + } + + /* Write the last few bytes. */ + asm volatile("rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" (len), "a" (x) : + "cx"); +} + +#else +#include <sysdeps/generic/bzero.c> +#endif diff --git a/sysdeps/i386/ffs.c b/sysdeps/i386/ffs.c new file mode 100644 index 0000000000..1e21585874 --- /dev/null +++ b/sysdeps/i386/ffs.c @@ -0,0 +1,45 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For Intel 80x86, x>=3. + Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +#undef ffs + +#ifdef __GNUC__ + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + int tmp; + + asm ("xorl %0,%0\n" /* Set CNT to zero. */ + "bsfl %2,%1\n" /* Count low bits in X and store in %1. */ + "jz nonzero\n" /* Jump if OK, i.e. X was non-zero. */ + "leal 1(%1),%0\n" /* Return bsfl-result plus one on %0. */ + "nonzero:" : "=&a" (cnt), "=r" (tmp) : "rm" (x)); + + return cnt; +} + +#else +#include <sysdeps/generic/ffs.c> +#endif diff --git a/sysdeps/i386/i586/memcopy.h b/sysdeps/i386/i586/memcopy.h new file mode 100644 index 0000000000..a9bb9e7a40 --- /dev/null +++ b/sysdeps/i386/i586/memcopy.h @@ -0,0 +1,94 @@ +/* memcopy.h -- definitions for memory copy functions. Pentium version. + Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Get the i386 definitions. We will override some of them below. */ +#include_next <memcopy.h> + + +/* Written like this, the Pentium pipeline can execute the loop at a + sustained rate of 2 instructions/clock, or asymptotically 480 + Mbytes/second at 60Mhz. */ + +#undef WORD_COPY_FWD +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + asm volatile ("subl $32,%2\n" \ + "js 2f\n" \ + "1:\n" \ + "movl 0(%1),%%eax\n" \ + "movl 4(%1),%%edx\n" \ + "movl %%eax,0(%0)\n" \ + "movl %%edx,4(%0)\n" \ + "movl 8(%1),%%eax\n" \ + "movl 12(%1),%%edx\n" \ + "movl %%eax,8(%0)\n" \ + "movl %%edx,12(%0)\n" \ + "movl 16(%1),%%eax\n" \ + "movl 20(%1),%%edx\n" \ + "movl %%eax,16(%0)\n" \ + "movl %%edx,20(%0)\n" \ + "movl 24(%1),%%eax\n" \ + "movl 28(%1),%%edx\n" \ + "movl %%eax,24(%0)\n" \ + "movl %%edx,28(%0)\n" \ + "addl $32,%1\n" \ + "addl $32,%0\n" \ + "subl $32,%2\n" \ + "jns 1b\n" \ + "2: addl $32,%2" : \ + "=r" (dst_bp), "=r" (src_bp), "=r" (nbytes_left) : \ + "0" (dst_bp), "1" (src_bp), "2" (nbytes) : \ + "ax", "dx"); \ + } while (0) + +#undef WORD_COPY_BWD +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + asm volatile ("subl $32,%2\n" \ + "js 2f\n" \ + "1:\n" \ + "movl -4(%1),%%eax\n" \ + "movl -8(%1),%%edx\n" \ + "movl %%eax,-4(%0)\n" \ + "movl %%edx,-8(%0)\n" \ + "movl -12(%1),%%eax\n" \ + "movl -16(%1),%%edx\n" \ + "movl %%eax,-12(%0)\n" \ + "movl %%edx,-16(%0)\n" \ + "movl -20(%1),%%eax\n" \ + "movl -24(%1),%%edx\n" \ + "movl %%eax,-20(%0)\n" \ + "movl %%edx,-24(%0)\n" \ + "movl -28(%1),%%eax\n" \ + "movl -32(%1),%%edx\n" \ + "movl %%eax,-28(%0)\n" \ + "movl %%edx,-32(%0)\n" \ + "subl $32,%1\n" \ + "subl $32,%0\n" \ + "subl $32,%2\n" \ + "jns 1b\n" \ + "2: addl $32,%2" : \ + "=r" (dst_bp), "=r" (src_bp), "=r" (nbytes_left) : \ + "0" (dst_bp), "1" (src_bp), "2" (nbytes) : \ + "ax", "dx"); \ + } while (0) diff --git a/sysdeps/i386/jmp_buf.h b/sysdeps/i386/jmp_buf.h new file mode 100644 index 0000000000..7686c4d278 --- /dev/null +++ b/sysdeps/i386/jmp_buf.h @@ -0,0 +1,9 @@ +/* Define the machine-dependent type `jmp_buf'. Intel 386 version. */ + +typedef struct + { + long int __bx, __si, __di; + __ptr_t __bp; + __ptr_t __sp; + __ptr_t __pc; + } __jmp_buf[1]; diff --git a/sysdeps/i386/lshift.S b/sysdeps/i386/lshift.S new file mode 100644 index 0000000000..ca48eda8ce --- /dev/null +++ b/sysdeps/i386/lshift.S @@ -0,0 +1,84 @@ +/* i80386 __mpn_lshift -- + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s_ptr (sp + 8) + size (sp + 12) + cnt (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +.text + ALIGN (3) + .globl C_SYMBOL_NAME(__mpn_lshift) +C_SYMBOL_NAME(__mpn_lshift:) + pushl %edi + pushl %esi + pushl %ebx + + movl 16(%esp),%edi /* res_ptr */ + movl 20(%esp),%esi /* s_ptr */ + movl 24(%esp),%edx /* size */ + movl 28(%esp),%ecx /* cnt */ + + subl $4,%esi /* adjust s_ptr */ + + movl (%esi,%edx,4),%ebx /* read most significant limb */ + xorl %eax,%eax + shldl %cl,%ebx,%eax /* compute carry limb */ + decl %edx + jz Lend + pushl %eax /* push carry limb onto stack */ + testb $1,%edx + jnz L1 /* enter loop in the middle */ + movl %ebx,%eax + + ALIGN (3) +Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */ + shldl %cl,%ebx,%eax /* compute result limb */ + movl %eax,(%edi,%edx,4) /* store it */ + decl %edx +L1: movl (%esi,%edx,4),%eax + shldl %cl,%eax,%ebx + movl %ebx,(%edi,%edx,4) + decl %edx + jnz Loop + + shll %cl,%eax /* compute least significant limb */ + movl %eax,(%edi) /* store it */ + + popl %eax /* pop carry limb */ + + popl %ebx + popl %esi + popl %edi + ret + +Lend: shll %cl,%ebx /* compute least significant limb */ + movl %ebx,(%edi) /* store it */ + + popl %ebx + popl %esi + popl %edi + ret diff --git a/sysdeps/i386/memchr.c b/sysdeps/i386/memchr.c new file mode 100644 index 0000000000..ff0f8d9044 --- /dev/null +++ b/sysdeps/i386/memchr.c @@ -0,0 +1,48 @@ +/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less + than N. + For Intel 80x86, x>=3. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +#ifdef __GNUC__ + +PTR +DEFUN(memchr, (str, c, len), + CONST PTR str AND int c AND size_t len) +{ + PTR retval; + asm("cld\n" /* Search forward. */ + "testl %1,%1\n" /* Clear Z flag, to handle LEN == 0. */ + /* Some old versions of gas need `repne' instead of `repnz'. */ + "repnz\n" /* Search for C in al. */ + "scasb\n" + "movl %2,%0\n" /* Set %0 to 0 (without affecting Z flag). */ + "jnz done\n" /* Jump if we found nothing equal to C. */ + "leal -1(%1),%0\n" /* edi has been incremented. Return edi-1. */ + "done:" : + "=a" (retval), "=D" (str), "=c" (len) : + "0" (c), "1" (str), "2" (len)); + return retval; +} + +#else +#include <sysdeps/generic/memchr.c> +#endif diff --git a/sysdeps/i386/memcopy.h b/sysdeps/i386/memcopy.h new file mode 100644 index 0000000000..506d3ea54d --- /dev/null +++ b/sysdeps/i386/memcopy.h @@ -0,0 +1,86 @@ +/* memcopy.h -- definitions for memory copy functions. i386 version. + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/generic/memcopy.h> + +#undef OP_T_THRES +#define OP_T_THRES 8 + +#undef BYTE_COPY_FWD +#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \ + asm volatile(/* Clear the direction flag, so copying goes forward. */ \ + "cld\n" \ + /* Copy bytes. */ \ + "rep\n" \ + "movsb" : \ + "=D" (dst_bp), "=S" (src_bp) : \ + "0" (dst_bp), "1" (src_bp), "c" (nbytes) : \ + "cx") + +#undef BYTE_COPY_BWD +#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \ + do \ + { \ + asm volatile(/* Set the direction flag, so copying goes backwards. */ \ + "std\n" \ + /* Copy bytes. */ \ + "rep\n" \ + "movsb\n" \ + /* Clear the dir flag. Convention says it should be 0. */ \ + "cld" : \ + "=D" (dst_ep), "=S" (src_ep) : \ + "0" (dst_ep - 1), "1" (src_ep - 1), "c" (nbytes) : \ + "cx"); \ + dst_ep += 1; \ + src_ep += 1; \ + } while (0) + +#undef WORD_COPY_FWD +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + asm volatile(/* Clear the direction flag, so copying goes forward. */ \ + "cld\n" \ + /* Copy longwords. */ \ + "rep\n" \ + "movsl" : \ + "=D" (dst_bp), "=S" (src_bp) : \ + "0" (dst_bp), "1" (src_bp), "c" ((nbytes) / 4) : \ + "cx"); \ + (nbytes_left) = (nbytes) % 4; \ + } while (0) + +#undef WORD_COPY_BWD +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + asm volatile(/* Set the direction flag, so copying goes backwards. */ \ + "std\n" \ + /* Copy longwords. */ \ + "rep\n" \ + "movsl\n" \ + /* Clear the dir flag. Convention says it should be 0. */ \ + "cld" : \ + "=D" (dst_ep), "=S" (src_ep) : \ + "0" (dst_ep - 4), "1" (src_ep - 4), "c" ((nbytes) / 4) : \ + "cx"); \ + dst_ep += 4; \ + src_ep += 4; \ + (nbytes_left) = (nbytes) % 4; \ + } while (0) diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c new file mode 100644 index 0000000000..2987445d4f --- /dev/null +++ b/sysdeps/i386/memset.c @@ -0,0 +1,83 @@ +/* memset -- set a block of memory to some byte value. + For Intel 80x86, x>=3. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <memcopy.h> + +#ifdef __GNUC__ + +PTR +DEFUN(memset, (dstpp, c, len), + PTR dstpp AND int c AND size_t len) +{ + unsigned long int dstp = (unsigned long int) dstpp; + + /* This explicit register allocation + improves code very much indeed. */ + register op_t x asm("ax"); + + x = (unsigned char) c; + + /* Clear the direction flag, so filling will move forward. */ + asm volatile("cld"); + + /* This threshold value is optimal. */ + if (len >= 12) + { + /* Fill X with four copies of the char we want to fill with. */ + x |= (x << 8); + x |= (x << 16); + + /* Adjust LEN for the bytes handled in the first loop. */ + len -= (-dstp) % OPSIZ; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + + /* Fill bytes until DSTP is aligned on a longword boundary. */ + asm volatile("rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" ((-dstp) % OPSIZ), "a" (x) : + "cx"); + + /* Fill longwords. */ + asm volatile("rep\n" + "stosl" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" (len / OPSIZ), "a" (x) : + "cx"); + len %= OPSIZ; + } + + /* Write the last few bytes. */ + asm volatile("rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp) : + "0" (dstp), "c" (len), "a" (x) : + "cx"); + + return dstpp; +} + +#else +#include <sysdeps/generic/memset.c> +#endif diff --git a/sysdeps/i386/mul_1.S b/sysdeps/i386/mul_1.S new file mode 100644 index 0000000000..303a940f0b --- /dev/null +++ b/sysdeps/i386/mul_1.S @@ -0,0 +1,74 @@ +/* i80386 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebp + + TEXT + ALIGN (3) + GLOBL C_SYMBOL_NAME(__mpn_mul_1) +C_SYMBOL_NAME(__mpn_mul_1:) + + INSN1(push,l ,R(edi)) + INSN1(push,l ,R(esi)) + INSN1(push,l ,R(ebx)) + INSN1(push,l ,R(ebp)) + + INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) + INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) + INSN2(mov,l ,R(size),MEM_DISP(esp,28)) + INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) + + INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) + INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) + INSN1(neg,l ,R(size)) + INSN2(xor,l ,R(ebx),R(ebx)) + ALIGN (3) +Loop: + INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) + INSN1(mul,l ,R(s2_limb)) + INSN2(add,l ,R(eax),R(ebx)) + INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax)) + INSN2(adc,l ,R(edx),$0) + INSN2(mov,l ,R(ebx),R(edx)) + + INSN1(inc,l ,R(size)) + INSN1(jnz, ,Loop) + INSN2(mov,l ,R(eax),R(ebx)) + + INSN1(pop,l ,R(ebp)) + INSN1(pop,l ,R(ebx)) + INSN1(pop,l ,R(esi)) + INSN1(pop,l ,R(edi)) + ret diff --git a/sysdeps/i386/rshift.S b/sysdeps/i386/rshift.S new file mode 100644 index 0000000000..d4aa0b93e6 --- /dev/null +++ b/sysdeps/i386/rshift.S @@ -0,0 +1,86 @@ +/* i80386 __mpn_rshift -- + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s_ptr (sp + 8) + size (sp + 12) + cnt (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +.text + ALIGN (3) + .globl C_SYMBOL_NAME(__mpn_rshift) +C_SYMBOL_NAME(__mpn_rshift:) + pushl %edi + pushl %esi + pushl %ebx + + movl 16(%esp),%edi /* res_ptr */ + movl 20(%esp),%esi /* s_ptr */ + movl 24(%esp),%edx /* size */ + movl 28(%esp),%ecx /* cnt */ + + leal -4(%edi,%edx,4),%edi + leal (%esi,%edx,4),%esi + negl %edx + + movl (%esi,%edx,4),%ebx /* read least significant limb */ + xorl %eax,%eax + shrdl %cl,%ebx,%eax /* compute carry limb */ + incl %edx + jz Lend + pushl %eax /* push carry limb onto stack */ + testb $1,%edx + jnz L1 /* enter loop in the middle */ + movl %ebx,%eax + + ALIGN (3) +Loop: movl (%esi,%edx,4),%ebx /* load next higher limb */ + shrdl %cl,%ebx,%eax /* compute result limb */ + movl %eax,(%edi,%edx,4) /* store it */ + incl %edx +L1: movl (%esi,%edx,4),%eax + shrdl %cl,%eax,%ebx + movl %ebx,(%edi,%edx,4) + incl %edx + jnz Loop + + shrl %cl,%eax /* compute most significant limb */ + movl %eax,(%edi) /* store it */ + + popl %eax /* pop carry limb */ + + popl %ebx + popl %esi + popl %edi + ret + +Lend: shrl %cl,%ebx /* compute most significant limb */ + movl %ebx,(%edi) /* store it */ + + popl %ebx + popl %esi + popl %edi + ret diff --git a/sysdeps/i386/setjmp.c b/sysdeps/i386/setjmp.c new file mode 100644 index 0000000000..fb8fc98659 --- /dev/null +++ b/sysdeps/i386/setjmp.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Put these global register declarations first, because we get an error if + they come after any function definition, including inlines which might + be in some header. */ + +#define REGS \ + REG (bx);\ + REG (si);\ + REG (di) + +#define REG(xx) register long int xx asm (#xx) +REGS; +#undef REG + +#include <errno.h> +#include <setjmp.h> + +/* Save the current program position in ENV and return 0. */ +int +__sigsetjmp (jmp_buf env, int savemask) +{ + /* Save the general registers. */ +#define REG(xx) env[0].__jmpbuf[0].__##xx = xx + REGS; +#undef REG + + /* Save the return PC. */ + env[0].__jmpbuf[0].__pc = ((void **) &env)[-1]; + + /* Save caller's FP, not our own. */ + env[0].__jmpbuf[0].__bp = ((void **) &env)[-2]; + + /* Save caller's SP, not our own. */ + env[0].__jmpbuf[0].__sp = (void *) &env; + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/sysdeps/i386/strlen.c b/sysdeps/i386/strlen.c new file mode 100644 index 0000000000..3c1398b461 --- /dev/null +++ b/sysdeps/i386/strlen.c @@ -0,0 +1,36 @@ +/* strlen -- determine the length of a string. + For Intel 80x86, x>=3. + Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +size_t +DEFUN(strlen, (str), CONST char *str) +{ + int cnt; + + asm("cld\n" /* Search forward. */ + /* Some old versions of gas need `repne' instead of `repnz'. */ + "repnz\n" /* Look for a zero byte. */ + "scasb" /* %0, %1, %3 */ : + "=c" (cnt) : "D" (str), "0" (-1), "a" (0)); + + return -2 - cnt; +} diff --git a/sysdeps/i386/sub_n.S b/sysdeps/i386/sub_n.S new file mode 100644 index 0000000000..a1630d4562 --- /dev/null +++ b/sysdeps/i386/sub_n.S @@ -0,0 +1,94 @@ +/* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 12) + size (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +.text + ALIGN (3) + .globl C_SYMBOL_NAME(__mpn_sub_n) +C_SYMBOL_NAME(__mpn_sub_n:) + pushl %edi + pushl %esi + + movl 12(%esp),%edi /* res_ptr */ + movl 16(%esp),%esi /* s1_ptr */ + movl 20(%esp),%edx /* s2_ptr */ + movl 24(%esp),%ecx /* size */ + + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax + andl $7,%eax /* get index where to start loop */ + jz Loop /* necessary special case for 0 */ + incl %ecx /* adjust loop count */ + shll $2,%eax /* adjustment for pointers... */ + subl %eax,%edi /* ... since they are offset ... */ + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ + leal (Loop - 3)(%eax,%eax,8),%eax /* calc start addr in loop */ + jmp *%eax /* jump into loop */ + ALIGN (3) +Loop: movl (%esi),%eax + sbbl (%edx),%eax + movl %eax,(%edi) + movl 4(%esi),%eax + sbbl 4(%edx),%eax + movl %eax,4(%edi) + movl 8(%esi),%eax + sbbl 8(%edx),%eax + movl %eax,8(%edi) + movl 12(%esi),%eax + sbbl 12(%edx),%eax + movl %eax,12(%edi) + movl 16(%esi),%eax + sbbl 16(%edx),%eax + movl %eax,16(%edi) + movl 20(%esi),%eax + sbbl 20(%edx),%eax + movl %eax,20(%edi) + movl 24(%esi),%eax + sbbl 24(%edx),%eax + movl %eax,24(%edi) + movl 28(%esi),%eax + sbbl 28(%edx),%eax + movl %eax,28(%edi) + leal 32(%edi),%edi + leal 32(%esi),%esi + leal 32(%edx),%edx + decl %ecx + jnz Loop + + sbbl %eax,%eax + negl %eax + + popl %esi + popl %edi + ret diff --git a/sysdeps/i386/submul_1.S b/sysdeps/i386/submul_1.S new file mode 100644 index 0000000000..5ab78f6846 --- /dev/null +++ b/sysdeps/i386/submul_1.S @@ -0,0 +1,75 @@ +/* i80386 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +#define res_ptr edi +#define s1_ptr esi +#define size ecx +#define s2_limb ebp + + TEXT + ALIGN (3) + GLOBL C_SYMBOL_NAME(__mpn_submul_1) +C_SYMBOL_NAME(__mpn_submul_1:) + + INSN1(push,l ,R(edi)) + INSN1(push,l ,R(esi)) + INSN1(push,l ,R(ebx)) + INSN1(push,l ,R(ebp)) + + INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) + INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) + INSN2(mov,l ,R(size),MEM_DISP(esp,28)) + INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) + + INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) + INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) + INSN1(neg,l ,R(size)) + INSN2(xor,l ,R(ebx),R(ebx)) + ALIGN (3) +Loop: + INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) + INSN1(mul,l ,R(s2_limb)) + INSN2(add,l ,R(eax),R(ebx)) + INSN2(adc,l ,R(edx),$0) + INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax)) + INSN2(adc,l ,R(edx),$0) + INSN2(mov,l ,R(ebx),R(edx)) + + INSN1(inc,l ,R(size)) + INSN1(jnz, ,Loop) + INSN2(mov,l ,R(eax),R(ebx)) + + INSN1(pop,l ,R(ebp)) + INSN1(pop,l ,R(ebx)) + INSN1(pop,l ,R(esi)) + INSN1(pop,l ,R(edi)) + ret diff --git a/sysdeps/i860/memcopy.h b/sysdeps/i860/memcopy.h new file mode 100644 index 0000000000..9f81326c97 --- /dev/null +++ b/sysdeps/i860/memcopy.h @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/generic/memcopy.h> + +#if 0 +#undef MERGE +/* In order to make this work properly, an 's' constraint need to be added + to tm-i860.h, to mean the SC register. */ +#define MERGE(w0, sh_1, w1, sh_2) \ + ({ \ + unsigned int __merge; \ + asm("shrd %2,%1,%0" : \ + "=r" (__merge) : \ + "r" (w0), "r" (w1), "s" (sh_1)); \ + __merge; \ + }) +#endif diff --git a/sysdeps/i960/Implies b/sysdeps/i960/Implies new file mode 100644 index 0000000000..f8c4079ab5 --- /dev/null +++ b/sysdeps/i960/Implies @@ -0,0 +1,2 @@ +# i960 family uses IEEE 754 floating point. +ieee754 diff --git a/sysdeps/i960/ffs.c b/sysdeps/i960/ffs.c new file mode 100644 index 0000000000..62b8742da7 --- /dev/null +++ b/sysdeps/i960/ffs.c @@ -0,0 +1,43 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For i960 Core architecture + Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +#undef ffs + +#if defined (__GNUC__) && defined (__i960__) + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + + asm("scanbit %1,%0" : "=d" (cnt) : "rm" (x & -x)); + + return cnt; +} + +#else + +#include <sysdeps/generic/ffs.c> + +#endif diff --git a/sysdeps/ieee754/Dist b/sysdeps/ieee754/Dist new file mode 100644 index 0000000000..94cc5c9ac4 --- /dev/null +++ b/sysdeps/ieee754/Dist @@ -0,0 +1,2 @@ +support.c +ieee754.h diff --git a/sysdeps/ieee754/cabs.c b/sysdeps/ieee754/cabs.c new file mode 100644 index 0000000000..6b0d4c4cde --- /dev/null +++ b/sysdeps/ieee754/cabs.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 1985 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)cabs.c 5.6 (Berkeley) 10/9/90"; +#endif /* not lint */ + +/* HYPOT(X,Y) + * RETURN THE SQUARE ROOT OF X^2 + Y^2 WHERE Z=X+iY + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 11/28/84; + * REVISED BY K.C. NG, 7/12/85. + * + * Required system supported functions : + * copysign(x,y) + * finite(x) + * scalb(x,N) + * sqrt(x) + * + * Method : + * 1. replace x by |x| and y by |y|, and swap x and + * y if y > x (hence x is never smaller than y). + * 2. Hypot(x,y) is computed by: + * Case I, x/y > 2 + * + * y + * hypot = x + ----------------------------- + * 2 + * sqrt ( 1 + [x/y] ) + x/y + * + * Case II, x/y <= 2 + * y + * hypot = x + -------------------------------------------------- + * 2 + * [x/y] - 2 + * (sqrt(2)+1) + (x-y)/y + ----------------------------- + * 2 + * sqrt ( 1 + [x/y] ) + sqrt(2) + * + * + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns the sqrt(x^2+y^2) with error less than 1 ulps (units + * in the last place). See Kahan's "Interval Arithmetic Options in the + * Proposed IEEE Floating Point Arithmetic Standard", Interval Mathematics + * 1980, Edited by Karl L.E. Nickel, pp 99-128. (A faster but less accurate + * code follows in comments.) In a test run with 500,000 random arguments + * on a VAX, the maximum observed error was .959 ulps. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +#include "mathimpl.h" + +vc(r2p1hi, 2.4142135623730950345E0 ,8279,411a,ef32,99fc, 2, .9A827999FCEF32) +vc(r2p1lo, 1.4349369327986523769E-17 ,597d,2484,754b,89b3, -55, .84597D89B3754B) +vc(sqrt2, 1.4142135623730950622E0 ,04f3,40b5,de65,33f9, 1, .B504F333F9DE65) + +ic(r2p1hi, 2.4142135623730949234E0 , 1, 1.3504F333F9DE6) +ic(r2p1lo, 1.2537167179050217666E-16 , -53, 1.21165F626CDD5) +ic(sqrt2, 1.4142135623730951455E0 , 0, 1.6A09E667F3BCD) + +#ifdef vccast +#define r2p1hi vccast(r2p1hi) +#define r2p1lo vccast(r2p1lo) +#define sqrt2 vccast(sqrt2) +#endif + +double +hypot(x,y) +double x, y; +{ + static const double zero=0, one=1, + small=1.0E-18; /* fl(1+small)==1 */ + static const ibig=30; /* fl(1+2**(2*ibig))==1 */ + double t,r; + int exp; + + if(finite(x)) + if(finite(y)) + { + x=copysign(x,one); + y=copysign(y,one); + if(y > x) + { t=x; x=y; y=t; } + if(x == zero) return(zero); + if(y == zero) return(x); + exp= logb(x); + if(exp-(int)logb(y) > ibig ) + /* raise inexact flag and return |x| */ + { one+small; return(x); } + + /* start computing sqrt(x^2 + y^2) */ + r=x-y; + if(r>y) { /* x/y > 2 */ + r=x/y; + r=r+sqrt(one+r*r); } + else { /* 1 <= x/y <= 2 */ + r/=y; t=r*(r+2.0); + r+=t/(sqrt2+sqrt(2.0+t)); + r+=r2p1lo; r+=r2p1hi; } + + r=y/r; + return(x+r); + + } + + else if(y==y) /* y is +-INF */ + return(copysign(y,one)); + else + return(y); /* y is NaN and x is finite */ + + else if(x==x) /* x is +-INF */ + return (copysign(x,one)); + else if(finite(y)) + return(x); /* x is NaN, y is finite */ +#if !defined(vax)&&!defined(tahoe) + else if(y!=y) return(y); /* x and y is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + else return(copysign(y,one)); /* y is INF */ +} + +/* CABS(Z) + * RETURN THE ABSOLUTE VALUE OF THE COMPLEX NUMBER Z = X + iY + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * CODED IN C BY K.C. NG, 11/28/84. + * REVISED BY K.C. NG, 7/12/85. + * + * Required kernel function : + * hypot(x,y) + * + * Method : + * cabs(z) = hypot(x,y) . + */ + +double +cabs(z) +struct __cabs_complex z; +{ + return hypot(z.__x,z.__y); +} + +double +z_abs(z) +struct __cabs_complex *z; +{ + return hypot(z->__x,z->__y); +} + +/* A faster but less accurate version of cabs(x,y) */ +#if 0 +double hypot(x,y) +double x, y; +{ + static const double zero=0, one=1; + small=1.0E-18; /* fl(1+small)==1 */ + static const ibig=30; /* fl(1+2**(2*ibig))==1 */ + double temp; + int exp; + + if(finite(x)) + if(finite(y)) + { + x=copysign(x,one); + y=copysign(y,one); + if(y > x) + { temp=x; x=y; y=temp; } + if(x == zero) return(zero); + if(y == zero) return(x); + exp= logb(x); + x=scalb(x,-exp); + if(exp-(int)logb(y) > ibig ) + /* raise inexact flag and return |x| */ + { one+small; return(scalb(x,exp)); } + else y=scalb(y,-exp); + return(scalb(sqrt(x*x+y*y),exp)); + } + + else if(y==y) /* y is +-INF */ + return(copysign(y,one)); + else + return(y); /* y is NaN and x is finite */ + + else if(x==x) /* x is +-INF */ + return (copysign(x,one)); + else if(finite(y)) + return(x); /* x is NaN, y is finite */ + else if(y!=y) return(y); /* x and y is NaN */ + else return(copysign(y,one)); /* y is INF */ +} +#endif diff --git a/sysdeps/ieee754/cbrt.c b/sysdeps/ieee754/cbrt.c new file mode 100644 index 0000000000..fe5fb95511 --- /dev/null +++ b/sysdeps/ieee754/cbrt.c @@ -0,0 +1,120 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)cbrt.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +#include <sys/cdefs.h> + +/* kahan's cube root (53 bits IEEE double precision) + * for IEEE machines only + * coded in C by K.C. Ng, 4/30/85 + * + * Accuracy: + * better than 0.667 ulps according to an error analysis. Maximum + * error observed was 0.666 ulps in an 1,000,000 random arguments test. + * + * Warning: this code is semi machine dependent; the ordering of words in + * a floating point number must be known in advance. I assume that the + * long interger at the address of a floating point number will be the + * leading 32 bits of that floating point number (i.e., sign, exponent, + * and the 20 most significant bits). + * On a National machine, it has different ordering; therefore, this code + * must be compiled with flag -DNATIONAL. + */ +#if !defined(vax)&&!defined(tahoe) + +static const unsigned long + B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ +static const double + C= 19./35., + D= -864./1225., + E= 99./70., + F= 45./28., + G= 5./14.; + +double cbrt(x) +double x; +{ + double r,s,t=0.0,w; + unsigned long *px = (unsigned long *) &x, + *pt = (unsigned long *) &t, + mexp,sign; + +#ifdef national /* ordering of words in a floating points number */ + const int n0=1,n1=0; +#else /* national */ + const int n0=0,n1=1; +#endif /* national */ + + mexp=px[n0]&0x7ff00000; + if(mexp==0x7ff00000) return(x); /* cbrt(NaN,INF) is itself */ + if(x==0.0) return(x); /* cbrt(0) is itself */ + + sign=px[n0]&0x80000000; /* sign= sign(x) */ + px[n0] ^= sign; /* x=|x| */ + + + /* rough cbrt to 5 bits */ + if(mexp==0) /* subnormal number */ + {pt[n0]=0x43500000; /* set t= 2**54 */ + t*=x; pt[n0]=pt[n0]/3+B2; + } + else + pt[n0]=px[n0]/3+B1; + + + /* new cbrt to 23 bits, may be implemented in single precision */ + r=t*t/x; + s=C+r*t; + t*=G+F/(s+E+D/s); + + /* chopped to 20 bits and make it larger than cbrt(x) */ + pt[n1]=0; pt[n0]+=0x00000001; + + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s=t*t; /* t*t is exact */ + r=x/s; + w=t+t; + r=(r-t)/(w+r); /* r-t is exact */ + t=t+t*r; + + + /* retore the sign bit */ + pt[n0] |= sign; + return(t); +} +#endif diff --git a/sysdeps/ieee754/copysign.c b/sysdeps/ieee754/copysign.c new file mode 100644 index 0000000000..f1f0591d5f --- /dev/null +++ b/sysdeps/ieee754/copysign.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> +#include "ieee754.h" + +/* Return X with its signed changed to Y's. */ +double +DEFUN(__copysign, (x, y), double x AND double y) +{ + union ieee754_double ux, uy; + + ux.d = x; + uy.d = y; + + ux.ieee.negative = uy.ieee.negative; + + return ux.d; +} + +weak_alias (__copysign, copysign) diff --git a/sysdeps/ieee754/dbl2mpn.c b/sysdeps/ieee754/dbl2mpn.c new file mode 100644 index 0000000000..6b690f711e --- /dev/null +++ b/sysdeps/ieee754/dbl2mpn.c @@ -0,0 +1,107 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" +#include "ieee754.h" +#include <float.h> +#include <stdlib.h> + +/* Convert a `double' in IEEE754 standard double-precision format to a + multi-precision integer representing the significand scaled up by its + number of bits (52 for double) and an integral power of two (MPN frexp). */ + +mp_size_t +__mpn_extract_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + double value) +{ + union ieee754_double u; + u.d = value; + + *is_neg = u.ieee.negative; + *expt = (int) u.ieee.exponent - IEEE754_DOUBLE_BIAS; + +#if BITS_PER_MP_LIMB == 32 + res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */ + res_ptr[1] = u.ieee.mantissa0; /* High-order 20 bits. */ + #define N 2 +#elif BITS_PER_MP_LIMB == 64 + /* Hopefully the compiler will combine the two bitfield extracts + and this composition into just the original quadword extract. */ + res_ptr[0] = (u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + #define N 1 +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif +/* The format does not fill the last limb. There are some zeros. */ +#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \ + - (DBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB))) + + if (u.ieee.exponent == 0) + { + /* A biased exponent of zero is a special case. + Either it is a zero or it is a denormal number. */ + if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */ + /* It's zero. */ + *expt = 0; + else + { + /* It is a denormal number, meaning it has no implicit leading + one bit, and its exponent is in fact the format minimum. */ + int cnt; + + if (res_ptr[N - 1] != 0) + { + count_leading_zeros (cnt, res_ptr[N - 1]); + cnt -= NUM_LEADING_ZEROS; +#if N == 2 + res_ptr[N - 1] = res_ptr[1] << cnt + | (N - 1) + * (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); + res_ptr[0] <<= cnt; +#else + res_ptr[N - 1] <<= cnt; +#endif + *expt = DBL_MIN_EXP - 1 - cnt; + } + else + { + count_leading_zeros (cnt, res_ptr[0]); + if (cnt >= NUM_LEADING_ZEROS) + { + res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS); + res_ptr[0] = 0; + } + else + { + res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt); + res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt); + } + *expt = DBL_MIN_EXP - 1 + - (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt; + } + } + } + else + /* Add the implicit leading one bit for a normalized number. */ + res_ptr[N - 1] |= 1 << (DBL_MANT_DIG - 1 - ((N - 1) * BITS_PER_MP_LIMB)); + + return N; +} diff --git a/sysdeps/ieee754/drem.c b/sysdeps/ieee754/drem.c new file mode 100644 index 0000000000..cab3a04535 --- /dev/null +++ b/sysdeps/ieee754/drem.c @@ -0,0 +1,107 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <ansidecl.h> +#include <math.h> +#include <float.h> +#include "ieee754.h" + +/* Return the remainder of X/Y. */ +double +DEFUN(__drem, (x, y), + double x AND double y) +{ + union ieee754_double ux, uy; + + ux.d = x; + uy.d = y; +#define x ux.d +#define y uy.d + + uy.ieee.negative = 0; + + if (!__finite (x) || y == 0.0) + return NAN; + else if (__isnan (y)) + return y; + else if (__isinf (y)) + return x; + else if (uy.ieee.exponent <= 1) + { + /* Subnormal (or almost subnormal) Y value. */ + double b = __scalb (1.0, 54); + y *= b; + x = __drem (x, y); + x *= b; + return __drem (x, y) / b; + } + else if (y >= 1.7e308 / 2) + { + y /= 2; + x /= 2; + return __drem (x, y) * 2; + } + else + { + union ieee754_double a; + double b; + unsigned int negative = ux.ieee.negative; + a.d = y + y; + b = y / 2; + ux.ieee.negative = 0; + while (x > a.d) + { + unsigned short int k = ux.ieee.exponent - a.ieee.exponent; + union ieee754_double tmp; + tmp.d = a.d; + tmp.ieee.exponent += k; + if (x < tmp.d) + --tmp.ieee.exponent; + x -= tmp.d; + } + if (x > b) + { + x -= y; + if (x >= b) + x -= y; + } + ux.ieee.negative ^= negative; + return x; + } +} + +weak_alias (__drem, drem) diff --git a/sysdeps/ieee754/frexp.c b/sysdeps/ieee754/frexp.c new file mode 100644 index 0000000000..c56a17f6c1 --- /dev/null +++ b/sysdeps/ieee754/frexp.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <math.h> +#include "ieee754.h" + +/* Break VALUE into a normalized fraction and an integral power of 2. */ + +double +frexp (value, exp) + double value; + int *exp; +{ + if (value == 0) + { + *exp = 0; + return 0; + } + else + { + union ieee754_double u; + u.d = value; + *exp = u.ieee.exponent - 1022; + u.ieee.exponent = 1022; + return u.d; + } +} diff --git a/sysdeps/ieee754/huge_val.h b/sysdeps/ieee754/huge_val.h new file mode 100644 index 0000000000..183f213b83 --- /dev/null +++ b/sysdeps/ieee754/huge_val.h @@ -0,0 +1,87 @@ +/* `HUGE_VAL' constant for IEEE 754 machines (where it is infinity). + Used by <stdlib.h> and <math.h> functions for overflow. + +Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HUGE_VAL_H +#define _HUGE_VAL_H 1 + +#include <features.h> +#include <sys/cdefs.h> +#include <endian.h> + +/* IEEE positive infinity (-HUGE_VAL is negative infinity). */ + +#if __BYTE_ORDER == __BIG_ENDIAN +#define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif + +#define __huge_val_t union { unsigned char __c[8]; double __d; } +#ifdef __GNUC__ +#define HUGE_VAL (__extension__ \ + ((__huge_val_t) { __c: __HUGE_VAL_bytes }).__d) +#else /* Not GCC. */ +static __huge_val_t __huge_val = { __HUGE_VAL_bytes }; +#define HUGE_VAL (__huge_val.__d) +#endif /* GCC. */ + + +/* GNU extensions: (float) HUGE_VALf and (long double) HUGE_VALl. */ + +#ifdef __USE_GNU + +#if __BYTE_ORDER == __BIG_ENDIAN +#define __HUGE_VALf_bytes { 0x7f, 0x80, 0, 0 } +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __HUGE_VALf_bytes { 0, 0, 0x80, 0x7f } +#endif + +#define __huge_valf_t union { unsigned char __c[4]; float __f; } +#ifdef __GNUC__ +#define HUGE_VALf (__extension__ \ + ((__huge_valf_t) { __c: __HUGE_VALf_bytes }).__f) +#else /* Not GCC. */ +static __huge_valf_t __huge_valf = { __HUGE_VALf_bytes }; +#define HUGE_VALf (__huge_valf.__f) +#endif /* GCC. */ + +#if __BYTE_ORDER == __BIG_ENDIAN +#define __HUGE_VALl_bytes { 0x7f, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __HUGE_VALl_bytes { 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0x7f, 0, 0 } +#endif + +#define __huge_vall_t union { unsigned char __c[12]; long double __ld; } +#ifdef __GNUC__ +#define HUGE_VALl (__extension__ \ + ((__huge_vall_t) { __c: __HUGE_VALl_bytes }).__ld) +#else /* Not GCC. */ +static __huge_vall_t __huge_vall = { __HUGE_VALl_bytes }; +#define HUGE_VALl (__huge_vall.__ld) +#endif /* GCC. */ + +#endif /* __USE_GNU. */ + + +#endif /* huge_val.h */ diff --git a/sysdeps/ieee754/ieee754.h b/sysdeps/ieee754/ieee754.h new file mode 100644 index 0000000000..9cc6f14707 --- /dev/null +++ b/sysdeps/ieee754/ieee754.h @@ -0,0 +1,153 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <endian.h> + +union ieee754_float + { + float f; + + /* This is the IEEE 754 single-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int mantissa:23; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int quiet_nan:1; + unsigned int mantissa:22; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:22; + unsigned int quiet_nan:1; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee_nan; + }; + +#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */ + + +union ieee754_double + { + double d; + + /* This is the IEEE 754 double-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + unsigned int quiet_nan:1; + /* Together these conprise the mantissa. */ + unsigned int mantissa0:19; + unsigned int mantissa1:32; +#else + /* Together these conprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; +#endif + } ieee_nan; + }; + +#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + + +union ieee854_long_double + { + long double d; + + /* This is the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa1:32; + unsigned int mantissa0:32; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +#endif + } ieee; + + /* This is for NaNs in the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int quiet_nan:1; + unsigned int mantissa0:31; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa1:32; + unsigned int mantissa0:31; + unsigned int quiet_nan:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +#endif + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff diff --git a/sysdeps/ieee754/infnan.c b/sysdeps/ieee754/infnan.c new file mode 100644 index 0000000000..89ab5b6e08 --- /dev/null +++ b/sysdeps/ieee754/infnan.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> +#include <float.h> +#include "ieee754.h" + +/* Deal with an infinite or NaN result. + If ERROR is ERANGE, result is +Inf; + if ERROR is - ERANGE, result is -Inf; + otherwise result is NaN. + This will set `errno' to either ERANGE or EDOM, + and may return an infinity or NaN, or may do something else. */ +double +DEFUN(__infnan, (error), int error) +{ + switch (error) + { + case ERANGE: + errno = ERANGE; + return HUGE_VAL; + + case - ERANGE: + errno = ERANGE; + return - HUGE_VAL; + + default: + errno = EDOM; + return NAN; + } +} + +weak_alias (__infnan, infnan) diff --git a/sysdeps/ieee754/isinf.c b/sysdeps/ieee754/isinf.c new file mode 100644 index 0000000000..79be916432 --- /dev/null +++ b/sysdeps/ieee754/isinf.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> +#include "ieee754.h" + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +int +DEFUN(__isinf, (value), double value) +{ + union ieee754_double u; + + u.d = value; + /* An IEEE 754 infinity has an exponent with the + maximum possible value and a zero mantissa. */ + if ((u.ieee.exponent & 0x7ff) == 0x7ff && + u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0) + return u.ieee.negative ? -1 : 1; + + return 0; +} + +weak_alias (__isinf, isinf) diff --git a/sysdeps/ieee754/isinfl.c b/sysdeps/ieee754/isinfl.c new file mode 100644 index 0000000000..ad03728ad8 --- /dev/null +++ b/sysdeps/ieee754/isinfl.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <math.h> +#include "ieee754.h" + +#undef __isinfl +#undef isinfl + + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +int +__isinfl (long double value) +{ + union ieee854_long_double u; + + u.d = value; + + /* An IEEE 854 infinity has an exponent with the + maximum possible value and a zero mantissa. */ + if ((u.ieee.exponent & 0x7fff) == 0x7fff && + u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0) + return u.ieee.negative ? -1 : 1; + + return 0; +} + +weak_alias (__isinfl, isinfl); diff --git a/sysdeps/ieee754/isnan.c b/sysdeps/ieee754/isnan.c new file mode 100644 index 0000000000..8a537cc0dd --- /dev/null +++ b/sysdeps/ieee754/isnan.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> +#include "ieee754.h" + +/* Return nonzero if VALUE is not a number. */ +int +DEFUN(__isnan, (value), double value) +{ + union ieee754_double u; + + u.d = value; + + /* IEEE 754 NaN's have the maximum possible + exponent and a nonzero mantissa. */ + return ((u.ieee.exponent & 0x7ff) == 0x7ff && + (u.ieee.mantissa0 != 0 || u.ieee.mantissa1 != 0)); +} + +weak_alias (__isnan, isnan) diff --git a/sysdeps/ieee754/isnanl.c b/sysdeps/ieee754/isnanl.c new file mode 100644 index 0000000000..b06b31a3d2 --- /dev/null +++ b/sysdeps/ieee754/isnanl.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <math.h> +#include "ieee754.h" + +#undef __isnanl +#undef isnanl + + +/* Return nonzero if VALUE is not a number. */ +int +__isnanl (long double value) +{ + union ieee854_long_double u; + + u.d = value; + + /* IEEE 854 NaN's have the maximum possible + exponent and a nonzero mantissa. */ + return ((u.ieee.exponent & 0x7fff) == 0x7fff && + (u.ieee.mantissa0 != 0 || u.ieee.mantissa1 != 0)); +} + +weak_alias (__isnanl, isnanl); diff --git a/sysdeps/ieee754/ldbl2mpn.c b/sysdeps/ieee754/ldbl2mpn.c new file mode 100644 index 0000000000..29e8a3b2ce --- /dev/null +++ b/sysdeps/ieee754/ldbl2mpn.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "longlong.h" +#include "ieee754.h" +#include <float.h> +#include <stdlib.h> + +/* Convert a `long double' in IEEE854 standard double-precision format to a + multi-precision integer representing the significand scaled up by its + number of bits (64 for long double) and an integral power of two + (MPN frexpl). */ + +mp_size_t +__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + long double value) +{ + union ieee854_long_double u; + u.d = value; + + *is_neg = u.ieee.negative; + *expt = (int) u.ieee.exponent - IEEE854_LONG_DOUBLE_BIAS; + +#if BITS_PER_MP_LIMB == 32 + res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */ + res_ptr[1] = u.ieee.mantissa0; /* High-order 32 bits. */ + #define N 2 +#elif BITS_PER_MP_LIMB == 64 + /* Hopefully the compiler will combine the two bitfield extracts + and this composition into just the original quadword extract. */ + res_ptr[0] = (u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + #define N 1 +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + if (u.ieee.exponent == 0) + { + /* A biased exponent of zero is a special case. + Either it is a zero or it is a denormal number. */ + if (res_ptr[0] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=2. */ + /* It's zero. */ + *expt = 0; + else + { + /* It is a denormal number, meaning it has no implicit leading + one bit, and its exponent is in fact the format minimum. */ + int cnt; + if (res_ptr[N - 1] != 0) + { + count_leading_zeros (cnt, res_ptr[N - 1]); + if (cnt != 0) + { +#if N == 2 + res_ptr[N - 1] = res_ptr[N - 1] << cnt + | (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); + res_ptr[0] <<= cnt; +#else + res_ptr[N - 1] <<= cnt; +#endif + } + *expt = LDBL_MIN_EXP - 2 - cnt; + } + else + { + count_leading_zeros (cnt, res_ptr[0]); + res_ptr[N - 1] = res_ptr[0] << cnt; + res_ptr[0] = 0; + *expt = LDBL_MIN_EXP - 2 - BITS_PER_MP_LIMB - cnt; + } + } + } + + return N; +} diff --git a/sysdeps/ieee754/ldexp.c b/sysdeps/ieee754/ldexp.c new file mode 100644 index 0000000000..7e1c74715b --- /dev/null +++ b/sysdeps/ieee754/ldexp.c @@ -0,0 +1,145 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <ansidecl.h> +#include <math.h> +#include <float.h> +#include "ieee754.h" + +double +DEFUN(ldexp, (x, exp), + double x AND int exp) +{ + union ieee754_double u; + unsigned int exponent; + + u.d = x; +#define x u.d + + exponent = u.ieee.exponent; + + /* The order of the tests is carefully chosen to handle + the usual case first, with no branches taken. */ + + if (exponent != 0) + { + /* X is nonzero and not denormalized. */ + + if (exponent <= DBL_MAX_EXP - DBL_MIN_EXP + 1) + { + /* X is finite. When EXP < 0, overflow is actually underflow. */ + + exponent += exp; + + if (exponent != 0) + { + if (exponent <= DBL_MAX_EXP - DBL_MIN_EXP + 1) + { + /* In range. */ + u.ieee.exponent = exponent; + return x; + } + + if (exp >= 0) + overflow: + { + CONST int negative = u.ieee.negative; + u.d = HUGE_VAL; + u.ieee.negative = negative; + errno = ERANGE; + return u.d; + } + + if (exponent <= - (unsigned int) (DBL_MANT_DIG + 1)) + { + /* Underflow. */ + CONST int negative = u.ieee.negative; + u.d = 0.0; + u.ieee.negative = negative; + errno = ERANGE; + return u.d; + } + } + + /* Gradual underflow. */ + u.ieee.exponent = 1; + u.d *= ldexp (1.0, (int) exponent - 1); + if (u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0) + /* Underflow. */ + errno = ERANGE; + return u.d; + } + + /* X is +-infinity or NaN. */ + if (u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0) + { + /* X is +-infinity. */ + if (exp >= 0) + goto overflow; + else + { + /* (infinity * number < 1). With infinite precision, + (infinity / finite) would be infinity, but otherwise it's + safest to regard (infinity / 2) as indeterminate. The + infinity might be (2 * finite). */ + CONST int negative = u.ieee.negative; + u.d = NAN; + u.ieee.negative = negative; + errno = EDOM; + return u.d; + } + } + + /* X is NaN. */ + errno = EDOM; + return u.d; + } + + /* X is zero or denormalized. */ + if (u.ieee.mantissa0 == 0 && u.ieee.mantissa1 == 0) + /* X is +-0.0. */ + return x; + + /* X is denormalized. + Multiplying by 2 ** DBL_MANT_DIG normalizes it; + we then subtract the DBL_MANT_DIG we added to the exponent. */ + return ldexp (x * ldexp (1.0, DBL_MANT_DIG), exp - DBL_MANT_DIG); +} + +/* Compatibility names for the same function. */ +weak_alias (ldexp, __scalb) +weak_alias (ldexp, scalb) diff --git a/sysdeps/ieee754/log10.c b/sysdeps/ieee754/log10.c new file mode 100644 index 0000000000..da2f5b4d2b --- /dev/null +++ b/sysdeps/ieee754/log10.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the base-ten logarithm of X. */ +double +DEFUN(log10, (x), double x) +{ + CONST double inverse_ln10 = 4.3429448190325181667e-1; /* 1 / log(10) */ + + return inverse_ln10 * log(x); +} diff --git a/sysdeps/ieee754/logb.c b/sysdeps/ieee754/logb.c new file mode 100644 index 0000000000..918de9ebad --- /dev/null +++ b/sysdeps/ieee754/logb.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> +#include <float.h> +#include "ieee754.h" + +/* Return the base 2 signed integral exponent of X. */ +double +DEFUN(__logb, (x), double x) +{ + union ieee754_double u; + + if (__isnan (x)) + return x; + else if (__isinf (x)) + return HUGE_VAL; + else if (x == 0.0) + return - HUGE_VAL; + + u.d = x; + + if (u.ieee.exponent == 0) + /* A denormalized number. + Multiplying by 2 ** DBL_MANT_DIG normalizes it; + we then subtract the DBL_MANT_DIG we added to the exponent. */ + return (__logb (x * ldexp (1.0, DBL_MANT_DIG)) - DBL_MANT_DIG); + + return (int) u.ieee.exponent - (DBL_MAX_EXP - 1); +} + +weak_alias (__logb, logb) diff --git a/sysdeps/ieee754/mpn2dbl.c b/sysdeps/ieee754/mpn2dbl.c new file mode 100644 index 0000000000..01e0019b8f --- /dev/null +++ b/sysdeps/ieee754/mpn2dbl.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "ieee754.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits (53 for + double) and an integral power of two to a `double' in IEEE754 double- + precision format. */ + +double +__mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative) +{ + union ieee754_double u; + + u.ieee.negative = negative; + u.ieee.exponent = expt + IEEE754_DOUBLE_BIAS; +#if BITS_PER_MP_LIMB == 32 + u.ieee.mantissa1 = frac_ptr[0]; + u.ieee.mantissa0 = frac_ptr[1] & ((1 << (DBL_MANT_DIG - 32)) - 1); +#elif BITS_PER_MP_LIMB == 64 + u.ieee.mantissa1 = frac_ptr[0] & ((1 << 32) - 1); + i.ieee.mantissa0 = (frac_ptr[0] >> 32) & ((1 << (DBL_MANT_DIG - 32)) - 1); +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + return u.d; +} diff --git a/sysdeps/ieee754/mpn2flt.c b/sysdeps/ieee754/mpn2flt.c new file mode 100644 index 0000000000..e9bbc490ad --- /dev/null +++ b/sysdeps/ieee754/mpn2flt.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "ieee754.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits (24 for + float) and an integral power of two to a `float' in IEEE754 single- + precision format. */ + +float +__mpn_construct_float (mp_srcptr frac_ptr, int expt, int sign) +{ + union ieee754_float u; + + u.ieee.negative = sign; + u.ieee.exponent = expt + IEEE754_FLOAT_BIAS; +#if BITS_PER_MP_LIMB > FLT_MANT_DIG + u.ieee.mantissa = frac_ptr[0] & ((1 << FLT_MANT_DIG) - 1); +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + return u.f; +} diff --git a/sysdeps/ieee754/mpn2ldbl.c b/sysdeps/ieee754/mpn2ldbl.c new file mode 100644 index 0000000000..831f2e5f7b --- /dev/null +++ b/sysdeps/ieee754/mpn2ldbl.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include "ieee754.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits (64 for + long double) and an integral power of two to a `long double' in IEEE854 + extended-precision format. */ + +long double +__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) +{ + union ieee854_long_double u; + + u.ieee.negative = sign; + u.ieee.exponent = expt + IEEE854_LONG_DOUBLE_BIAS; +#if BITS_PER_MP_LIMB == 32 + u.ieee.mantissa1 = frac_ptr[0]; + u.ieee.mantissa0 = frac_ptr[1]; +#elif BITS_PER_MP_LIMB == 64 + u.ieee.mantissa1 = frac_ptr[0] & ((1 << 32) - 1); + i.ieee.mantissa0 = frac_ptr[0] >> 32; +#else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +#endif + + return u.d; +} diff --git a/sysdeps/ieee754/nan.h b/sysdeps/ieee754/nan.h new file mode 100644 index 0000000000..e34c172dcb --- /dev/null +++ b/sysdeps/ieee754/nan.h @@ -0,0 +1,46 @@ +/* `NAN' constant for IEEE 754 machines. + +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _NAN_H + +#define _NAN_H 1 + +/* IEEE Not A Number. */ + +#include <endian.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +#define __nan_bytes { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __nan_bytes { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } +#endif + +#ifdef __GNUC__ +#define NAN \ + (__extension__ ((union { unsigned char __c[8]; \ + double __d; }) \ + { __nan_bytes }).__d) +#else /* Not GCC. */ +static CONST char __nan[8] = __nan_bytes; +#define NAN (*(CONST double *) __nan) +#endif /* GCC. */ + +#endif /* nan.h */ diff --git a/sysdeps/ieee754/sqrt.c b/sysdeps/ieee754/sqrt.c new file mode 100644 index 0000000000..7e350e0d91 --- /dev/null +++ b/sysdeps/ieee754/sqrt.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the square root of X. */ +double +DEFUN (sqrt, (x), double x) +{ + double q, s, b, r, t; + CONST double zero = 0.0; + int m, n, i; + + /* sqrt (NaN) is NaN; sqrt (+-0) is +-0. */ + if (__isnan (x) || x == zero) + return x; + + if (x < zero) + return zero / zero; + + /* sqrt (Inf) is Inf. */ + if (__isinf (x)) + return x; + + /* Scale X to [1,4). */ + n = __logb (x); + x = __scalb (x, -n); + m = __logb (x); + if (m != 0) + /* Subnormal number. */ + x = __scalb (x, -m); + + m += n; + n = m / 2; + + if ((n + n) != m) + { + x *= 2; + --m; + n = m / 2; + } + + /* Generate sqrt (X) bit by bit (accumulating in Q). */ + q = 1.0; + s = 4.0; + x -= 1.0; + r = 1; + for (i = 1; i <= 51; i++) + { + t = s + 1; + x *= 4; + r /= 2; + if (t <= x) + { + s = t + t + 2, x -= t; + q += r; + } + else + s *= 2; + } + + /* Generate the last bit and determine the final rounding. */ + r /= 2; + x *= 4; + if (x == zero) + goto end; + (void) (100 + r); /* Trigger inexact flag. */ + if (s < x) + { + q += r; + x -= s; + s += 2; + s *= 2; + x *= 4; + t = (x - s) - 5; + b = 1.0 + 3 * r / 4; + if (b == 1.0) + goto end; /* B == 1: Round to zero. */ + b = 1.0 + r / 4; + if (b > 1.0) + t = 1; /* B > 1: Round to +Inf. */ + if (t >= 0) + q += r; + } /* Else round to nearest. */ + else + { + s *= 2; + x *= 4; + t = (x - s) - 1; + b = 1.0 + 3 * r / 4; + if (b == 1.0) + goto end; + b = 1.0 + r / 4; + if (b > 1.0) + t = 1; + if (t >= 0) + q += r; + } + +end: + return __scalb (q, n); +} diff --git a/sysdeps/ieee754/support.c b/sysdeps/ieee754/support.c new file mode 100644 index 0000000000..e976839421 --- /dev/null +++ b/sysdeps/ieee754/support.c @@ -0,0 +1,524 @@ +/* + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)support.c 8.1 (Berkeley) 6/4/93"; +#endif /* not lint */ + +/* + * Some IEEE standard 754 recommended functions and remainder and sqrt for + * supporting the C elementary functions. + ****************************************************************************** + * WARNING: + * These codes are developed (in double) to support the C elementary + * functions temporarily. They are not universal, and some of them are very + * slow (in particular, drem and sqrt is extremely inefficient). Each + * computer system should have its implementation of these functions using + * its own assembler. + ****************************************************************************** + * + * IEEE 754 required operations: + * drem(x,p) + * returns x REM y = x - [x/y]*y , where [x/y] is the integer + * nearest x/y; in half way case, choose the even one. + * sqrt(x) + * returns the square root of x correctly rounded according to + * the rounding mod. + * + * IEEE 754 recommended functions: + * (a) copysign(x,y) + * returns x with the sign of y. + * (b) scalb(x,N) + * returns x * (2**N), for integer values N. + * (c) logb(x) + * returns the unbiased exponent of x, a signed integer in + * double precision, except that logb(0) is -INF, logb(INF) + * is +INF, and logb(NAN) is that NAN. + * (d) finite(x) + * returns the value TRUE if -INF < x < +INF and returns + * FALSE otherwise. + * + * + * CODED IN C BY K.C. NG, 11/25/84; + * REVISED BY K.C. NG on 1/22/85, 2/13/85, 3/24/85. + */ + +#include "mathimpl.h" + +#if defined(vax)||defined(tahoe) /* VAX D format */ +#include <errno.h> + static const unsigned short msign=0x7fff , mexp =0x7f80 ; + static const short prep1=57, gap=7, bias=129 ; + static const double novf=1.7E38, nunf=3.0E-39, zero=0.0 ; +#else /* defined(vax)||defined(tahoe) */ + static const unsigned short msign=0x7fff, mexp =0x7ff0 ; + static const short prep1=54, gap=4, bias=1023 ; + static const double novf=1.7E308, nunf=3.0E-308,zero=0.0; +#endif /* defined(vax)||defined(tahoe) */ + +double scalb(x,N) +double x; int N; +{ + int k; + +#ifdef national + unsigned short *px=(unsigned short *) &x + 3; +#else /* national */ + unsigned short *px=(unsigned short *) &x; +#endif /* national */ + + if( x == zero ) return(x); + +#if defined(vax)||defined(tahoe) + if( (k= *px & mexp ) != ~msign ) { + if (N < -260) + return(nunf*nunf); + else if (N > 260) { + return(copysign(infnan(ERANGE),x)); + } +#else /* defined(vax)||defined(tahoe) */ + if( (k= *px & mexp ) != mexp ) { + if( N<-2100) return(nunf*nunf); else if(N>2100) return(novf+novf); + if( k == 0 ) { + x *= scalb(1.0,(int)prep1); N -= prep1; return(scalb(x,N));} +#endif /* defined(vax)||defined(tahoe) */ + + if((k = (k>>gap)+ N) > 0 ) + if( k < (mexp>>gap) ) *px = (*px&~mexp) | (k<<gap); + else x=novf+novf; /* overflow */ + else + if( k > -prep1 ) + /* gradual underflow */ + {*px=(*px&~mexp)|(short)(1<<gap); x *= scalb(1.0,k-1);} + else + return(nunf*nunf); + } + return(x); +} + + +double copysign(x,y) +double x,y; +{ +#ifdef national + unsigned short *px=(unsigned short *) &x+3, + *py=(unsigned short *) &y+3; +#else /* national */ + unsigned short *px=(unsigned short *) &x, + *py=(unsigned short *) &y; +#endif /* national */ + +#if defined(vax)||defined(tahoe) + if ( (*px & mexp) == 0 ) return(x); +#endif /* defined(vax)||defined(tahoe) */ + + *px = ( *px & msign ) | ( *py & ~msign ); + return(x); +} + +double logb(x) +double x; +{ + +#ifdef national + short *px=(short *) &x+3, k; +#else /* national */ + short *px=(short *) &x, k; +#endif /* national */ + +#if defined(vax)||defined(tahoe) + return (int)(((*px&mexp)>>gap)-bias); +#else /* defined(vax)||defined(tahoe) */ + if( (k= *px & mexp ) != mexp ) + if ( k != 0 ) + return ( (k>>gap) - bias ); + else if( x != zero) + return ( -1022.0 ); + else + return(-(1.0/zero)); + else if(x != x) + return(x); + else + {*px &= msign; return(x);} +#endif /* defined(vax)||defined(tahoe) */ +} + +finite(x) +double x; +{ +#if defined(vax)||defined(tahoe) + return(1); +#else /* defined(vax)||defined(tahoe) */ +#ifdef national + return( (*((short *) &x+3 ) & mexp ) != mexp ); +#else /* national */ + return( (*((short *) &x ) & mexp ) != mexp ); +#endif /* national */ +#endif /* defined(vax)||defined(tahoe) */ +} + +double drem(x,p) +double x,p; +{ + short sign; + double hp,dp,tmp; + unsigned short k; +#ifdef national + unsigned short + *px=(unsigned short *) &x +3, + *pp=(unsigned short *) &p +3, + *pd=(unsigned short *) &dp +3, + *pt=(unsigned short *) &tmp+3; +#else /* national */ + unsigned short + *px=(unsigned short *) &x , + *pp=(unsigned short *) &p , + *pd=(unsigned short *) &dp , + *pt=(unsigned short *) &tmp; +#endif /* national */ + + *pp &= msign ; + +#if defined(vax)||defined(tahoe) + if( ( *px & mexp ) == ~msign ) /* is x a reserved operand? */ +#else /* defined(vax)||defined(tahoe) */ + if( ( *px & mexp ) == mexp ) +#endif /* defined(vax)||defined(tahoe) */ + return (x-p)-(x-p); /* create nan if x is inf */ + if (p == zero) { +#if defined(vax)||defined(tahoe) + return(infnan(EDOM)); +#else /* defined(vax)||defined(tahoe) */ + return zero/zero; +#endif /* defined(vax)||defined(tahoe) */ + } + +#if defined(vax)||defined(tahoe) + if( ( *pp & mexp ) == ~msign ) /* is p a reserved operand? */ +#else /* defined(vax)||defined(tahoe) */ + if( ( *pp & mexp ) == mexp ) +#endif /* defined(vax)||defined(tahoe) */ + { if (p != p) return p; else return x;} + + else if ( ((*pp & mexp)>>gap) <= 1 ) + /* subnormal p, or almost subnormal p */ + { double b; b=scalb(1.0,(int)prep1); + p *= b; x = drem(x,p); x *= b; return(drem(x,p)/b);} + else if ( p >= novf/2) + { p /= 2 ; x /= 2; return(drem(x,p)*2);} + else + { + dp=p+p; hp=p/2; + sign= *px & ~msign ; + *px &= msign ; + while ( x > dp ) + { + k=(*px & mexp) - (*pd & mexp) ; + tmp = dp ; + *pt += k ; + +#if defined(vax)||defined(tahoe) + if( x < tmp ) *pt -= 128 ; +#else /* defined(vax)||defined(tahoe) */ + if( x < tmp ) *pt -= 16 ; +#endif /* defined(vax)||defined(tahoe) */ + + x -= tmp ; + } + if ( x > hp ) + { x -= p ; if ( x >= hp ) x -= p ; } + +#if defined(vax)||defined(tahoe) + if (x) +#endif /* defined(vax)||defined(tahoe) */ + *px ^= sign; + return( x); + + } +} + + +double sqrt(x) +double x; +{ + double q,s,b,r; + double t; + double const zero=0.0; + int m,n,i; +#if defined(vax)||defined(tahoe) + int k=54; +#else /* defined(vax)||defined(tahoe) */ + int k=51; +#endif /* defined(vax)||defined(tahoe) */ + + /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */ + if(x!=x||x==zero) return(x); + + /* sqrt(negative) is invalid */ + if(x<zero) { +#if defined(vax)||defined(tahoe) + return (infnan(EDOM)); /* NaN */ +#else /* defined(vax)||defined(tahoe) */ + return(zero/zero); +#endif /* defined(vax)||defined(tahoe) */ + } + + /* sqrt(INF) is INF */ + if(!finite(x)) return(x); + + /* scale x to [1,4) */ + n=logb(x); + x=scalb(x,-n); + if((m=logb(x))!=0) x=scalb(x,-m); /* subnormal number */ + m += n; + n = m/2; + if((n+n)!=m) {x *= 2; m -=1; n=m/2;} + + /* generate sqrt(x) bit by bit (accumulating in q) */ + q=1.0; s=4.0; x -= 1.0; r=1; + for(i=1;i<=k;i++) { + t=s+1; x *= 4; r /= 2; + if(t<=x) { + s=t+t+2, x -= t; q += r;} + else + s *= 2; + } + + /* generate the last bit and determine the final rounding */ + r/=2; x *= 4; + if(x==zero) goto end; 100+r; /* trigger inexact flag */ + if(s<x) { + q+=r; x -=s; s += 2; s *= 2; x *= 4; + t = (x-s)-5; + b=1.0+3*r/4; if(b==1.0) goto end; /* b==1 : Round-to-zero */ + b=1.0+r/4; if(b>1.0) t=1; /* b>1 : Round-to-(+INF) */ + if(t>=0) q+=r; } /* else: Round-to-nearest */ + else { + s *= 2; x *= 4; + t = (x-s)-1; + b=1.0+3*r/4; if(b==1.0) goto end; + b=1.0+r/4; if(b>1.0) t=1; + if(t>=0) q+=r; } + +end: return(scalb(q,n)); +} + +#if 0 +/* DREM(X,Y) + * RETURN X REM Y =X-N*Y, N=[X/Y] ROUNDED (ROUNDED TO EVEN IN THE HALF WAY CASE) + * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) + * INTENDED FOR ASSEMBLY LANGUAGE + * CODED IN C BY K.C. NG, 3/23/85, 4/8/85. + * + * Warning: this code should not get compiled in unless ALL of + * the following machine-dependent routines are supplied. + * + * Required machine dependent functions (not on a VAX): + * swapINX(i): save inexact flag and reset it to "i" + * swapENI(e): save inexact enable and reset it to "e" + */ + +double drem(x,y) +double x,y; +{ + +#ifdef national /* order of words in floating point number */ + static const n0=3,n1=2,n2=1,n3=0; +#else /* VAX, SUN, ZILOG, TAHOE */ + static const n0=0,n1=1,n2=2,n3=3; +#endif + + static const unsigned short mexp =0x7ff0, m25 =0x0190, m57 =0x0390; + static const double zero=0.0; + double hy,y1,t,t1; + short k; + long n; + int i,e; + unsigned short xexp,yexp, *px =(unsigned short *) &x , + nx,nf, *py =(unsigned short *) &y , + sign, *pt =(unsigned short *) &t , + *pt1 =(unsigned short *) &t1 ; + + xexp = px[n0] & mexp ; /* exponent of x */ + yexp = py[n0] & mexp ; /* exponent of y */ + sign = px[n0] &0x8000; /* sign of x */ + +/* return NaN if x is NaN, or y is NaN, or x is INF, or y is zero */ + if(x!=x) return(x); if(y!=y) return(y); /* x or y is NaN */ + if( xexp == mexp ) return(zero/zero); /* x is INF */ + if(y==zero) return(y/y); + +/* save the inexact flag and inexact enable in i and e respectively + * and reset them to zero + */ + i=swapINX(0); e=swapENI(0); + +/* subnormal number */ + nx=0; + if(yexp==0) {t=1.0,pt[n0]+=m57; y*=t; nx=m57;} + +/* if y is tiny (biased exponent <= 57), scale up y to y*2**57 */ + if( yexp <= m57 ) {py[n0]+=m57; nx+=m57; yexp+=m57;} + + nf=nx; + py[n0] &= 0x7fff; + px[n0] &= 0x7fff; + +/* mask off the least significant 27 bits of y */ + t=y; pt[n3]=0; pt[n2]&=0xf800; y1=t; + +/* LOOP: argument reduction on x whenever x > y */ +loop: + while ( x > y ) + { + t=y; + t1=y1; + xexp=px[n0]&mexp; /* exponent of x */ + k=xexp-yexp-m25; + if(k>0) /* if x/y >= 2**26, scale up y so that x/y < 2**26 */ + {pt[n0]+=k;pt1[n0]+=k;} + n=x/t; x=(x-n*t1)-n*(t-t1); + } + /* end while (x > y) */ + + if(nx!=0) {t=1.0; pt[n0]+=nx; x*=t; nx=0; goto loop;} + +/* final adjustment */ + + hy=y/2.0; + if(x>hy||((x==hy)&&n%2==1)) x-=y; + px[n0] ^= sign; + if(nf!=0) { t=1.0; pt[n0]-=nf; x*=t;} + +/* restore inexact flag and inexact enable */ + swapINX(i); swapENI(e); + + return(x); +} +#endif + +#if 0 +/* SQRT + * RETURN CORRECTLY ROUNDED (ACCORDING TO THE ROUNDING MODE) SQRT + * FOR IEEE DOUBLE PRECISION ONLY, INTENDED FOR ASSEMBLY LANGUAGE + * CODED IN C BY K.C. NG, 3/22/85. + * + * Warning: this code should not get compiled in unless ALL of + * the following machine-dependent routines are supplied. + * + * Required machine dependent functions: + * swapINX(i) ...return the status of INEXACT flag and reset it to "i" + * swapRM(r) ...return the current Rounding Mode and reset it to "r" + * swapENI(e) ...return the status of inexact enable and reset it to "e" + * addc(t) ...perform t=t+1 regarding t as a 64 bit unsigned integer + * subc(t) ...perform t=t-1 regarding t as a 64 bit unsigned integer + */ + +static const unsigned long table[] = { +0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740, +58733, 67158, 75992, 85215, 83599, 71378, 60428, 50647, 41945, 34246, 27478, +21581, 16499, 12183, 8588, 5674, 3403, 1742, 661, 130, }; + +double newsqrt(x) +double x; +{ + double y,z,t,addc(),subc() + double const b54=134217728.*134217728.; /* b54=2**54 */ + long mx,scalx; + long const mexp=0x7ff00000; + int i,j,r,e,swapINX(),swapRM(),swapENI(); + unsigned long *py=(unsigned long *) &y , + *pt=(unsigned long *) &t , + *px=(unsigned long *) &x ; +#ifdef national /* ordering of word in a floating point number */ + const int n0=1, n1=0; +#else + const int n0=0, n1=1; +#endif +/* Rounding Mode: RN ...round-to-nearest + * RZ ...round-towards 0 + * RP ...round-towards +INF + * RM ...round-towards -INF + */ + const int RN=0,RZ=1,RP=2,RM=3; + /* machine dependent: work on a Zilog Z8070 + * and a National 32081 & 16081 + */ + +/* exceptions */ + if(x!=x||x==0.0) return(x); /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */ + if(x<0) return((x-x)/(x-x)); /* sqrt(negative) is invalid */ + if((mx=px[n0]&mexp)==mexp) return(x); /* sqrt(+INF) is +INF */ + +/* save, reset, initialize */ + e=swapENI(0); /* ...save and reset the inexact enable */ + i=swapINX(0); /* ...save INEXACT flag */ + r=swapRM(RN); /* ...save and reset the Rounding Mode to RN */ + scalx=0; + +/* subnormal number, scale up x to x*2**54 */ + if(mx==0) {x *= b54 ; scalx-=0x01b00000;} + +/* scale x to avoid intermediate over/underflow: + * if (x > 2**512) x=x/2**512; if (x < 2**-512) x=x*2**512 */ + if(mx>0x5ff00000) {px[n0] -= 0x20000000; scalx+= 0x10000000;} + if(mx<0x1ff00000) {px[n0] += 0x20000000; scalx-= 0x10000000;} + +/* magic initial approximation to almost 8 sig. bits */ + py[n0]=(px[n0]>>1)+0x1ff80000; + py[n0]=py[n0]-table[(py[n0]>>15)&31]; + +/* Heron's rule once with correction to improve y to almost 18 sig. bits */ + t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; + +/* triple to almost 56 sig. bits; now y approx. sqrt(x) to within 1 ulp */ + t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; + t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; + +/* twiddle last bit to force y correctly rounded */ + swapRM(RZ); /* ...set Rounding Mode to round-toward-zero */ + swapINX(0); /* ...clear INEXACT flag */ + swapENI(e); /* ...restore inexact enable status */ + t=x/y; /* ...chopped quotient, possibly inexact */ + j=swapINX(i); /* ...read and restore inexact flag */ + if(j==0) { if(t==y) goto end; else t=subc(t); } /* ...t=t-ulp */ + b54+0.1; /* ..trigger inexact flag, sqrt(x) is inexact */ + if(r==RN) t=addc(t); /* ...t=t+ulp */ + else if(r==RP) { t=addc(t);y=addc(y);}/* ...t=t+ulp;y=y+ulp; */ + y=y+t; /* ...chopped sum */ + py[n0]=py[n0]-0x00100000; /* ...correctly rounded sqrt(x) */ +end: py[n0]=py[n0]+scalx; /* ...scale back y */ + swapRM(r); /* ...restore Rounding Mode */ + return(y); +} +#endif diff --git a/sysdeps/m68k/Implies b/sysdeps/m68k/Implies new file mode 100644 index 0000000000..a67e1c2741 --- /dev/null +++ b/sysdeps/m68k/Implies @@ -0,0 +1,2 @@ +# 68k uses IEEE 754 floating point. +ieee754 diff --git a/sysdeps/m68k/Makefile b/sysdeps/m68k/Makefile new file mode 100644 index 0000000000..ea0c7d5cbb --- /dev/null +++ b/sysdeps/m68k/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# This uses MIT assembler syntax. We have no convenient +# way to choose a sysdep file based on MIT vs Motorola syntax. +# No existing m68k ports use Motorola syntax. + +crypt := crypt.sun3 # Use crypt/crypt.sun3.S. + +# The mpn functions need this. All existing 68k ports use MIT syntax. If +# a new port wants to use Motorola or Sony syntax, it can redefine this +# variable. +ifndef m68k-syntax-flag +m68k-syntax-flag = -DMIT_SYNTAX +endif + +asm-CPPFLAGS := $(asm-CPPFLAGS) $(m68k-syntax-flag) diff --git a/sysdeps/m68k/__longjmp.c b/sysdeps/m68k/__longjmp.c new file mode 100644 index 0000000000..4fc61084a0 --- /dev/null +++ b/sysdeps/m68k/__longjmp.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <stdlib.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +void +__longjmp (__jmp_buf env, int val) +{ + /* This restores the FP and SP that setjmp's caller had, + and puts the return address into A0 and VAL into D0. */ + +#if defined(__HAVE_68881__) || defined(__HAVE_FPU__) + /* Restore the floating-point registers. */ + asm volatile("fmovem%.x %0, fp0-fp7" : + /* No outputs. */ : "g" (env[0].__fpregs[0]) : + "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"); +#endif + + /* Put VAL in D0. */ + asm volatile("move%.l %0, d0" : /* No outputs. */ : + "g" (val == 0 ? 1 : val) : "d0"); + + asm volatile(/* Restore the data and address registers. */ + "movem%.l %0, d1-d7/a0-a7\n" + /* Return to setjmp's caller. */ +#ifdef __motorola__ + "jmp (a0)" +#else + "jmp a0@" +#endif + : /* No outputs. */ : "g" (env[0].__dregs[0]) + /* We don't bother with the clobbers, + because this code always jumps out anyway. */ + ); + + /* This call avoids `volatile function does return' warnings. */ + abort (); +} diff --git a/sysdeps/m68k/bsd-_setjmp.S b/sysdeps/m68k/bsd-_setjmp.S new file mode 100644 index 0000000000..a0b639306d --- /dev/null +++ b/sysdeps/m68k/bsd-_setjmp.S @@ -0,0 +1,42 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. m68k version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +#ifdef MOTOROLA_SYNTAX +#define d0 %d0 +#define d1 %d1 +#define PUSH(reg) move.l reg, -(%esp) +#define POP(reg) move.l (%esp)+, reg +#else +#define PUSH(reg) movel reg, sp@- +#define POP(reg) movel sp@+, reg +#endif + +ENTRY (_setjmp) + POP (d0) /* Pop return PC. */ + POP (d1) /* Pop jmp_buf argument. */ + PUSH (#0) /* Push second argument of zero. */ + PUSH (d1) /* Push back first argument. */ + PUSH (d0) /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/m68k/bsd-setjmp.S b/sysdeps/m68k/bsd-setjmp.S new file mode 100644 index 0000000000..d218b44279 --- /dev/null +++ b/sysdeps/m68k/bsd-setjmp.S @@ -0,0 +1,42 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. m68k version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +#ifdef MOTOROLA_SYNTAX +#define d0 %d0 +#define d1 %d1 +#define PUSH(reg) move.l reg, -(%esp) +#define POP(reg) move.l (%esp)+, reg +#else +#define PUSH(reg) movel reg, sp@- +#define POP(reg) movel sp@+, reg +#endif + +ENTRY (setjmp) + POP (d0) /* Pop return PC. */ + POP (d1) /* Pop jmp_buf argument. */ + PUSH (#1) /* Push second argument of one. */ + PUSH (d1) /* Push back first argument. */ + PUSH (d0) /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/m68k/bytesex.h b/sysdeps/m68k/bytesex.h new file mode 100644 index 0000000000..6f985293f2 --- /dev/null +++ b/sysdeps/m68k/bytesex.h @@ -0,0 +1,3 @@ +/* m68k is big-endian. */ + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/m68k/ffs.c b/sysdeps/m68k/ffs.c new file mode 100644 index 0000000000..d9ec2b1ced --- /dev/null +++ b/sysdeps/m68k/ffs.c @@ -0,0 +1,42 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For mc68020, mc68030, mc68040. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + +#undef ffs + +#if defined (__GNUC__) && defined (__mc68020__) + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + + asm("bfffo %1{#0:#0},%0" : "=d" (cnt) : "rm" (x & -x)); + + return 32 - cnt; +} + +#else + +#include <sysdeps/generic/ffs.c> + +#endif diff --git a/sysdeps/m68k/fpu/Makefile b/sysdeps/m68k/fpu/Makefile new file mode 100644 index 0000000000..42db6381d3 --- /dev/null +++ b/sysdeps/m68k/fpu/Makefile @@ -0,0 +1,11 @@ +ifeq ($(subdir),math) +ifndef math-twiddled + +# Avoid twiddling in generic/Makefile. +math-twiddled := t + +endif + +bsdmath_dirs := $(bsdmath_dirs) mc68881 + +endif diff --git a/sysdeps/m68k/fpu/__math.h b/sysdeps/m68k/fpu/__math.h new file mode 100644 index 0000000000..a9ae2d966c --- /dev/null +++ b/sysdeps/m68k/fpu/__math.h @@ -0,0 +1,168 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef __GNUC__ + +#include <sys/cdefs.h> + +#ifdef __NO_MATH_INLINES +/* This is used when defining the functions themselves. Define them with + __ names, and with `static inline' instead of `extern inline' so the + bodies will always be used, never an external function call. */ +#define __m81_u(x) __CONCAT(__,x) +#define __m81_inline static __inline +#else +#define __m81_u(x) x +#define __m81_inline exter __inline +#define __MATH_INLINES 1 +#endif + +#define __inline_mathop2(func, op) \ + __m81_inline __CONSTVALUE double \ + __m81_u(func)(double __mathop_x) \ + { \ + double __result; \ + __asm("f" __STRING(op) "%.x %1, %0" : "=f" (__result) : "f" (__mathop_x));\ + return __result; \ + } +#define __inline_mathop(op) __inline_mathop2(op, op) + +__inline_mathop(acos) +__inline_mathop(asin) +__inline_mathop(atan) +__inline_mathop(cos) +__inline_mathop(sin) +__inline_mathop(tan) +__inline_mathop(cosh) +__inline_mathop(sinh) +__inline_mathop(tanh) +__inline_mathop2(exp, etox) +__inline_mathop2(fabs, abs) +__inline_mathop(log10) +__inline_mathop2(log, logn) +__inline_mathop2(floor, intrz) +__inline_mathop(sqrt) + +__inline_mathop2(__rint, int) +__inline_mathop2(__expm1, etoxm1) + +#ifdef __USE_MISC +__inline_mathop2(rint, int) +__inline_mathop2(expm1, etoxm1) +__inline_mathop2(log1p, lognp1) +__inline_mathop(atanh) +#endif + +__m81_inline __CONSTVALUE double +__m81_u(__drem)(double __x, double __y) +{ + double __result; + __asm("frem%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_inline __CONSTVALUE double +__m81_u(ldexp)(double __x, int __e) +{ + double __result; + double __double_e = (double) __e; + __asm("fscale%.x %1, %0" : "=f" (__result) : "f" (__double_e), "0" (__x)); + return __result; +} + +__m81_inline __CONSTVALUE double +__m81_u(fmod)(double __x, double __y) +{ + double __result; + __asm("fmod%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_inline double +__m81_u(frexp)(double __value, int *__expptr) +{ + double __mantissa, __exponent; + __asm("fgetexp%.x %1, %0" : "=f" (__exponent) : "f" (__value)); + __asm("fgetman%.x %1, %0" : "=f" (__mantissa) : "f" (__value)); + *__expptr = (int) __exponent; + return __mantissa; +} + +__m81_inline __CONSTVALUE double +__m81_u(pow)(double __x, double __y) +{ + double __result; + if (__y == 0.0 || __x == 1.0) + __result = 1.0; + else if (__y == 1.0) + __result = __x; + else if (__y == 2.0) + __result = __x * __x; + else if (__x == 10.0) + __asm("ftentox%.x %1, %0" : "=f" (__result) : "f" (__y)); + else if (__x == 2.0) + __asm("ftwotox%.x %1, %0" : "=f" (__result) : "f" (__y)); + else + __result = __m81_u(exp)(__y * __m81_u(log)(__x)); + return __result; +} + +__m81_inline __CONSTVALUE double +__m81_u(ceil)(double __x) +{ + double __result; + unsigned long int __ctrl_reg; + __asm("fmove%.l fpcr, %0" : "=g" (__ctrl_reg)); + /* Set rounding towards positive infinity. */ + __asm("fmove%.l %0, fpcr" : /* No outputs. */ : "g" (__ctrl_reg | 0x30)); + /* Convert X to an integer, using +Inf rounding. */ + __asm("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); + /* Restore the previous rounding mode. */ + __asm("fmove%.l %0, fpcr" : /* No outputs. */ : "g" (__ctrl_reg)); + return __result; +} + +__m81_inline double +__m81_u(modf)(double __value, double *__iptr) +{ + double __modf_int = __m81_u(floor)(__value); + *__iptr = __modf_int; + return __value - __modf_int; +} + +__m81_inline __CONSTVALUE int +__m81_u(__isinf)(double __value) +{ + /* There is no branch-condition for infinity, + so we must extract and examine the condition codes manually. */ + unsigned long int __fpsr; + __asm("ftst%.x %1\n" + "fmove%.l fpsr, %0" : "=g" (__fpsr) : "f" (__value)); + return (__fpsr & (2 << (3 * 8))) ? (__value < 0 ? -1 : 1) : 0; +} + +__m81_inline __CONSTVALUE int +__m81_u(__isnan)(double __value) +{ + char __result; + __asm("ftst%.x %1\n" + "fsun %0" : "=g" (__result) : "f" (__value)); + return __result; +} + +#endif /* GCC. */ diff --git a/sysdeps/m68k/fpu/acos.c b/sysdeps/m68k/fpu/acos.c new file mode 100644 index 0000000000..d4be88f17c --- /dev/null +++ b/sysdeps/m68k/fpu/acos.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +#ifndef FUNC +#define FUNC acos +#endif + + +__CONSTVALUE double +DEFUN(FUNC, (x), double x) +{ + return __m81_u(FUNC)(x); +} diff --git a/sysdeps/m68k/fpu/asin.c b/sysdeps/m68k/fpu/asin.c new file mode 100644 index 0000000000..0e3e58f697 --- /dev/null +++ b/sysdeps/m68k/fpu/asin.c @@ -0,0 +1,2 @@ +#define FUNC asin +#include <acos.c> diff --git a/sysdeps/m68k/fpu/atan.c b/sysdeps/m68k/fpu/atan.c new file mode 100644 index 0000000000..b9d428e170 --- /dev/null +++ b/sysdeps/m68k/fpu/atan.c @@ -0,0 +1,2 @@ +#define FUNC atan +#include <acos.c> diff --git a/sysdeps/m68k/fpu/atan2.c b/sysdeps/m68k/fpu/atan2.c new file mode 100644 index 0000000000..1efdb1f7a6 --- /dev/null +++ b/sysdeps/m68k/fpu/atan2.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +#ifdef __GNUC__ + +__CONSTVALUE double +DEFUN(atan2, (y, x), double y AND double x) +{ + static CONST double one = 1.0, zero = 0.0; + double signx, signy; + double pi, PIo4, PIo2; + + if (__isnan(x)) + return x; + if (__isnan(y)) + return y; + + signy = __copysign(one, y); + signx = __copysign(one, x); + + asm("fmovecr%.x %1, %0" : "=f" (pi) : "i" (0)); + PIo2 = pi / 2; + PIo4 = pi / 4; + + if (y == zero) + return signx == one ? y : __copysign(pi, signy); + + if (x == zero) + return __copysign(PIo2, signy); + + if (__isinf(x)) + { + if (__isinf(y)) + return __copysign(signx == one ? PIo4 : 3 * PIo4, signy); + else + return __copysign(signx == one ? zero : pi, signy); + } + + if (__isinf(y)) + return __copysign(PIo2, signy); + + y = fabs(y); + + if (x < 0.0) + /* X is negative. */ + return __copysign(pi - atan(y / -x), signy); + + return __copysign(atan(y / x), signy); +} + +#else +#include <sysdeps/generic/atan2.c> +#endif diff --git a/sysdeps/m68k/fpu/atanh.c b/sysdeps/m68k/fpu/atanh.c new file mode 100644 index 0000000000..d4636ec035 --- /dev/null +++ b/sysdeps/m68k/fpu/atanh.c @@ -0,0 +1,2 @@ +#define FUNC atanh +#include <acos.c> diff --git a/sysdeps/m68k/fpu/ceil.c b/sysdeps/m68k/fpu/ceil.c new file mode 100644 index 0000000000..b4605e1b29 --- /dev/null +++ b/sysdeps/m68k/fpu/ceil.c @@ -0,0 +1,4 @@ + +#define FUNC ceil + +#include <acos.c> diff --git a/sysdeps/m68k/fpu/cos.c b/sysdeps/m68k/fpu/cos.c new file mode 100644 index 0000000000..fa50130af7 --- /dev/null +++ b/sysdeps/m68k/fpu/cos.c @@ -0,0 +1,2 @@ +#define FUNC cos +#include <acos.c> diff --git a/sysdeps/m68k/fpu/cosh.c b/sysdeps/m68k/fpu/cosh.c new file mode 100644 index 0000000000..78a81943c6 --- /dev/null +++ b/sysdeps/m68k/fpu/cosh.c @@ -0,0 +1,2 @@ +#define FUNC cosh +#include <acos.c> diff --git a/sysdeps/m68k/fpu/drem.c b/sysdeps/m68k/fpu/drem.c new file mode 100644 index 0000000000..16caacfd81 --- /dev/null +++ b/sysdeps/m68k/fpu/drem.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +#undef drem + +double +DEFUN(__drem, (x, y), double x AND double y) +{ + return ____drem(x, y); +} + +weak_alias (__drem, drem) diff --git a/sysdeps/m68k/fpu/exp.c b/sysdeps/m68k/fpu/exp.c new file mode 100644 index 0000000000..2649d72143 --- /dev/null +++ b/sysdeps/m68k/fpu/exp.c @@ -0,0 +1,3 @@ +#define FUNC exp +#define OP etox +#include <acos.c> diff --git a/sysdeps/m68k/fpu/expm1.c b/sysdeps/m68k/fpu/expm1.c new file mode 100644 index 0000000000..19f1802e56 --- /dev/null +++ b/sysdeps/m68k/fpu/expm1.c @@ -0,0 +1,3 @@ +#define FUNC __expm1 +#define OP expm1 +#include <acos.c> diff --git a/sysdeps/m68k/fpu/fabs.c b/sysdeps/m68k/fpu/fabs.c new file mode 100644 index 0000000000..f9538a599c --- /dev/null +++ b/sysdeps/m68k/fpu/fabs.c @@ -0,0 +1,3 @@ +#define FUNC fabs +#define OP abs +#include <acos.c> diff --git a/sysdeps/m68k/fpu/fl.h b/sysdeps/m68k/fpu/fl.h new file mode 100644 index 0000000000..098e880601 --- /dev/null +++ b/sysdeps/m68k/fpu/fl.h @@ -0,0 +1,41 @@ +/* Floating-point constants for the 68881. + Copyright (C) 1992 Free Software Foundation, Inc. */ + +/* IGNORE($ This is used internally in the library. */ +#include <sysdeps/ieee754/fl.h> +/* ansidecl.m4 here inserts the ieee file. Kludge o rama. + $) ENDCOMMENT INCLUDE($sysdeps/ieee754/fl.h$) STARTCOMMENT */ + +#ifndef __need_HUGE_VAL + +#ifdef __GNUC__ + +#undef FLT_ROUNDS + +/* Interrogate the 68881 to find the current rounding mode. */ + +static __const __inline int +DEFUN_VOID(__flt_rounds) +{ + unsigned long int __fpcr; + __asm("fmove%.l fpcr, %0" : "=g" (__fpcr)); + switch (__fpcr & (1 | 2)) + { + case 0: + return _FLT_ROUNDS_TONEAREST; + case 1: + return _FLT_ROUNDS_TOZERO; + case 2: + return _FLT_ROUNDS_TONEGINF; + case 3: + return _FLT_ROUNDS_TOPOSINF; + default: + return _FLT_ROUNDS_INDETERMINATE; + } +} + +#define FLT_ROUNDS (__flt_rounds()) + +#endif /* GCC. */ + +#endif /* Don't need HUGE_VAL. */ diff --git a/sysdeps/m68k/fpu/floor.c b/sysdeps/m68k/fpu/floor.c new file mode 100644 index 0000000000..92a2ca68bb --- /dev/null +++ b/sysdeps/m68k/fpu/floor.c @@ -0,0 +1,3 @@ +#define FUNC floor +#define OP intrz +#include <acos.c> diff --git a/sysdeps/m68k/fpu/fmod.c b/sysdeps/m68k/fpu/fmod.c new file mode 100644 index 0000000000..9a6c8cd162 --- /dev/null +++ b/sysdeps/m68k/fpu/fmod.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +__CONSTVALUE double +DEFUN(fmod, (x, y), double x AND double y) +{ + return __fmod(x, y); +} diff --git a/sysdeps/m68k/fpu/frexp.c b/sysdeps/m68k/fpu/frexp.c new file mode 100644 index 0000000000..de74851de9 --- /dev/null +++ b/sysdeps/m68k/fpu/frexp.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +double +DEFUN(frexp, (value, expptr), double value AND int *expptr) +{ + return __frexp(value, expptr); +} diff --git a/sysdeps/m68k/fpu/isinf.c b/sysdeps/m68k/fpu/isinf.c new file mode 100644 index 0000000000..ab2cf0bb03 --- /dev/null +++ b/sysdeps/m68k/fpu/isinf.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +#ifndef FUNC +#define FUNC __isinf +#endif + + +int +DEFUN(FUNC, (x), double x) +{ + return __m81_u(FUNC)(x); +} + +weak_alias (__isinf, isinf) diff --git a/sysdeps/m68k/fpu/isnan.c b/sysdeps/m68k/fpu/isnan.c new file mode 100644 index 0000000000..d0984911d2 --- /dev/null +++ b/sysdeps/m68k/fpu/isnan.c @@ -0,0 +1,4 @@ +#define FUNC __isnan +#include <isinf.c> + +weak_alias (__isnan, isnan) diff --git a/sysdeps/m68k/fpu/ldexp.c b/sysdeps/m68k/fpu/ldexp.c new file mode 100644 index 0000000000..ba912805d6 --- /dev/null +++ b/sysdeps/m68k/fpu/ldexp.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +__CONSTVALUE double +DEFUN(ldexp, (x, exp), double x AND int exp) +{ + return __ldexp(x, exp); +} diff --git a/sysdeps/m68k/fpu/log.c b/sysdeps/m68k/fpu/log.c new file mode 100644 index 0000000000..4de3346545 --- /dev/null +++ b/sysdeps/m68k/fpu/log.c @@ -0,0 +1,3 @@ +#define FUNC log +#define OP logn +#include <acos.c> diff --git a/sysdeps/m68k/fpu/log10.c b/sysdeps/m68k/fpu/log10.c new file mode 100644 index 0000000000..246b69a364 --- /dev/null +++ b/sysdeps/m68k/fpu/log10.c @@ -0,0 +1,2 @@ +#define FUNC log10 +#include <acos.c> diff --git a/sysdeps/m68k/fpu/log1p.c b/sysdeps/m68k/fpu/log1p.c new file mode 100644 index 0000000000..028783819b --- /dev/null +++ b/sysdeps/m68k/fpu/log1p.c @@ -0,0 +1,2 @@ +#define FUNC log1p +#include <acos.c> diff --git a/sysdeps/m68k/fpu/logb.c b/sysdeps/m68k/fpu/logb.c new file mode 100644 index 0000000000..8619c908c8 --- /dev/null +++ b/sysdeps/m68k/fpu/logb.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +#ifdef __GNUC__ + +/* Return the base 2 signed integral exponent of X. */ + +double +DEFUN(__logb, (x), double x) +{ + if (__isnan (x)) + return x; + if (__isinf (x)) + return fabs (x); + + if (x == 0.0) + asm ("flog2%.x %0, %0" : "=f" (x) : "0" (x)); + else + asm ("fgetexp%.x %0, %0" : "=f" (x) : "0" (x)); + + return x; +} + +weak_alias (__logb, logb) + +#else +#include <sysdeps/ieee754/logb.c> +#endif diff --git a/sysdeps/m68k/fpu/pow.c b/sysdeps/m68k/fpu/pow.c new file mode 100644 index 0000000000..3360020f1d --- /dev/null +++ b/sysdeps/m68k/fpu/pow.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#define __NO_MATH_INLINES +#include <math.h> + +__CONSTVALUE double +DEFUN(pow, (x, y), double x AND double y) +{ + return __pow(x, y); +} diff --git a/sysdeps/m68k/fpu/rint.c b/sysdeps/m68k/fpu/rint.c new file mode 100644 index 0000000000..f83a4e4c3f --- /dev/null +++ b/sysdeps/m68k/fpu/rint.c @@ -0,0 +1,5 @@ +#define FUNC __rint +#define OP intr +#include <acos.c> + +weak_alias (__rint, rint) diff --git a/sysdeps/m68k/fpu/sin.c b/sysdeps/m68k/fpu/sin.c new file mode 100644 index 0000000000..28ac9e50c3 --- /dev/null +++ b/sysdeps/m68k/fpu/sin.c @@ -0,0 +1,2 @@ +#define FUNC sin +#include <acos.c> diff --git a/sysdeps/m68k/fpu/sinh.c b/sysdeps/m68k/fpu/sinh.c new file mode 100644 index 0000000000..fae7c71459 --- /dev/null +++ b/sysdeps/m68k/fpu/sinh.c @@ -0,0 +1,2 @@ +#define FUNC sinh +#include <acos.c> diff --git a/sysdeps/m68k/fpu/sqrt.c b/sysdeps/m68k/fpu/sqrt.c new file mode 100644 index 0000000000..2365b61780 --- /dev/null +++ b/sysdeps/m68k/fpu/sqrt.c @@ -0,0 +1,2 @@ +#define FUNC sqrt +#include <acos.c> diff --git a/sysdeps/m68k/fpu/switch/68881-sw.h b/sysdeps/m68k/fpu/switch/68881-sw.h new file mode 100644 index 0000000000..3d7a3927f5 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/68881-sw.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _68881_SWITCH_H + +#define _68881_SWITCH_H 1 +#include <sys/cdefs.h> + +/* This is the format of the data at the code label for a function which + wants to switch depending on whether or not a 68881 is present. + + Initially, `insn' is a `jsr' instruction, and `target' is __68881_switch. + The first time such a function is called, __68881_switch determines whether + or not a 68881 is present, and modifies the function accordingly. + Then `insn' is a `jmp' instruction, and `target' is the value of `fpu' + if there is 68881, or the value of `soft' if not. */ + +struct switch_caller + { + unsigned short int insn; /* The `jsr' or `jmp' instruction. */ + __ptr_t target; /* The target of the instruction. */ + __ptr_t soft; /* The address of the soft function. */ + __ptr_t fpu; /* The address of the 68881 function. */ + }; + +/* These are opcodes (values for `insn', above) for `jmp' and `jsr' + instructions, respectively, to 32-bit absolute addresses. */ +#define JMP 0x4ef9 +#define JSR 0x4eb9 + + +/* Function to determine whether or not a 68881 is available, + and modify its caller (which must be a `struct switch_caller', above, + in data space) to use the appropriate version. */ +extern void EXFUN(__68881_switch, (int __dummy)); + + +/* Define FUNCTION as a `struct switch_caller' which will call + `__FUNCTION_68881' if a 68881 is present, and `__FUNCTION_soft' if not. +#define switching_function(FUNCTION) \ + struct switch_caller FUNCTION = \ + { \ + JSR, (__ptr_t) __68881_switch, \ + __CONCAT(__CONCAT(__,FUNCTION),_soft), \ + __CONCAT(__CONCAT(__,FUNCTION),_68881) \ + } + + +#endif /* 68881-switch.h */ diff --git a/sysdeps/m68k/fpu/switch/Dist b/sysdeps/m68k/fpu/switch/Dist new file mode 100644 index 0000000000..1e00e4cd07 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/Dist @@ -0,0 +1 @@ +68881-sw.h switch.c diff --git a/sysdeps/m68k/fpu/switch/Makefile b/sysdeps/m68k/fpu/switch/Makefile new file mode 100644 index 0000000000..fd8d7c11f4 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/Makefile @@ -0,0 +1,52 @@ +# Copyright (C) 1991, 1992 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),math) + +sysdep_routines := $(sysdep_routines) switch + +# Find all the sources that have 68881 versions. ++68881-sources := \ + $(notdir $(wildcard $(addprefix $(filter %/fpu,$(sysdirs)),$(sources)))) + +# Sysdep directories other than fpu and fpu/switch (this one). ++non68881-dirs := $(filter-out %/fpu %/fpu/switch,$(+sysdep_dirs)) + +# Get a non-68881 version of the target. ++non68881-version = $(firstword $(wildcard $(addsuffix /$@,$(+non68881-dirs)))) + +# Directory containing 68881 sources. ++68881-dir := $(filter %/fpu,$(+sysdep_dirs)) + +# For all the files that have 68881 versions and don't exist already in +# the source directory (math), automatically make ones that switch between +# 68881 and soft versions. +$(addprefix $(objpfx), \ + $(filter-out $(wildcard $(+68881-sources)),$(+68881-sources))): + (echo '#include <ansidecl.h>' ;\ + echo '#include <68881-sw.h>' ;\ + echo '#define $* __$*_68881' ;\ + echo '#include <$(+68881-dir)/$@>' ;\ + echo '#undef $*' ;\ + echo '#define $* __$*_soft' ;\ + echo '#include <$(non68881-version)>' ;\ + echo '#undef $*' ;\ + echo 'switching_function($*);') > $@-tmp + mv $@-tmp $@ + +endif diff --git a/sysdeps/m68k/fpu/switch/__math.h b/sysdeps/m68k/fpu/switch/__math.h new file mode 100644 index 0000000000..c0f6966981 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/__math.h @@ -0,0 +1 @@ +/* We don't want any inlines when we might not have a 68881. */ diff --git a/sysdeps/m68k/fpu/switch/switch.c b/sysdeps/m68k/fpu/switch/switch.c new file mode 100644 index 0000000000..057bd1509a --- /dev/null +++ b/sysdeps/m68k/fpu/switch/switch.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <68881-sw.h> + + +/* The signal that is sent when a 68881 instruction + is executed and there is no 68881. */ +#ifndef TRAPSIG +#define TRAPSIG SIGILL +#endif + +/* Zero if no 68881, one if we have a 68881, or -1 if we don't know yet. */ +static int have_fpu = -1; + + +/* Signal handler for the trap that happens if we don't have a 68881. */ +static void +DEFUN(trap, (sig), int sig) +{ + have_fpu = 0; +} + +/* This function is called by functions that want to switch. + The calling function must be a `struct switch_caller' in data space. + It determines whether a 68881 is present, and modifies its caller + to be a static jump to either the 68881 version or the soft version. + It then returns into the function it has chosen to do the work. */ +void +DEFUN(__68881_switch, (dummy), int dummy) +{ + PTR *return_address_location = &((PTR *) &dummy)[-1]; + struct switch_caller *CONST caller + = (struct switch_caller *) (((short int *) *return_address_location) - 1); + + if (have_fpu < 0) + { + /* Figure out whether or not we have a 68881. */ + __sighandler_t handler = signal (TRAPSIG, trap); + if (handler == SIG_ERR) + /* We can't figure it out, so assume we don't have a 68881. + This assumption will never cause us any problems other than + lost performance, while the reverse assumption could cause + the program to crash. */ + have_fpu = 0; + else + { + /* We set `have_fpu' to nonzero, and then execute a 68881 + no-op instruction. If we have a 68881, this will do nothing. + If we don't have one, this will trap and the signal handler + will clear `have_fpu'. */ + have_fpu = 1; + asm ("fnop"); + + /* Restore the old signal handler. */ + (void) signal (TRAPSIG, handler); + } + } + + /* Modify the caller to be a jump to the appropriate address. */ + caller->insn = JMP; + caller->target = have_fpu ? caller->fpu : caller->soft; + + /* Make the address we will return to be the target we have chosen. + Our return will match the `jsr' done by the caller we have + just modified, and it will be just as if that had instead + been a `jmp' to the new target. */ + *return_address_location = caller->target; +} diff --git a/sysdeps/m68k/fpu/tan.c b/sysdeps/m68k/fpu/tan.c new file mode 100644 index 0000000000..53b3b5342e --- /dev/null +++ b/sysdeps/m68k/fpu/tan.c @@ -0,0 +1,2 @@ +#define FUNC tan +#include <acos.c> diff --git a/sysdeps/m68k/fpu/tanh.c b/sysdeps/m68k/fpu/tanh.c new file mode 100644 index 0000000000..cc6739539a --- /dev/null +++ b/sysdeps/m68k/fpu/tanh.c @@ -0,0 +1,2 @@ +#define FUNC tanh +#include <acos.c> diff --git a/sysdeps/m68k/jmp_buf.h b/sysdeps/m68k/jmp_buf.h new file mode 100644 index 0000000000..96240f0d8e --- /dev/null +++ b/sysdeps/m68k/jmp_buf.h @@ -0,0 +1,19 @@ +/* Define the machine-dependent type `jmp_buf'. m68k version. */ + +typedef struct + { + /* There are eight 4-byte data registers, but D0 is not saved. */ + long int __dregs[7]; + + /* There are six 4-byte address registers, plus the FP and SP. */ + int *__aregs[6]; + int * __fp; + int * __sp; + +#if defined(__HAVE_68881__) || defined(__HAVE_FPU__) + /* There are eight floating point registers which + are saved in IEEE 96-bit extended format. */ + char __fpregs[8 * (96 / 8)]; +#endif + + } __jmp_buf[1]; diff --git a/sysdeps/m68k/m68020/add_n.S b/sysdeps/m68k/m68020/add_n.S new file mode 100644 index 0000000000..ea7a4458ea --- /dev/null +++ b/sysdeps/m68k/m68020/add_n.S @@ -0,0 +1,76 @@ +/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 16) + size (sp + 12) +*/ + +#include "asm-syntax.h" + + TEXT + ALIGN + GLOBL ___mpn_add_n + +LAB(___mpn_add_n) +/* Save used registers on the stack. */ + INSN2(move,l ,MEM_PREDEC(sp),d2) + INSN2(move,l ,MEM_PREDEC(sp),a2) + +/* Copy the arguments to registers. Better use movem? */ + INSN2(move,l ,a2,MEM_DISP(sp,12)) + INSN2(move,l ,a0,MEM_DISP(sp,16)) + INSN2(move,l ,a1,MEM_DISP(sp,20)) + INSN2(move,l ,d2,MEM_DISP(sp,24)) + + INSN2(eor,w ,d2,#1) + INSN2(lsr,l ,d2,#1) + bcc L1 + INSN2(subq,l ,d2,#1) /* clears cy as side effect */ + +LAB(Loop) + INSN2(move,l ,d0,MEM_POSTINC(a0)) + INSN2(move,l ,d1,MEM_POSTINC(a1)) + INSN2(addx,l ,d0,d1) + INSN2(move,l ,MEM_POSTINC(a2),d0) +LAB(L1) INSN2(move,l ,d0,MEM_POSTINC(a0)) + INSN2(move,l ,d1,MEM_POSTINC(a1)) + INSN2(addx,l ,d0,d1) + INSN2(move,l ,MEM_POSTINC(a2),d0) + + dbf d2,Loop /* loop until 16 lsb of %4 == -1 */ + INSN2(subx,l ,d0,d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + INSN2(sub,l ,d2,#0x10000) + bcs L2 + INSN2(add,l ,d0,d0) /* restore cy */ + bra Loop + +LAB(L2) + INSN1(neg,l ,d0) + +/* Restore used registers from stack frame. */ + INSN2(move,l ,a2,MEM_POSTINC(sp)) + INSN2(move,l ,d2,MEM_POSTINC(sp)) + + rts diff --git a/sysdeps/m68k/m68020/addmul_1.S b/sysdeps/m68k/m68020/addmul_1.S new file mode 100644 index 0000000000..3f244c40b4 --- /dev/null +++ b/sysdeps/m68k/m68020/addmul_1.S @@ -0,0 +1,80 @@ +/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "asm-syntax.h" + + TEXT + ALIGN + GLOBL ___mpn_addmul_1 + +LAB(___mpn_addmul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + INSN2(movem,l ,MEM_PREDEC(sp),d2-d5) + +/* Copy the arguments to registers. Better use movem? */ + INSN2(move,l ,res_ptr,MEM_DISP(sp,20)) + INSN2(move,l ,s1_ptr,MEM_DISP(sp,24)) + INSN2(move,l ,size,MEM_DISP(sp,28)) + INSN2(move,l ,s2_limb,MEM_DISP(sp,32)) + + INSN2(eor,w ,size,#1) + INSN1(clr,l ,d1) + INSN1(clr,l ,d5) + INSN2(lsr,l ,size,#1) + bcc L1 + INSN2(subq,l ,size,#1) + INSN2(sub,l ,d0,d0) /* (d0,cy) <= (0,0) */ + +LAB(Loop) + INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d1:d3,s2_limb) + INSN2(addx,l ,d3,d0) + INSN2(addx,l ,d1,d5) + INSN2(add,l ,MEM_POSTINC(res_ptr),d3) +LAB(L1) INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d0:d3,s2_limb) + INSN2(addx,l ,d3,d1) + INSN2(addx,l ,d0,d5) + INSN2(add,l ,MEM_POSTINC(res_ptr),d3) + + dbf size,Loop + INSN2(addx,l ,d0,d5) + INSN2(sub,l ,size,#0x10000) + bcc Loop + +/* Restore used registers from stack frame. */ + INSN2(movem,l ,d2-d5,MEM_POSTINC(sp)) + + rts diff --git a/sysdeps/m68k/m68020/asm-syntax.h b/sysdeps/m68k/m68020/asm-syntax.h new file mode 100644 index 0000000000..394b3ca739 --- /dev/null +++ b/sysdeps/m68k/m68020/asm-syntax.h @@ -0,0 +1,105 @@ +/* asm.h -- Definitions for 68k syntax variations. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef MIT_SYNTAX +#define MEM(base)base@ +#define MEM_DISP(base,displacement)base@(displacement) +#define MEM_PREDEC(memory_base)memory_base@- +#define MEM_POSTINC(memory_base)memory_base@+ +#ifdef __STDC__ +#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst +#else +#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst +#endif +#define LAB(label) label: +#define TEXT .text +#define ALIGN .even +#define GLOBL .globl +#endif + +#ifdef SONY_SYNTAX +#define MEM(base)(base) +#define MEM_DISP(base,displacement)(displacement,base) +#define MEM_PREDEC(memory_base)-(memory_base) +#define MEM_POSTINC(memory_base)(memory_base)+ +#define INSN1(mnemonic,size_suffix,dst)mnemonic.size_suffix dst +#ifdef __STDC__ +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic.size_suffix src##,dst +#else +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic.size_suffix src/**/,dst +#endif +#define LAB(label) label: +#define TEXT .text +#define ALIGN .even +#define GLOBL .globl +#endif + +#ifdef MOTOROLA_SYNTAX +#define MEM(base)(base) +#define MEM_DISP(base,displacement)(displacement,base) +#define MEM_PREDEC(memory_base)-(memory_base) +#define MEM_POSTINC(memory_base)(memory_base)+ +#define INSN1(mnemonic,size_suffix,dst)mnemonic.size_suffix dst +#ifdef __STDC__ +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic.size_suffix src##,dst +#else +#define INSN2(mnemonic,size_suffix,dst,src)mnemonic.size_suffix src/**/,dst +#endif +#define LAB(label) label +#define TEXT +#define ALIGN +#define GLOBL XDEF +#define l L +#define w W +#define move MOVE +#define eor EOR +#define lsr LSR +#define add ADD +#define addx ADDX +#define addq ADDQ +#define sub SUB +#define subx SUBX +#define subq SUBQ +#define neg NEG +#define bcc BCC +#define bcs BCS +#define bra BRA +#define dbf DBF +#define rts RTS +#define d0 D0 +#define d1 D1 +#define d2 D2 +#define d3 D3 +#define d4 D4 +#define d5 D5 +#define d6 D6 +#define d7 D7 +#define a0 A0 +#define a1 A1 +#define a2 A2 +#define a3 A3 +#define a4 A4 +#define a5 A5 +#define a6 A6 +#define a7 A7 +#define sp SP +#endif diff --git a/sysdeps/m68k/m68020/mul_1.S b/sysdeps/m68k/m68020/mul_1.S new file mode 100644 index 0000000000..548ca0091b --- /dev/null +++ b/sysdeps/m68k/m68020/mul_1.S @@ -0,0 +1,87 @@ +/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "asm-syntax.h" + + TEXT + ALIGN + GLOBL ___mpn_mul_1 + +LAB(___mpn_mul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + INSN2(movem,l ,MEM_PREDEC(sp),d2-d4) +#if 0 + INSN2(move,l ,MEM_PREDEC(sp),d2) + INSN2(move,l ,MEM_PREDEC(sp),d3) + INSN2(move,l ,MEM_PREDEC(sp),d4) +#endif + +/* Copy the arguments to registers. Better use movem? */ + INSN2(move,l ,res_ptr,MEM_DISP(sp,16)) + INSN2(move,l ,s1_ptr,MEM_DISP(sp,20)) + INSN2(move,l ,size,MEM_DISP(sp,24)) + INSN2(move,l ,s2_limb,MEM_DISP(sp,28)) + + INSN2(eor,w ,size,#1) + INSN1(clr,l ,d1) + INSN2(lsr,l ,size,#1) + bcc L1 + INSN2(subq,l ,size,#1) + INSN2(sub,l ,d0,d0) /* (d0,cy) <= (0,0) */ + +LAB(Loop) + INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d1:d3,s2_limb) + INSN2(addx,l ,d3,d0) + INSN2(move,l ,MEM_POSTINC(res_ptr),d3) +LAB(L1) INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d0:d3,s2_limb) + INSN2(addx,l ,d3,d1) + INSN2(move,l ,MEM_POSTINC(res_ptr),d3) + + dbf size,Loop + INSN1(clr,l ,d3) + INSN2(addx,l ,d0,d3) + INSN2(sub,l ,size,#0x10000) + bcc Loop + +/* Restore used registers from stack frame. */ + INSN2(movem,l ,d2-d4,MEM_POSTINC(sp)) +#if 0 + INSN2(move,l ,d4,MEM_POSTINC(sp)) + INSN2(move,l ,d3,MEM_POSTINC(sp)) + INSN2(move,l ,d2,MEM_POSTINC(sp)) +#endif + rts diff --git a/sysdeps/m68k/m68020/sub_n.S b/sysdeps/m68k/m68020/sub_n.S new file mode 100644 index 0000000000..19f0ec1568 --- /dev/null +++ b/sysdeps/m68k/m68020/sub_n.S @@ -0,0 +1,76 @@ +/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and + store difference in a third limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 16) + size (sp + 12) +*/ + +#include "asm-syntax.h" + + TEXT + ALIGN + GLOBL ___mpn_sub_n + +LAB(___mpn_sub_n) +/* Save used registers on the stack. */ + INSN2(move,l ,MEM_PREDEC(sp),d2) + INSN2(move,l ,MEM_PREDEC(sp),a2) + +/* Copy the arguments to registers. Better use movem? */ + INSN2(move,l ,a2,MEM_DISP(sp,12)) + INSN2(move,l ,a0,MEM_DISP(sp,16)) + INSN2(move,l ,a1,MEM_DISP(sp,20)) + INSN2(move,l ,d2,MEM_DISP(sp,24)) + + INSN2(eor,w ,d2,#1) + INSN2(lsr,l ,d2,#1) + bcc L1 + INSN2(subq,l ,d2,#1) /* clears cy as side effect */ + +LAB(Loop) + INSN2(move,l ,d0,MEM_POSTINC(a0)) + INSN2(move,l ,d1,MEM_POSTINC(a1)) + INSN2(subx,l ,d0,d1) + INSN2(move,l ,MEM_POSTINC(a2),d0) +LAB(L1) INSN2(move,l ,d0,MEM_POSTINC(a0)) + INSN2(move,l ,d1,MEM_POSTINC(a1)) + INSN2(subx,l ,d0,d1) + INSN2(move,l ,MEM_POSTINC(a2),d0) + + dbf d2,Loop /* loop until 16 lsb of %4 == -1 */ + INSN2(subx,l ,d0,d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + INSN2(sub,l ,d2,#0x10000) + bcs L2 + INSN2(add,l ,d0,d0) /* restore cy */ + bra Loop + +LAB(L2) + INSN1(neg,l ,d0) + +/* Restore used registers from stack frame. */ + INSN2(move,l ,a2,MEM_POSTINC(sp)) + INSN2(move,l ,d2,MEM_POSTINC(sp)) + + rts diff --git a/sysdeps/m68k/m68020/submul_1.S b/sysdeps/m68k/m68020/submul_1.S new file mode 100644 index 0000000000..ef7f39de7a --- /dev/null +++ b/sysdeps/m68k/m68020/submul_1.S @@ -0,0 +1,80 @@ +/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + +Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "asm-syntax.h" + + TEXT + ALIGN + GLOBL ___mpn_submul_1 + +LAB(___mpn_submul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + INSN2(movem,l ,MEM_PREDEC(sp),d2-d5) + +/* Copy the arguments to registers. Better use movem? */ + INSN2(move,l ,res_ptr,MEM_DISP(sp,20)) + INSN2(move,l ,s1_ptr,MEM_DISP(sp,24)) + INSN2(move,l ,size,MEM_DISP(sp,28)) + INSN2(move,l ,s2_limb,MEM_DISP(sp,32)) + + INSN2(eor,w ,size,#1) + INSN1(clr,l ,d1) + INSN1(clr,l ,d5) + INSN2(lsr,l ,size,#1) + bcc L1 + INSN2(subq,l ,size,#1) + INSN2(sub,l ,d0,d0) /* (d0,cy) <= (0,0) */ + +LAB(Loop) + INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d1:d3,s2_limb) + INSN2(addx,l ,d3,d0) + INSN2(addx,l ,d1,d5) + INSN2(sub,l ,MEM_POSTINC(res_ptr),d3) +LAB(L1) INSN2(move,l ,d3,MEM_POSTINC(s1_ptr)) + INSN2(mulu,l ,d0:d3,s2_limb) + INSN2(addx,l ,d3,d1) + INSN2(addx,l ,d0,d5) + INSN2(sub,l ,MEM_POSTINC(res_ptr),d3) + + dbf size,Loop + INSN2(addx,l ,d0,d5) + INSN2(sub,l ,size,#0x10000) + bcc Loop + +/* Restore used registers from stack frame. */ + INSN2(movem,l ,d2-d5,MEM_POSTINC(sp)) + + rts diff --git a/sysdeps/m68k/memcopy.h b/sysdeps/m68k/memcopy.h new file mode 100644 index 0000000000..862e1b8a7f --- /dev/null +++ b/sysdeps/m68k/memcopy.h @@ -0,0 +1,95 @@ +/* memcopy.h -- definitions for memory copy functions. Motorola 68020 version. + Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/generic/memcopy.h> + +#if defined(__mc68020__) || defined(mc68020) + +#undef OP_T_THRES +#define OP_T_THRES 16 + +/* WORD_COPY_FWD and WORD_COPY_BWD are not symmetric on the 68020, + because of its weird instruction overlap characteristics. */ + +#undef WORD_COPY_FWD +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + size_t __nwords = (nbytes) / sizeof (op_t); \ + size_t __nblocks = __nwords / 8 + 1; \ + dst_bp -= (8 - __nwords % 8) * sizeof (op_t); \ + src_bp -= (8 - __nwords % 8) * sizeof (op_t); \ + switch (__nwords % 8) \ + do \ + { \ + ((op_t *) dst_bp)[0] = ((op_t *) src_bp)[0]; \ + case 7: \ + ((op_t *) dst_bp)[1] = ((op_t *) src_bp)[1]; \ + case 6: \ + ((op_t *) dst_bp)[2] = ((op_t *) src_bp)[2]; \ + case 5: \ + ((op_t *) dst_bp)[3] = ((op_t *) src_bp)[3]; \ + case 4: \ + ((op_t *) dst_bp)[4] = ((op_t *) src_bp)[4]; \ + case 3: \ + ((op_t *) dst_bp)[5] = ((op_t *) src_bp)[5]; \ + case 2: \ + ((op_t *) dst_bp)[6] = ((op_t *) src_bp)[6]; \ + case 1: \ + ((op_t *) dst_bp)[7] = ((op_t *) src_bp)[7]; \ + case 0: \ + src_bp += 32; \ + dst_bp += 32; \ + __nblocks--; \ + } \ + while (__nblocks != 0); \ + (nbytes_left) = (nbytes) % sizeof (op_t); \ + } while (0) + +#undef WORD_COPY_BWD +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + size_t __nblocks = (nbytes) / 32 + 1; \ + switch ((nbytes) / sizeof (op_t) % 8) \ + do \ + { \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 7: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 6: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 5: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 4: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 3: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 2: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 1: \ + *--((op_t *) dst_ep) = *--((op_t *) src_ep); \ + case 0: \ + __nblocks--; \ + } \ + while (__nblocks != 0); \ + (nbytes_left) = (nbytes) % sizeof (op_t); \ + } while (0) + +#endif diff --git a/sysdeps/m68k/setjmp.c b/sysdeps/m68k/setjmp.c new file mode 100644 index 0000000000..853977eab9 --- /dev/null +++ b/sysdeps/m68k/setjmp.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> + +/* Save the current program position in ENV and return 0. */ +int +__sigsetjmp (jmp_buf env, int savemask) +{ + /* Save data registers D1 through D7. */ + asm volatile ("movem%.l d1-d7, %0" : : "m" (env[0].__jmpbuf[0].__dregs[0])); + + /* Save return address in place of register A0. */ + env[0].__jmpbuf[0].__aregs[0] = ((void **) &env)[-1]; + + /* Save address registers A1 through A5. */ + asm volatile ("movem%.l a1-a5, %0" : : "m" (env[0].__jmpbuf[0].__aregs[1])); + + /* Save caller's FP, not our own. */ + env[0].__jmpbuf[0].__fp = ((void **) &env)[-2]; + + /* Save caller's SP, not our own. */ + env[0].__jmpbuf[0].__sp = (void *) &env; + +#if defined(__HAVE_68881__) || defined(__HAVE_FPU__) + /* Save floating-point (68881) registers FP0 through FP7. */ + asm volatile ("fmovem%.x fp0-fp7, %0" + : : "m" (env[0].__jmpbuf[0].__fpregs[0])); +#endif + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/sysdeps/m88k/ffs.c b/sysdeps/m88k/ffs.c new file mode 100644 index 0000000000..effca9a0d2 --- /dev/null +++ b/sysdeps/m88k/ffs.c @@ -0,0 +1,42 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For Motorola 88000. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <bstring.h> + +#undef ffs + +#ifdef __GNUC__ + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + + if (x == 0) + return 0; + + asm ("ff1 %0,%1" : "=r" (cnt) : "r" (x & -x)); + return cnt + 1; +} + +#else +#include <sysdeps/generic/ffs.c> +#endif diff --git a/sysdeps/m88k/m88100/add_n.S b/sysdeps/m88k/m88100/add_n.S new file mode 100644 index 0000000000..2107eb55cb --- /dev/null +++ b/sysdeps/m88k/m88100/add_n.S @@ -0,0 +1,133 @@ +; mc88100 __mpn_add -- Add two limb vectors of the same length > 0 and store +; sum in a third limb vector. + +; Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +; This file is part of the GNU MP Library. + +; The GNU MP Library is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2, or (at your option) +; any later version. + +; The GNU MP Library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with the GNU MP Library; see the file COPYING. If not, write to +; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +; INPUT PARAMETERS +; res_ptr r2 +; s1_ptr r3 +; s2_ptr r4 +; size r5 + +; This code has been optimized to run one instruction per clock, avoiding +; load stalls and writeback contention. As a result, the instruction +; order is not always natural. + +; The speed is approximately 4.3 clocks/limb + 18 clocks/limb-vector. + +#include "sysdep.h" + +ENTRY (__mpn_add_n) + ld r6,r3,0 ; read first limb from s1_ptr + extu r10,r5,4 + ld r7,r4,0 ; read first limb from s2_ptr + + subu.co r5,r0,r5 ; (clear carry as side effect) + mak r5,r5,4<4> + bcnd eq0,r5,Lzero + + or r12,r0,lo16(Lbase) + or.u r12,r12,hi16(Lbase) + addu r12,r12,r5 ; r12 is address for entering in loop + + extu r5,r5,2 ; divide by 4 + subu r2,r2,r5 ; adjust res_ptr + subu r3,r3,r5 ; adjust s1_ptr + subu r4,r4,r5 ; adjust s2_ptr + + or r8,r6,r0 + + jmp.n r12 + or r9,r7,r0 + +Loop: addu r3,r3,64 + st r8,r2,60 + addu r4,r4,64 + ld r6,r3,0 + addu r2,r2,64 + ld r7,r4,0 +Lzero: subu r10,r10,1 ; add 0 + 16r limbs (adjust loop counter) +Lbase: ld r8,r3,4 + addu.cio r6,r6,r7 + ld r9,r4,4 + st r6,r2,0 + ld r6,r3,8 ; add 15 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,8 + st r8,r2,4 + ld r8,r3,12 ; add 14 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,12 + st r6,r2,8 + ld r6,r3,16 ; add 13 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,16 + st r8,r2,12 + ld r8,r3,20 ; add 12 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,20 + st r6,r2,16 + ld r6,r3,24 ; add 11 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,24 + st r8,r2,20 + ld r8,r3,28 ; add 10 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,28 + st r6,r2,24 + ld r6,r3,32 ; add 9 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,32 + st r8,r2,28 + ld r8,r3,36 ; add 8 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,36 + st r6,r2,32 + ld r6,r3,40 ; add 7 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,40 + st r8,r2,36 + ld r8,r3,44 ; add 6 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,44 + st r6,r2,40 + ld r6,r3,48 ; add 5 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,48 + st r8,r2,44 + ld r8,r3,52 ; add 4 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,52 + st r6,r2,48 + ld r6,r3,56 ; add 3 + 16r limbs + addu.cio r8,r8,r9 + ld r7,r4,56 + st r8,r2,52 + ld r8,r3,60 ; add 2 + 16r limbs + addu.cio r6,r6,r7 + ld r9,r4,60 + st r6,r2,56 + bcnd.n ne0,r10,Loop ; add 1 + 16r limbs + addu.cio r8,r8,r9 + + st r8,r2,60 ; store most significant limb + + jmp.n r1 + addu.ci r2,r0,r0 ; return carry-out from most sign. limb diff --git a/sysdeps/m88k/m88100/mul_1.S b/sysdeps/m88k/m88100/mul_1.S new file mode 100644 index 0000000000..503897b298 --- /dev/null +++ b/sysdeps/m88k/m88100/mul_1.S @@ -0,0 +1,127 @@ +; mc88100 __mpn_mul_1 -- Multiply a limb vector with a single limb and +; store the product in a second limb vector. + +; Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +; This file is part of the GNU MP Library. + +; The GNU MP Library is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2, or (at your option) +; any later version. + +; The GNU MP Library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with the GNU MP Library; see the file COPYING. If not, write to +; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +; INPUT PARAMETERS +; res_ptr r2 +; s1_ptr r3 +; size r4 +; s2_limb r5 + +; Common overhead is about 11 cycles/invocation. + +; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb. (The +; pipeline stalls 2 cycles due to WB contention.) + +; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb. (The +; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.) + +; To enhance speed: +; 1. Unroll main loop 4-8 times. +; 2. Schedule code to avoid WB contention. It might be tempting to move the +; ld instruction in the loops down to save 2 cycles (less WB contention), +; but that looses because the ultimate value will be read from outside +; the allocated space. But if we handle the ultimate multiplication in +; the tail, we can do this. +; 3. Make the multiplication with less instructions. I think the code for +; (S2_LIMB >= 0x10000) is not minimal. +; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or +; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11 +; cycles/limb. (Assuming infinite unrolling.) + +#include "sysdep.h" + +ENTRY (__mpn_mul_1) + + ; Make S1_PTR and RES_PTR point at the end of their blocks + ; and negate SIZE. + lda r3,r3[r4] + lda r6,r2[r4] ; RES_PTR in r6 since r2 is retval + subu r4,r0,r4 + + addu.co r2,r0,r0 ; r2 = cy = 0 + ld r9,r3[r4] + mask r7,r5,0xffff ; r7 = lo(S2_LIMB) + extu r8,r5,16 ; r8 = hi(S2_LIMB) + bcnd.n eq0,r8,Lsmall ; jump if (hi(S2_LIMB) == 0) + subu r6,r6,4 + +; General code for any value of S2_LIMB. + + ; Make a stack frame and save r25 and r26 + subu r31,r31,16 + st.d r25,r31,8 + + ; Enter the loop in the middle + br.n L1 + addu r4,r4,1 + +Loop: + ld r9,r3[r4] + st r26,r6[r4] +; bcnd ne0,r0,0 ; bubble + addu r4,r4,1 +L1: mul r26,r9,r5 ; low word of product mul_1 WB ld + mask r12,r9,0xffff ; r12 = lo(s1_limb) mask_1 + mul r11,r12,r7 ; r11 = prod_0 mul_2 WB mask_1 + mul r10,r12,r8 ; r10 = prod_1a mul_3 + extu r13,r9,16 ; r13 = hi(s1_limb) extu_1 WB mul_1 + mul r12,r13,r7 ; r12 = prod_1b mul_4 WB extu_1 + mul r25,r13,r8 ; r25 = prod_2 mul_5 WB mul_2 + extu r11,r11,16 ; r11 = hi(prod_0) extu_2 WB mul_3 + addu r10,r10,r11 ; addu_1 WB extu_2 +; bcnd ne0,r0,0 ; bubble WB addu_1 + addu.co r10,r10,r12 ; WB mul_4 + mask.u r10,r10,0xffff ; move the 16 most significant bits... + addu.ci r10,r10,r0 ; ...to the low half of the word... + rot r10,r10,16 ; ...and put carry in pos 16. + addu.co r26,r26,r2 ; add old carry limb + bcnd.n ne0,r4,Loop + addu.ci r2,r25,r10 ; compute new carry limb + + st r26,r6[r4] + ld.d r25,r31,8 + jmp.n r1 + addu r31,r31,16 + +; Fast code for S2_LIMB < 0x10000 +Lsmall: + ; Enter the loop in the middle + br.n SL1 + addu r4,r4,1 + +SLoop: + ld r9,r3[r4] ; + st r8,r6[r4] ; + addu r4,r4,1 ; +SL1: mul r8,r9,r5 ; low word of product + mask r12,r9,0xffff ; r12 = lo(s1_limb) + extu r13,r9,16 ; r13 = hi(s1_limb) + mul r11,r12,r7 ; r11 = prod_0 + mul r12,r13,r7 ; r12 = prod_1b + addu.cio r8,r8,r2 ; add old carry limb + extu r10,r11,16 ; r11 = hi(prod_0) + addu r10,r10,r12 ; + bcnd.n ne0,r4,SLoop + extu r2,r10,16 ; r2 = new carry limb + + jmp.n r1 + st r8,r6[r4] diff --git a/sysdeps/m88k/m88100/sub_n.S b/sysdeps/m88k/m88100/sub_n.S new file mode 100644 index 0000000000..927ece4f15 --- /dev/null +++ b/sysdeps/m88k/m88100/sub_n.S @@ -0,0 +1,134 @@ +; mc88100 __mpn_sub -- Subtract two limb vectors of the same length > 0 and +; store difference in a third limb vector. + +; Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +; This file is part of the GNU MP Library. + +; The GNU MP Library is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2, or (at your option) +; any later version. + +; The GNU MP Library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with the GNU MP Library; see the file COPYING. If not, write to +; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +; INPUT PARAMETERS +; res_ptr r2 +; s1_ptr r3 +; s2_ptr r4 +; size r5 + +; This code has been optimized to run one instruction per clock, avoiding +; load stalls and writeback contention. As a result, the instruction +; order is not always natural. + +; The speed is approximately 4.3 clocks/limb + 18 clocks/limb-vector. + +#include "sysdep.h" + +ENTRY (__mpn_sub_n) + ld r6,r3,0 ; read first limb from s1_ptr + extu r10,r5,4 + ld r7,r4,0 ; read first limb from s2_ptr + + subu.co r5,r0,r5 ; (clear carry as side effect) + mak r5,r5,4<4> + bcnd eq0,r5,Lzero + + or r12,r0,lo16(Lbase) + or.u r12,r12,hi16(Lbase) + addu r12,r12,r5 ; r12 is address for entering in loop + + extu r5,r5,2 ; divide by 4 + subu r2,r2,r5 ; adjust res_ptr + subu r3,r3,r5 ; adjust s1_ptr + subu r4,r4,r5 ; adjust s2_ptr + + or r8,r6,r0 + + jmp.n r12 + or r9,r7,r0 + +Loop: addu r3,r3,64 + st r8,r2,60 + addu r4,r4,64 + ld r6,r3,0 + addu r2,r2,64 + ld r7,r4,0 +Lzero: subu r10,r10,1 ; subtract 0 + 16r limbs (adjust loop counter) +Lbase: ld r8,r3,4 + subu.cio r6,r6,r7 + ld r9,r4,4 + st r6,r2,0 + ld r6,r3,8 ; subtract 15 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,8 + st r8,r2,4 + ld r8,r3,12 ; subtract 14 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,12 + st r6,r2,8 + ld r6,r3,16 ; subtract 13 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,16 + st r8,r2,12 + ld r8,r3,20 ; subtract 12 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,20 + st r6,r2,16 + ld r6,r3,24 ; subtract 11 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,24 + st r8,r2,20 + ld r8,r3,28 ; subtract 10 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,28 + st r6,r2,24 + ld r6,r3,32 ; subtract 9 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,32 + st r8,r2,28 + ld r8,r3,36 ; subtract 8 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,36 + st r6,r2,32 + ld r6,r3,40 ; subtract 7 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,40 + st r8,r2,36 + ld r8,r3,44 ; subtract 6 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,44 + st r6,r2,40 + ld r6,r3,48 ; subtract 5 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,48 + st r8,r2,44 + ld r8,r3,52 ; subtract 4 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,52 + st r6,r2,48 + ld r6,r3,56 ; subtract 3 + 16r limbs + subu.cio r8,r8,r9 + ld r7,r4,56 + st r8,r2,52 + ld r8,r3,60 ; subtract 2 + 16r limbs + subu.cio r6,r6,r7 + ld r9,r4,60 + st r6,r2,56 + bcnd.n ne0,r10,Loop ; subtract 1 + 16r limbs + subu.cio r8,r8,r9 + + st r8,r2,60 ; store most significant limb + + addu.ci r2,r0,r0 ; return carry-out from most sign. limb + jmp.n r1 + xor r2,r2,1 diff --git a/sysdeps/m88k/m88110/mul_1.S b/sysdeps/m88k/m88110/mul_1.S new file mode 100644 index 0000000000..7a07623865 --- /dev/null +++ b/sysdeps/m88k/m88110/mul_1.S @@ -0,0 +1,80 @@ +; mc88110 __mpn_mul_1 -- Multiply a limb vector with a single limb and +; store the product in a second limb vector. + +; Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +; This file is part of the GNU MP Library. + +; The GNU MP Library is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2, or (at your option) +; any later version. + +; The GNU MP Library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with the GNU MP Library; see the file COPYING. If not, write to +; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + +; INPUT PARAMETERS +; res_ptr r2 +; s1_ptr r3 +; size r4 +; s2_limb r5 + +#include "sysdep.h" + +ENTRY (__mpn_mul_1) + ld r6,r3,0 + sub r4,r0,r4 + sub r3,r3,r4 ; r3 is offset s1_ptr + sub r2,r2,r4 + sub r8,r2,8 ; r8 is offset res_ptr + mulu.d r10,r6,r5 + + addu r4,r4,1 + bcnd eq0,r4,Lend + addu.co r2,r0,0 ; clear cy_limb + +Loop: ld r6,r3[r4] + addu.cio r9,r11,r2 + or r2,r10,r0 ; could be avoided if unrolled + addu r4,r4,1 + mulu.d r10,r6,r5 + bcnd ne0,r4,Loop + st r9,r8[r4] + +Lend: addu.cio r9,r11,r2 + st r9,r8,4 + jmp.n r1 + addu.ci r2,r10,r0 + +; This is the Right Way to do this on '110. 4 cycles / 64-bit limb. +; ld.d r10, +; mulu.d +; addu.cio +; addu.cio +; st.d +; mulu.d ,r11,r5 +; ld.d r12, +; mulu.d ,r10,r5 +; addu.cio +; addu.cio +; st.d +; mulu.d +; ld.d r10, +; mulu.d +; addu.cio +; addu.cio +; st.d +; mulu.d +; ld.d r10, +; mulu.d +; addu.cio +; addu.cio +; st.d +; mulu.d diff --git a/sysdeps/mach/Makefile b/sysdeps/mach/Makefile new file mode 100644 index 0000000000..fab174c0d6 --- /dev/null +++ b/sysdeps/mach/Makefile @@ -0,0 +1,74 @@ +# Copyright (C) 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifndef mach-srcdir-computed +mach-srcdir-computed := yes + +# If we were configured with `--with-mach=DIR', then config.make sets +# mach-srcdir to DIR. Otherwise guess we are in a big source tree. +ifndef mach-srcdir +mach-srcdir = ../mach +endif + +# mach-srcdir is now set to the logical directory name. This name might be +# relative to $(objdir), might be relative to the source directory $(..), or +# might be absolute. We choose among these possibilities by looking for a +# canonical file in each of those places (in that order). +f := mach/mach.defs # Random file that identifies the Mach source dir. +f := $(strip $f) +mach-srcdir := $(firstword $(patsubst %/$f,%,$(wildcard $(addsuffix /$f,\ + $(objpfx)$(mach-srcdir) $(..)$(mach-srcdir)))) $(mach-srcdir)) + +endif # ! mach-srcdir-computed + +ifdef in-Makerules + +# Look for header files in mach/ under the top-level library source directory. +includes += -I$(..)mach + +# When compiling, use the Mach header files directly from the kernel sources. +includes += -I$(mach-srcdir) + +# Find Mach header files in the kernel source. +vpath mach/%.h $(mach-srcdir) +vpath device/%.h $(mach-srcdir) + +ifneq (mach,$(subdir)) +# Subdirectories other than mach/ might use the generated Mach headers. +# So make sure we get a chance to run in mach/ to make them before all else. + +ifdef objpfx +mach-objpfx = $(objpfx) +else +mach-objpfx = $(..)mach/ +endif + +# These are all the generated files that <mach.h> includes. +mach-before-compile := $(mach-objpfx)mach-shortcuts.h \ + $(patsubst %,$(mach-objpfx)mach/mach_%.h,\ + interface port host) + +# This patsubst generates patterns like `m%h-shortcuts.h', which are damn +# likely to match just the corresponding particular file we want. +$(patsubst mach%,m\%h%,$(mach-before-compile)): # Run only if doesn't exist. + $(MAKE) -C $(..)mach generated no_deps=t + +before-compile += $(mach-before-compile) +endif + +endif # in-Makerules diff --git a/sysdeps/mach/Subdirs b/sysdeps/mach/Subdirs new file mode 100644 index 0000000000..fc6ac35d83 --- /dev/null +++ b/sysdeps/mach/Subdirs @@ -0,0 +1 @@ +mach diff --git a/sysdeps/mach/_strerror.c b/sysdeps/mach/_strerror.c new file mode 100644 index 0000000000..4740902a10 --- /dev/null +++ b/sysdeps/mach/_strerror.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> +#include <mach/error.h> +#include <mach/errorlib.h> + +/* Return a string describing the errno code in ERRNUM. */ +char * +DEFUN(_strerror_internal, (errnum, buf), int errnum AND char buf[1024]) +{ + int system; + int sub; + int code; + const struct error_system *es; + extern void __mach_error_map_compat (int *); + + __mach_error_map_compat (&errnum); + + system = err_get_system (errnum); + sub = err_get_sub (errnum); + code = err_get_code (errnum); + + if (system > err_max_system) + { + sprintf (buf, "Unknown error system %d", system); + return buf; + } + + es = &__mach_error_systems[system]; + + if (sub >= es->max_sub) + return (char *) es->bad_sub; + + if (code >= es->subsystem[sub].max_code) + { + sprintf (buf, "Unknown error %d in system %d subsystem %d", + code, system, sub); + return buf; + } + + return (char *) es->subsystem[sub].codes[code]; +} diff --git a/sysdeps/mach/adjtime.c b/sysdeps/mach/adjtime.c new file mode 100644 index 0000000000..f20153565b --- /dev/null +++ b/sysdeps/mach/adjtime.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> +#include <hurd.h> + +/* Adjust the current time of day by the amount in DELTA. + If OLDDELTA is not NULL, it is filled in with the amount + of time adjustment remaining to be done from the last `__adjtime' call. + This call is restricted to the super-user. */ +int +DEFUN(__adjtime, (delta, olddelta), + CONST struct timeval *delta AND + struct timeval *olddelta) +{ + error_t err; + mach_port_t hostpriv; + + hostpriv = __pid2task (-1); + if (hostpriv == MACH_PORT_NULL) + return -1; + err = __host_adjust_time (hostpriv, delta, olddelta); + __mach_port_deallocate (__mach_task_self (), hostpriv); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__adjtime, adjtime) diff --git a/sysdeps/mach/alpha/machine-lock.h b/sysdeps/mach/alpha/machine-lock.h new file mode 100644 index 0000000000..42e21d8df2 --- /dev/null +++ b/sysdeps/mach/alpha/machine-lock.h @@ -0,0 +1,80 @@ +/* Machine-specific definition for spin locks. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef __volatile long int __spin_lock_t; + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER 0L + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + __asm__ __volatile__ ("mb; stq $31, %0; mb" + : "=m" (__lock)); +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (register __spin_lock_t *__lock) +{ + register long int __rtn, __tmp; + + do + { + __asm__ __volatile__ ("mb; ldq_l %0,%1" /* Load lock value into TMP. */ + : "=r" (__tmp) : "m" (*__lock)); + __rtn = 2; /* Load locked value into RTN. */ + if (__tmp) + /* The lock is already taken. */ + return 0; + + /* The lock is not taken; try to get it now. */ + __asm__ __volatile__ ("stq_c %0,%1" + : "=r" (__rtn), "=m" (*__lock) + : "0" (__rtn), "1" (*__lock)); + /* RTN is clear if stq_c was interrupted; loop to try the lock again. */ + } while (! __rtn); + /* RTN is now nonzero; we have the lock. */ + return __rtn; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + return *__lock != 0; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/mach/alpha/machine-sp.h b/sysdeps/mach/alpha/machine-sp.h new file mode 100644 index 0000000000..6a8a3c6d40 --- /dev/null +++ b/sysdeps/mach/alpha/machine-sp.h @@ -0,0 +1,36 @@ +/* Machine-specific function to return the stack pointer. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +_EXTERN_INLINE void * +__thread_stack_pointer (void) +{ + register void *__sp__ __asm__ ("$30"); + return __sp__; +} + +#endif /* machine-sp.h */ diff --git a/sysdeps/mach/alpha/syscall.S b/sysdeps/mach/alpha/syscall.S new file mode 100644 index 0000000000..31ccb5fc30 --- /dev/null +++ b/sysdeps/mach/alpha/syscall.S @@ -0,0 +1,39 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#include <mach/machine/alpha_instruction.h> + +ENTRY (syscall) + .frame sp,0,ra + mov a0, v0 /* Load system call number from first arg. */ + mov a1, a0 + mov a2, a1 + mov a3, a2 + mov a4, a3 + mov a5, a4 + /* Load the remaining possible args (up to 11) from the stack. */ + ldq a5,0(sp) + ldq t0,8(sp) + ldq t1,16(sp) + ldq t2,24(sp) + ldq t3,32(sp) + ldq t4,40(sp) + call_pal op_chmk + RET + .end syscall diff --git a/sysdeps/mach/alpha/sysdep.h b/sysdeps/mach/alpha/sysdep.h new file mode 100644 index 0000000000..a32766270b --- /dev/null +++ b/sysdeps/mach/alpha/sysdep.h @@ -0,0 +1,41 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define MOVE(x,y) mov x, y + +#define LOSE asm volatile ("call_pal 0") /* halt */ + +#define START_MACHDEP \ + asm ("_start: mov $30, $16\n" /* Put initial SP in a0. */ \ + " br $27, 1f\n" /* Load GP from PC. */ \ + "1: ldgp $29, 0($27)\n" \ + " jmp $26, _start0"); /* Jump to _start0; don't return. */ +#define START_ARGS char **sparg +#define SNARF_ARGS(argc, argv, envp) \ + (envp = &(argv = &sparg[1])[(argc = *(int *) sparg) + 1]) + +#define CALL_WITH_SP(fn, sp) \ + ({ register long int __fn = (long int) fn, __sp = (long int) sp; \ + asm volatile ("mov %0,$30; jmp $31, (%1); ldgp $29, 0(%1)" \ + : : "r" (__sp), "r" (__fn)); }) + +#define ENTRY(name) LEAF(name, ***loser no arg count***) + +#define STACK_GROWTH_DOWN + +#include_next <sysdep.h> diff --git a/sysdeps/mach/alpha/thread_state.h b/sysdeps/mach/alpha/thread_state.h new file mode 100644 index 0000000000..28b0a15758 --- /dev/null +++ b/sysdeps/mach/alpha/thread_state.h @@ -0,0 +1,39 @@ +/* Mach thread state definitions for machine-independent code. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach/machine/thread_status.h> + +#define MACHINE_THREAD_STATE_FLAVOR ALPHA_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT ALPHA_THREAD_STATE_COUNT + +#define machine_thread_state alpha_thread_state + +#define PC pc +#define SP r30 +#define SYSRETURN r0 + +struct machine_thread_all_state + { + int set; /* Mask of bits (1 << FLAVOR). */ + struct alpha_thread_state basic; + struct alpha_exc_state exc; + struct alpha_float_state fpu; + }; + +#include_next <thread_state.h> diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure new file mode 100644 index 0000000000..fb1d8b0979 --- /dev/null +++ b/sysdeps/mach/configure @@ -0,0 +1,17 @@ + +# If configure is passed `--with-mach=DIR', set `mach-srcdir' to DIR in +# config.make. + +ac_help="$ac_help + --with-mach=DIRECTORY find Mach kernel source code in DIRECTORY [../mach]" +# Check whether --with-mach or --without-mach was given. +withval="$with_mach" +if test -n "$withval"; then + case z"$with_mach" in +z | zno | zyes) ;; # Not specified, or specified with no value. +z*) config_vars="$config_vars +mach-srcdir = $with_mach" ;; +esac + +fi + diff --git a/sysdeps/mach/configure.in b/sysdeps/mach/configure.in new file mode 100644 index 0000000000..2628886f1f --- /dev/null +++ b/sysdeps/mach/configure.in @@ -0,0 +1,15 @@ +sinclude(./aclocal.m4)dnl Autoconf lossage. +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +# If configure is passed `--with-mach=DIR', set `mach-srcdir' to DIR in +# config.make. + +AC_ARG_WITH(mach, dnl +[ --with-mach=DIRECTORY find Mach kernel source code in DIRECTORY [../mach]], + [dnl +case z"$with_mach" in +z | zno | zyes) ;; # Not specified, or specified with no value. +z*) config_vars="$config_vars +mach-srcdir = $with_mach" ;; +esac +]) diff --git a/sysdeps/mach/getpagesize.c b/sysdeps/mach/getpagesize.c new file mode 100644 index 0000000000..84f227f04f --- /dev/null +++ b/sysdeps/mach/getpagesize.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <unistd.h> +#include <errno.h> +#include <mach.h> + +/* Return the system page size. */ +size_t +DEFUN_VOID(__getpagesize) +{ + return __vm_page_size; +} + +weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c new file mode 100644 index 0000000000..9271490ad5 --- /dev/null +++ b/sysdeps/mach/gettimeofday.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> +#include <mach.h> + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. */ +int +DEFUN(__gettimeofday, (tv, tz), + struct timeval *tv AND struct timezone *tz) +{ + kern_return_t err; + + if (tz != NULL) + { + errno = ENOSYS; + return -1; + } + + if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv)) + { + errno = err; + return -1; + } + return 0; +} + +weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/mach/hppa/machine-lock.h b/sysdeps/mach/hppa/machine-lock.h new file mode 100644 index 0000000000..0a178357a3 --- /dev/null +++ b/sysdeps/mach/hppa/machine-lock.h @@ -0,0 +1,63 @@ +/* Machine-specific definition for spin locks. HPPA version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef __volatile int __spin_lock_t __attribute__ ((__aligned__ (16))); + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER -1 + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + *__lock = -1; +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (__spin_lock_t *__lock) +{ + register int __result; + __asm__ __volatile__ ("ldcws %0, %1" : "=m" (*__lock), "=r" (__result)); + return __result != 0; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + return *__lock == 0; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/mach/hurd/.cvsignore b/sysdeps/mach/hurd/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/sysdeps/mach/hurd/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/sysdeps/mach/hurd/Dist b/sysdeps/mach/hurd/Dist new file mode 100644 index 0000000000..89a6b56f32 --- /dev/null +++ b/sysdeps/mach/hurd/Dist @@ -0,0 +1,3 @@ +errnos.awk errlist.awk err_hurd.sub +libc-ldscript + diff --git a/sysdeps/mach/hurd/Implies b/sysdeps/mach/hurd/Implies new file mode 100644 index 0000000000..b6e4d864d5 --- /dev/null +++ b/sysdeps/mach/hurd/Implies @@ -0,0 +1,2 @@ +# The Hurd provides a rough superset of the functionality of 4.4 BSD. +unix/bsd/bsd4.4 diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile new file mode 100644 index 0000000000..70b6ec5d49 --- /dev/null +++ b/sysdeps/mach/hurd/Makefile @@ -0,0 +1,132 @@ +# Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# Get mach-srcdir defined. +old-in-Makerules := $(in-Makerules) +in-Makerules := +include $(..)sysdeps/mach/Makefile +in-Makerules := $(old-in-Makerules) + + +ifndef hurd-srcdir-computed +hurd-srcdir-computed := yes + +# If we were configured with `--with-hurd=DIR', then config.make sets +# hurd-srcdir to DIR. Otherwise guess we are in a big source tree. +ifndef hurd-srcdir +hurd-srcdir = ../hurd +endif + +# hurd-srcdir is now set to the logical directory name. This name might be +# relative to $(objdir), might be relative to the source directory $(..), or +# might be absolute. We choose among these possibilities by looking for a +# canonical file in each of those places (in that order). +f := hurd/hurd_types.defs # Random file that identifies the Hurd source dir. +f := $(strip $f) +hurd-srcdir := $(firstword $(patsubst %/$f,%,$(wildcard $(addsuffix /$f,\ + $(objpfx)$(hurd-srcdir) $(..)$(hurd-srcdir)))) $(hurd-srcdir)) + +endif # ! hurd-srcdir-computed + +ifdef in-Makerules + +# For the time being, elide directories where nothing at all works. +subdirs := $(filter-out sunrpc manual,$(subdirs)) # XXX + +# Look for header files in hurd/ under the top-level library source directory. +includes += -I$(..)hurd + +# When compiling, use the Hurd header files directly from the sources. +includes += -I$(hurd-srcdir) + +# When compiling, find cthreads.h in the Hurd cthreads source. +# This directory has some other (private) header file with +# conflicting names, so we put it last. +last-includes += -I$(hurd-srcdir)/libthreads + +# Find the Hurd header files in the Hurd source. +vpath hurd/%.h $(hurd-srcdir) + +# Do not use any assembly code from sysdeps/unix (and subdirectories). +# This bypasses all the system call stubs and uses any existing posix or +# generic C files instead. +inhibit-sysdep-asm += unix* + +# Don't try to generate anything from the installed Unix system and its +# libraries. That is only of use when building for a Unix system, so as to +# be compatible with some existing binaries for that system. +inhibit-glue = yes + + +ifeq (,$(filter mach hurd,$(subdir))) +# Subdirectories other than hurd/ might use the generated Hurd headers. +# So make sure we get a chance to run in hurd/ to make them before all else. +# (But we don't want to do this in mach/, because hurd/ needs some things +# there, and we know mach/ doesn't need anything from hurd/.) + +ifdef objpfx +hurd-objpfx = $(objpfx) +else +hurd-objpfx = $(..)hurd/ +endif + +# These are all the generated headers that <hurd.h> includes. +before-compile += $(patsubst %,$(hurd-objpfx)hurd/%.h,io fs process) +$(patsubst %,$(hurd-objpfx)hurd/%.%,io fs process): + $(MAKE) -C $(..)hurd generated no_deps=t +endif + +# Generate errnos.h and sys_errlist.c from the section of the manual that +# lists all the errno codes. + +errno.texinfo = $(..)manual/errno.texi + +hurd = $(..)sysdeps/mach/hurd + +$(hurd)/errnos.h: $(objpfx)stamp-errnos ; +$(objpfx)stamp-errnos: $(hurd)/errnos.awk $(errno.texinfo) \ + $(mach-srcdir)/mach/message.h \ + $(mach-srcdir)/mach/kern_return.h \ + $(mach-srcdir)/mach/mig_errors.h \ + $(mach-srcdir)/device/device_types.h + gawk -f $^ > $(hurd)/errnos.h-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $(hurd)/errnos.h-tmp + ./$(..)move-if-change $(hurd)/errnos.h-tmp $(hurd)/errnos.h + test -d CVS && cvs commit -m'Regenerated from $^' $@ + touch $@ + +$(hurd)/errlist.c: $(hurd)/errlist.awk $(errno.texinfo) + gawk -f $^ > $@-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $@-tmp + mv -f $@-tmp $@ + test -d CVS && cvs commit -m'Regenerated from $^' $@ + +# We install the real libc.a as libcrt.a and as libc.a we install a linker +# script which does -( -lcrt -lmachuser -lhurduser -). + +libc-name = crt + +ifeq (,$(subdir)) +install-others += $(libdir)/libc.a +$(libdir)/libc.a: $(hurd)/libc-ldscript; $(do-install) +endif + + +endif # in-Makerules diff --git a/sysdeps/mach/hurd/Subdirs b/sysdeps/mach/hurd/Subdirs new file mode 100644 index 0000000000..16b8348437 --- /dev/null +++ b/sysdeps/mach/hurd/Subdirs @@ -0,0 +1 @@ +hurd diff --git a/sysdeps/mach/hurd/_exit.c b/sysdeps/mach/hurd/_exit.c new file mode 100644 index 0000000000..fd56791ee8 --- /dev/null +++ b/sysdeps/mach/hurd/_exit.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> +#include <sysdep.h> +#include <sys/wait.h> + +void +_hurd_exit (int status) +{ + /* Give the proc server our exit status. */ + __USEPORT (PROC, __proc_mark_exit (port, status)); + + /* Commit suicide. */ + __task_terminate (__mach_task_self ()); + + /* Perhaps the cached mach_task_self was bogus. */ + __task_terminate ((__mach_task_self) ()); + + /* This sucker really doesn't want to die. */ + while (1) + { +#ifdef LOSE + LOSE; +#else + volatile const int zero = 0, one = 1; + volatile int lossage = one / zero; +#endif + } +} + +void +DEFUN(_exit, (status), int status) +{ + _hurd_exit (W_EXITCODE (status, 0)); +} diff --git a/sysdeps/mach/hurd/accept.c b/sysdeps/mach/hurd/accept.c new file mode 100644 index 0000000000..48402b1227 --- /dev/null +++ b/sysdeps/mach/hurd/accept.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <sys/socket.h> +#include <hurd/socket.h> +#include <fcntl.h> +#include <string.h> + +/* Await a connection on socket FD. + When a connection arrives, open a new socket to communicate with it, + set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting + peer and *ADDR_LEN to the address's actual length, and return the + new socket's descriptor, or -1 for errors. */ +int +DEFUN(accept, (fd, addr, addr_len), + int fd AND struct sockaddr *addr AND size_t *addr_len) +{ + error_t err; + socket_t new; + addr_port_t aport; + char *buf = (char *) addr; + mach_msg_type_number_t buflen = *addr_len; + int type; + + if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport))) + return __hurd_dfail (fd, err); + + if (addr != NULL) + err = __socket_whatis_address (aport, &type, &buf, &buflen); + __mach_port_deallocate (__mach_task_self (), aport); + + if (err) + { + __mach_port_deallocate (__mach_task_self (), new); + return __hurd_dfail (fd, err); + } + + if (addr != NULL) + { + if (buf != (char *) addr) + { + if (*addr_len < buflen) + *addr_len = buflen; + memcpy (addr, buf, *addr_len); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + addr->sa_family = type; + } + + return _hurd_intern_fd (new, O_IGNORE_CTTY, 1); +} diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c new file mode 100644 index 0000000000..90938060e0 --- /dev/null +++ b/sysdeps/mach/hurd/access.c @@ -0,0 +1,138 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> +#include <hurd/id.h> +#include <fcntl.h> + +/* Test for access to FILE by our real user and group IDs. */ +int +DEFUN(__access, (file, type), CONST char *file AND int type) +{ + error_t err; + file_t crdir, cwdir, rcrdir, rcwdir, io; + struct hurd_userlink crdir_ulink, cwdir_ulink; + int flags, allowed; + mach_port_t ref; + + HURD_CRITICAL_BEGIN; + + __mutex_lock (&_hurd_id.lock); + /* Get _hurd_id up to date. */ + if (err = _hurd_check_ids ()) + goto lose; + + if (_hurd_id.rid_auth == MACH_PORT_NULL) + { + /* Set up _hurd_id.rid_auth. This is a special auth server port + which uses the real uid and gid (the first aux uid and gid) as + the only effective uid and gid. */ + + if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1) + { + /* We do not have a real UID and GID. Lose, lose, lose! */ + err = EGRATUITOUS; + goto lose; + } + + /* Create a new auth port using our real UID and GID (the first + auxiliary UID and GID) as the only effective IDs. */ + if (err = __USEPORT (AUTH, + __auth_makeauth (port, + NULL, MACH_MSG_TYPE_COPY_SEND, 0, + _hurd_id.aux.uids, 1, + _hurd_id.aux.gids, 1, + _hurd_id.aux.uids, + _hurd_id.aux.nuids, + _hurd_id.aux.gids, + _hurd_id.aux.ngids, + &_hurd_id.rid_auth))) + goto lose; + } + + /* Get a port to our root directory, authenticated with the real IDs. */ + crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); + ref = __mach_reply_port (); + err = __io_reauthenticate (crdir, ref, MACH_MSG_TYPE_MAKE_SEND); + if (!err) + err = __auth_user_authenticate (_hurd_id.rid_auth, + crdir, + ref, MACH_MSG_TYPE_MAKE_SEND, + &rcrdir); + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + __mach_port_destroy (__mach_task_self (), ref); + + if (!err) + { + /* Get a port to our current working directory, authenticated with + the real IDs. */ + cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink); + ref = __mach_reply_port (); + err = __io_reauthenticate (cwdir, ref, MACH_MSG_TYPE_MAKE_SEND); + if (!err) + err = __auth_user_authenticate (_hurd_id.rid_auth, + cwdir, + ref, MACH_MSG_TYPE_MAKE_SEND, + &rcwdir); + _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir); + __mach_port_destroy (__mach_task_self (), ref); + } + + /* We are done with _hurd_id.rid_auth now. */ + lose: + __mutex_unlock (&_hurd_id.lock); + + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Now do a path lookup on FILE, using the crdir and cwdir + reauthenticated with _hurd_id.rid_auth. */ + + err = __hurd_file_name_lookup (rcrdir, rcwdir, file, 0, 0, &io); + __mach_port_deallocate (__mach_task_self (), rcrdir); + __mach_port_deallocate (__mach_task_self (), rcwdir); + if (err) + return __hurd_fail (err); + + /* Find out what types of access we are allowed to this file. */ + err = __file_check_access (io, &allowed); + __mach_port_deallocate (__mach_task_self (), io); + if (err) + return __hurd_fail (err); + + flags = 0; + if (type & R_OK) + flags |= O_READ; + if (type & W_OK) + flags |= O_WRITE; + if (type & X_OK) + flags |= O_EXEC; + + if (flags & ~allowed) + /* We are not allowed all the requested types of access. */ + return __hurd_fail (EACCES); + + return 0; +} + +weak_alias (__access, access) diff --git a/sysdeps/mach/hurd/adjtime.c b/sysdeps/mach/hurd/adjtime.c new file mode 100644 index 0000000000..d88f404ce4 --- /dev/null +++ b/sysdeps/mach/hurd/adjtime.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> +#include <hurd.h> + +/* Adjust the current time of day by the amount in DELTA. + If OLDDELTA is not NULL, it is filled in with the amount + of time adjustment remaining to be done from the last `__adjtime' call. + This call is restricted to the super-user. */ +int +DEFUN(__adjtime, (delta, olddelta), + CONST struct timeval *delta AND + struct timeval *olddelta) +{ + error_t err; + mach_port_t hostpriv, devmaster; + + if (err = __USEPORT (PROC, __proc_getprivports (port, + &hostpriv, &devmaster))) + return __hurd_fail (err); + __mach_port_deallocate (__mach_task_self (), devmaster); + + err = __host_adjust_time (hostpriv, + /* `time_value_t' and `struct timeval' are in + fact identical with the names changed. */ + *(time_value_t *) delta, + (time_value_t *) olddelta); + __mach_port_deallocate (__mach_task_self (), hostpriv); + + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__adjtime, adjtime) diff --git a/sysdeps/mach/hurd/alpha/exc2signal.c b/sysdeps/mach/hurd/alpha/exc2signal.c new file mode 100644 index 0000000000..edac0aaa67 --- /dev/null +++ b/sysdeps/mach/hurd/alpha/exc2signal.c @@ -0,0 +1,76 @@ +/* Translate Mach exception codes into signal numbers. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <mach/exception.h> + +/* Translate the Mach exception codes, as received in an `exception_raise' RPC, + into a signal number and signal subcode. */ + +void +_hurd_exception2signal (int exception, int code, int subcode, + int *signo, long int *sigcode, int *error) +{ + *error = 0; + + switch (exception) + { + default: + *signo = SIGIOT; + *sigcode = exception; + break; + + case EXC_BAD_ACCESS: + if (code == KERN_PROTECTION_FAILURE) + *signo = SIGSEGV; + else + *signo = SIGBUS; + *sigcode = subcode; + *error = code; + break; + + case EXC_BAD_INSTRUCTION: + *signo = SIGILL; + *sigcode = code; + break; + + case EXC_ARITHMETIC: + *signo = SIGFPE; + *sigcode = code; + break; + break; + + case EXC_EMULATION: + /* 3.0 doesn't give this one, why, I don't know. */ + *signo = SIGEMT; + *sigcode = code; + break; + + case EXC_SOFTWARE: + *signo = SIGEMT; + *sigcode = code; + break; + + case EXC_BREAKPOINT: + *signo = SIGTRAP; + *sigcode = code; + break; + } +} diff --git a/sysdeps/mach/hurd/alpha/longjmp-ctx.c b/sysdeps/mach/hurd/alpha/longjmp-ctx.c new file mode 100644 index 0000000000..dfc16fdfe4 --- /dev/null +++ b/sysdeps/mach/hurd/alpha/longjmp-ctx.c @@ -0,0 +1,38 @@ +/* Perform a `longjmp' on a `struct sigcontext'. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <hurd/signal.h> +#include <string.h> + +void +_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval) +{ + memset (scp, 0, sizeof (*scp)); + scp->sc_regs[9] = env[0].__9; + scp->sc_regs[11] = env[0].__11; + scp->sc_regs[12] = env[0].__12; + scp->sc_regs[13] = env[0].__13; + scp->sc_regs[14] = env[0].__14; + scp->sc_regs[15] = (long int) env[0].__fp; + scp->sc_regs[30] = (long int) env[0].__sp; + scp->sc_pc = (long int) env[0].__pc; + + memcpy (&scp->sc_fpregs[2], &env[0].__f2, sizeof (double)); +} diff --git a/sysdeps/mach/hurd/alpha/longjmp-ts.c b/sysdeps/mach/hurd/alpha/longjmp-ts.c new file mode 100644 index 0000000000..ad6f80cdb0 --- /dev/null +++ b/sysdeps/mach/hurd/alpha/longjmp-ts.c @@ -0,0 +1,41 @@ +/* Perform a `longjmp' on a Mach thread_state. Alpha version. +Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <setjmp.h> +#include <mach/thread_status.h> + + +/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ + +void +_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) +{ + struct alpha_thread_state *ts = state; + + ts->r9 = env[0].__jmpbuf[0].__9; + ts->r11 = env[0].__jmpbuf[0].__11; + ts->r12 = env[0].__jmpbuf[0].__12; + ts->r13 = env[0].__jmpbuf[0].__13; + ts->r14 = env[0].__jmpbuf[0].__14; + ts->r15 = (long int) env[0].__jmpbuf[0].__fp; + ts->r30 = (long int) env[0].__jmpbuf[0].__sp; + ts->pc = (long int) env[0].__jmpbuf[0].__pc; + ts->r0 = val ?: 1; +} diff --git a/sysdeps/mach/hurd/alpha/sigcontext.h b/sysdeps/mach/hurd/alpha/sigcontext.h new file mode 100644 index 0000000000..32e0c94f98 --- /dev/null +++ b/sysdeps/mach/hurd/alpha/sigcontext.h @@ -0,0 +1,65 @@ +/* Machine-dependent signal context structure for GNU Hurd. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Signal handlers are actually called: + void handler (int sig, int code, struct sigcontext *scp); */ + +/* State of this thread when the signal was taken. */ +struct sigcontext + { + /* These first members are machine-independent. */ + + long int sc_onstack; /* Nonzero if running on sigstack. */ + __sigset_t sc_mask; /* Blocked signals to restore. */ + + /* MiG reply port this thread is using. */ + unsigned long int sc_reply_port; + + /* Port this thread is doing an interruptible RPC on. */ + unsigned long int sc_intr_port; + + /* Error code associated with this signal (interpreted as `error_t'). */ + int sc_error; + + /* All following members are machine-dependent. The rest of this + structure is written to be laid out identically to: + { + struct alpha_thread_state basic; + struct alpha_exc_state exc; + struct alpha_float_state fpu; + } + trampoline.c knows this, so it must be changed if this changes. */ + +#define sc_alpha_thread_state sc_regs /* Beginning of correspondence. */ + long int sc_regs[31]; /* General registers $0..$30. */ + long int sc_pc; /* Program counter. */ + + /* struct alpha_exc_state */ +#define sc_alpha_exc_state sc_badvaddr + unsigned long int sc_badvaddr; + unsigned int sc_cause; /* Machine-level trap code. */ +#define SC_CAUSE_SET_SSTEP 1 + int sc_used_fpa; /* Nonzero if FPU was used. */ + + /* struct alpha_float_state + This is only filled in if sc_used_fpa is nonzero. */ +#define sc_alpha_float_state sc_fpregs + double sc_fpregs[31]; /* Floating point registers $f0..$f30. */ + long int sc_fpcsr; /* Floating point control/status register. */ + }; diff --git a/sysdeps/mach/hurd/alpha/sigreturn.c b/sysdeps/mach/hurd/alpha/sigreturn.c new file mode 100644 index 0000000000..e5dc383a3a --- /dev/null +++ b/sysdeps/mach/hurd/alpha/sigreturn.c @@ -0,0 +1,212 @@ +/* Return from signal handler in GNU C library for Hurd. Alpha version. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/threadvar.h> +#include <hurd/msg.h> +#include <stdlib.h> +#include <string.h> +#include <mach/machine/alpha_instruction.h> + +int +__sigreturn (struct sigcontext *scp) +{ + struct hurd_sigstate *ss; + mach_port_t *reply_port; + + if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) + { + errno = EINVAL; + return -1; + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + + /* Restore the set of blocked signals, and the intr_port slot. */ + ss->blocked = scp->sc_mask; + ss->intr_port = scp->sc_intr_port; + + /* Check for pending signals that were blocked by the old set. */ + if (ss->pending & ~ss->blocked) + { + /* There are pending signals that just became unblocked. Wake up the + signal thread to deliver them. But first, squirrel away SCP where + the signal thread will notice it if it runs another handler, and + arrange to have us called over again in the new reality. */ + ss->context = scp; + /* Clear the intr_port slot, since we are not in fact doing + an interruptible RPC right now. If SS->intr_port is not null, + the SCP context is doing an interruptible RPC, but the signal + thread will examine us while we are blocked in the sig_post RPC. */ + ss->intr_port = MACH_PORT_NULL; + __spin_unlock (&ss->lock); + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + /* If a pending signal was handled, sig_post never returned. */ + __spin_lock (&ss->lock); + } + + if (scp->sc_onstack) + { + ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */ + /* XXX cannot unlock until off sigstack */ + abort (); + } + else + __spin_unlock (&ss->lock); + + /* Destroy the MiG reply port used by the signal handler, and restore the + reply port in use by the thread when interrupted. */ + reply_port = + (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); + if (*reply_port) + __mach_port_destroy (__mach_task_self (), *reply_port); + *reply_port = scp->sc_reply_port; + + if (scp->sc_used_fpa) + { + /* Restore FPU state. */ + + /* Restore the floating-point control/status register. + We must do this first because the compiler will need + a temporary FP register for the load. */ + asm volatile ("mt_fpcr %0" : : "f" (scp->sc_fpcsr)); + + /* Restore floating-point registers. */ +#define restore_fpr(n) \ + asm volatile ("ldt $f" #n ",%0" : : "m" (scp->sc_fpregs[n])) + restore_fpr (0); + restore_fpr (1); + restore_fpr (2); + restore_fpr (3); + restore_fpr (4); + restore_fpr (5); + restore_fpr (6); + restore_fpr (7); + restore_fpr (8); + restore_fpr (9); + restore_fpr (10); + restore_fpr (11); + restore_fpr (12); + restore_fpr (13); + restore_fpr (14); + restore_fpr (15); + restore_fpr (16); + restore_fpr (17); + restore_fpr (18); + restore_fpr (19); + restore_fpr (20); + restore_fpr (21); + restore_fpr (22); + restore_fpr (23); + restore_fpr (24); + restore_fpr (25); + restore_fpr (26); + restore_fpr (27); + restore_fpr (28); + restore_fpr (29); + restore_fpr (30); + } + + /* Load all the registers from the sigcontext. */ +#define restore_gpr(n) \ + asm volatile ("ldq $" #n ",%0" : : "m" (scpreg->sc_regs[n])) + + { + /* The `rei' PAL pseudo-instruction restores registers $2..$7, the PC + and processor status. So we can use these few registers for our + working variables. Unfortunately, it finds its data on the stack + and merely pops the SP ($30) over the words of state restored, + allowing no other option for the new SP value. So we must push the + registers and PSW it will to restore, onto the user's stack and let + it pop them from there. */ + register const struct sigcontext *const scpreg asm ("$2") = scp; + register integer_t *usp asm ("$3") = (integer_t *) scpreg->sc_regs[30]; + register integer_t usp_align asm ("$4"); + + /* Push an 8-word "trap frame" onto the user stack for `rei': + registers $2..$7, the PC, and the PSW. */ + + register struct rei_frame + { + integer_t regs[5], pc, ps; + } *rei_frame asm ("$5"); + + usp -= 8; + /* `rei' demands that the stack be aligned to a 64 byte (8 word) + boundary; bits 61..56 of the PSW are OR'd back into the SP value + after popping the 8-word trap frame, so we store (sp % 64) + there and this restores the original user SP. */ + usp_align = (integer_t) usp & 63L; + rei_frame = (void *) ((integer_t) usp & ~63L); + + /* Copy the registers and PC from the sigcontext. */ + memcpy (rei_frame->regs, &scpreg->sc_regs[2], sizeof rei_frame->regs); + rei_frame->pc = scpreg->sc_pc; + + /* Compute the new PS value to be restored. `rei' adds the value at + bits 61..56 to the SP to compensate for the alignment above that + cleared the low 6 bits; bits 5..3 are the new mode/privilege level + (must be >= current mode; 3 == user mode); bits 2..0 are "software", + unused by the processor or kernel (XXX should trampoline save these? + How?); in user mode, `rei' demands that all other bits be zero. */ + rei_frame->ps = (usp_align << 56) | (3 << 3); /* XXX low 3 bits??? */ + + /* Restore the other general registers: everything except $2..$7, which + are in the `rei' trap frame we set up above, and $30, which is the + SP which is popped by `rei'. */ + restore_gpr (1); + restore_gpr (8); + restore_gpr (9); + restore_gpr (10); + restore_gpr (11); + restore_gpr (12); + restore_gpr (13); + restore_gpr (14); + restore_gpr (15); + restore_gpr (16); + restore_gpr (17); + restore_gpr (18); + restore_gpr (19); + restore_gpr (20); + restore_gpr (21); + restore_gpr (22); + restore_gpr (23); + restore_gpr (24); + restore_gpr (25); + restore_gpr (26); + restore_gpr (27); + restore_gpr (28); + restore_gpr (29); + + /* Switch the stack pointer to the trap frame set up on + the user stack and do the magical `rei' PAL call. */ + asm volatile ("mov %0, $30\n" + "call_pal %1" + : : "r" (rei_frame), "i" (op_rei)); + /* Firewall. */ + asm volatile ("call_pal %0" : : "i" (op_halt)); + } + + /* NOTREACHED */ + return -1; +} + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/mach/hurd/alpha/trampoline.c b/sysdeps/mach/hurd/alpha/trampoline.c new file mode 100644 index 0000000000..85f4964e14 --- /dev/null +++ b/sysdeps/mach/hurd/alpha/trampoline.c @@ -0,0 +1,286 @@ +/* Set thread_state for sighandler, and sigcontext to recover. Alpha version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include "thread_state.h" +#include <mach/machine/alpha_instruction.h> +#include "hurdfault.h" +#include <assert.h> + +struct mach_msg_trap_args + { + /* This is the order of arguments to mach_msg_trap. */ + mach_msg_header_t *msg; + mach_msg_option_t option; + mach_msg_size_t send_size; + mach_msg_size_t rcv_size; + mach_port_t rcv_name; + mach_msg_timeout_t timeout; + mach_port_t notify; + }; + + +struct sigcontext * +_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, + int signo, long int sigcode, + int rpc_wait, + struct machine_thread_all_state *state) +{ + __label__ trampoline, rpc_wait_trampoline; + void *sigsp; + struct sigcontext *scp; + + if (ss->context) + { + /* We have a previous sigcontext that sigreturn was about + to restore when another signal arrived. We will just base + our setup on that. */ + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode >= (long int) ss->context && + _hurdsig_fault_sigcode < (long int) (ss->context + 1)); + else + { + memcpy (&state->basic, &ss->context->sc_alpha_thread_state, + sizeof (state->basic)); + memcpy (&state->exc, &ss->context->sc_alpha_exc_state, + sizeof (state->exc)); + state->set = (1 << ALPHA_THREAD_STATE) | (1 << ALPHA_EXC_STATE); + if (state->exc.used_fpa) + { + memcpy (&state->fpu, &ss->context->sc_alpha_float_state, + sizeof (state->fpu)); + state->set |= (1 << ALPHA_FLOAT_STATE); + } + assert (! rpc_wait); + /* The intr_port slot was cleared before sigreturn sent us the + sig_post that made us notice this pending signal, so + _hurd_internal_post_signal wouldn't do interrupt_operation. + After we return, our caller will set SCP->sc_intr_port (in the + new context) from SS->intr_port and clear SS->intr_port. Now + that we are restoring this old context recorded by sigreturn, + we want to restore its intr_port too; so store it in + SS->intr_port now, so it will end up in SCP->sc_intr_port + later. */ + ss->intr_port = ss->context->sc_intr_port; + } + /* If the sigreturn context was bogus, just ignore it. */ + ss->context = NULL; + } + else if (! machine_get_basic_state (ss->thread, state)) + return NULL; + + if ((ss->actions[signo].sa_flags & SA_ONSTACK) && + !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK))) + { + sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size; + ss->sigaltstack.ss_flags |= SA_ONSTACK; + /* XXX need to set up base of new stack for + per-thread variables, cthreads. */ + } + else + sigsp = (char *) state->basic.SP; + + /* Set up the sigcontext structure on the stack. This is all the stack + needs, since the args are passed in registers (below). */ + sigsp -= sizeof (*scp); + scp = sigsp; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) scp && + _hurdsig_fault_sigcode < (long int) (scp + 1)); + /* We got a fault trying to write the stack frame. + We cannot set up the signal handler. + Returning NULL tells our caller, who will nuke us with a SIGILL. */ + return NULL; + } + else + { + /* Set up the sigcontext from the current state of the thread. */ + + scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0; + + /* struct sigcontext is laid out so that starting at sc_regs + mimics a struct alpha_thread_state. */ + memcpy (&scp->sc_alpha_thread_state, + &state->basic, sizeof (state->basic)); + + /* struct sigcontext is laid out so that starting at sc_badvaddr + mimics a struct mips_exc_state. */ + if (! machine_get_state (ss->thread, state, ALPHA_EXC_STATE, + &state->exc, &scp->sc_alpha_exc_state, + sizeof (state->exc))) + return NULL; + + if (state->exc.used_fpa && + /* struct sigcontext is laid out so that starting at sc_fpregs + mimics a struct alpha_float_state. This state + is only meaningful if the coprocessor was used. */ + ! machine_get_state (ss->thread, state, ALPHA_FLOAT_STATE, + &state->fpu, + &scp->sc_alpha_float_state, + sizeof (state->fpu))) + return NULL; + } + + /* Modify the thread state to call the trampoline code on the new stack. */ + if (rpc_wait) + { + /* The signalee thread was blocked in a mach_msg_trap system call, + still waiting for a reply. We will have it run the special + trampoline code which retries the message receive before running + the signal handler. + + To do this we change the OPTION argument in its registers to + enable only message reception, since the request message has + already been sent. */ + + /* The system call arguments are stored in consecutive registers + starting with a0 ($16). */ + struct mach_msg_trap_args *args = (void *) &state->basic.r16; + + assert (args->option & MACH_RCV_MSG); + /* Disable the message-send, since it has already completed. The + calls we retry need only wait to receive the reply message. */ + args->option &= ~MACH_SEND_MSG; + + state->basic.pc = (long int) &&rpc_wait_trampoline; + /* After doing the message receive, the trampoline code will need to + update the v0 ($0) value to be restored by sigreturn. To simplify + the assembly code, we pass the address of its slot in SCP to the + trampoline code in at ($28). */ + state->basic.r28 = (long int) &scp->sc_regs[0]; + /* We must preserve the mach_msg_trap args in a0..a5 and t0 + ($16..$21, $1). Pass the handler args to the trampoline code in + t8..t10 ($22.$24). */ + state->basic.r22 = signo; + state->basic.r23 = sigcode; + state->basic.r24 = (long int) scp; + } + else + { + state->basic.pc = (long int) &&trampoline; + state->basic.r16 = signo; + state->basic.r17 = sigcode; + state->basic.r18 = (long int) scp; + } + + state->basic.r30 = (long int) sigsp; /* $30 is the stack pointer. */ + + /* We pass the handler function to the trampoline code in ra ($26). */ + state->basic.r26 = (long int) handler; + /* In the callee-saved register t12/pv ($27), we store the + address of __sigreturn itself, for the trampoline code to use. */ + state->basic.r27 = (long int) &__sigreturn; + /* In the callee-saved register t11/ai ($25), we save the SCP value to pass + to __sigreturn after the handler returns. */ + state->basic.r25 = (long int) scp; + + return scp; + + /* The trampoline code follows. This is not actually executed as part of + this function, it is just convenient to write it that way. */ + + rpc_wait_trampoline: + /* This is the entry point when we have an RPC reply message to receive + before running the handler. The MACH_MSG_SEND bit has already been + cleared in the OPTION argument in our registers. For our convenience, + at ($28) points to the sc_regs[0] member of the sigcontext (saved v0 + ($0)). */ + asm volatile + (/* Retry the interrupted mach_msg system call. */ + "lda $0, -25($31)\n" /* mach_msg_trap */ + "call_pal %0\n" /* Magic system call instruction. */ + /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But + now the message receive has completed and the original caller of + the RPC (i.e. the code running when the signal arrived) needs to + see the final return value of the message receive in v0. So + store the new v0 value into the sc_regs[0] member of the sigcontext + (whose address is in at to make this code simpler). */ + "stq $0, 0($28)\n" + /* Since the argument registers needed to have the mach_msg_trap + arguments, we've stored the arguments to the handler function + in registers t8..t10 ($22..$24). */ + "mov $22, $16\n" + "mov $23, $17\n" + "mov $24, $18\n" + : : "i" (op_chmk)); + + trampoline: + /* Entry point for running the handler normally. The arguments to the + handler function are already in the standard registers: + + a0 SIGNO + a1 SIGCODE + a2 SCP + + t12 also contains SCP; this value is callee-saved (and so should not get + clobbered by running the handler). We use this saved value to pass to + __sigreturn, so the handler can clobber the argument registers if it + likes. */ + /* Call the handler function, saving return address in ra ($26). */ + asm volatile ("jsr $26, ($26)"); + /* Reset gp ($29) from the return address (here) in ra ($26). */ + asm volatile ("ldgp $29, 0($26)"); + asm volatile ("mov $25, $16"); /* Move saved SCP to argument register. */ + /* Call __sigreturn (SCP); this cannot return. */ + asm volatile ("jmp $31, ($27)"); + + /* NOTREACHED */ + return NULL; +} + +/* STATE describes a thread that had intr_port set (meaning it was inside + HURD_EINTR_RPC), after it has been thread_abort'd. If it looks to have + just completed a mach_msg_trap system call that returned + MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right + being waited on. */ +int +_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, + mach_port_t *port) +{ + if (state->basic.r0 == MACH_RCV_INTERRUPTED) + { + const unsigned int *pc = (void *) state->basic.pc; + struct mach_msg_trap_args *args = (void *) &state->basic.r16; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode == (long int) (pc - 1) || + _hurdsig_fault_sigcode == (long int) &args->rcv_name); + /* We got a fault trying to read the PC or stack. */ + return 0; + } + else + { + if (pc[-1] == ((alpha_instruction) { pal_format: + { opcode: op_pal, + function: op_chmk } }).bits) + { + /* We did just return from a mach_msg_trap system call + doing a message receive that was interrupted. + Examine the parameters to find the receive right. */ + *port = args->rcv_name; + return 1; + } + } + } + + return 0; +} diff --git a/sysdeps/mach/hurd/bind.c b/sysdeps/mach/hurd/bind.c new file mode 100644 index 0000000000..e9e54ec8dc --- /dev/null +++ b/sysdeps/mach/hurd/bind.c @@ -0,0 +1,102 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <hurd/paths.h> +#include <fcntl.h> +#include <stddef.h> +#include <hurd/ifsock.h> +#include <sys/un.h> +#include <string.h> + +/* Give the socket FD the local address ADDR (which is LEN bytes long). */ +int +DEFUN(bind, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t len) +{ + addr_port_t aport; + error_t err; + + if (addr->sa_family == AF_LOCAL) + { + /* For the local domain, we must create a node in the filesystem + using the ifsock translator and then fetch the address from it. */ + struct sockaddr_un *unaddr = (struct sockaddr_un *) addr; + file_t dir, node; + char name[len - offsetof (struct sockaddr_un, sun_path)], *n; + strncpy (name, unaddr->sun_path, sizeof name); + dir = __file_name_split (name, &n); + if (dir == MACH_PORT_NULL) + return -1; + + /* Create a new, unlinked node in the target directory. */ + err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node); + + if (! err) + { + file_t ifsock; + /* Set the node's translator to make it a local-domain socket. */ + err = __file_set_translator (node, + FS_TRANS_EXCL | FS_TRANS_SET, + FS_TRANS_EXCL | FS_TRANS_SET, 0, + _HURD_IFSOCK, sizeof _HURD_IFSOCK, + MACH_PORT_NULL, + MACH_MSG_TYPE_COPY_SEND); + if (! err) + /* Get a port to the ifsock translator. */ + err = __hurd_invoke_translator (node, 0, &ifsock); + if (! err) + /* Get the address port. */ + err = __ifsock_getsockaddr (ifsock, &aport); + __mach_port_deallocate (__mach_task_self (), ifsock); + if (! err) + /* Link the node, now a socket, into the target directory. */ + err = __dir_link (node, dir, name); + __mach_port_deallocate (__mach_task_self (), node); + } + __mach_port_deallocate (__mach_task_self (), dir); + + if (err) + return __hurd_fail (err); + } + else + err = EIEIO; + + err = HURD_DPORT_USE (fd, + ({ + if (err) + err = __socket_create_address (port, + addr->sa_family, + (char *) addr, len, + &aport, 1); + if (! err) + { + err = __socket_bind (port, aport); + __mach_port_deallocate (__mach_task_self (), + aport); + } + err; + })); + + return err ? __hurd_dfail (fd, err) : 0; +} diff --git a/sysdeps/mach/hurd/brk.c b/sysdeps/mach/hurd/brk.c new file mode 100644 index 0000000000..a96286b2d9 --- /dev/null +++ b/sysdeps/mach/hurd/brk.c @@ -0,0 +1,130 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/resource.h> +#include <cthreads.h> /* For `struct mutex'. */ + + +/* Initial maximum size of the data segment (32MB, which is arbitrary). */ +#define DATA_SIZE (32 * 1024 * 1024) + + +/* Up to the page including this address is allocated from the kernel. + This address is the data resource limit. */ +vm_address_t _hurd_data_end; + +/* Up to this address is actually available to the user. + Pages beyond the one containing this address allow no access. */ +vm_address_t _hurd_brk; + +struct mutex _hurd_brk_lock; + +extern int __data_start, _end; + + +/* Set the end of the process's data space to INADDR. + Return 0 if successful, -1 if not. */ +int +DEFUN(__brk, (inaddr), PTR inaddr) +{ + int ret; + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_brk_lock); + ret = _hurd_set_brk ((vm_address_t) inaddr); + __mutex_unlock (&_hurd_brk_lock); + HURD_CRITICAL_END; + return ret; +} +weak_alias (__brk, brk) + + +int +_hurd_set_brk (vm_address_t addr) +{ + error_t err; + vm_address_t pagend = round_page (addr); + vm_address_t pagebrk = round_page (_hurd_brk); + long int rlimit; + + if (pagend <= pagebrk) + { + if (pagend < pagebrk) + /* Make that memory inaccessible. */ + __vm_protect (__mach_task_self (), pagend, pagebrk - pagend, + 0, VM_PROT_NONE); + _hurd_brk = addr; + return 0; + } + + __mutex_lock (&_hurd_rlimit_lock); + rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur; + __mutex_unlock (&_hurd_rlimit_lock); + + if (addr - (vm_address_t) &__data_start > rlimit) + { + /* Need to increase the resource limit. */ + errno = ENOMEM; + return -1; + } + + /* Make the memory accessible. */ + if (err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk, + 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) + { + errno = err; + return -1; + } + + _hurd_brk = addr; + return 0; +} + +static void +init_brk (void) +{ + vm_address_t pagend; + + __mutex_init (&_hurd_brk_lock); + + /* If _hurd_brk is already set, don't change it. The assumption is that + it was set in a previous run before something like Emacs's unexec was + called and dumped all the data up to the break at that point. */ + if (_hurd_brk == 0) + _hurd_brk = (vm_address_t) &_end; + + pagend = round_page (_hurd_brk); + + _hurd_data_end = (vm_address_t) &__data_start + DATA_SIZE; + + if (pagend < _hurd_data_end) + { + /* We use vm_map to allocate and change permissions atomically. */ + if (__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend, + 0, 0, MACH_PORT_NULL, 0, 0, + 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, + VM_INHERIT_COPY)) + /* Couldn't allocate the memory. The break will be very short. */ + _hurd_data_end = pagend; + } + + (void) &init_brk; /* Avoid ``defined but not used'' warning. */ +} +text_set_element (_hurd_preinit_hook, init_brk); diff --git a/sysdeps/mach/hurd/chdir.c b/sysdeps/mach/hurd/chdir.c new file mode 100644 index 0000000000..912ca08683 --- /dev/null +++ b/sysdeps/mach/hurd/chdir.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <fcntl.h> +#include <hurd/port.h> + +/* Change the current directory to FILE_NAME. */ +int +DEFUN(__chdir, (file_name), CONST char *file_name) +{ + file_t file, dir; + error_t err; + + file = __file_name_lookup (file_name, O_EXEC, 0); + if (file == MACH_PORT_NULL) + return -1; + err = __USEPORT (CRDIR, __hurd_file_name_lookup (port, file, "", + O_EXEC, 0, &dir)); + __mach_port_deallocate (__mach_task_self (), file); + if (err) + return __hurd_fail (err); + + _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], dir); + return 0; +} + +weak_alias (__chdir, chdir) diff --git a/sysdeps/mach/hurd/chflags.c b/sysdeps/mach/hurd/chflags.c new file mode 100644 index 0000000000..157940d19b --- /dev/null +++ b/sysdeps/mach/hurd/chflags.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> + +/* Change the flags of FILE to FLAGS. */ +int +DEFUN(chflags, (file, flags), CONST char *file AND int flags) +{ + error_t err; + file_t port = __file_name_lookup (file, 0, 0); + if (port == MACH_PORT_NULL) + return -1; + err = __file_chflags (port, flags); + __mach_port_deallocate (__mach_task_self (), port); + if (err) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/chmod.c b/sysdeps/mach/hurd/chmod.c new file mode 100644 index 0000000000..00a81ef0cf --- /dev/null +++ b/sysdeps/mach/hurd/chmod.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> + +/* Change the protections of FILE to MODE. */ +int +DEFUN(__chmod, (file, mode), CONST char *file AND mode_t mode) +{ + error_t err; + file_t port = __file_name_lookup (file, 0, 0); + if (port == MACH_PORT_NULL) + return -1; + err = __file_chmod (port, mode); + __mach_port_deallocate (__mach_task_self (), port); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__chmod, chmod) diff --git a/sysdeps/mach/hurd/chown.c b/sysdeps/mach/hurd/chown.c new file mode 100644 index 0000000000..a1ed9d5e14 --- /dev/null +++ b/sysdeps/mach/hurd/chown.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> + +/* Change the owner and group of FILE. */ +int +DEFUN(__chown, (file, owner, group), + CONST char *file AND uid_t owner AND gid_t group) +{ + error_t err; + file_t port = __file_name_lookup (file, 0, 0); + if (port == MACH_PORT_NULL) + return -1; + err = __file_chown (port, owner, group); + __mach_port_deallocate (__mach_task_self (), port); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__chown, chown) diff --git a/sysdeps/mach/hurd/chroot.c b/sysdeps/mach/hurd/chroot.c new file mode 100644 index 0000000000..415a068004 --- /dev/null +++ b/sysdeps/mach/hurd/chroot.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> +#include <fcntl.h> +#include <hurd/port.h> + +/* Change the current root to FILE_NAME. */ +int +DEFUN(chroot, (file_name), CONST char *file_name) +{ + file_t file, dir; + error_t err; + + file = __file_name_lookup (file_name, O_EXEC, 0); + if (file == MACH_PORT_NULL) + return -1; + err = __USEPORT (CRDIR, __hurd_file_name_lookup (port, file, "", + O_EXEC, 0, &dir)); + __mach_port_deallocate (__mach_task_self (), file); + if (err) + return __hurd_fail (err); + + _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir); + return 0; +} diff --git a/sysdeps/mach/hurd/close.c b/sysdeps/mach/hurd/close.c new file mode 100644 index 0000000000..259687e1fb --- /dev/null +++ b/sysdeps/mach/hurd/close.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Close the file descriptor FD. */ +int +DEFUN(__close, (fd), int fd) +{ + error_t err; + + err = HURD_FD_USE (fd, _hurd_fd_close (descriptor)); + + return err ? __hurd_fail (err) : 0; +} + +weak_alias (__close, close) diff --git a/sysdeps/mach/hurd/closedir.c b/sysdeps/mach/hurd/closedir.c new file mode 100644 index 0000000000..9d20621747 --- /dev/null +++ b/sysdeps/mach/hurd/closedir.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <dirent.h> +#include <unistd.h> +#include <hurd.h> + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +int +DEFUN(closedir, (dirp), DIR *dirp) +{ + error_t err; + + if (dirp == NULL) + { + errno = EINVAL; + return -1; + } + + if ((err = __vm_deallocate (__mach_task_self (), + (vm_address_t) dirp->__data, dirp->__allocation)) + || (err = __mach_port_deallocate (__mach_task_self (), dirp->__port))) + { + errno = err; + return -1; + } + + free (dirp); + + return 0; +} + diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure new file mode 100755 index 0000000000..a396cd0024 --- /dev/null +++ b/sysdeps/mach/hurd/configure @@ -0,0 +1,21 @@ + +# If configure is passed `--with-hurd=DIR', set `hurd-srcdir' to DIR in +# config.make. + +ac_help="$ac_help + --with-hurd=DIRECTORY find Hurd source code in DIRECTORY [../hurd]" +# Check whether --with-hurd or --without-hurd was given. +withval="$with_hurd" +if test -n "$withval"; then + case z"$with_hurd" in +z | zno | zyes) ;; # Not specified, or specified with no value. +z*) config_vars="$config_vars +hurd-srcdir = $with_hurd" ;; +esac + +fi + + +# Don't bother trying to generate any glue code to be compatible with the +# existing system library, because we are the only system library. +inhibit_glue=yes diff --git a/sysdeps/mach/hurd/configure.in b/sysdeps/mach/hurd/configure.in new file mode 100644 index 0000000000..39e1002d6e --- /dev/null +++ b/sysdeps/mach/hurd/configure.in @@ -0,0 +1,19 @@ +sinclude(./aclocal.m4)dnl Autoconf lossage. +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +# If configure is passed `--with-hurd=DIR', set `hurd-srcdir' to DIR in +# config.make. + +AC_ARG_WITH(hurd, dnl +[ --with-hurd=DIRECTORY find Hurd source code in DIRECTORY [../hurd]], + [dnl +case z"$with_hurd" in +z | zno | zyes) ;; # Not specified, or specified with no value. +z*) config_vars="$config_vars +hurd-srcdir = $with_hurd" ;; +esac +]) + +# Don't bother trying to generate any glue code to be compatible with the +# existing system library, because we are the only system library. +inhibit_glue=yes diff --git a/sysdeps/mach/hurd/connect.c b/sysdeps/mach/hurd/connect.c new file mode 100644 index 0000000000..e015a14c50 --- /dev/null +++ b/sysdeps/mach/hurd/connect.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <sys/socket.h> +#include <hurd/socket.h> +#include <sys/un.h> +#include <hurd/ifsock.h> + +/* Open a connection on socket FD to peer at ADDR (which LEN bytes long). + For connectionless socket types, just set the default address to send to + and the only address from which to accept transmissions. + Return 0 on success, -1 for errors. */ +int +DEFUN(connect, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t len) +{ + error_t err; + addr_port_t aport; + + if (addr->sa_family == AF_LOCAL) + { + /* For the local domain, we must look up the name as a file and talk + to it with the ifsock protocol. */ + struct sockaddr_un *unaddr = (struct sockaddr_un *) addr; + file_t file = __file_name_lookup (unaddr->sun_path, 0, 0); + if (file == MACH_PORT_NULL) + return -1; + err = __ifsock_getsockaddr (file, &aport); + __mach_port_deallocate (__mach_task_self (), file); + if (err == MIG_BAD_ID || err == EOPNOTSUPP) + /* The file did not grok the ifsock protocol. */ + err = ENOTSOCK; + if (err) + return __hurd_fail (err); + } + else + err = EIEIO; + + err = HURD_DPORT_USE (fd, + ({ + if (err) + err = __socket_create_address (port, + addr->sa_family, + (char *) addr, len, + &aport, 0); + if (! err) + { + err = __socket_connect (port, aport); + __mach_port_deallocate (__mach_task_self (), + aport); + } + err; + })); + + return err ? __hurd_dfail (fd, err) : 0; +} diff --git a/sysdeps/mach/hurd/defs.c b/sysdeps/mach/hurd/defs.c new file mode 100644 index 0000000000..b2cfe7c4ff --- /dev/null +++ b/sysdeps/mach/hurd/defs.c @@ -0,0 +1,85 @@ +/* Definitions of global stdio data structures. + +Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <hurd/fd.h> +#include <unistd.h> + +FILE *stdin, *stdout, *stderr; + +/* Pointer to the first stream in the list. */ +FILE *__stdio_head = NULL; + +static void +init_stdio (void) +{ + inline void init (FILE **streamptr, int fd) + { + /* We want to use the existing FILE object if one has been allocated. + (This will only be the case if our image came from something like + Emacs's unexec, where we were called in the first run.) */ + FILE *s = *streamptr ?: __newstream (); + struct hurd_fd *d = _hurd_fd_get (fd); + if (d == NULL) + { + /* There is no file descriptor allocated. We want the standard + streams to always refer to their standard file descriptors, even + if those descriptors are not set up until later. So allocate + the descriptor structure with no ports and store it in the + stream. Operations will fail until ports are installed in the + file descriptor. */ + if (d = _hurd_alloc_fd (NULL, fd)) + __spin_unlock (&d->port.lock); + } + if (s) + s->__cookie = d; + *streamptr = s; + } +#define S(NAME, FD, MODE) \ + init (&NAME, FD); if (NAME) NAME->__mode.__##MODE = 1; + + S (stdin, STDIN_FILENO, read); + S (stdout, STDOUT_FILENO, write); + S (stderr, STDERR_FILENO, write); + +#undef S + + if (stderr) + stderr->__userbuf = 1; /* stderr is always unbuffered. */ + + (void) &init_stdio; /* Avoid "defined but not used" warning. */ +} +text_set_element (_hurd_fd_subinit, init_stdio); + +/* This function MUST be in this file! + This is because we want _cleanup to go into the __libc_atexit set + when any stdio code is used (and to use any stdio code, one must reference + something defined in this file), and since only local symbols can be made + set elements, having the set element stab entry here and _cleanup elsewhere + loses; and having them both elsewhere loses because there is no reference + to cause _cleanup to be linked in. */ + +void +DEFUN_VOID(_cleanup) +{ + (void) fclose ((FILE *) NULL); +} +text_set_element (__libc_atexit, _cleanup); diff --git a/sysdeps/mach/hurd/dirstream.h b/sysdeps/mach/hurd/dirstream.h new file mode 100644 index 0000000000..0bcec36f0f --- /dev/null +++ b/sysdeps/mach/hurd/dirstream.h @@ -0,0 +1,40 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + +/* Directory stream type. + + The Hurd directory format is the same as `struct dirent', so `readdir' + returns a pointer into the buffer we read directory data into. */ + +typedef struct + { + /* XXX we need a namespace-clean name for mach_port_t! */ + unsigned int __port; /* Port to the directory. */ + char *__data; /* Directory block. */ + int __entry_data; /* Entry number `__data' corresponds to. */ + char *__ptr; /* Current pointer into the block. */ + int __entry_ptr; /* Entry number `__ptr' corresponds to. */ + unsigned long int __allocation; /* Space allocated for the block. */ + unsigned long int __size; /* Total valid data in the block. */ + } DIR; + +#endif /* dirstream.h */ diff --git a/sysdeps/mach/hurd/dup2.c b/sysdeps/mach/hurd/dup2.c new file mode 100644 index 0000000000..f4ec623b05 --- /dev/null +++ b/sysdeps/mach/hurd/dup2.c @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + + +/* Duplicate FD to FD2, closing the old FD2 and making FD2 be + open on the same file as FD is. Return FD2 or -1. */ +int +DEFUN(__dup2, (fd, fd2), int fd AND int fd2) +{ + struct hurd_fd *d; + + /* Extract the ports and flags from FD. */ + d = _hurd_fd_get (fd); + if (d == NULL) + { + errno = EBADF; + return -1; + } + + HURD_CRITICAL_BEGIN; + + __spin_lock (&d->port.lock); + if (d->port.port == MACH_PORT_NULL) + { + __spin_unlock (&d->port.lock); + errno = EBADF; + fd2 = -1; + } + else if (fd2 == fd) + /* FD is valid and FD2 is already the same; just return it. */ + __spin_unlock (&d->port.lock); + else + { + struct hurd_userlink ulink, ctty_ulink; + int flags = d->flags; + io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink); + io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */ + + __mutex_lock (&_hurd_dtable_lock); + if (fd2 < 0 || fd2 >= _hurd_dtablesize) + { + errno = EBADF; + fd2 = -1; + } + else + { + /* Get a hold of the destination descriptor. */ + struct hurd_fd *d2 = _hurd_dtable[fd2]; + if (d2 == NULL) + { + /* Must allocate a new one. We don't initialize the port cells + with this call so that if it fails (out of memory), we will + not have already added user references for the ports, which we + would then have to deallocate. */ + d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL, + MACH_PORT_NULL); + } + if (d2 == NULL) + { + fd2 = -1; + if (errno == EINVAL) + errno = EBADF; /* POSIX.1-1990 6.2.1.2 ll 54-55. */ + } + else + { + /* Give the ports each a user ref for the new descriptor. */ + __mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_SEND, 1); + if (ctty != MACH_PORT_NULL) + __mach_port_mod_refs (__mach_task_self (), ctty, + MACH_PORT_RIGHT_SEND, 1); + + /* Install the ports and flags in the new descriptor slot. */ + __spin_lock (&d2->port.lock); + d2->flags = flags & ~FD_CLOEXEC; /* Dup clears FD_CLOEXEC. */ + _hurd_port_set (&d2->ctty, ctty); + _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */ + } + } + __mutex_unlock (&_hurd_dtable_lock); + + _hurd_port_free (&d->port, &ulink, port); + if (ctty != MACH_PORT_NULL) + _hurd_port_free (&d->ctty, &ctty_ulink, port); + } + + HURD_CRITICAL_END; + + return fd2; +} + +weak_alias (__dup2, dup2) diff --git a/sysdeps/mach/hurd/err_hurd.sub b/sysdeps/mach/hurd/err_hurd.sub new file mode 100644 index 0000000000..b077d24786 --- /dev/null +++ b/sysdeps/mach/hurd/err_hurd.sub @@ -0,0 +1,11 @@ +/* This file defines the Mach error system for Hurd server errors. */ + +#include <stdio.h> +#include <errno.h> + +/* Omit `const' because we are included with `static' + defined to `static const'. */ +static struct error_subsystem err_hurd_sub[] = + { + { "(os/hurd)", _HURD_ERRNOS, (const char *const *) _sys_errlist }, + }; diff --git a/sysdeps/mach/hurd/errlist.awk b/sysdeps/mach/hurd/errlist.awk new file mode 100644 index 0000000000..a06ec88af7 --- /dev/null +++ b/sysdeps/mach/hurd/errlist.awk @@ -0,0 +1,77 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# errno.texinfo contains lines like: +# @comment errno.h +# @comment POSIX.1: Function not implemented +# @deftypevr Macro int ENOSYS +# @comment errno 78 + +BEGIN { + print "/* This file is generated from errno.texi by errlist.awk. */" + print ""; + print "#ifndef HAVE_GNU_LD" + print "#define _sys_nerr sys_nerr" + print "#define _sys_errlist sys_errlist" + print "#endif" + print "" + print "const char *_sys_errlist[] ="; + print " {"; + maxerrno = 0; + print " \"Success\"," + } +$1 == "@comment" && $2 == "errno.h" { errnoh=1; next } +errnoh == 1 && $1 == "@comment" \ + { + ++errnoh; + etext = $3; + for (i = 4; i <= NF; ++i) + etext = etext " " $i; + next; + } +errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" \ + { + e = $4; errnoh++; next; + } +errnoh == 3 && $1 == "@comment" && $2 == "errno" \ + { + errno = $3 + 0; + msgs[errno] = etext; + names[errno] = e; + if (errno > maxerrno) maxerrno = errno; + next; + } +{ errnoh=0 } +END { + for (i = 1; i <= maxerrno; ++i) + { + if (names[i] == "") + print " \"Reserved error " i "\","; + else + printf "%-40s/* %d = %s */\n", " \"" msgs[i] "\",", i, names[i]; + } + print " };"; + print ""; + print "#include <errno.h>"; + printf "#if _HURD_ERRNOS != %d\n", maxerrno+1; + print "#error errlist/errnos generation bug"; + print "#endif" + printf "const int _sys_nerr = %d;\n", maxerrno+1; + print "weak_alias (_sys_errlist, sys_errlist)" + print "weak_alias (_sys_nerr, sys_nerr)" + } diff --git a/sysdeps/mach/hurd/errlist.c b/sysdeps/mach/hurd/errlist.c new file mode 100644 index 0000000000..b72cd7379a --- /dev/null +++ b/sysdeps/mach/hurd/errlist.c @@ -0,0 +1,93 @@ +/* This file is generated from errno.texi by errlist.awk. */ + +#ifndef HAVE_GNU_LD +#define _sys_nerr sys_nerr +#define _sys_errlist sys_errlist +#endif + +const char *_sys_errlist[] = + { + "Success", + "Operation not permitted", /* 1 = EPERM */ + "No such file or directory", /* 2 = ENOENT */ + "No such process", /* 3 = ESRCH */ + "Interrupted system call", /* 4 = EINTR */ + "Input/output error", /* 5 = EIO */ + "Device not configured", /* 6 = ENXIO */ + "Argument list too long", /* 7 = E2BIG */ + "Exec format error", /* 8 = ENOEXEC */ + "Bad file descriptor", /* 9 = EBADF */ + "No child processes", /* 10 = ECHILD */ + "Resource deadlock avoided", /* 11 = EDEADLK */ + "Cannot allocate memory", /* 12 = ENOMEM */ + "Permission denied", /* 13 = EACCES */ + "Bad address", /* 14 = EFAULT */ + "Block device required", /* 15 = ENOTBLK */ + "Device busy", /* 16 = EBUSY */ + "File exists", /* 17 = EEXIST */ + "Invalid cross-device link", /* 18 = EXDEV */ + "Operation not supported by device",/* 19 = ENODEV */ + "Not a directory", /* 20 = ENOTDIR */ + "Is a directory", /* 21 = EISDIR */ + "Invalid argument", /* 22 = EINVAL */ + "Too many open files", /* 23 = EMFILE */ + "Too many open files in system", /* 24 = ENFILE */ + "Inappropriate ioctl for device", /* 25 = ENOTTY */ + "Text file busy", /* 26 = ETXTBSY */ + "File too large", /* 27 = EFBIG */ + "No space left on device", /* 28 = ENOSPC */ + "Illegal seek", /* 29 = ESPIPE */ + "Read-only file system", /* 30 = EROFS */ + "Too many links", /* 31 = EMLINK */ + "Broken pipe", /* 32 = EPIPE */ + "Numerical argument out of domain", /* 33 = EDOM */ + "Numerical result out of range", /* 34 = ERANGE */ + "Operation would block", /* 35 = EWOULDBLOCK */ + "Operation now in progress", /* 36 = EINPROGRESS */ + "Operation already in progress", /* 37 = EALREADY */ + "Socket operation on non-socket", /* 38 = ENOTSOCK */ + "Destination address required", /* 39 = EDESTADDRREQ */ + "Message too long", /* 40 = EMSGSIZE */ + "Protocol wrong type for socket", /* 41 = EPROTOTYPE */ + "Protocol not available", /* 42 = ENOPROTOOPT */ + "Protocol not supported", /* 43 = EPROTONOSUPPORT */ + "Socket type not supported", /* 44 = ESOCKTNOSUPPORT */ + "Operation not supported", /* 45 = EOPNOTSUPP */ + "Protocol family not supported", /* 46 = EPFNOSUPPORT */ + "Address family not supported by protocol family",/* 47 = EAFNOSUPPORT */ + "Address already in use", /* 48 = EADDRINUSE */ + "Can't assign requested address", /* 49 = EADDRNOTAVAIL */ + "Network is down", /* 50 = ENETDOWN */ + "Network is unreachable", /* 51 = ENETUNREACH */ + "Network dropped connection on reset",/* 52 = ENETRESET */ + "Software caused connection abort", /* 53 = ECONNABORTED */ + "Connection reset by peer", /* 54 = ECONNRESET */ + "No buffer space available", /* 55 = ENOBUFS */ + "Socket is already connected", /* 56 = EISCONN */ + "Socket is not connected", /* 57 = ENOTCONN */ + "Can't send after socket shutdown", /* 58 = ESHUTDOWN */ + "Connection timed out", /* 59 = ETIMEDOUT */ + "Connection refused", /* 60 = ECONNREFUSED */ + "Too many levels of symbolic links",/* 61 = ELOOP */ + "File name too long", /* 62 = ENAMETOOLONG */ + "Host is down", /* 63 = EHOSTDOWN */ + "No route to host", /* 64 = EHOSTUNREACH */ + "Directory not empty", /* 65 = ENOTEMPTY */ + "Too many users", /* 66 = EUSERS */ + "Disc quota exceeded", /* 67 = EDQUOT */ + "Stale NFS file handle", /* 68 = ESTALE */ + "Too many levels of remote in path",/* 69 = EREMOTE */ + "No locks available", /* 70 = ENOLCK */ + "Function not implemented", /* 71 = ENOSYS */ + "Inappropriate operation for background process",/* 72 = EBACKGROUND */ + "?", /* 73 = ED */ + "You really blew it this time", /* 74 = EGREGIOUS */ + "Computer bought the farm", /* 75 = EIEIO */ + "Gratuitous error", /* 76 = EGRATUITOUS */ + }; + +#include <errno.h> +#if _HURD_ERRNOS != 77 +#error errlist/errnos generation bug +#endif +const int _sys_nerr = 77; diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk new file mode 100644 index 0000000000..a6b251f211 --- /dev/null +++ b/sysdeps/mach/hurd/errnos.awk @@ -0,0 +1,157 @@ +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# errno.texinfo contains lines like: +# @comment errno.h +# @comment POSIX.1: Function not implemented +# @deftypevr Macro int ENOSYS + +BEGIN { + printf "/* This file generated by"; + for (i = 0; i < ARGC; ++i) + printf " %s", ARGV[i]; + printf ". */\n"; + print ""; + print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */"; + print "#ifndef _HURD_ERRNO"; + print "#define _HURD_ERRNO(n)\t((0x10 << 26) | ((n) & 0x3fff))"; + print "#endif"; + print ""; + print "#ifdef _ERRNO_H\n"; + print "enum __error_t_codes\n{"; + errnoh = 0; + maxerrno = 0; + in_mach_errors = 0; + in_math = 0; + edom = erange = ""; + print "#undef EDOM\n#undef ERANGE"; + } + +$1 == "@comment" && $2 == "errno.h" { errnoh=1; next } +$1 == "@comment" && errnoh == 1 \ + { + ++errnoh; + etext = ""; + for (i = 3; i <= NF; ++i) + etext = etext " " $i; + next; + } + +errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" \ + { ++errnoh; e = $4; next; } + +errnoh == 3 && $1 == "@comment" && $2 == "errno" { + errno = $3 + 0; + if (errno > maxerrno) maxerrno = errno; + if (e == "EWOULDBLOCK") + { + print "#define EWOULDBLOCK EAGAIN /* Operation would block */"; + next; + } + x = sprintf ("%-40s/*%s */", sprintf ("%-24s%s", "#define\t" e, + "_HURD_ERRNO (" errno ")"), + etext); + if (e == "EDOM") + edom = x; + else if (e == "ERANGE") + erange = x; + printf "\t%-16s= _HURD_ERRNO (%d),\n", e, errno; + print x; + next; + } +{ errnoh=0 } + +NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \ + { + in_mach_errors = 1; + print "\n\t/* Errors from <mach/message.h>. */"; + } +NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \ + { + in_mach_errors = 1; + print "\n\t/* Errors from <mach/kern_return.h>. */"; + next; + } + +in_mach_errors && $2 == "MACH_IPC_COMPAT" \ + { + in_mach_errors = 0; + } + +in_mach_errors == 1 && NF == 3 && $1 == "#define" \ + { + printf "\t%-32s= %s,\n", "E" $2, $3; + } + +$1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \ + { + in_mig_errors = 1; + print "\n\t/* Errors from <mach/mig_errors.h>. */"; + next; + } +in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \ + { + in_mig_errors = 0; + } + +(in_mig_errors && $1 == "#define" && $3 <= -300) || \ +(in_device_errors && $1 == "#define") \ + { + printf "%-32s", sprintf ("\t%-24s= %s,", "E" $2, $3); + for (i = 4; i <= NF; ++i) + printf " %s", $i; + printf "\n"; + } + +$1 == "#define" && $2 == "D_SUCCESS" \ + { + in_device_errors = 1; + print "\n\t/* Errors from <device/device_types.h>. */"; + next; + } +in_device_errors && $1 == "#endif" \ + { + in_device_errors = 0; + } + + +END \ + { + print ""; + print "};"; + print ""; + printf "#define\t_HURD_ERRNOS\t%d\n", maxerrno+1; + print ""; + print "\ +/* User-visible type of error codes. It is ok to use `int' or\n\ + `kern_return_t' for these, but with `error_t' the debugger prints\n\ + symbolic values. */"; + print "#ifdef __USE_GNU"; + print "typedef enum __error_t_codes error_t;" + print "#endif"; + print ""; + print "/* errno is a per-thread variable. */"; + print "#include <hurd/threadvar.h>"; + print "#define errno (*__hurd_errno_location ())"; + print ""; + print "#endif /* <errno.h> included. */"; + print ""; + print "#if !defined (_ERRNO_H) && defined (__need_Emath)"; + print edom; print erange; + print "#endif /* <errno.h> not included and need math error codes. */"; + } diff --git a/sysdeps/mach/hurd/errnos.h b/sysdeps/mach/hurd/errnos.h new file mode 100644 index 0000000000..911af3c5c8 --- /dev/null +++ b/sysdeps/mach/hurd/errnos.h @@ -0,0 +1,266 @@ +/* This file generated by gawk manual/errno.texi ../mach/mach/message.h ../mach/mach/kern_return.h ../mach/mach/mig_errors.h ../mach/device/device_types.h. */ + +/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */ +#ifndef _HURD_ERRNO +#define _HURD_ERRNO(n) ((0x10 << 26) | ((n) & 0x3fff)) +#endif + +#ifdef _ERRNO_H + +enum __error_t_codes +{ +#undef EDOM +#undef ERANGE + EPERM = _HURD_ERRNO (1), +#define EPERM _HURD_ERRNO (1) /* Operation not permitted */ + ENOENT = _HURD_ERRNO (2), +#define ENOENT _HURD_ERRNO (2) /* No such file or directory */ + ESRCH = _HURD_ERRNO (3), +#define ESRCH _HURD_ERRNO (3) /* No such process */ + EINTR = _HURD_ERRNO (4), +#define EINTR _HURD_ERRNO (4) /* Interrupted system call */ + EIO = _HURD_ERRNO (5), +#define EIO _HURD_ERRNO (5) /* Input/output error */ + ENXIO = _HURD_ERRNO (6), +#define ENXIO _HURD_ERRNO (6) /* Device not configured */ + E2BIG = _HURD_ERRNO (7), +#define E2BIG _HURD_ERRNO (7) /* Argument list too long */ + ENOEXEC = _HURD_ERRNO (8), +#define ENOEXEC _HURD_ERRNO (8) /* Exec format error */ + EBADF = _HURD_ERRNO (9), +#define EBADF _HURD_ERRNO (9) /* Bad file descriptor */ + ECHILD = _HURD_ERRNO (10), +#define ECHILD _HURD_ERRNO (10)/* No child processes */ + EDEADLK = _HURD_ERRNO (11), +#define EDEADLK _HURD_ERRNO (11)/* Resource deadlock avoided */ + ENOMEM = _HURD_ERRNO (12), +#define ENOMEM _HURD_ERRNO (12)/* Cannot allocate memory */ + EACCES = _HURD_ERRNO (13), +#define EACCES _HURD_ERRNO (13)/* Permission denied */ + EFAULT = _HURD_ERRNO (14), +#define EFAULT _HURD_ERRNO (14)/* Bad address */ + ENOTBLK = _HURD_ERRNO (15), +#define ENOTBLK _HURD_ERRNO (15)/* Block device required */ + EBUSY = _HURD_ERRNO (16), +#define EBUSY _HURD_ERRNO (16)/* Device busy */ + EEXIST = _HURD_ERRNO (17), +#define EEXIST _HURD_ERRNO (17)/* File exists */ + EXDEV = _HURD_ERRNO (18), +#define EXDEV _HURD_ERRNO (18)/* Invalid cross-device link */ + ENODEV = _HURD_ERRNO (19), +#define ENODEV _HURD_ERRNO (19)/* Operation not supported by device */ + ENOTDIR = _HURD_ERRNO (20), +#define ENOTDIR _HURD_ERRNO (20)/* Not a directory */ + EISDIR = _HURD_ERRNO (21), +#define EISDIR _HURD_ERRNO (21)/* Is a directory */ + EINVAL = _HURD_ERRNO (22), +#define EINVAL _HURD_ERRNO (22)/* Invalid argument */ + EMFILE = _HURD_ERRNO (23), +#define EMFILE _HURD_ERRNO (23)/* Too many open files */ + ENFILE = _HURD_ERRNO (24), +#define ENFILE _HURD_ERRNO (24)/* Too many open files in system */ + ENOTTY = _HURD_ERRNO (25), +#define ENOTTY _HURD_ERRNO (25)/* Inappropriate ioctl for device */ + ETXTBSY = _HURD_ERRNO (26), +#define ETXTBSY _HURD_ERRNO (26)/* Text file busy */ + EFBIG = _HURD_ERRNO (27), +#define EFBIG _HURD_ERRNO (27)/* File too large */ + ENOSPC = _HURD_ERRNO (28), +#define ENOSPC _HURD_ERRNO (28)/* No space left on device */ + ESPIPE = _HURD_ERRNO (29), +#define ESPIPE _HURD_ERRNO (29)/* Illegal seek */ + EROFS = _HURD_ERRNO (30), +#define EROFS _HURD_ERRNO (30)/* Read-only file system */ + EMLINK = _HURD_ERRNO (31), +#define EMLINK _HURD_ERRNO (31)/* Too many links */ + EPIPE = _HURD_ERRNO (32), +#define EPIPE _HURD_ERRNO (32)/* Broken pipe */ + EDOM = _HURD_ERRNO (33), +#define EDOM _HURD_ERRNO (33)/* Numerical argument out of domain */ + ERANGE = _HURD_ERRNO (34), +#define ERANGE _HURD_ERRNO (34)/* Numerical result out of range */ + EAGAIN = _HURD_ERRNO (35), +#define EAGAIN _HURD_ERRNO (35)/* Resource temporarily unavailable */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ + EINPROGRESS = _HURD_ERRNO (36), +#define EINPROGRESS _HURD_ERRNO (36)/* Operation now in progress */ + EALREADY = _HURD_ERRNO (37), +#define EALREADY _HURD_ERRNO (37)/* Operation already in progress */ + ENOTSOCK = _HURD_ERRNO (38), +#define ENOTSOCK _HURD_ERRNO (38)/* Socket operation on non-socket */ + EDESTADDRREQ = _HURD_ERRNO (39), +#define EDESTADDRREQ _HURD_ERRNO (39)/* Destination address required */ + EMSGSIZE = _HURD_ERRNO (40), +#define EMSGSIZE _HURD_ERRNO (40)/* Message too long */ + EPROTOTYPE = _HURD_ERRNO (41), +#define EPROTOTYPE _HURD_ERRNO (41)/* Protocol wrong type for socket */ + ENOPROTOOPT = _HURD_ERRNO (42), +#define ENOPROTOOPT _HURD_ERRNO (42)/* Protocol not available */ + EPROTONOSUPPORT = _HURD_ERRNO (43), +#define EPROTONOSUPPORT _HURD_ERRNO (43)/* Protocol not supported */ + ESOCKTNOSUPPORT = _HURD_ERRNO (44), +#define ESOCKTNOSUPPORT _HURD_ERRNO (44)/* Socket type not supported */ + EOPNOTSUPP = _HURD_ERRNO (45), +#define EOPNOTSUPP _HURD_ERRNO (45)/* Operation not supported */ + EPFNOSUPPORT = _HURD_ERRNO (46), +#define EPFNOSUPPORT _HURD_ERRNO (46)/* Protocol family not supported */ + EAFNOSUPPORT = _HURD_ERRNO (47), +#define EAFNOSUPPORT _HURD_ERRNO (47)/* Address family not supported by protocol family */ + EADDRINUSE = _HURD_ERRNO (48), +#define EADDRINUSE _HURD_ERRNO (48)/* Address already in use */ + EADDRNOTAVAIL = _HURD_ERRNO (49), +#define EADDRNOTAVAIL _HURD_ERRNO (49)/* Can't assign requested address */ + ENETDOWN = _HURD_ERRNO (50), +#define ENETDOWN _HURD_ERRNO (50)/* Network is down */ + ENETUNREACH = _HURD_ERRNO (51), +#define ENETUNREACH _HURD_ERRNO (51)/* Network is unreachable */ + ENETRESET = _HURD_ERRNO (52), +#define ENETRESET _HURD_ERRNO (52)/* Network dropped connection on reset */ + ECONNABORTED = _HURD_ERRNO (53), +#define ECONNABORTED _HURD_ERRNO (53)/* Software caused connection abort */ + ECONNRESET = _HURD_ERRNO (54), +#define ECONNRESET _HURD_ERRNO (54)/* Connection reset by peer */ + ENOBUFS = _HURD_ERRNO (55), +#define ENOBUFS _HURD_ERRNO (55)/* No buffer space available */ + EISCONN = _HURD_ERRNO (56), +#define EISCONN _HURD_ERRNO (56)/* Socket is already connected */ + ENOTCONN = _HURD_ERRNO (57), +#define ENOTCONN _HURD_ERRNO (57)/* Socket is not connected */ + ESHUTDOWN = _HURD_ERRNO (58), +#define ESHUTDOWN _HURD_ERRNO (58)/* Can't send after socket shutdown */ + ETIMEDOUT = _HURD_ERRNO (59), +#define ETIMEDOUT _HURD_ERRNO (59)/* Connection timed out */ + ECONNREFUSED = _HURD_ERRNO (60), +#define ECONNREFUSED _HURD_ERRNO (60)/* Connection refused */ + ELOOP = _HURD_ERRNO (61), +#define ELOOP _HURD_ERRNO (61)/* Too many levels of symbolic links */ + ENAMETOOLONG = _HURD_ERRNO (62), +#define ENAMETOOLONG _HURD_ERRNO (62)/* File name too long */ + EHOSTDOWN = _HURD_ERRNO (63), +#define EHOSTDOWN _HURD_ERRNO (63)/* Host is down */ + EHOSTUNREACH = _HURD_ERRNO (64), +#define EHOSTUNREACH _HURD_ERRNO (64)/* No route to host */ + ENOTEMPTY = _HURD_ERRNO (65), +#define ENOTEMPTY _HURD_ERRNO (65)/* Directory not empty */ + EUSERS = _HURD_ERRNO (66), +#define EUSERS _HURD_ERRNO (66)/* Too many users */ + EDQUOT = _HURD_ERRNO (67), +#define EDQUOT _HURD_ERRNO (67)/* Disc quota exceeded */ + ESTALE = _HURD_ERRNO (68), +#define ESTALE _HURD_ERRNO (68)/* Stale NFS file handle */ + EREMOTE = _HURD_ERRNO (69), +#define EREMOTE _HURD_ERRNO (69)/* Too many levels of remote in path */ + ENOLCK = _HURD_ERRNO (70), +#define ENOLCK _HURD_ERRNO (70)/* No locks available */ + ENOSYS = _HURD_ERRNO (71), +#define ENOSYS _HURD_ERRNO (71)/* Function not implemented */ + EBACKGROUND = _HURD_ERRNO (72), +#define EBACKGROUND _HURD_ERRNO (72)/* Inappropriate operation for background process */ + ED = _HURD_ERRNO (73), +#define ED _HURD_ERRNO (73)/* ? */ + EGREGIOUS = _HURD_ERRNO (74), +#define EGREGIOUS _HURD_ERRNO (74)/* You really blew it this time */ + EIEIO = _HURD_ERRNO (75), +#define EIEIO _HURD_ERRNO (75)/* Computer bought the farm */ + EGRATUITOUS = _HURD_ERRNO (76), +#define EGRATUITOUS _HURD_ERRNO (76)/* Gratuitous error */ + + /* Errors from <mach/message.h>. */ + EMACH_SEND_IN_PROGRESS = 0x10000001, + EMACH_SEND_INVALID_DATA = 0x10000002, + EMACH_SEND_INVALID_DEST = 0x10000003, + EMACH_SEND_TIMED_OUT = 0x10000004, + EMACH_SEND_WILL_NOTIFY = 0x10000005, + EMACH_SEND_NOTIFY_IN_PROGRESS = 0x10000006, + EMACH_SEND_INTERRUPTED = 0x10000007, + EMACH_SEND_MSG_TOO_SMALL = 0x10000008, + EMACH_SEND_INVALID_REPLY = 0x10000009, + EMACH_SEND_INVALID_RIGHT = 0x1000000a, + EMACH_SEND_INVALID_NOTIFY = 0x1000000b, + EMACH_SEND_INVALID_MEMORY = 0x1000000c, + EMACH_SEND_NO_BUFFER = 0x1000000d, + EMACH_SEND_NO_NOTIFY = 0x1000000e, + EMACH_SEND_INVALID_TYPE = 0x1000000f, + EMACH_SEND_INVALID_HEADER = 0x10000010, + EMACH_RCV_IN_PROGRESS = 0x10004001, + EMACH_RCV_INVALID_NAME = 0x10004002, + EMACH_RCV_TIMED_OUT = 0x10004003, + EMACH_RCV_TOO_LARGE = 0x10004004, + EMACH_RCV_INTERRUPTED = 0x10004005, + EMACH_RCV_PORT_CHANGED = 0x10004006, + EMACH_RCV_INVALID_NOTIFY = 0x10004007, + EMACH_RCV_INVALID_DATA = 0x10004008, + EMACH_RCV_PORT_DIED = 0x10004009, + EMACH_RCV_IN_SET = 0x1000400a, + EMACH_RCV_HEADER_ERROR = 0x1000400b, + EMACH_RCV_BODY_ERROR = 0x1000400c, + + /* Errors from <mach/kern_return.h>. */ + EKERN_INVALID_ADDRESS = 1, + EKERN_PROTECTION_FAILURE = 2, + EKERN_NO_SPACE = 3, + EKERN_INVALID_ARGUMENT = 4, + EKERN_FAILURE = 5, + EKERN_RESOURCE_SHORTAGE = 6, + EKERN_NOT_RECEIVER = 7, + EKERN_NO_ACCESS = 8, + EKERN_MEMORY_FAILURE = 9, + EKERN_MEMORY_ERROR = 10, + EKERN_NOT_IN_SET = 12, + EKERN_NAME_EXISTS = 13, + EKERN_ABORTED = 14, + EKERN_INVALID_NAME = 15, + EKERN_INVALID_TASK = 16, + EKERN_INVALID_RIGHT = 17, + EKERN_INVALID_VALUE = 18, + EKERN_UREFS_OVERFLOW = 19, + EKERN_INVALID_CAPABILITY = 20, + EKERN_RIGHT_EXISTS = 21, + EKERN_INVALID_HOST = 22, + EKERN_MEMORY_PRESENT = 23, + + /* Errors from <mach/mig_errors.h>. */ + EMIG_TYPE_ERROR = -300, /* client type check failure */ + EMIG_REPLY_MISMATCH = -301, /* wrong reply message ID */ + EMIG_REMOTE_ERROR = -302, /* server detected error */ + EMIG_BAD_ID = -303, /* bad request message ID */ + EMIG_BAD_ARGUMENTS = -304, /* server type check failure */ + EMIG_NO_REPLY = -305, /* no reply should be sent */ + EMIG_EXCEPTION = -306, /* server raised exception */ + EMIG_ARRAY_TOO_LARGE = -307, /* array not large enough */ + EMIG_SERVER_DIED = -308, /* server died */ + EMIG_DESTROY_REQUEST = -309, /* destroy request with no reply */ + + /* Errors from <device/device_types.h>. */ + ED_IO_ERROR = 2500, /* hardware IO error */ + ED_WOULD_BLOCK = 2501, /* would block, but D_NOWAIT set */ + ED_NO_SUCH_DEVICE = 2502, /* no such device */ + ED_ALREADY_OPEN = 2503, /* exclusive-use device already open */ + ED_DEVICE_DOWN = 2504, /* device has been shut down */ + ED_INVALID_OPERATION = 2505, /* bad operation for device */ + ED_INVALID_RECNUM = 2506, /* invalid record (block) number */ + ED_INVALID_SIZE = 2507, /* invalid IO size */ + ED_NO_MEMORY = 2508, /* memory allocation failure */ + ED_READ_ONLY = 2509, /* device cannot be written to */ + +}; + +#define _HURD_ERRNOS 77 + +/* User-visible type of error codes. It is ok to use `int' or + `kern_return_t' for these, but with `error_t' the debugger prints + symbolic values. */ +#ifdef __USE_GNU +typedef enum __error_t_codes error_t; +#endif + +/* errno is a per-thread variable. */ +#include <hurd/threadvar.h> +#define errno (*__hurd_errno_location ()) + +#endif /* <errno.h> included. */ + +#if !defined (_ERRNO_H) && defined (__need_Emath) +#define EDOM _HURD_ERRNO (33)/* Numerical argument out of domain */ +#define ERANGE _HURD_ERRNO (34)/* Numerical result out of range */ +#endif /* <errno.h> not included and need math error codes. */ diff --git a/sysdeps/mach/hurd/execve.c b/sysdeps/mach/hurd/execve.c new file mode 100644 index 0000000000..5a45f5f42e --- /dev/null +++ b/sysdeps/mach/hurd/execve.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <fcntl.h> + +/* Replace the current process, executing FILE_NAME with arguments ARGV and + environment ENVP. ARGV and ENVP are terminated by NULL pointers. */ +int +DEFUN(__execve, (file_name, argv, envp), + CONST char *file_name AND char *CONST argv[] AND char *CONST envp[]) +{ + error_t err; + file_t file = __file_name_lookup (file_name, O_EXEC, 0); + + if (file == MACH_PORT_NULL) + return -1; + + /* Hopefully this will not return. */ + err = _hurd_exec (__mach_task_self (), file, argv, envp); + + /* Oh well. Might as well be tidy. */ + __mach_port_deallocate (__mach_task_self (), file); + + return __hurd_fail (err); +} + +weak_alias (__execve, execve) diff --git a/sysdeps/mach/hurd/fchdir.c b/sysdeps/mach/hurd/fchdir.c new file mode 100644 index 0000000000..088bba9d16 --- /dev/null +++ b/sysdeps/mach/hurd/fchdir.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> +#include <hurd/fd.h> + +/* Change the current directory to FD. */ +int +DEFUN(fchdir, (fd), int fd) +{ + error_t err; + file_t cwdir; + + err = __USEPORT (CRDIR, + ({ file_t crdir = port; + HURD_DPORT_USE (fd, + __hurd_file_name_lookup (crdir, port, "", + 0, 0, &cwdir)); + })); + + if (err) + return __hurd_fail (err); + + _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], cwdir); + return 0; +} diff --git a/sysdeps/mach/hurd/fchflags.c b/sysdeps/mach/hurd/fchflags.c new file mode 100644 index 0000000000..aa1e32696d --- /dev/null +++ b/sysdeps/mach/hurd/fchflags.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Change the flags of the file FD refers to to FLAGS. */ +int +DEFUN(fchflags, (fd, flags), int fd AND int flags) +{ + error_t err; + + if (err = HURD_DPORT_USE (fd, __file_chflags (port, flags))) + return __hurd_dfail (fd, err); + + return 0; +} diff --git a/sysdeps/mach/hurd/fchmod.c b/sysdeps/mach/hurd/fchmod.c new file mode 100644 index 0000000000..3dc84ff11a --- /dev/null +++ b/sysdeps/mach/hurd/fchmod.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Change the protections of the file FD refers to to MODE. */ +int +DEFUN(__fchmod, (fd, mode), int fd AND mode_t mode) +{ + error_t err; + + if (err = HURD_DPORT_USE (fd, __file_chmod (port, mode))) + return __hurd_dfail (fd, err); + + return 0; +} + +weak_alias (__fchmod, fchmod) diff --git a/sysdeps/mach/hurd/fchown.c b/sysdeps/mach/hurd/fchown.c new file mode 100644 index 0000000000..c2f873c78d --- /dev/null +++ b/sysdeps/mach/hurd/fchown.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Change the owner and group of the file referred to by FD. */ +int +DEFUN(__fchown, (fd, owner, group), + int fd AND uid_t owner AND gid_t group) +{ + error_t err; + + if (err = HURD_DPORT_USE (fd, __file_chown (port, owner, group))) + return __hurd_dfail (fd, err); + + return 0; +} + +weak_alias (__fchown, fchown) diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c new file mode 100644 index 0000000000..4b7207f7ee --- /dev/null +++ b/sysdeps/mach/hurd/fcntl.c @@ -0,0 +1,159 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <stdarg.h> + + +/* Perform file control operations on FD. */ +int +DEFUN(__fcntl, (fd, cmd), int fd AND int cmd DOTS) +{ + va_list ap; + struct hurd_fd *d; + int result; + + d = _hurd_fd_get (fd); + + if (d == NULL) + return __hurd_fail (EBADF); + + va_start (ap, cmd); + + switch (cmd) + { + error_t err; + + default: /* Bad command. */ + errno = EINVAL; + result = -1; + break; + + /* First the descriptor-based commands, which do no RPCs. */ + + case F_DUPFD: /* Duplicate the file descriptor. */ + { + struct hurd_fd *new; + io_t port, ctty; + struct hurd_userlink ulink, ctty_ulink; + int flags; + + HURD_CRITICAL_BEGIN; + + /* Extract the ports and flags from the file descriptor. */ + __spin_lock (&d->port.lock); + flags = d->flags; + ctty = _hurd_port_get (&d->ctty, &ctty_ulink); + port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D. */ + + /* Get a new file descriptor. The third argument to __fcntl is the + minimum file descriptor number for it. */ + new = _hurd_alloc_fd (&result, va_arg (ap, int)); + if (new == NULL) + /* _hurd_alloc_fd has set errno. */ + result = -1; + else + { + /* Give the ports each a user ref for the new descriptor. */ + __mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_SEND, 1); + if (ctty != MACH_PORT_NULL) + __mach_port_mod_refs (__mach_task_self (), ctty, + MACH_PORT_RIGHT_SEND, 1); + + /* Install the ports and flags in the new descriptor. */ + if (ctty != MACH_PORT_NULL) + _hurd_port_set (&new->ctty, ctty); + /* Duplication clears the FD_CLOEXEC flag. */ + new->flags = flags & ~FD_CLOEXEC; + _hurd_port_locked_set (&new->port, port); /* Unlocks NEW. */ + } + + HURD_CRITICAL_END; + + _hurd_port_free (&d->port, &ulink, port); + if (ctty != MACH_PORT_NULL) + _hurd_port_free (&d->ctty, &ctty_ulink, port); + + break; + } + + /* Set RESULT by evaluating EXPR with the descriptor locked. + Check for an empty descriptor and return EBADF. */ +#define LOCKED(expr) \ + HURD_CRITICAL_BEGIN; \ + __spin_lock (&d->port.lock); \ + if (d->port.port == MACH_PORT_NULL) \ + result = __hurd_fail (EBADF); \ + else \ + result = (expr); \ + __spin_unlock (&d->port.lock); \ + HURD_CRITICAL_END; + + case F_GETFD: /* Get descriptor flags. */ + LOCKED (d->flags); + break; + + case F_SETFD: /* Set descriptor flags. */ + LOCKED ((d->flags = va_arg (ap, int), 0)); + break; + + + /* Now the real io operations, done by RPCs to io servers. */ + + case F_GETLK: + case F_SETLK: + case F_SETLKW: + { + struct flock *fl = va_arg (ap, struct flock *); + errno = fl?ENOSYS:EINVAL; /* XXX mib needs to implement io rpcs. */ + result = -1; + break; + } + + case F_GETFL: /* Get per-open flags. */ + if (err = HURD_FD_PORT_USE (d, __io_get_openmodes (port, &result))) + result = __hurd_dfail (fd, err); + break; + + case F_SETFL: /* Set per-open flags. */ + err = HURD_FD_PORT_USE (d, __io_set_all_openmodes (port, + va_arg (ap, int))); + result = err ? __hurd_dfail (fd, err) : 0; + + case F_GETOWN: /* Get owner. */ + if (err = HURD_FD_PORT_USE (d, __io_get_owner (port, &result))) + result = __hurd_dfail (fd, err); + break; + + case F_SETOWN: /* Set owner. */ + err = HURD_FD_PORT_USE (d, __io_mod_owner (port, va_arg (ap, pid_t))); + result = err ? __hurd_dfail (fd, err) : 0; + break; + } + + va_end (ap); + + return result; +} + +weak_alias (__fcntl, fcntl) diff --git a/sysdeps/mach/hurd/fcntlbits.h b/sysdeps/mach/hurd/fcntlbits.h new file mode 100644 index 0000000000..8a5e4cd52a --- /dev/null +++ b/sysdeps/mach/hurd/fcntlbits.h @@ -0,0 +1,178 @@ +/* O_*, F_*, FD_* bit values for GNU. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes. These are understood by io servers; they can be + passed in `dir_lookup', and are returned by `io_get_openmodes'. + Consequently they can be passed to `open', `hurd_file_name_lookup', and + `file_name_lookup'; and are returned by `fcntl' with the F_GETFL + command. */ + +/* In GNU, read and write are bits (unlike BSD). */ +#ifdef __USE_GNU +#define O_READ O_RDONLY /* Open for reading. */ +#define O_WRITE O_WRONLY /* Open for writing. */ +#define O_EXEC 0x0004 /* Open for execution. */ +#endif +/* POSIX.1 standard names. */ +#define O_RDONLY 0x0001 /* Open read-only. */ +#define O_WRONLY 0x0002 /* Open write-only. */ +#define O_RDWR (O_RDONLY|O_WRONLY) /* Open for reading and writing. */ +#define O_ACCMODE O_RDWR /* Mask for file access modes. */ + + + +/* File name translation flags. These are understood by io servers; + they can be passed in `dir_lookup', and consequently to `open', + `hurd_file_name_lookup', and `file_name_lookup'. */ + +#define O_CREAT 0x0010 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0020 /* Fail if file already exists. */ +#ifdef __USE_GNU +#define O_NOLINK 0x0040 /* No name mappings on final component. */ +#define O_NOTRANS 0x0080 /* No translator on final component. */ +#endif + + +/* I/O operating modes. These are understood by io servers; they can be + passed in `dir_lookup' and set or fetched with `io_*_openmodes'. + Consequently they can be passed to `open', `hurd_file_name_lookup', + `file_name_lookup', and `fcntl' with the F_SETFL command; and are + returned by `fcntl' with the F_GETFL command. */ + +#define O_APPEND 0x0100 /* Writes always append to the file. */ +#ifdef __USE_BSD +#define O_ASYNC 0x0200 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x0400 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#endif +#ifdef __USE_GNU +#define O_NOATIME 0x0800 /* Don't set access time on read (owner). */ +#endif + + +/* The name O_NONBLOCK is unfortunately overloaded; it is both a file name + translation flag and an I/O operating mode. O_NDELAY is the deprecated + BSD name for the same flag, overloaded in the same way. + + When used in `dir_lookup' (and consequently `open', `hurd_file_name_lookup', + or `file_name_lookup'), O_NONBLOCK says the open should return immediately + instead of blocking for any significant length of time (e.g., to wait + for carrier detect on a serial line). It is also saved as an I/O + operating mode, and after open has the following meaning. + + When used in `io_*_openmodes' (and consequently `fcntl' with the F_SETFL + command), the O_NONBLOCK flag means to do nonblocking i/o: any i/o + operation that would block for any significant length of time will instead + fail with EAGAIN. */ + +#define O_NONBLOCK 0x0008 /* Non-blocking open or non-blocking I/O. */ +#ifdef __USE_BSD +#define O_NDELAY O_NONBLOCK /* Deprecated. */ +#endif + + +#ifdef __USE_GNU +/* Mask of bits which are understood by io servers. */ +#define O_HURD 0xffff /* XXX name? want this? */ +#endif + + +/* Open-time action flags. These are understood by `hurd_file_name_lookup' + and consequently by `open' and `file_name_lookup'. They are not preserved + once the file has been opened. */ + +#define O_TRUNC 0x00010000 /* Truncate file to zero length. */ +#ifdef __USE_MISC +#define O_SHLOCK 0x00020000 /* Open with shared file lock. */ +#define O_EXLOCK 0x00040000 /* Open with exclusive file lock. */ +#endif + + +/* Controlling terminal flags. These are understood only by `open', + and are not preserved once the file has been opened. */ + +#ifdef __USE_GNU +#define O_IGNORE_CTTY 0x00080000 /* Don't do any ctty magic at all. */ +#endif +/* `open' never assigns a controlling terminal in GNU. */ +#define O_NOCTTY 0 /* Don't assign a controlling terminal. */ + + +#ifdef __USE_BSD +/* Bits in the file status flags returned by F_GETFL. */ +#define FREAD O_RDONLY +#define FWRITE O_WRONLY + +/* Traditional BSD names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNDELAY O_NDELAY +#endif + + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/mach/hurd/fdopen.c b/sysdeps/mach/hurd/fdopen.c new file mode 100644 index 0000000000..3fdd742a59 --- /dev/null +++ b/sysdeps/mach/hurd/fdopen.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <hurd/fd.h> +#include <fcntl.h> +#include <hurd/io.h> + +/* Defined in fopen.c. */ +extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr)); + +/* Open a new stream on a given system file descriptor. */ +FILE * +DEFUN(fdopen, (fd, mode), int fd AND CONST char *mode) +{ + FILE *stream; + __io_mode m; + struct hurd_fd *d; + error_t err; + int openmodes; + + if (!__getmode (mode, &m)) + return NULL; + + HURD_CRITICAL_BEGIN; + d = _hurd_fd_get (fd); + if (d == NULL) + err = EBADF; + else + err = HURD_FD_PORT_USE (d, __io_get_openmodes (port, &openmodes)); + HURD_CRITICAL_END; + + if (err) + return __hurd_dfail (fd, err), NULL; + + /* Check the access mode. */ + if ((m.__read && !(openmodes & O_READ)) || + (m.__write && !(openmodes & O_WRITE))) + { + errno = EBADF; + return NULL; + } + + stream = __newstream (); + if (stream == NULL) + return NULL; + + stream->__cookie = d; + stream->__mode = m; + + return stream; +} diff --git a/sysdeps/mach/hurd/fexecve.c b/sysdeps/mach/hurd/fexecve.c new file mode 100644 index 0000000000..e4f2cda1a2 --- /dev/null +++ b/sysdeps/mach/hurd/fexecve.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <errno.h> + +/* Execute the file FD refers to, overlaying the running program image. */ + +int +fexecve (int fd, char *const argv[], char *const envp[]) +{ + error_t err = HURD_DPORT_USE (fd, _hurd_exec (__mach_task_self (), port, + argv, envp)); + if (! err) + err = EGRATUITOUS; + return __hurd_fail (err); +} diff --git a/sysdeps/mach/hurd/flock.c b/sysdeps/mach/hurd/flock.c new file mode 100644 index 0000000000..6154fd2292 --- /dev/null +++ b/sysdeps/mach/hurd/flock.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/file.h> +#include <hurd/fd.h> +#include <hurd/fs.h> + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +int +DEFUN(__flock, (fd, operation), + int fd AND int operation) +{ + error_t err; + + if (err = HURD_DPORT_USE (fd, __file_lock (port, operation))) + return __hurd_dfail (fd, err); + + return 0; +} + +weak_alias (__flock, flock) diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c new file mode 100644 index 0000000000..b9170f155e --- /dev/null +++ b/sysdeps/mach/hurd/fork.c @@ -0,0 +1,574 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <setjmp.h> +#include "thread_state.h" +#include <sysdep.h> /* For stack growth direction. */ +#include "set-hooks.h" +#include <assert.h> +#include "hurdmalloc.h" /* XXX */ + +extern void _hurd_longjmp_thread_state (struct machine_thread_state *, + jmp_buf env, int value); + + +/* Things that want to be locked while forking. */ +struct + { + size_t n; + struct mutex *locks[0]; + } _hurd_fork_locks; + + +/* Things that want to be called before we fork, to prepare the parent for + task_create, when the new child task will inherit our address space. */ +DEFINE_HOOK (_hurd_fork_prepare_hook, (void)); + +/* Things that want to be called when we are forking, with the above all + locked. They are passed the task port of the child. The child process + is all set up except for doing proc_child, and has no threads yet. */ +DEFINE_HOOK (_hurd_fork_setup_hook, (void)); + +/* Things to be run in the child fork. */ +DEFINE_HOOK (_hurd_fork_child_hook, (void)); + +/* Things to be run in the parent fork. */ +DEFINE_HOOK (_hurd_fork_parent_hook, (void)); + + +/* Clone the calling process, creating an exact copy. + Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +pid_t +__fork (void) +{ + jmp_buf env; + pid_t pid; + size_t i; + error_t err; + thread_t thread_self = __mach_thread_self (); + struct hurd_sigstate *volatile ss; + sigset_t pending; + + void unlockss (void) + { + __spin_lock (&ss->lock); + ss->critical_section = 0; + pending = ss->pending & ~ss->blocked; + __spin_unlock (&ss->lock); + /* XXX Copying mutex into child and calling mutex_unlock lossy. */ + __mutex_unlock (&_hurd_siglock); + ss = NULL; /* Make sure we crash if we use it again. */ + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + ss->critical_section = 1; + __spin_unlock (&ss->lock); + __mutex_lock (&_hurd_siglock); + + if (! setjmp (env)) + { + process_t newproc; + task_t newtask; + thread_t thread, sigthread; + mach_port_urefs_t thread_refs, sigthread_refs; + struct machine_thread_state state; + mach_msg_type_number_t statecount; + mach_port_t *portnames = NULL; + mach_msg_type_number_t nportnames = 0; + mach_port_type_t *porttypes = NULL; + mach_msg_type_number_t nporttypes = 0; + thread_t *threads = NULL; + mach_msg_type_number_t nthreads = 0; + int ports_locked = 0; + + /* Run things that prepare for forking before we create the task. */ + RUN_HOOK (_hurd_fork_prepare_hook, ()); + + /* Lock things that want to be locked before we fork. */ + for (i = 0; i < _hurd_fork_locks.n; ++i) + __mutex_lock (_hurd_fork_locks.locks[i]); + + newtask = MACH_PORT_NULL; + thread = sigthread = MACH_PORT_NULL; + newproc = MACH_PORT_NULL; + + /* Lock all the port cells for the standard ports while we copy the + address space. We want to insert all the send rights into the + child with the same names. */ + for (i = 0; i < _hurd_nports; ++i) + __spin_lock (&_hurd_ports[i].lock); + ports_locked = 1; + + /* Create the child task. It will inherit a copy of our memory. */ + if (err = __task_create (__mach_task_self (), 1, &newtask)) + goto lose; + + /* Fetch the names of all ports used in this task. */ + if (err = __mach_port_names (__mach_task_self (), + &portnames, &nportnames, + &porttypes, &nporttypes)) + goto lose; + if (nportnames != nporttypes) + { + err = EGRATUITOUS; + goto lose; + } + + /* Get send rights for all the threads in this task. + We want to avoid giving these rights to the child. */ + if (err = __task_threads (__mach_task_self (), &threads, &nthreads)) + goto lose; + + /* Get the child process's proc server port. We will insert it into + the child with the same name as we use for our own proc server + port; and we will need it to set the child's message port. */ + if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port, + newtask, &newproc)) + goto lose; + + /* Insert all our port rights into the child task. */ + thread_refs = sigthread_refs = 0; + for (i = 0; i < nportnames; ++i) + { + if (porttypes[i] & MACH_PORT_TYPE_RECEIVE) + { + /* This is a receive right. We want to give the child task + its own new receive right under the same name. */ + err = __mach_port_allocate_name (newtask, + MACH_PORT_RIGHT_RECEIVE, + portnames[i]); + if (err == KERN_NAME_EXISTS) + { + /* It already has a right under this name (?!). Well, + there is this bizarre old Mach IPC feature (in #ifdef + MACH_IPC_COMPAT in the ukernel) which results in new + tasks getting a new receive right for task special + port number 2. What else might be going on I'm not + sure. So let's check. */ +#if !MACH_IPC_COMPAT +#define TASK_NOTIFY_PORT 2 +#endif + assert (({ mach_port_t thisport, notify_port; + mach_msg_type_name_t poly; + (__task_get_special_port (newtask, + TASK_NOTIFY_PORT, + ¬ify_port) == 0 && + __mach_port_extract_right + (newtask, + portnames[i], + MACH_MSG_TYPE_MAKE_SEND, + &thisport, &poly) == 0 && + (thisport == notify_port) && + __mach_port_deallocate (__mach_task_self (), + thisport) == 0 && + __mach_port_deallocate (__mach_task_self (), + notify_port) == 0); + })); + } + else if (err) + goto lose; + if (porttypes[i] & MACH_PORT_TYPE_SEND) + { + /* Give the child as many send rights for its receive + right as we have for ours. */ + mach_port_urefs_t refs; + mach_port_t port; + mach_msg_type_name_t poly; + if (err = __mach_port_get_refs (__mach_task_self (), + portnames[i], + MACH_PORT_RIGHT_SEND, + &refs)) + goto lose; + if (err = __mach_port_extract_right (newtask, + portnames[i], + MACH_MSG_TYPE_MAKE_SEND, + &port, &poly)) + goto lose; + if (portnames[i] == _hurd_msgport) + { + /* We just created a receive right for the child's + message port and are about to insert send rights + for it. Now, while we happen to have a send right + for it, give it to the proc server. */ + mach_port_t old; + if (err = __proc_setmsgport (newproc, port, &old)) + goto lose; + if (old != MACH_PORT_NULL) + /* XXX what to do here? */ + __mach_port_deallocate (__mach_task_self (), old); + } + if (err = __mach_port_insert_right (newtask, + portnames[i], + port, + MACH_MSG_TYPE_MOVE_SEND)) + goto lose; + if (refs > 1 && + (err = __mach_port_mod_refs (newtask, + portnames[i], + MACH_PORT_RIGHT_SEND, + refs - 1))) + goto lose; + } + if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE) + { + /* Give the child a send-once right for its receive right, + since we have one for ours. */ + mach_port_t port; + mach_msg_type_name_t poly; + if (err = __mach_port_extract_right + (newtask, + portnames[i], + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &port, &poly)) + goto lose; + if (err = __mach_port_insert_right + (newtask, + portnames[i], port, + MACH_MSG_TYPE_MOVE_SEND_ONCE)) + goto lose; + } + } + else if (porttypes[i] & MACH_PORT_TYPE_SEND) + { + /* This is a send right or a dead name. + Give the child as many references for it as we have. */ + mach_port_urefs_t refs, *record_refs = NULL; + mach_port_t insert; + if (portnames[i] == newtask) + /* Skip the name we use for the child's task port. */ + continue; + if (portnames[i] == __mach_task_self ()) + /* For the name we use for our own task port, + insert the child's task port instead. */ + insert = newtask; + else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port) + { + /* Get the proc server port for the new task. */ + if (err = __proc_task2proc (portnames[i], newtask, &insert)) + goto lose; + } + else if (portnames[i] == thread_self) + { + /* For the name we use for our own thread port, we will + insert the thread port for the child main user thread + after we create it. */ + insert = MACH_PORT_NULL; + record_refs = &thread_refs; + /* Allocate a dead name right for this name as a + placeholder, so the kernel will not chose this name + for any other new port (it might use it for one of the + rights created when a thread is created). */ + if (err = __mach_port_allocate_name + (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i])) + goto lose; + } + else if (portnames[i] == _hurd_msgport_thread) + /* For the name we use for our signal thread's thread port, + we will insert the thread port for the child's signal + thread after we create it. */ + { + insert = MACH_PORT_NULL; + record_refs = &sigthread_refs; + /* Allocate a dead name right as a placeholder. */ + if (err = __mach_port_allocate_name + (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i])) + goto lose; + } + else + { + /* Skip the name we use for any of our own thread ports. */ + mach_msg_type_number_t j; + for (j = 0; j < nthreads; ++j) + if (portnames[i] == threads[j]) + break; + if (j < nthreads) + continue; + + insert = portnames[i]; + } + /* Find out how many user references we have for + the send right with this name. */ + if (err = __mach_port_get_refs (__mach_task_self (), + portnames[i], + MACH_PORT_RIGHT_SEND, + record_refs ?: &refs)) + goto lose; + if (insert == MACH_PORT_NULL) + continue; + /* Insert the chosen send right into the child. */ + err = __mach_port_insert_right (newtask, + portnames[i], + insert, + MACH_MSG_TYPE_COPY_SEND); + if (err == KERN_NAME_EXISTS) + { + /* It already has a send right under this name (?!). + Well, it starts out with a send right for its task + port, and inherits the bootstrap and exception ports + from us. */ + mach_port_t childport; + mach_msg_type_name_t poly; + assert (__mach_port_extract_right (newtask, portnames[i], + MACH_MSG_TYPE_COPY_SEND, + &childport, &poly) == 0 && + childport == insert && + __mach_port_deallocate (__mach_task_self (), + childport) == 0); + } + else if (err) + goto lose; + /* Give the child as many user references as we have. */ + if (refs > 1 && + (err = __mach_port_mod_refs (newtask, + portnames[i], + MACH_PORT_RIGHT_SEND, + refs - 1))) + goto lose; + } + } + + /* Unlock the standard port cells. The child must unlock its own + copies too. */ + for (i = 0; i < _hurd_nports; ++i) + __spin_unlock (&_hurd_ports[i].lock); + ports_locked = 0; + + /* Unlock the signal state. The child must unlock its own copy too. */ + unlockss (); + + /* Create the child main user thread and signal thread. */ + if ((err = __thread_create (newtask, &thread)) || + (err = __thread_create (newtask, &sigthread))) + goto lose; + + /* Insert send rights for those threads. We previously allocated + dead name rights with the names we want to give the thread ports + in the child as placeholders. Now deallocate them so we can use + the names. */ + if ((err = __mach_port_deallocate (newtask, thread_self)) || + (err = __mach_port_insert_right (newtask, thread_self, + thread, MACH_MSG_TYPE_COPY_SEND))) + goto lose; + /* We have one extra user reference created at the beginning of this + function, accounted for by mach_port_names (and which will thus be + accounted for in the child below). This extra right gets consumed + in the child by the store into _hurd_sigthread in the child fork. */ + if (thread_refs > 1 && + (err = __mach_port_mod_refs (newtask, thread_self, + MACH_PORT_RIGHT_SEND, + thread_refs - 1))) + goto lose; + if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none. */ + && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) || + (err = __mach_port_insert_right (newtask, _hurd_msgport_thread, + sigthread, + MACH_MSG_TYPE_COPY_SEND)))) + goto lose; + if (sigthread_refs > 1 && + (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread, + MACH_PORT_RIGHT_SEND, + sigthread_refs - 1))) + goto lose; + + /* This seems like a convenient juncture to copy the proc server's + idea of what addresses our argv and envp are found at from the + parent into the child. Since we happen to know that the child + shares our memory image, it is we who should do this copying. */ + { + vm_address_t argv, envp; + err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp)) + ?: __proc_set_arg_locations (newproc, argv, envp)); + if (err) + goto lose; + } + + /* Set the child signal thread up to run the msgport server function + using the same signal thread stack copied from our address space. + We fetch the state before longjmp'ing it so that miscellaneous + registers not affected by longjmp (such as i386 segment registers) + are in their normal default state. */ + statecount = MACHINE_THREAD_STATE_COUNT; + if (err = __thread_get_state (_hurd_msgport_thread, + MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, &statecount)) + goto lose; +#if STACK_GROWTH_UP + state.SP = __hurd_sigthread_stack_base; +#else + state.SP = __hurd_sigthread_stack_end; +#endif + MACHINE_THREAD_STATE_SET_PC (&state, + (unsigned long int) _hurd_msgport_receive); + if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, statecount)) + goto lose; + /* We do not thread_resume SIGTHREAD here because the child + fork needs to do more setup before it can take signals. */ + + /* Set the child user thread up to return 1 from the setjmp above. */ + _hurd_longjmp_thread_state (&state, env, 1); + if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, statecount)) + goto lose; + + /* Get the PID of the child from the proc server. We must do this + before calling proc_child below, because at that point any + authorized POSIX.1 process may kill the child task with SIGKILL. */ + if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid))) + goto lose; + + /* Register the child with the proc server. It is important that + this be that last thing we do before starting the child thread + running. Once proc_child has been done for the task, it appears + as a POSIX.1 process. Any errors we get must be detected before + this point, and the child must have a message port so it responds + to POSIX.1 signals. */ + if (err = __USEPORT (PROC, __proc_child (port, newtask))) + goto lose; + + /* This must be the absolutely last thing we do; we can't assume that + the child will remain alive for even a moment once we do this. We + ignore errors because we have committed to the fork and are not + allowed to return them after the process becomes visible to + POSIX.1 (which happened right above when we called proc_child). */ + (void) __thread_resume (thread); + + lose: + if (ports_locked) + for (i = 0; i < _hurd_nports; ++i) + __spin_unlock (&_hurd_ports[i].lock); + + if (newtask != MACH_PORT_NULL) + { + if (err) + __task_terminate (newtask); + __mach_port_deallocate (__mach_task_self (), newtask); + } + if (thread != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), thread); + if (sigthread != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), sigthread); + if (newproc != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), newproc); + if (thread_self != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), thread_self); + + if (portnames) + __vm_deallocate (__mach_task_self (), + (vm_address_t) portnames, + nportnames * sizeof (*portnames)); + if (porttypes) + __vm_deallocate (__mach_task_self (), + (vm_address_t) porttypes, + nporttypes * sizeof (*porttypes)); + if (threads) + { + for (i = 0; i < nthreads; ++i) + __mach_port_deallocate (__mach_task_self (), threads[i]); + __vm_deallocate (__mach_task_self (), + (vm_address_t) threads, + nthreads * sizeof (*threads)); + } + + /* Run things that want to run in the parent to restore it to + normality. Usually prepare hooks and parent hooks are + symmetrical: the prepare hook arrests state in some way for the + fork, and the parent hook restores the state for the parent to + continue executing normally. */ + RUN_HOOK (_hurd_fork_parent_hook, ()); + } + else + { + struct hurd_sigstate *oldstates; + + /* We are the child task. Unlock the standard port cells, which were + locked in the parent when we copied its memory. The parent has + inserted send rights with the names that were in the cells then. */ + for (i = 0; i < _hurd_nports; ++i) + __spin_unlock (&_hurd_ports[i].lock); + + /* We are the only thread in this new task, so we will + take the task-global signals. */ + _hurd_sigthread = thread_self; + + /* Unchain the sigstate structures for threads that existed in the + parent task but don't exist in this task (the child process). + Delay freeing them until later because some of the further setup + and unlocking might be required for free to work. */ + oldstates = _hurd_sigstates; + if (oldstates == ss) + oldstates = ss->next; + else + { + while (_hurd_sigstates->next != ss) + _hurd_sigstates = _hurd_sigstates->next; + _hurd_sigstates->next = ss->next; + } + ss->next = NULL; + _hurd_sigstates = ss; + + /* Unlock our copies of the signal state locks. */ + unlockss (); + + /* Fetch our new process IDs from the proc server. No need to + refetch our pgrp; it is always inherited from the parent (so + _hurd_pgrp is already correct), and the proc server will send us a + proc_newids notification when it changes. */ + err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid, + &_hurd_orphaned)); + + /* Run things that want to run in the child task to set up. */ + RUN_HOOK (_hurd_fork_child_hook, ()); + + /* Set up proc server-assisted fault recovery for the signal thread. */ + _hurdsig_fault_init (); + + /* Start the signal thread listening on the message port. */ + if (!err) + err = __thread_resume (_hurd_msgport_thread); + + /* Free the old sigstate structures. */ + while (oldstates != NULL) + { + struct hurd_sigstate *next = oldstates->next; + free (oldstates); + oldstates = next; + } + /* XXX what to do if we have any errors here? */ + + pid = 0; + } + + /* Unlock things we locked before creating the child task. + They are locked in both the parent and child tasks. */ + for (i = 0; i < _hurd_fork_locks.n; ++i) + __mutex_unlock (_hurd_fork_locks.locks[i]); + + if (pending) + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + + return err ? __hurd_fail (err) : pid; +} + +weak_alias (__fork, fork) diff --git a/sysdeps/mach/hurd/fstat.c b/sysdeps/mach/hurd/fstat.c new file mode 100644 index 0000000000..5341e3e4a4 --- /dev/null +++ b/sysdeps/mach/hurd/fstat.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Get information about the file descriptor FD in BUF. */ +int +DEFUN(__fstat, (fd, buf), int fd AND struct stat *buf) +{ + error_t err; + + if (err = HURD_DPORT_USE (fd, __io_stat (port, buf))) + return __hurd_dfail (fd, err); + + return 0; +} + +weak_alias (__fstat, fstat) diff --git a/sysdeps/mach/hurd/fsync.c b/sysdeps/mach/hurd/fsync.c new file mode 100644 index 0000000000..adfe9800d3 --- /dev/null +++ b/sysdeps/mach/hurd/fsync.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Make all changes done to FD actually appear on disk. */ +int +DEFUN(fsync, (fd), int fd) +{ + error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1)); + if (err) + return __hurd_dfail (fd, err); + return 0; +} diff --git a/sysdeps/mach/hurd/ftruncate.c b/sysdeps/mach/hurd/ftruncate.c new file mode 100644 index 0000000000..23a5e796cc --- /dev/null +++ b/sysdeps/mach/hurd/ftruncate.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +DEFUN(ftruncate, (fd, length), + int fd AND off_t length) +{ + error_t err; + if (err = HURD_DPORT_USE (fd, __file_truncate (port, length))) + return __hurd_dfail (fd, err); + return 0; +} diff --git a/sysdeps/mach/hurd/getcwd.c b/sysdeps/mach/hurd/getcwd.c new file mode 100644 index 0000000000..c0d9bcd567 --- /dev/null +++ b/sysdeps/mach/hurd/getcwd.c @@ -0,0 +1,250 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <hurd.h> +#include <hurd/port.h> +#include <dirent.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> + + +/* Get the pathname of the current working directory, and put it in SIZE + bytes of BUF. Returns NULL if the directory couldn't be determined or + SIZE was too small. If successful, returns BUF. In GNU, if BUF is + NULL, an array is allocated with `malloc'; the array is SIZE bytes long, + unless SIZE <= 0, in which case it is as big as necessary. */ + +char * +getcwd (char *buf, size_t size) +{ + error_t err; + dev_t rootdev, thisdev; + ino_t rootino, thisino; + char *file_name; + register char *file_namep; + struct stat st; + file_t parent; + char *dirbuf = NULL; + unsigned int dirbufsize = 0; + file_t crdir; + struct hurd_userlink crdir_ulink; + + inline void cleanup (void) + { + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + __mach_port_deallocate (__mach_task_self (), parent); + + if (dirbuf != NULL) + __vm_deallocate (__mach_task_self (), + (vm_address_t) dirbuf, dirbufsize); + } + + + if (size == 0) + { + if (buf != NULL) + { + errno = EINVAL; + return NULL; + } + + size = FILENAME_MAX * 4 + 1; /* Good starting guess. */ + } + + if (buf != NULL) + file_name = buf; + else + { + file_name = malloc (size); + if (file_name == NULL) + return NULL; + } + + file_namep = file_name + size; + *--file_namep = '\0'; + + /* Get a port to our root directory and stat it. */ + + crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink); + if (err = __io_stat (crdir, &st)) + { + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + return __hurd_fail (err), NULL; + } + rootdev = st.st_dev; + rootino = st.st_ino; + + /* Get a port to our current working directory and stat it. */ + + if (err = __USEPORT (CWDIR, __mach_port_mod_refs (__mach_task_self (), + (parent = port), + MACH_PORT_RIGHT_SEND, + 1))) + { + _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir); + return __hurd_fail (err), NULL; + } + if (err = __io_stat (parent, &st)) + { + cleanup (); + return __hurd_fail (err), NULL; + } + + thisdev = st.st_dev; + thisino = st.st_ino; + + while (!(thisdev == rootdev && thisino == rootino)) + { + /* PARENT is a port to the directory we are currently on; + THISDEV and THISINO are its device and node numbers. + Look in its parent (..) for a file with the same numbers. */ + + struct dirent *d; + dev_t dotdev; + ino_t dotino; + int mount_point; + file_t newp; + char *dirdata; + unsigned int dirdatasize; + int direntry, nentries; + + /* Look at the parent directory. */ + if (err = __hurd_file_name_lookup (crdir, parent, "..", O_READ, 0, &newp)) + goto lose; + __mach_port_deallocate (__mach_task_self (), parent); + parent = newp; + + /* Figure out if this directory is a mount point. */ + if (err = __io_stat (parent, &st)) + goto lose; + dotdev = st.st_dev; + dotino = st.st_ino; + mount_point = dotdev != thisdev; + + /* Search for the last directory. */ + direntry = 0; + dirdata = dirbuf; + dirdatasize = dirbufsize; + while (!(err = __dir_readdir (parent, &dirdata, &dirdatasize, + direntry, -1, 0, &nentries)) && + nentries != 0) + { + /* We have a block of directory entries. */ + + unsigned int offset; + + direntry += nentries; + + if (dirdata != dirbuf) + { + /* The data was passed out of line, so our old buffer is no + longer useful. Deallocate the old buffer and reset our + information for the new buffer. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) dirbuf, dirbufsize); + dirbuf = dirdata; + dirbufsize = round_page (dirdatasize); + } + + /* Iterate over the returned directory entries, looking for one + whose file number is THISINO. */ + + offset = 0; + while (offset < dirdatasize) + { + d = (struct dirent *) &dirdata[offset]; + offset += d->d_reclen; + + /* Ignore `.' and `..'. */ + if (d->d_name[0] == '.' && + (d->d_namlen == 1 || + (d->d_namlen == 2 && d->d_name[1] == '.'))) + continue; + + if (mount_point || d->d_ino == thisino) + { + file_t try; + if (err = __hurd_file_name_lookup (crdir, parent, d->d_name, + O_NOLINK, 0, &try)) + goto lose; + err = __io_stat (try, &st); + __mach_port_deallocate (__mach_task_self (), try); + if (err) + goto lose; + if (st.st_dev == thisdev && st.st_ino == thisino) + break; + } + } + } + + if (err) + goto lose; + else + { + /* Prepend the directory name just discovered. */ + + if (file_namep - file_name < d->d_namlen + 1) + { + if (buf != NULL) + { + errno = ERANGE; + return NULL; + } + else + { + size *= 2; + buf = realloc (file_name, size); + if (buf == NULL) + { + free (file_name); + return NULL; + } + file_namep = &buf[file_namep - file_name]; + file_name = buf; + } + } + file_namep -= d->d_namlen; + (void) memcpy (file_namep, d->d_name, d->d_namlen); + *--file_namep = '/'; + } + + /* The next iteration will find the name of the directory we + just searched through. */ + thisdev = dotdev; + thisino = dotino; + } + + if (file_namep == &file_name[size - 1]) + /* We found nothing and got all the way to the root. + So the root is our current directory. */ + *--file_namep = '/'; + + memmove (file_name, file_namep, file_name + size - file_namep); + cleanup (); + return file_name; + + lose: + cleanup (); + return NULL; +} diff --git a/sysdeps/mach/hurd/getdents.c b/sysdeps/mach/hurd/getdents.c new file mode 100644 index 0000000000..4de2eb351d --- /dev/null +++ b/sysdeps/mach/hurd/getdents.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Ince + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <string.h> + +ssize_t +DEFUN(__getdirentries, (fd, buf, nbytes, basep), + int fd AND PTR buf AND size_t nbytes AND off_t *basep) +{ + error_t err; + int entriesread; + char *data = buf; + mach_msg_type_number_t bytesread = nbytes; + + /* Fault before taking any locks. */ + *(volatile off_t *) basep = *basep; + + err = HURD_DPORT_USE (fd, __dir_readdir (port, &data, &bytesread, + *basep, -1, nbytes, &entriesread)); + if (err) + return __hurd_dfail (fd, err); + + if (data != buf) + { + size_t copy = bytesread; + if (copy > nbytes) + /* The server has a violated the dir_readdir protocol. */ + copy = nbytes; + memcpy (buf, data, copy); + __vm_deallocate (__mach_task_self (), (vm_address_t) data, bytesread); + bytesread = copy; + } + + *basep += entriesread; + + return bytesread; +} + +weak_alias (__getdirentries, getdirentries) + diff --git a/sysdeps/mach/hurd/getdtsz.c b/sysdeps/mach/hurd/getdtsz.c new file mode 100644 index 0000000000..e506963ac3 --- /dev/null +++ b/sysdeps/mach/hurd/getdtsz.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Return the maximum number of file descriptors the current process + could possibly have (until it raises the resource limit). */ +int +DEFUN_VOID(__getdtablesize) +{ + int size; + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + size = _hurd_dtablesize; + __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; + return size; +} + +weak_alias (__getdtablesize, getdtablesize) diff --git a/sysdeps/mach/hurd/getegid.c b/sysdeps/mach/hurd/getegid.c new file mode 100644 index 0000000000..88f6ea00e2 --- /dev/null +++ b/sysdeps/mach/hurd/getegid.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> + +/* Get the effective group ID of the calling process. */ +gid_t +DEFUN_VOID(__getegid) +{ + error_t err; + gid_t egid; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + errno = err; + egid = -1; + } + else if (_hurd_id.gen.ngids >= 1) + egid = _hurd_id.gen.gids[0]; + else if (_hurd_id.aux.ngids >= 1) + /* We have no effective gids. Return the real gid. */ + egid = _hurd_id.aux.gids[0]; + else + { + /* We do not even have a real gid. */ + errno = EGRATUITOUS; + egid = -1; + } + + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + return egid; +} + +weak_alias (__getegid, getegid) diff --git a/sysdeps/mach/hurd/geteuid.c b/sysdeps/mach/hurd/geteuid.c new file mode 100644 index 0000000000..416cd31f82 --- /dev/null +++ b/sysdeps/mach/hurd/geteuid.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> + +/* Get the effective user ID of the calling process. */ +uid_t +DEFUN_VOID(__geteuid) +{ + error_t err; + uid_t euid; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + errno = err; + euid = -1; + } + else if (_hurd_id.gen.nuids >= 1) + euid = _hurd_id.gen.uids[0]; + else if (_hurd_id.aux.nuids >= 1) + /* We have no effective uids. Return the real uid. */ + euid = _hurd_id.aux.uids[0]; + else + { + /* We do not even have a real uid. */ + errno = EGRATUITOUS; + euid = -1; + } + + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + return euid; +} + +weak_alias (__geteuid, geteuid) diff --git a/sysdeps/mach/hurd/getgid.c b/sysdeps/mach/hurd/getgid.c new file mode 100644 index 0000000000..0d1b27f8e6 --- /dev/null +++ b/sysdeps/mach/hurd/getgid.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> + +/* Get the real group ID of the calling process. */ +gid_t +DEFUN_VOID(__getgid) +{ + error_t err; + gid_t gid; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + errno = err; + gid = -1; + } + else if (_hurd_id.aux.ngids >= 1) + gid = _hurd_id.aux.gids[0]; + else + { + /* We do not even have a real gid. */ + errno = EGRATUITOUS; + gid = -1; + } + + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + return gid; +} + +weak_alias (__getgid, getgid) diff --git a/sysdeps/mach/hurd/getgroups.c b/sysdeps/mach/hurd/getgroups.c new file mode 100644 index 0000000000..d985d29317 --- /dev/null +++ b/sysdeps/mach/hurd/getgroups.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +int +__getgroups (int n, gid_t *gidset) +{ + error_t err; + int ngids; + void *crit; + + crit = _hurd_critical_section_lock (); + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + return __hurd_fail (err); + } + + ngids = _hurd_id.gen.ngids; + + if (n != 0) + { + /* Copy the gids onto stack storage and then release the idlock. */ + gid_t gids[ngids]; + memcpy (gids, _hurd_id.gen.gids, sizeof (gids)); + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + + /* Now that the lock is released, we can safely copy the + group set into the user's array, which might fault. */ + if (ngids > n) + ngids = n; + memcpy (gidset, gids, ngids * sizeof (gid_t)); + } + else + { + __mutex_unlock (&_hurd_id.lock); + _hurd_critical_section_unlock (crit); + } + + return ngids; +} + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/mach/hurd/gethostid.c b/sysdeps/mach/hurd/gethostid.c new file mode 100644 index 0000000000..5a3309266e --- /dev/null +++ b/sysdeps/mach/hurd/gethostid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Return the current machine's Internet number. */ +long int +DEFUN_VOID(gethostid) +{ + int hostid; + error_t err; + if (err = __USEPORT (PROC, __proc_gethostid (port, &hostid))) + return __hurd_fail (err); + return hostid; +} diff --git a/sysdeps/mach/hurd/gethostname.c b/sysdeps/mach/hurd/gethostname.c new file mode 100644 index 0000000000..94a0537d91 --- /dev/null +++ b/sysdeps/mach/hurd/gethostname.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> +#include <string.h> + +/* Put the name of the current host in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +int +DEFUN(__gethostname, (name, len), + char *name AND size_t len) +{ + error_t err; + char *buf = name; + mach_msg_type_number_t buflen = len; + if (err = __USEPORT (PROC, __proc_gethostname (port, &buf, &buflen))) + return __hurd_fail (err); + if (buf != name) + { + memcpy (name, buf, len < buflen ? len : buflen); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + if (buflen > len) + return __hurd_fail (ENAMETOOLONG); + return 0; +} + +weak_alias (__gethostname, gethostname) diff --git a/sysdeps/mach/hurd/getitimer.c b/sysdeps/mach/hurd/getitimer.c new file mode 100644 index 0000000000..15c46cae68 --- /dev/null +++ b/sysdeps/mach/hurd/getitimer.c @@ -0,0 +1,104 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/time.h> +#include <hurd.h> + +/* XXX Temporary cheezoid implementation; see __setitmr.c. */ + +/* These are defined in __setitmr.c. */ +extern spin_lock_t _hurd_itimer_lock; +extern struct itimerval _hurd_itimerval; +extern struct timeval _hurd_itimer_started; + +static inline void +subtract_timeval (struct timeval *from, const struct timeval *subtract) +{ + from->tv_usec -= subtract->tv_usec; + from->tv_sec -= subtract->tv_sec; + while (from->tv_usec < 0) + { + --from->tv_sec; + from->tv_usec += 1000000; + } +} + +/* Set *VALUE to the current setting of timer WHICH. + Return 0 on success, -1 on errors. */ +int +DEFUN(__getitimer, (which, value), + enum __itimer_which which AND struct itimerval *value) +{ + struct itimerval val; + struct timeval elapsed; + + switch (which) + { + default: + return __hurd_fail (EINVAL); + + case ITIMER_VIRTUAL: + case ITIMER_PROF: + return __hurd_fail (ENOSYS); + + case ITIMER_REAL: + break; + } + + /* Get the time now. */ + if (__gettimeofday (&elapsed, NULL) < 0) + return -1; + + /* Extract the current timer setting; and the time it was set, so we can + calculate the time elapsed so far. */ + HURD_CRITICAL_BEGIN; + __spin_lock (&_hurd_itimer_lock); + val = _hurd_itimerval; + subtract_timeval (&elapsed, &_hurd_itimer_started); + __spin_unlock (&_hurd_itimer_lock); + HURD_CRITICAL_END; + + if ((val.it_value.tv_sec | val.it_value.tv_usec) != 0) + { + /* There is a pending alarm set. VAL indicates the interval it was + set for, relative to the time recorded in _hurd_itimer_started. + Now compensate for the time elapsed since to get the user's + conception of the current value of the timer (as if the value + stored decreased every microsecond). */ + if (timercmp (&val.it_value, &elapsed, <)) + { + /* Hmm. The timer should have just gone off, but has not been + reset. This is a possible timing glitch. The alarm will signal + soon, so fabricate a value for how soon. */ + val.it_value.tv_sec = 0; + val.it_value.tv_usec = 10; /* Random. */ + } + else + /* Subtract the time elapsed since the timer was set + from the current timer value the user sees. */ + subtract_timeval (&val.it_value, &elapsed); + } + + *value = val; + return 0; +} + +weak_alias (__getitimer, getitimer) diff --git a/sysdeps/mach/hurd/getlogin.c b/sysdeps/mach/hurd/getlogin.c new file mode 100644 index 0000000000..523db3f2d7 --- /dev/null +++ b/sysdeps/mach/hurd/getlogin.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Return the login name of the user, or NULL if it can't be determined. + The returned pointer, if not NULL, is good only until the next call. */ +char * +DEFUN_VOID(getlogin) +{ + static char login[1024]; /* XXX */ + error_t err; + + if (err = __USEPORT (PROC, __proc_getlogin (port, login))) + { + errno = err; + return NULL; + } + + return login; +} diff --git a/sysdeps/mach/hurd/getpeername.c b/sysdeps/mach/hurd/getpeername.c new file mode 100644 index 0000000000..a9ea32c2ae --- /dev/null +++ b/sysdeps/mach/hurd/getpeername.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <string.h> + +/* Put the address of the peer connected to socket FD into *ADDR + (which is *LEN bytes long), and its actual length into *LEN. */ +int +DEFUN(getpeername, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t *len) +{ + error_t err; + char *buf = (char *) addr; + mach_msg_type_number_t buflen = *len; + int type; + addr_port_t aport; + + if (err = HURD_DPORT_USE (fd, __socket_peername (port, &aport))) + return __hurd_dfail (fd, err); + + err = __socket_whatis_address (aport, &type, &buf, &buflen); + __mach_port_deallocate (__mach_task_self (), aport); + + if (err) + return __hurd_dfail (fd, err); + + if (buf != (char *) addr) + { + if (*len < buflen) + *len = buflen; + memcpy (addr, buf, *len); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + addr->sa_family = type; + + return 0; +} diff --git a/sysdeps/mach/hurd/getpgid.c b/sysdeps/mach/hurd/getpgid.c new file mode 100644 index 0000000000..b9a3634fed --- /dev/null +++ b/sysdeps/mach/hurd/getpgid.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> + +/* Get the process group ID of process PID. */ +int +DEFUN(__getpgid, (pid), pid_t pid) +{ + error_t err; + pid_t pgrp; + + if (pid == 0) + { + /* Assume atomic word fetch and store, so don't lock _hurd_pid_lock. */ + pgrp = _hurd_pgrp; + err = 0; + } + else + err = __USEPORT (PROC, __proc_getpgrp (port, pid, &pgrp)); + + return err ? __hurd_fail (err) : pgrp; +} + +weak_alias (__getpgid, getpgid) diff --git a/sysdeps/mach/hurd/getpid.c b/sysdeps/mach/hurd/getpid.c new file mode 100644 index 0000000000..bbff6a3ca0 --- /dev/null +++ b/sysdeps/mach/hurd/getpid.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Get the process ID of the calling process. */ +pid_t +DEFUN_VOID(__getpid) +{ + /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */ + return _hurd_pid; +} + +weak_alias (__getpid, getpid) diff --git a/sysdeps/mach/hurd/getppid.c b/sysdeps/mach/hurd/getppid.c new file mode 100644 index 0000000000..6a5ac1dd1b --- /dev/null +++ b/sysdeps/mach/hurd/getppid.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <hurd.h> + + +/* Get the parent process ID of the calling process. */ +pid_t +DEFUN_VOID(__getppid) +{ + /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */ + return _hurd_ppid; +} + +weak_alias (__getppid, getppid) diff --git a/sysdeps/mach/hurd/getpriority.c b/sysdeps/mach/hurd/getpriority.c new file mode 100644 index 0000000000..5b24ce23f8 --- /dev/null +++ b/sysdeps/mach/hurd/getpriority.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <limits.h> +#include <hurd.h> +#include <hurd/resource.h> + +/* Return the highest priority of any process specified by WHICH and WHO + (see <sys/resource.h>); if WHO is zero, the current process, process group, + or user (as specified by WHO) is used. A lower priority number means higher + priority. Priorities range from PRIO_MIN to PRIO_MAX. */ +int +getpriority (enum __priority_which which, int who) +{ + error_t err, onerr; + int maxpri = INT_MIN; + struct procinfo *pip; /* Just for sizeof. */ + int pibuf[sizeof *pip + 2 * sizeof (pip->threadinfos[0])], *pi = pibuf; + unsigned int pisize = sizeof pibuf / sizeof pibuf[0]; + + error_t getonepriority (pid_t pid, struct procinfo *pip) + { + if (pip) + onerr = 0; + else + { + int *oldpi = pi; + unsigned int oldpisize = pisize; + onerr = __USEPORT (PROC, __proc_getprocinfo (port, + pid, + &pi, &pisize)); + if (pi != oldpi && oldpi != pibuf) + /* Old buffer from last call was not reused; free it. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) oldpi, oldpisize * sizeof pi[0]); + pip = (struct procinfo *) pi; + } + if (!onerr && pip->taskinfo.base_priority > maxpri) + maxpri = pip->taskinfo.base_priority; + return 0; + } + + onerr = 0; + err = _hurd_priority_which_map (which, who, getonepriority); + + if (pi != pibuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pi, pisize * sizeof pi[0]); + + if (!err && maxpri == INT_MIN) + /* No error, but no pids found. */ + err = onerr ?: ESRCH; + + if (err) + return __hurd_fail (err); + + return MACH_PRIORITY_TO_NICE (maxpri); +} diff --git a/sysdeps/mach/hurd/getrlimit.c b/sysdeps/mach/hurd/getrlimit.c new file mode 100644 index 0000000000..a05d32277d --- /dev/null +++ b/sysdeps/mach/hurd/getrlimit.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/resource.h> + +/* Put the soft and hard limits for RESOURCE in *RLIMITS. + Returns 0 if successful, -1 if not (and sets errno). */ +int +DEFUN(getrlimit, (resource, rlimits), + enum __rlimit_resource resource AND struct rlimit *rlimits) +{ + struct rlimit lim; + + if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS) + { + errno = EINVAL; + return -1; + } + + __mutex_lock (&_hurd_rlimit_lock); + lim = _hurd_rlimits[resource]; + __mutex_unlock (&_hurd_rlimit_lock); + + *rlimits = lim; + + return 0; +} diff --git a/sysdeps/mach/hurd/getsockname.c b/sysdeps/mach/hurd/getsockname.c new file mode 100644 index 0000000000..5a9182b4fc --- /dev/null +++ b/sysdeps/mach/hurd/getsockname.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <string.h> + +/* Put the local address of FD into *ADDR and its length in *LEN. */ +int +DEFUN(getsockname, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t *len) +{ + error_t err; + char *buf = (char *) addr; + mach_msg_type_number_t buflen = *len; + int type; + addr_port_t aport; + + if (err = HURD_DPORT_USE (fd, __socket_name (port, &aport))) + return __hurd_dfail (fd, err); + + err = __socket_whatis_address (aport, &type, &buf, &buflen); + __mach_port_deallocate (__mach_task_self (), aport); + + if (err) + return __hurd_dfail (fd, err); + + if (buf != (char *) addr) + { + if (*len < buflen) + *len = buflen; + memcpy (addr, buf, *len); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + addr->sa_family = type; + + return 0; +} diff --git a/sysdeps/mach/hurd/getsockopt.c b/sysdeps/mach/hurd/getsockopt.c new file mode 100644 index 0000000000..a9c91ea0f1 --- /dev/null +++ b/sysdeps/mach/hurd/getsockopt.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <string.h> + +/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL + into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's + actual length. Returns 0 on success, -1 for errors. */ +int +DEFUN(getsockopt, (fd, level, optname, optval, optlen), + int fd AND int level AND int optname AND + PTR optval AND size_t *optlen) +{ + error_t err; + char *buf = optval; + mach_msg_type_number_t buflen = *optlen; + + if (err = HURD_DPORT_USE (fd, __socket_getopt (port, + level, optname, + &buf, &buflen))) + return __hurd_dfail (fd, err); + + if (buf != optval) + { + if (*optlen < buflen) + *optlen = buflen; + memcpy (optval, buf, *optlen); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + return 0; +} diff --git a/sysdeps/mach/hurd/getuid.c b/sysdeps/mach/hurd/getuid.c new file mode 100644 index 0000000000..9381c6e8ec --- /dev/null +++ b/sysdeps/mach/hurd/getuid.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> + +/* Get the real user ID of the calling process. */ +uid_t +DEFUN_VOID(__getuid) +{ + error_t err; + uid_t uid; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + + if (err = _hurd_check_ids ()) + { + errno = err; + uid = -1; + } + else if (_hurd_id.aux.nuids >= 1) + uid = _hurd_id.aux.uids[0]; + else + { + /* We do not even have a real uid. */ + errno = EGRATUITOUS; + uid = -1; + } + + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + return uid; +} + +weak_alias (__getuid, getuid) diff --git a/sysdeps/mach/hurd/hppa/sigcontext.h b/sysdeps/mach/hurd/hppa/sigcontext.h new file mode 100644 index 0000000000..b616469f21 --- /dev/null +++ b/sysdeps/mach/hurd/hppa/sigcontext.h @@ -0,0 +1,86 @@ +/* Machine-dependent signal context structure for GNU Hurd. HPPA version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Signal handlers are actually called: + void handler (int sig, int code, struct sigcontext *scp); */ + +/* State of this thread when the signal was taken. */ +struct sigcontext + { + /* These first members are machine-independent. */ + + int sc_onstack; /* Nonzero if running on sigstack. */ + __sigset_t sc_mask; /* Blocked signals to restore. */ + + /* MiG reply port this thread is using. */ + unsigned int sc_reply_port; + + /* Port this thread is doing an interruptible RPC on. */ + unsigned int sc_intr_port; + + /* Error code associated with this signal (interpreted as `error_t'). */ + int sc_error; + + /* All following members are machine-dependent. The rest of this + structure is written to be laid out identically to a `struct + parisc_thread_state'. trampoline.c knows this, so it must be + changed if this changes. */ + +#define sc_parisc_thread_state sc_flags /* Beginning of correspondence. */ + /* "General" registers $1..$31. */ + unsigned int sc_regs[31]; + + /* Control registers. */ + unsigned int sc_cr11; /* sar */ + /* These four registers make up the PC. */ + unsigned int iioq_head; + unsigned int iisq_head; + unsigned int iioq_tail; + unsigned int iisq_tail; + unsigned int sc_cr15; + unsigned int sc_cr19; + unsigned int sc_cr20; + unsigned int sc_cr21; + unsigned int sc_cr22; /* ipsw */ + unsigned int sc_bsd_goto; /* unused */ + unsigned int sc_sr4; + unsigned int sc_sr0; + unsigned int sc_sr1; + unsigned int sc_sr2; + unsigned int sc_sr3; + unsigned int sc_sr5; + unsigned int sc_sr6; + unsigned int sc_sr7; + unsigned int sc_cr0; + unsigned int sc_cr8; + unsigned int sc_cr9; + unsigned int sc_cr10; /* unused */ + unsigned int sc_cr12; + unsigned int sc_cr13; + unsigned int sc_cr24; /* unused */ + unsigned int sc_cr25; /* unused */ + unsigned int sc_cr26; /* unused */ + unsigned sc_mpsfu_high; /* unused */ + unsigned sc_mpsfu_low; /* unused */ + unsigned sc_mpsfu_ovflo; /* unused */ + int sc_pad; + + /* Floating point registers $f0..$f31. */ + double sc_fpregs[32]; + }; diff --git a/sysdeps/mach/hurd/hppa/trampoline.c b/sysdeps/mach/hurd/hppa/trampoline.c new file mode 100644 index 0000000000..09ab71e88d --- /dev/null +++ b/sysdeps/mach/hurd/hppa/trampoline.c @@ -0,0 +1,258 @@ +/* Set thread_state for sighandler, and sigcontext to recover. HPPA version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include "thread_state.h" +#include <assert.h> +#include <errno.h> +#include "hurdfault.h" + + +struct mach_msg_trap_regargs + { + /* These first four arguments are in registers 26..23. */ + mach_msg_size_t rcv_size; /* arg3 */ + mach_msg_size_t send_size; /* arg2 */ + mach_msg_option_t option; /* arg1 */ + mach_msg_header_t *msg; /* arg0 */ + }; + +struct sigcontext * +_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, + int signo, long int sigcode, + volatile int rpc_wait, + struct machine_thread_all_state *state) +{ + __label__ trampoline, rpc_wait_trampoline; + void *volatile sigsp; + struct sigcontext *scp; + + if (ss->context) + { + /* We have a previous sigcontext that sigreturn was about + to restore when another signal arrived. We will just base + our setup on that. */ + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode >= (long int) ss->context && + _hurdsig_fault_sigcode < (long int) (ss->context + 1)); + else + { + memcpy (&state->basic, &ss->context->sc_parisc_thread_state, + sizeof (state->basic)); + state->set = (1 << PARISC_THREAD_STATE); + assert (! rpc_wait); + /* The intr_port slot was cleared before sigreturn sent us the + sig_post that made us notice this pending signal, so + _hurd_internal_post_signal wouldn't do interrupt_operation. + After we return, our caller will set SCP->sc_intr_port (in the + new context) from SS->intr_port and clear SS->intr_port. Now + that we are restoring this old context recorded by sigreturn, + we want to restore its intr_port too; so store it in + SS->intr_port now, so it will end up in SCP->sc_intr_port + later. */ + ss->intr_port = ss->context->sc_intr_port; + } + /* If the sigreturn context was bogus, just ignore it. */ + ss->context = NULL; + } + else if (! machine_get_basic_state (ss->thread, state)) + return NULL; + + if ((ss->actions[signo].sa_flags & SA_ONSTACK) && + !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK))) + { + sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size; + ss->sigaltstack.ss_flags |= SA_ONSTACK; + /* XXX need to set up base of new stack for + per-thread variables, cthreads. */ + } + else + sigsp = (char *) state->basic.uesp; + + /* Push the signal context on the stack. */ + sigsp -= sizeof (*scp); + scp = sigsp; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) scp && + _hurdsig_fault_sigcode <= (long int) (scp + 1)); + /* We got a fault trying to write the stack frame. + We cannot set up the signal handler. + Returning NULL tells our caller, who will nuke us with a SIGILL. */ + return NULL; + } + else + { + int ok; + + /* Set up the sigcontext from the current state of the thread. */ + + scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0; + + /* struct sigcontext is laid out so that starting at sc_regs mimics a + struct parisc_thread_state. */ + memcpy (&scp->sc_parisc_thread_state, + &state->basic, sizeof (state->basic)); + + _hurdsig_end_catch_fault (); + + if (! ok) + return NULL; + } + + /* Modify the thread state to call the trampoline code on the new stack. */ + if (rpc_wait) + { + /* The signalee thread was blocked in a mach_msg_trap system call, + still waiting for a reply. We will have it run the special + trampoline code which retries the message receive before running + the signal handler. + + To do this we change the OPTION argument on its stack to enable only + message reception, since the request message has already been + sent. */ + + struct mach_msg_trap_regargs *args = (void *) &state->basic.r23; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) args && + _hurdsig_fault_sigcode < (long int) (args + 1)); + /* Faulted accessing ARGS. Bomb. */ + return NULL; + } + + assert (args->option & MACH_RCV_MSG); + /* Disable the message-send, since it has already completed. The + calls we retry need only wait to receive the reply message. */ + args->option &= ~MACH_SEND_MSG; + + _hurdsig_end_catch_fault (); + + MACHINE_THREAD_STATE_SET_PC (&state->basic, &&rpc_wait_trampoline); + /* The reply-receiving trampoline code runs initially on the original + user stack. We pass it the signal stack pointer in %r5. */ + state->basic.r5 = (int) sigsp; + /* After doing the message receive, the trampoline code will need to + update the %r28 value to be restored by sigreturn. To simplify + the assembly code, we pass the address of its slot in SCP to the + trampoline code in %r4. */ + state->basic.r4 = (unsigned int) &scp->sc_regs[27]; + /* Set up the arguments for the handler function in callee-saved + registers that we will move to the argument registers after + mach_msg_trap returns. */ + state->basic.r6 = signo; + state->basic.r7 = sigcode; + state->basic.r8 = (unsigned int) scp; + } + else + { + MACHINE_THREAD_STATE_SET_PC (&state->basic, &&trampoline); + state->basic.r20 = (unsigned int) sigsp; + /* Set up the arguments for the handler function. */ + state->basic.r26 = signo; + state->basic.r25 = sigcode; + state->basic.r24 = (unsigned int) scp; + } + + /* We pass the handler function to the trampoline code in %r9. */ + state->basic.r9 = (unsigned int) handler; + /* For convenience, we pass the address of __sigreturn in %r10. */ + state->basic.r10 = (unsigned int) &__sigreturn; + /* The extra copy of SCP for the __sigreturn arg goes in %r8. */ + state->basic.r10 = (unsigned int) scp; + + return scp; + + /* The trampoline code follows. This is not actually executed as part of + this function, it is just convenient to write it that way. */ + + rpc_wait_trampoline: + /* This is the entry point when we have an RPC reply message to receive + before running the handler. The MACH_MSG_SEND bit has already been + cleared in the OPTION argument on our stack. The interrupted user + stack pointer has not been changed, so the system call can find its + arguments; the signal stack pointer is in %ebx. For our convenience, + %ecx points to the sc_eax member of the sigcontext. */ + asm volatile + (/* Retry the interrupted mach_msg system call. */ + "ldil L%0xC0000000,%r1\nble 4(%sr7,%r1)\n" + "ldi -25, %r22\n" /* mach_msg_trap */ + /* When the sigcontext was saved, %r28 was MACH_RCV_INTERRUPTED. But + now the message receive has completed and the original caller of + the RPC (i.e. the code running when the signal arrived) needs to + see the final return value of the message receive in %r28. So + store the new %r28 value into the sc_regs[27] member of the sigcontext + (whose address is in %r4 to make this code simpler). */ + "stw (%r4), %r28\n" + /* Switch to the signal stack. */ + "copy %r5, %r30\n" + /* Copy the handler arguments to the argument registers. */ + "copy %r6, %r26\n" + "copy %r7, %r25\n" + "copy %r8, %r24\n" + ); + + trampoline: + /* Entry point for running the handler normally. The arguments to the + handler function are already in the argument registers. */ + asm volatile + ("bv (%r9); nop" /* Call the handler function. */ + "bv (%r10)\n" /* Call __sigreturn (SCP); never returns. */ + "copy %r8, %r26" /* Set up arg in delay slot. */ + : : "i" (&__sigreturn)); + + /* NOTREACHED */ + return NULL; +} + +/* STATE describes a thread that had intr_port set (meaning it was inside + HURD_EINTR_RPC), after it has been thread_abort'd. It it looks to have + just completed a mach_msg_trap system call that returned + MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right + being waited on. */ +int +_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, + mach_port_t *port) +{ + const unsigned int *volatile pc + = MACHINE_THREAD_STATE_PC (&state->basic); + const mach_port_t *rcv_name + = (void *) state->r30 -32-20; /* VA_ARG4 from <mach/machine/asm.h>. */ + + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode == (long int) pc || + _hurdsig_fault_sigcode == (long int) rcv_name); + else + { + int rcving = (state->basic.r28 == MACH_RCV_INTERRUPTED && + pc == ???unfinished???); + if (rcving) + /* We did just return from a mach_msg_trap system call + doing a message receive that was interrupted. + Examine the parameters to find the receive right. */ + *port = *rcv_name; + _hurdsig_end_catch_fault (); + if (rcving) + return 1; + } + + return 0; +} diff --git a/sysdeps/mach/hurd/i386/exc2signal.c b/sysdeps/mach/hurd/i386/exc2signal.c new file mode 100644 index 0000000000..19f845a49e --- /dev/null +++ b/sysdeps/mach/hurd/i386/exc2signal.c @@ -0,0 +1,165 @@ +/* Translate Mach exception codes into signal numbers. i386 version. +Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <mach/exception.h> + +/* Translate the Mach exception codes, as received in an `exception_raise' RPC, + into a signal number and signal subcode. */ + +void +_hurd_exception2signal (int exception, int code, int subcode, + int *signo, long int *sigcode, int *error) +{ + *error = 0; + + switch (exception) + { + default: + *signo = SIGIOT; + *sigcode = exception; + break; + + case EXC_BAD_ACCESS: + if (code == KERN_PROTECTION_FAILURE) + *signo = SIGSEGV; + else + *signo = SIGBUS; + *sigcode = subcode; + *error = code; + break; + + case EXC_BAD_INSTRUCTION: + *signo = SIGILL; + if (code == EXC_I386_INVOP) + *sigcode = ILL_INVOPR_FAULT; + else if (code == EXC_I386_STKFLT) + *sigcode = ILL_STACK_FAULT; + else + *sigcode = 0; + break; + + case EXC_ARITHMETIC: + switch (code) + { + case EXC_I386_DIV: /* integer divide by zero */ + *signo = SIGFPE; + *sigcode = FPE_INTDIV_FAULT; + break; + + case EXC_I386_INTO: /* integer overflow */ + *signo = SIGFPE; + *sigcode = FPE_INTOVF_TRAP; + break; + + /* These aren't anywhere documented or used in Mach 3.0. */ + case EXC_I386_NOEXT: + case EXC_I386_EXTOVR: + default: + *signo = SIGFPE; + *sigcode = 0; + break; + + case EXC_I386_EXTERR: + /* Subcode is the fp_status word saved by the hardware. + Give an error code corresponding to the first bit set. */ + if (subcode & FPS_IE) + { + *signo = SIGILL; + *sigcode = ILL_FPEOPR_FAULT; + } + else if (subcode & FPS_DE) + { + *signo = SIGFPE; + *sigcode = FPE_FLTDNR_FAULT; + } + else if (subcode & FPS_ZE) + { + *signo = SIGFPE; + *sigcode = FPE_FLTDIV_FAULT; + } + else if (subcode & FPS_OE) + { + *signo = SIGFPE; + *sigcode = FPE_FLTOVF_FAULT; + } + else if (subcode & FPS_UE) + { + *signo = SIGFPE; + *sigcode = FPE_FLTUND_FAULT; + } + else if (subcode & FPS_PE) + { + *signo = SIGFPE; + *sigcode = FPE_FLTINX_FAULT; + } + else + { + *signo = SIGFPE; + *sigcode = 0; + } + break; + + /* These two can only be arithmetic exceptions if we + are in V86 mode, which sounds like emulation to me. + (See Mach 3.0 i386/trap.c.) */ + case EXC_I386_EMERR: + *signo = SIGFPE; + *sigcode = FPE_EMERR_FAULT; + break; + case EXC_I386_BOUND: + *signo = SIGFPE; + *sigcode = FPE_EMBND_FAULT; + break; + } + break; + + case EXC_EMULATION: + /* 3.0 doesn't give this one, why, I don't know. */ + *signo = SIGEMT; + *sigcode = 0; + break; + + case EXC_SOFTWARE: + /* The only time we get this in Mach 3.0 + is for an out of bounds trap. */ + if (code == EXC_I386_BOUND) + { + *signo = SIGFPE; + *sigcode = FPE_SUBRNG_FAULT; + } + else + { + *signo = SIGEMT; + *sigcode = 0; + } + break; + + case EXC_BREAKPOINT: + *signo = SIGTRAP; + if (code == EXC_I386_SGL) + *sigcode = DBG_SINGLE_TRAP; + else if (code == EXC_I386_BPT) + *sigcode = DBG_BRKPNT_FAULT; + else + *sigcode = 0; + break; + } +} diff --git a/sysdeps/mach/hurd/i386/init-fault.c b/sysdeps/mach/hurd/i386/init-fault.c new file mode 100644 index 0000000000..ff22814308 --- /dev/null +++ b/sysdeps/mach/hurd/i386/init-fault.c @@ -0,0 +1,41 @@ +/* Set up a thread_state for proc_handle_exceptions. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <mach/thread_status.h> +#include <string.h> +#include <setjmp.h> + +extern jmp_buf _hurd_sigthread_fault_env; + +static char fault_stack[32]; +static volatile void +faulted (void) +{ + __longjmp (_hurd_sigthread_fault_env, 1); +} + +void +_hurd_initialize_fault_recovery_state (void *state) +{ + struct i386_thread_state *ts = state; + memset (ts, 0, sizeof (*ts)); + ts->uesp = (int) &fault_stack[sizeof (fault_stack)]; + ts->eip = (int) &faulted; +} diff --git a/sysdeps/mach/hurd/i386/longjmp-ctx.c b/sysdeps/mach/hurd/i386/longjmp-ctx.c new file mode 100644 index 0000000000..acfbee602e --- /dev/null +++ b/sysdeps/mach/hurd/i386/longjmp-ctx.c @@ -0,0 +1,35 @@ +/* Perform a `longjmp' on a `struct sigcontext'. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <hurd/signal.h> +#include <string.h> + +void +_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval) +{ + memset (scp, 0, sizeof (*scp)); + scp->sc_ebx = env[0].__bx; + scp->sc_esi = env[0].__si; + scp->sc_edi = env[0].__di; + scp->sc_ebp = (int) env[0].__bp; + scp->sc_uesp = (int) env[0].__sp; + scp->sc_eip = (int) env[0].__pc; + scp->sc_eax = retval == 0 ? 1 : retval; +} diff --git a/sysdeps/mach/hurd/i386/longjmp-ts.c b/sysdeps/mach/hurd/i386/longjmp-ts.c new file mode 100644 index 0000000000..7da9be2a26 --- /dev/null +++ b/sysdeps/mach/hurd/i386/longjmp-ts.c @@ -0,0 +1,39 @@ +/* Perform a `longjmp' on a Mach thread_state. i386 version. +Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <setjmp.h> +#include <mach/thread_status.h> + + +/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ + +void +_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) +{ + struct i386_thread_state *ts = state; + + ts->ebx = env[0].__jmpbuf[0].__bx; + ts->esi = env[0].__jmpbuf[0].__si; + ts->edi = env[0].__jmpbuf[0].__di; + ts->ebp = (int) env[0].__jmpbuf[0].__bp; + ts->uesp = (int) env[0].__jmpbuf[0].__sp; + ts->eip = (int) env[0].__jmpbuf[0].__pc; + ts->eax = val ?: 1; +} diff --git a/sysdeps/mach/hurd/i386/sigcontext.h b/sysdeps/mach/hurd/i386/sigcontext.h new file mode 100644 index 0000000000..b742326bdb --- /dev/null +++ b/sysdeps/mach/hurd/i386/sigcontext.h @@ -0,0 +1,106 @@ +/* Machine-dependent signal context structure for GNU Hurd. i386 version. +Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Signal handlers are actually called: + void handler (int sig, int code, struct sigcontext *scp); */ + +#include <mach/machine/fp_reg.h> + +/* State of this thread when the signal was taken. */ +struct sigcontext + { + /* These first members are machine-independent. */ + + int sc_onstack; /* Nonzero if running on sigstack. */ + __sigset_t sc_mask; /* Blocked signals to restore. */ + + /* MiG reply port this thread is using. */ + unsigned int sc_reply_port; + + /* Port this thread is doing an interruptible RPC on. */ + unsigned int sc_intr_port; + + /* Error code associated with this signal (interpreted as `error_t'). */ + int sc_error; + + /* All following members are machine-dependent. The rest of this + structure is written to be laid out identically to: + { + struct i386_thread_state basic; + struct i386_float_state fpu; + } + trampoline.c knows this, so it must be changed if this changes. */ + +#define sc_i386_thread_state sc_gs /* Beginning of correspondence. */ + /* Segment registers. */ + int sc_gs; + int sc_fs; + int sc_es; + int sc_ds; + + /* "General" registers. These members are in the order that the i386 + `pusha' and `popa' instructions use (`popa' ignores %esp). */ + int sc_edi; + int sc_esi; + int sc_ebp; + int sc_esp; /* Not used; sc_uesp is used instead. */ + int sc_ebx; + int sc_edx; + int sc_ecx; + int sc_eax; + + int sc_eip; /* Instruction pointer. */ + int sc_cs; /* Code segment register. */ + + int sc_efl; /* Processor flags. */ + + int sc_uesp; /* This stack pointer is used. */ + int sc_ss; /* Stack segment register. */ + + /* Following mimics struct i386_float_state. Structures and symbolic + values can be found in <mach/i386/fp_reg.h>. */ +#define sc_i386_float_state sc_fpkind + int sc_fpkind; /* FP_NO, FP_387, etc. */ + int sc_fpused; /* If zero, ignore rest of float state. */ + struct i386_fp_save sc_fpsave; + struct i386_fp_regs sc_fpregs; + int sc_fpexcsr; /* FPSR including exception bits. */ + }; + + +/* Codes for SIGFPE. */ +#define FPE_INTOVF_TRAP 0x1 /* integer overflow */ +#define FPE_INTDIV_FAULT 0x2 /* integer divide by zero */ +#define FPE_FLTOVF_FAULT 0x3 /* floating overflow */ +#define FPE_FLTDIV_FAULT 0x4 /* floating divide by zero */ +#define FPE_FLTUND_FAULT 0x5 /* floating underflow */ +#define FPE_SUBRNG_FAULT 0x7 /* BOUNDS instruction failed */ +#define FPE_FLTDNR_FAULT 0x8 /* denormalized operand */ +#define FPE_FLTINX_FAULT 0x9 /* floating loss of precision */ +#define FPE_EMERR_FAULT 0xa /* mysterious emulation error 33 */ +#define FPE_EMBND_FAULT 0xb /* emulation BOUNDS instruction failed */ + +/* Codes for SIGILL. */ +#define ILL_INVOPR_FAULT 0x1 /* invalid operation */ +#define ILL_STACK_FAULT 0x2 /* fault on microkernel stack access */ +#define ILL_FPEOPR_FAULT 0x3 /* invalid floating operation */ + +/* Codes for SIGTRAP. */ +#define DBG_SINGLE_TRAP 0x1 /* single step */ +#define DBG_BRKPNT_FAULT 0x2 /* breakpoint instruction */ diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c new file mode 100644 index 0000000000..df8960669f --- /dev/null +++ b/sysdeps/mach/hurd/i386/sigreturn.c @@ -0,0 +1,126 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +register int *sp asm ("%esp"); + +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/threadvar.h> +#include <hurd/msg.h> +#include <stdlib.h> + +int +__sigreturn (struct sigcontext *scp) +{ + struct hurd_sigstate *ss; + mach_port_t *reply_port; + + if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) + { + errno = EINVAL; + return -1; + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + + /* Restore the set of blocked signals, and the intr_port slot. */ + ss->blocked = scp->sc_mask; + ss->intr_port = scp->sc_intr_port; + + /* Check for pending signals that were blocked by the old set. */ + if (ss->pending & ~ss->blocked) + { + /* There are pending signals that just became unblocked. Wake up the + signal thread to deliver them. But first, squirrel away SCP where + the signal thread will notice it if it runs another handler, and + arrange to have us called over again in the new reality. */ + ss->context = scp; + /* Clear the intr_port slot, since we are not in fact doing + an interruptible RPC right now. If SS->intr_port is not null, + the SCP context is doing an interruptible RPC, but the signal + thread will examine us while we are blocked in the sig_post RPC. */ + ss->intr_port = MACH_PORT_NULL; + __spin_unlock (&ss->lock); + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + /* If a pending signal was handled, sig_post never returned. */ + __spin_lock (&ss->lock); + } + + if (scp->sc_onstack) + { + ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */ + /* XXX cannot unlock until off sigstack */ + abort (); + } + else + __spin_unlock (&ss->lock); + + /* Destroy the MiG reply port used by the signal handler, and restore the + reply port in use by the thread when interrupted. */ + reply_port = + (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); + if (*reply_port) + __mach_port_destroy (__mach_task_self (), *reply_port); + *reply_port = scp->sc_reply_port; + + if (scp->sc_fpused) + { + /* XXX should restore FPU state here XXX roland needs 387 manual */ + /* abort (); */ + } + + { + /* There are convenient instructions to pop state off the stack, so we + copy the registers onto the user's stack, switch there, pop and + return. */ + + int *usp = (int *) scp->sc_uesp; + + *--usp = scp->sc_eip; + *--usp = scp->sc_efl; + memcpy (usp -= 12, &scp->sc_i386_thread_state, 12 * sizeof (int)); + + sp = usp; + +#define A(line) asm volatile (#line) + /* The members in the sigcontext are arranged in this order + so we can pop them easily. */ + + /* Pop the segment registers (except %cs and %ss, done last). */ + A (popl %gs); + A (popl %fs); + A (popl %es); + A (popl %ds); + /* Pop the general registers. */ + A (popa); + /* Pop the processor flags. */ + A (popf); + /* Return to the saved PC. */ + A (ret); + + /* Firewall. */ + A (hlt); +#undef A + } + + /* NOTREACHED */ + return -1; +} + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c new file mode 100644 index 0000000000..eabf940b44 --- /dev/null +++ b/sysdeps/mach/hurd/i386/trampoline.c @@ -0,0 +1,271 @@ +/* Set thread_state for sighandler, and sigcontext to recover. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include "thread_state.h" +#include <assert.h> +#include <errno.h> +#include "hurdfault.h" + + +struct mach_msg_trap_args + { + void *retaddr; /* Address mach_msg_trap will return to. */ + /* This is the order of arguments to mach_msg_trap. */ + mach_msg_header_t *msg; + mach_msg_option_t option; + mach_msg_size_t send_size; + mach_msg_size_t rcv_size; + mach_port_t rcv_name; + mach_msg_timeout_t timeout; + mach_port_t notify; + }; + +struct sigcontext * +_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, + int signo, long int sigcode, + volatile int rpc_wait, + struct machine_thread_all_state *state) +{ + __label__ trampoline, rpc_wait_trampoline; + void *volatile sigsp; + struct sigcontext *scp; + struct + { + int signo; + long int sigcode; + struct sigcontext *scp; /* Points to ctx, below. */ + struct sigcontext *return_scp; /* Same; arg to sigreturn. */ + struct sigcontext ctx; + } *stackframe; + + if (ss->context) + { + /* We have a previous sigcontext that sigreturn was about + to restore when another signal arrived. We will just base + our setup on that. */ + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode >= (long int) ss->context && + _hurdsig_fault_sigcode < (long int) (ss->context + 1)); + else + { + memcpy (&state->basic, &ss->context->sc_i386_thread_state, + sizeof (state->basic)); + memcpy (&state->fpu, &ss->context->sc_i386_float_state, + sizeof (state->fpu)); + state->set = (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE); + assert (! rpc_wait); + /* The intr_port slot was cleared before sigreturn sent us the + sig_post that made us notice this pending signal, so + _hurd_internal_post_signal wouldn't do interrupt_operation. + After we return, our caller will set SCP->sc_intr_port (in the + new context) from SS->intr_port and clear SS->intr_port. Now + that we are restoring this old context recorded by sigreturn, + we want to restore its intr_port too; so store it in + SS->intr_port now, so it will end up in SCP->sc_intr_port + later. */ + ss->intr_port = ss->context->sc_intr_port; + } + /* If the sigreturn context was bogus, just ignore it. */ + ss->context = NULL; + } + else if (! machine_get_basic_state (ss->thread, state)) + return NULL; + + if ((ss->actions[signo].sa_flags & SA_ONSTACK) && + !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK))) + { + sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size; + ss->sigaltstack.ss_flags |= SA_ONSTACK; + /* XXX need to set up base of new stack for + per-thread variables, cthreads. */ + } + else + sigsp = (char *) state->basic.uesp; + + /* Push the arguments to call `trampoline' on the stack. */ + sigsp -= sizeof (*stackframe); + stackframe = sigsp; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) stackframe && + _hurdsig_fault_sigcode <= (long int) (stackframe + 1)); + /* We got a fault trying to write the stack frame. + We cannot set up the signal handler. + Returning NULL tells our caller, who will nuke us with a SIGILL. */ + return NULL; + } + else + { + int ok; + + /* Set up the arguments for the signal handler. */ + stackframe->signo = signo; + stackframe->sigcode = sigcode; + stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx; + + /* Set up the sigcontext from the current state of the thread. */ + + scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0; + + /* struct sigcontext is laid out so that starting at sc_gs mimics a + struct i386_thread_state. */ + memcpy (&scp->sc_i386_thread_state, + &state->basic, sizeof (state->basic)); + + /* struct sigcontext is laid out so that starting at sc_fpkind mimics + a struct i386_float_state. */ + ok = machine_get_state (ss->thread, state, i386_FLOAT_STATE, + &state->fpu, &scp->sc_i386_float_state, + sizeof (state->fpu)); + + _hurdsig_end_catch_fault (); + + if (! ok) + return NULL; + } + + /* Modify the thread state to call the trampoline code on the new stack. */ + if (rpc_wait) + { + /* The signalee thread was blocked in a mach_msg_trap system call, + still waiting for a reply. We will have it run the special + trampoline code which retries the message receive before running + the signal handler. + + To do this we change the OPTION argument on its stack to enable only + message reception, since the request message has already been + sent. */ + + struct mach_msg_trap_args *args = (void *) state->basic.uesp; + + if (_hurdsig_catch_fault (SIGSEGV)) + { + assert (_hurdsig_fault_sigcode >= (long int) args && + _hurdsig_fault_sigcode < (long int) (args + 1)); + /* Faulted accessing ARGS. Bomb. */ + return NULL; + } + + assert (args->option & MACH_RCV_MSG); + /* Disable the message-send, since it has already completed. The + calls we retry need only wait to receive the reply message. */ + args->option &= ~MACH_SEND_MSG; + + _hurdsig_end_catch_fault (); + + state->basic.eip = (int) &&rpc_wait_trampoline; + /* The reply-receiving trampoline code runs initially on the original + user stack. We pass it the signal stack pointer in %ebx. */ + state->basic.ebx = (int) sigsp; + /* After doing the message receive, the trampoline code will need to + update the %eax value to be restored by sigreturn. To simplify + the assembly code, we pass the address of its slot in SCP to the + trampoline code in %ecx. */ + state->basic.ecx = (int) &scp->sc_eax; + } + else + { + state->basic.eip = (int) &&trampoline; + state->basic.uesp = (int) sigsp; + } + /* We pass the handler function to the trampoline code in %edx. */ + state->basic.edx = (int) handler; + + return scp; + + /* The trampoline code follows. This is not actually executed as part of + this function, it is just convenient to write it that way. */ + + rpc_wait_trampoline: + /* This is the entry point when we have an RPC reply message to receive + before running the handler. The MACH_MSG_SEND bit has already been + cleared in the OPTION argument on our stack. The interrupted user + stack pointer has not been changed, so the system call can find its + arguments; the signal stack pointer is in %ebx. For our convenience, + %ecx points to the sc_eax member of the sigcontext. */ + asm volatile + (/* Retry the interrupted mach_msg system call. */ + "movl $-25, %eax\n" /* mach_msg_trap */ + "lcall $7, $0\n" + /* When the sigcontext was saved, %eax was MACH_RCV_INTERRUPTED. But + now the message receive has completed and the original caller of + the RPC (i.e. the code running when the signal arrived) needs to + see the final return value of the message receive in %eax. So + store the new %eax value into the sc_eax member of the sigcontext + (whose address is in %ecx to make this code simpler). */ + "movl %eax, (%ecx)\n" + /* Switch to the signal stack. */ + "movl %ebx, %esp\n"); + + trampoline: + /* Entry point for running the handler normally. The arguments to the + handler function are already on the top of the stack: + + 0(%esp) SIGNO + 4(%esp) SIGCODE + 8(%esp) SCP + */ + asm volatile + ("call %*%%edx\n" /* Call the handler function. */ + "addl $12, %%esp\n" /* Pop its args. */ + "call %P0\n" /* Call __sigreturn (SCP); never returns. */ + "hlt" /* Just in case. */ + : : "i" (&__sigreturn)); + + /* NOTREACHED */ + return NULL; +} + +/* STATE describes a thread that had intr_port set (meaning it was inside + HURD_EINTR_RPC), after it has been thread_abort'd. It it looks to have + just completed a mach_msg_trap system call that returned + MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right + being waited on. */ +int +_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, + mach_port_t *port) +{ + static const unsigned char syscall[] = { 0x9a, 0, 0, 0, 0, 7, 0 }; + const unsigned char *volatile pc + = (void *) state->basic.eip - sizeof syscall; + + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode >= (long int) pc && + _hurdsig_fault_sigcode < (long int) pc + sizeof syscall); + else + { + int rcving = (state->basic.eax == MACH_RCV_INTERRUPTED && + !memcmp (pc, &syscall, sizeof syscall)); + _hurdsig_end_catch_fault (); + if (rcving) + { + /* We did just return from a mach_msg_trap system call + doing a message receive that was interrupted. + Examine the parameters to find the receive right. */ + struct mach_msg_trap_args *args = (void *) state->basic.uesp; + + *port = args->rcv_name; + return 1; + } + } + + return 0; +} diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c new file mode 100644 index 0000000000..4aad0bb377 --- /dev/null +++ b/sysdeps/mach/hurd/ioctl.c @@ -0,0 +1,242 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/signal.h> +#include <stdarg.h> +#include <mach/notify.h> +#include <assert.h> +#include <string.h> +#include <hurd/ioctl.h> + + +#define typesize(type) (1 << (type)) + + +/* Perform the I/O control operation specified by REQUEST on FD. + The actual type and use of ARG and the return value depend on REQUEST. */ +int +DEFUN(__ioctl, (fd, request), + int fd AND unsigned long int request DOTS) +{ + /* Map individual type fields to Mach IPC types. */ + static const int mach_types[] = + { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32, + -1 }; +#define io2mach_type(count, type) \ + ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 }) + + /* Extract the type information encoded in the request. */ + unsigned int type = _IOC_TYPE (request); + + /* Message buffer. */ + struct + { + mig_reply_header_t header; + char data[3 * sizeof (mach_msg_type_t) + + _IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) + + _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) + + _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))]; + } msg; + mach_msg_header_t *const m = &msg.header.Head; + mach_msg_type_t *t = &msg.header.RetCodeType; + mach_msg_id_t msgid; + unsigned int reply_size; + + void *arg; + + error_t err; + + /* Send the RPC already packed up in MSG to IOPORT + and decode the return value. */ + error_t send_rpc (io_t ioport) + { + error_t err; + + m->msgh_size = (char *) t - (char *) &msg; + m->msgh_remote_port = ioport; + m->msgh_local_port = __mig_get_reply_port (); + m->msgh_seqno = 0; + m->msgh_id = msgid; + m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, + MACH_MSG_TYPE_MAKE_SEND_ONCE); + err = HURD_EINTR_RPC (ioport, __mach_msg (m, MACH_SEND_MSG|MACH_RCV_MSG, + m->msgh_size, sizeof (msg), + m->msgh_local_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL)); + switch (err) + { + case MACH_MSG_SUCCESS: + break; + case MACH_SEND_INVALID_REPLY: + case MACH_RCV_INVALID_NAME: + __mig_dealloc_reply_port (m->msgh_local_port); + default: + return err; + } + + if ((m->msgh_bits & MACH_MSGH_BITS_COMPLEX)) + { + /* Allow no ports or VM. */ + __mach_msg_destroy (m); + /* Want to return a different error below for a different msgid. */ + if (m->msgh_id == msgid + 100) + return MIG_TYPE_ERROR; + } + + if (m->msgh_id != msgid + 100) + return (m->msgh_id == MACH_NOTIFY_SEND_ONCE ? + MIG_SERVER_DIED : MIG_REPLY_MISMATCH); + + if (m->msgh_size != reply_size && + m->msgh_size != sizeof (mig_reply_header_t)) + return MIG_TYPE_ERROR; + + if (*(int *) &msg.header.RetCodeType != + ((union { mach_msg_type_t t; int i; }) + { t: io2mach_type (1, _IOTS (sizeof msg.header.RetCode)) }).i) + return MIG_TYPE_ERROR; + return msg.header.RetCode; + } + + va_list ap; + + va_start (ap, request); + arg = va_arg (ap, void *); + va_end (ap); + + { + /* Check for a registered handler for REQUEST. */ + ioctl_handler_t handler = _hurd_lookup_ioctl_handler (request); + if (handler) + /* This handler groks REQUEST. Se lo puntamonos. */ + return (*handler) (fd, request, arg); + } + + /* Compute the Mach message ID for the RPC from the group and command + parts of the ioctl request. */ + msgid = 100000 + ((_IOC_GROUP (request) - 'f') * 4000); /* Base subsystem */ + /* Because of MiG's poorly chosen algorithm of adding 100 to a request + msgid to produce the reply msgid, we cannot just add the command part + of the ioctl request to the subsystem base msgid. For ioctl requests + past 99, we must skip blocks of 100 msgids to allow for the reply + msgids corresponding to the earlier requests. */ + if (_IOC_COMMAND (request) >= 100) + msgid += 100; + if (_IOC_COMMAND (request) >= 200) + msgid += 100; + msgid += _IOC_COMMAND (request); + + if (_IOC_INOUT (request) & IOC_IN) + { + /* Pack an argument into the message buffer. */ + void in (unsigned int count, enum __ioctl_datum type) + { + if (count > 0) + { + void *p = &t[1]; + const size_t len = count * typesize ((unsigned int) type); + *t = io2mach_type (count, type); + memcpy (p, arg, len); + arg += len; + p += len; + p = (void *) (((unsigned long int) p + sizeof (*t) - 1) + & ~(sizeof (*t) - 1)); + t = p; + } + } + + /* Pack the argument data. */ + in (_IOT_COUNT0 (type), _IOT_TYPE0 (type)); + in (_IOT_COUNT1 (type), _IOT_TYPE1 (type)); + in (_IOT_COUNT2 (type), _IOT_TYPE2 (type)); + } + + /* Compute the expected size of the reply. There is a standard header + consisting of the message header and the reply code. Then, for out + and in/out ioctls, there come the data with their type headers. */ + reply_size = sizeof (mig_reply_header_t); + + if (_IOC_INOUT (request) & IOC_OUT) + { + inline void figure_reply (unsigned int count, enum __ioctl_datum type) + { + if (count > 0) + { + /* Add the size of the type and data. */ + reply_size += sizeof (mach_msg_type_t) + typesize (type) * count; + /* Align it to word size. */ + reply_size += sizeof (mach_msg_type_t) - 1; + reply_size &= ~(sizeof (mach_msg_type_t) - 1); + } + } + figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type)); + figure_reply (_IOT_COUNT1 (type), _IOT_TYPE1 (type)); + figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type)); + } + + err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc)); + + t = (mach_msg_type_t *) msg.data; + switch (err) + { + /* Unpack the message buffer into the argument location. */ + int out (unsigned int count, unsigned int type, + void *store, void **update) + { + if (count > 0) + { + const size_t len = count * typesize (type); + union { mach_msg_type_t t; int i; } ipctype; + ipctype.t = io2mach_type (count, type); + if (*(int *) t != ipctype.i) + return 1; + ++t; + memcpy (store, t, len); + if (update != NULL) + *update += len; + t = (void *) (((unsigned long int) t + len + sizeof (*t) - 1) + & ~(sizeof (*t) - 1)); + } + return 0; + } + + case 0: + if (m->msgh_size != reply_size || + ((_IOC_INOUT (request) & IOC_OUT) && + (out (_IOT_COUNT0 (type), _IOT_TYPE0 (type), arg, &arg) || + out (_IOT_COUNT1 (type), _IOT_TYPE1 (type), arg, &arg) || + out (_IOT_COUNT2 (type), _IOT_TYPE2 (type), arg, &arg)))) + return __hurd_fail (MIG_TYPE_ERROR); + return 0; + + case MIG_BAD_ID: + case EOPNOTSUPP: + /* The server didn't understand the RPC. */ + err = ENOTTY; + default: + return __hurd_fail (err); + } +} + +weak_alias (__ioctl, ioctl) diff --git a/sysdeps/mach/hurd/ioctls.h b/sysdeps/mach/hurd/ioctls.h new file mode 100644 index 0000000000..af44873cb7 --- /dev/null +++ b/sysdeps/mach/hurd/ioctls.h @@ -0,0 +1,323 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _IOCTLS_H + +#define _IOCTLS_H 1 + +/* Hurd ioctl request are made up of several fields: + bits 31-30: inout direction (enum __ioctl_dir) + bits 29-12: type encoding as follows; zero count indicates omitted datum + 29-28: datum #0 type (enum __ioctl_datum) + 27-26: datum #1 type (enum __ioctl_datum) + 25-24: datum #2 type (enum __ioctl_datum) + 23-19: datum #0 count [0..31] + 18-14: datum #1 count [0..31] + 13-12: datum #2 count [0..3] + bits 11- 8: group (letter - 'f': ['f'..'v']) + bits 7- 0: command [0..127] + + The following macros construct and dissect these fields. */ + +enum __ioctl_dir + { + IOC_VOID = 0, /* No parameters. */ + IOC_OUT = 1, /* Data is written into the user's buffer. */ + IOC_IN = 2, /* Data is read from the user's buffer. */ + IOC_INOUT = (IOC_IN|IOC_OUT) + }; + +enum __ioctl_datum { IOC_8, IOC_16, IOC_32 }; + +/* Construct an ioctl from constructed type plus other fields. */ +#define _IOC(inout, group, num, type) \ + ((num) | ((((group) - 'f') | ((type) | (inout) << 19) << 4) << 7)) + +/* Dissect an ioctl into its component fields. */ +#define _IOC_INOUT(request) (((unsigned int) (request) >> 30) & IOC_INOUT) +#define _IOC_GROUP(request) ('f' + (((unsigned int) (request) >> 7) & 15)) +#define _IOC_COMMAND(request) ((unsigned int) (request) & 0x7f) +#define _IOC_TYPE(request) (((unsigned int) (request) >> 11) & 0x7ffff) + +/* Construct a type information field from + the broken-out type and count fields. */ +#define _IOT(t0, c0, t1, c1, t2, c2) \ + ((c2) | (((c1) | ((c0) | ((t2) | ((t1) | (t0) << 2) << 2) << 5) << 5) << 3)) + +/* Dissect a type information field into the type and count fields. */ +#define _IOT_TYPE0(type) (((unsigned int) (type) >> 17) & 3) +#define _IOT_TYPE1(type) (((unsigned int) (type) >> 15) & 3) +#define _IOT_TYPE2(type) (((unsigned int) (type) >> 13) & 3) +#define _IOT_COUNT0(type) (((unsigned int) (type) >> 8) & 0x1f) +#define _IOT_COUNT1(type) (((unsigned int) (type) >> 3) & 0x1f) +#define _IOT_COUNT2(type) (((unsigned int) (type) >> 0) & 3) + +/* Construct an ioctl from all the broken-out fields. */ +#define _IOCT(inout, group, num, t0, c0, t1, c1, t2, c2) \ + _IOC ((inout), (group), (num), _IOT ((t0), (c0), (t1), (c1), (t2), (c2))) + +/* Standard flavors of ioctls. + _IOT_foobar is defined either in this file, + or where struct foobar is defined. */ +#define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0) +#define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOT_##t) +#define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOT_##t) +#define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOT_##t) + +/* Construct an individual type field for TYPE. */ +#define _IOTS(type) (sizeof (type) >> 1) + +/* Construct a type information field for + a single argument of the scalar TYPE. */ +#define _IOT_SIMPLE(type) _IOT (_IOTS (type), 1, 0, 0, 0, 0) + +/* Basic C types. */ +#define _IOT_int _IOT_SIMPLE (int) +#define _IOT_char _IOT_SIMPLE (char) +#define _IOT_short _IOT_SIMPLE (short) + + +/* ioctls verbatim from 4.4 <sys/ioctl.h>, with `struct' keywords removed. */ + +#define TIOCMODG _IOR('t', 3, int) /* get modem control state */ +#define TIOCMODS _IOW('t', 4, int) /* set modem control state */ +#define TIOCM_LE 0001 /* line enable */ +#define TIOCM_DTR 0002 /* data terminal ready */ +#define TIOCM_RTS 0004 /* request to send */ +#define TIOCM_ST 0010 /* secondary transmit */ +#define TIOCM_SR 0020 /* secondary receive */ +#define TIOCM_CTS 0040 /* clear to send */ +#define TIOCM_CAR 0100 /* carrier detect */ +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RNG 0200 /* ring */ +#define TIOCM_RI TIOCM_RNG +#define TIOCM_DSR 0400 /* data set ready */ + /* 8-10 compat */ +#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */ +#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */ + /* 15 unused */ +#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */ + /* 17-18 compat */ +#define TIOCGETA _IOR('t', 19, termios) /* get termios struct */ +#define TIOCSETA _IOW('t', 20, termios) /* set termios struct */ +#define TIOCSETAW _IOW('t', 21, termios) /* drain output, set */ +#define TIOCSETAF _IOW('t', 22, termios) /* drn out, fls in, set */ +#define TIOCGETD _IOR('t', 26, int) /* get line discipline */ +#define TIOCSETD _IOW('t', 27, int) /* set line discipline */ + /* 127-124 compat */ +#define TIOCSBRK _IO('t', 123) /* set break bit */ +#define TIOCCBRK _IO('t', 122) /* clear break bit */ +#define TIOCSDTR _IO('t', 121) /* set data terminal ready */ +#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */ +#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */ +#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */ + /* 117-116 compat */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ +#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */ +#define TIOCNOTTY _IO('t', 113) /* void tty association */ +#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */ +#define TIOCPKT_DATA 0x00 /* data packet */ +#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define TIOCPKT_STOP 0x04 /* stop output */ +#define TIOCPKT_START 0x08 /* start output */ +#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ +#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */ +#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */ +#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ +#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */ +#define TIOCGWINSZ _IOR('t', 104, winsize) /* get window size */ +#define TIOCSWINSZ _IOW('t', 103, winsize) /* set window size */ +#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */ +#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */ +#define TIOCCONS _IOW('t', 98, int) /* become virtual console */ +#define TIOCSCTTY _IO('t', 97) /* become controlling tty */ +#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */ +#define TIOCSIG _IO('t', 95) /* pty: generate signal */ +#define TIOCDRAIN _IO('t', 94) /* wait till output drained */ + +#define TTYDISC 0 /* termios tty line discipline */ +#define TABLDISC 3 /* tablet discipline */ +#define SLIPDISC 4 /* serial IP discipline */ + + +#define FIOCLEX _IO('f', 1) /* set close on exec on fd */ +#define FIONCLEX _IO('f', 2) /* remove close on exec */ +#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */ +#define FIOSETOWN _IOW('f', 124, int) /* set owner */ +#define FIOGETOWN _IOR('f', 123, int) /* get owner */ + +/* socket i/o controls */ +#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */ +#define SIOCSPGRP _IOW('s', 8, int) /* set process group */ +#define SIOCGPGRP _IOR('s', 9, int) /* get process group */ + +#define SIOCADDRT _IOW('r', 10, ortentry) /* add route */ +#define SIOCDELRT _IOW('r', 11, ortentry) /* delete route */ + +#define SIOCSIFADDR _IOW('i', 12, ifreq) /* set ifnet address */ +#define OSIOCGIFADDR _IOWR('i',13, ifreq) /* get ifnet address */ +#define SIOCGIFADDR _IOWR('i',33, ifreq) /* get ifnet address */ +#define SIOCSIFDSTADDR _IOW('i', 14, ifreq) /* set p-p address */ +#define OSIOCGIFDSTADDR _IOWR('i',15, ifreq) /* get p-p address */ +#define SIOCGIFDSTADDR _IOWR('i',34, ifreq) /* get p-p address */ +#define SIOCSIFFLAGS _IOW('i', 16, ifreq) /* set ifnet flags */ +#define SIOCGIFFLAGS _IOWR('i',17, ifreq) /* get ifnet flags */ +#define OSIOCGIFBRDADDR _IOWR('i',18, ifreq) /* get broadcast addr */ +#define SIOCGIFBRDADDR _IOWR('i',35, ifreq) /* get broadcast addr */ +#define SIOCSIFBRDADDR _IOW('i',19, ifreq) /* set broadcast addr */ +#define OSIOCGIFCONF _IOWR('i',20, ifconf) /* get ifnet list */ +#define SIOCGIFCONF _IOWR('i',36, ifconf) /* get ifnet list */ +#define OSIOCGIFNETMASK _IOWR('i',21, ifreq) /* get net addr mask */ +#define SIOCGIFNETMASK _IOWR('i',37, ifreq) /* get net addr mask */ +#define SIOCSIFNETMASK _IOW('i',22, ifreq) /* set net addr mask */ +#define SIOCGIFMETRIC _IOWR('i',23, ifreq) /* get IF metric */ +#define SIOCSIFMETRIC _IOW('i',24, ifreq) /* set IF metric */ +#define SIOCDIFADDR _IOW('i',25, ifreq) /* delete IF addr */ +#define SIOCAIFADDR _IOW('i',26, ifaliasreq) /* add/chg IF alias */ + +#define SIOCSARP _IOW('i', 30, arpreq) /* set arp entry */ +#define OSIOCGARP _IOWR('i',31, arpreq) /* get arp entry */ +#define SIOCGARP _IOWR('i',38, arpreq) /* get arp entry */ +#define SIOCDARP _IOW('i', 32, arpreq) /* delete arp entry */ + + +/* Compatibility with 4.3 BSD terminal driver. + From 4.4 <sys/ioctl_compat.h>. */ + +#ifdef USE_OLD_TTY +# undef TIOCGETD +# define TIOCGETD _IOR('t', 0, int) /* get line discipline */ +# undef TIOCSETD +# define TIOCSETD _IOW('t', 1, int) /* set line discipline */ +#else +# define OTIOCGETD _IOR('t', 0, int) /* get line discipline */ +# define OTIOCSETD _IOW('t', 1, int) /* set line discipline */ +#endif +#define TIOCHPCL _IO('t', 2) /* hang up on last close */ +#define TIOCGETP _IOR('t', 8,sgttyb)/* get parameters -- gtty */ +#define TIOCSETP _IOW('t', 9,sgttyb)/* set parameters -- stty */ +#define TIOCSETN _IOW('t',10,sgttyb)/* as above, but no flushtty*/ +#define TIOCSETC _IOW('t',17,tchars)/* set special characters */ +#define TIOCGETC _IOR('t',18,tchars)/* get special characters */ +#define TANDEM 0x00000001 /* send stopc on out q full */ +#define CBREAK 0x00000002 /* half-cooked mode */ +#define LCASE 0x00000004 /* simulate lower case */ +#define ECHO 0x00000008 /* echo input */ +#define CRMOD 0x00000010 /* map \r to \r\n on output */ +#define RAW 0x00000020 /* no i/o processing */ +#define ODDP 0x00000040 /* get/send odd parity */ +#define EVENP 0x00000080 /* get/send even parity */ +#define ANYP 0x000000c0 /* get any parity/send none */ +#define NLDELAY 0x00000300 /* \n delay */ +#define NL0 0x00000000 +#define NL1 0x00000100 /* tty 37 */ +#define NL2 0x00000200 /* vt05 */ +#define NL3 0x00000300 +#define TBDELAY 0x00000c00 /* horizontal tab delay */ +#define TAB0 0x00000000 +#define TAB1 0x00000400 /* tty 37 */ +#define TAB2 0x00000800 +#define XTABS 0x00000c00 /* expand tabs on output */ +#define CRDELAY 0x00003000 /* \r delay */ +#define CR0 0x00000000 +#define CR1 0x00001000 /* tn 300 */ +#define CR2 0x00002000 /* tty 37 */ +#define CR3 0x00003000 /* concept 100 */ +#define VTDELAY 0x00004000 /* vertical tab delay */ +#define FF0 0x00000000 +#define FF1 0x00004000 /* tty 37 */ +#define BSDELAY 0x00008000 /* \b delay */ +#define BS0 0x00000000 +#define BS1 0x00008000 +#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY) +#define CRTBS 0x00010000 /* do backspacing for crt */ +#define PRTERA 0x00020000 /* \ ... / erase */ +#define CRTERA 0x00040000 /* " \b " to wipe out char */ +#define TILDE 0x00080000 /* hazeltine tilde kludge */ +#define MDMBUF 0x00100000 /*start/stop output on carrier*/ +#define LITOUT 0x00200000 /* literal output */ +#define TOSTOP 0x00400000 /*SIGSTOP on background output*/ +#define FLUSHO 0x00800000 /* flush output to terminal */ +#define NOHANG 0x01000000 /* (no-op) was no SIGHUP on carrier drop */ +#define L001000 0x02000000 +#define CRTKIL 0x04000000 /* kill line with " \b " */ +#define PASS8 0x08000000 +#define CTLECH 0x10000000 /* echo control chars as ^X */ +#define PENDIN 0x20000000 /* tp->t_rawq needs reread */ +#define DECCTQ 0x40000000 /* only ^Q starts after ^S */ +#define NOFLSH 0x80000000 /* no output flush on signal */ +#define TIOCLBIS _IOW('t', 127, int) /* bis local mode bits */ +#define TIOCLBIC _IOW('t', 126, int) /* bic local mode bits */ +#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */ +#define TIOCLGET _IOR('t', 124, int) /* get local modes */ +#define LCRTBS (CRTBS>>16) +#define LPRTERA (PRTERA>>16) +#define LCRTERA (CRTERA>>16) +#define LTILDE (TILDE>>16) +#define LMDMBUF (MDMBUF>>16) +#define LLITOUT (LITOUT>>16) +#define LTOSTOP (TOSTOP>>16) +#define LFLUSHO (FLUSHO>>16) +#define LNOHANG (NOHANG>>16) +#define LCRTKIL (CRTKIL>>16) +#define LPASS8 (PASS8>>16) +#define LCTLECH (CTLECH>>16) +#define LPENDIN (PENDIN>>16) +#define LDECCTQ (DECCTQ>>16) +#define LNOFLSH (NOFLSH>>16) +#define TIOCSLTC _IOW('t',117,ltchars)/* set local special chars*/ +#define TIOCGLTC _IOR('t',116,ltchars)/* get local special chars*/ +#define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */ +#define OTTYDISC 0 +#define NETLDISC 1 +#define NTTYDISC 2 + +/* From 4.4 <sys/ttydev.h>. */ +#ifdef USE_OLD_TTY +#define B0 0 +#define B50 1 +#define B75 2 +#define B110 3 +#define B134 4 +#define B150 5 +#define B200 6 +#define B300 7 +#define B600 8 +#define B1200 9 +#define B1800 10 +#define B2400 11 +#define B4800 12 +#define B9600 13 +#define EXTA 14 +#define EXTB 15 +#endif /* USE_OLD_TTY */ + + +#endif /* ioctls.h */ diff --git a/sysdeps/mach/hurd/isatty.c b/sysdeps/mach/hurd/isatty.c new file mode 100644 index 0000000000..e04793a6a2 --- /dev/null +++ b/sysdeps/mach/hurd/isatty.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd/fd.h> +#include <hurd/term.h> + +/* Return 1 if FD is a terminal, 0 if not. */ +int +DEFUN(__isatty, (fd), int fd) +{ + error_t err; + mach_port_t id; + + err = HURD_DPORT_USE (fd, __term_getctty (port, &id)); + if (! err) + __mach_port_deallocate (__mach_task_self (), id); + + return !err; +} + +weak_alias (__isatty, isatty) diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c new file mode 100644 index 0000000000..0d4af62127 --- /dev/null +++ b/sysdeps/mach/hurd/kill.c @@ -0,0 +1,106 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <sys/types.h> +#include <signal.h> +#include <hurd.h> +#include <hurd/port.h> +#include <hurd/signal.h> +#include <hurd/msg.h> + +/* Send signal SIG to process number PID. If PID is zero, + send SIG to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. */ +int +__kill (pid_t pid, int sig) +{ + int delivered = 0; /* Set when we deliver any signal. */ + error_t err; + mach_port_t proc; + struct hurd_userlink ulink; + + inline void kill_pid (pid_t pid) /* Kill one PID. */ + { + /* SIGKILL is not delivered as a normal signal. + Sending SIGKILL to a process means to terminate its task. */ + if (sig == SIGKILL) + /* Fetch the process's task port and terminate the task. We + loop in case the process execs and changes its task port. + If the old task port dies after we fetch it but before we + send the RPC, we get MACH_SEND_INVALID_DEST; if it dies + after we send the RPC request but before it is serviced, we + get MIG_SERVER_DIED. */ + do + { + task_t refport; + err = __proc_pid2task (proc, pid, &refport); + if (!err) + { + err = __task_terminate (refport); + __mach_port_deallocate (__mach_task_self (), refport); + } + } while (err == MACH_SEND_INVALID_DEST || + err == MIG_SERVER_DIED); + else + err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport), + __proc_pid2task (proc, pid, &refport) ? + __proc_getsidport (proc, &refport) : 0, 1, + /* If no msgport, we cannot send a signal. */ + msgport == MACH_PORT_NULL ? EPERM : + __msg_sig_post (msgport, sig, refport)); + if (! err) + delivered = 1; + } + + proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); + + if (pid <= 0) + { + /* Send SIG to each process in pgrp (- PID). */ + pid_t pidbuf[10], *pids = pidbuf; + mach_msg_type_number_t i, npids = sizeof (pidbuf) / sizeof (pidbuf[0]); + + err = __proc_getpgrppids (proc, - pid, &pids, &npids); + if (!err) + { + for (i = 0; i < npids; ++i) + { + kill_pid (pids[i]); + if (err == ESRCH) + /* The process died already. Ignore it. */ + err = 0; + } + if (pids != pidbuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) pids, npids * sizeof (pids[0])); + } + } + else + kill_pid (pid); + + _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc); + + /* If we delivered no signals, but ERR is clear, this must mean that + every kill_pid call failed with ESRCH, meaning all the processes in + the pgrp died between proc_getpgrppids and kill_pid; in that case we + fail with ESRCH. */ + return delivered ? 0 : __hurd_fail (err ?: ESRCH); +} + +weak_alias (__kill, kill) diff --git a/sysdeps/mach/hurd/libc-ldscript b/sysdeps/mach/hurd/libc-ldscript new file mode 100644 index 0000000000..26aca50272 --- /dev/null +++ b/sysdeps/mach/hurd/libc-ldscript @@ -0,0 +1,5 @@ +/* This linker script is installed as /lib/libc.a. + It makes -lc become just like -( -lcrt -lmachuser -lhurduser -). + */ + +GROUP ( libcrt.a libmachuser.a libhurduser.a ) diff --git a/sysdeps/mach/hurd/link.c b/sysdeps/mach/hurd/link.c new file mode 100644 index 0000000000..11262f5a0f --- /dev/null +++ b/sysdeps/mach/hurd/link.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> + +/* Make a link to FROM called TO. */ +int +DEFUN(__link, (from, to), CONST char *from AND CONST char *to) +{ + error_t err; + file_t oldfile, linknode, todir; + char *toname; + + oldfile = __file_name_lookup (from, 0, 0); + if (oldfile == MACH_PORT_NULL) + return -1; + + /* The file_getlinknode RPC returns the port that should be passed to + the receiving filesystem (the one containing TODIR) in dir_link. */ + + err = __file_getlinknode (oldfile, &linknode); + __mach_port_deallocate (__mach_task_self (), oldfile); + if (err) + return __hurd_fail (err); + + todir = __file_name_split (to, &toname); + if (todir != MACH_PORT_NULL) + { + err = __dir_link (linknode, todir, toname); + __mach_port_deallocate (__mach_task_self (), todir); + } + __mach_port_deallocate (__mach_task_self (), linknode); + if (todir == MACH_PORT_NULL) + return -1; + + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__link, link) diff --git a/sysdeps/mach/hurd/listen.c b/sysdeps/mach/hurd/listen.c new file mode 100644 index 0000000000..2f9c412c8b --- /dev/null +++ b/sysdeps/mach/hurd/listen.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <sys/socket.h> +#include <hurd/socket.h> + +/* Prepare to accept connections on socket FD. + N connection requests will be queued before further requests are refused. + Returns 0 on success, -1 for errors. */ +int +DEFUN(listen, (fd, n), int fd AND unsigned int n) +{ + error_t err = HURD_DPORT_USE (fd, __socket_listen (port, n)); + if (err) + return __hurd_dfail (fd, err); + return 0; +} diff --git a/sysdeps/mach/hurd/local_lim.h b/sysdeps/mach/hurd/local_lim.h new file mode 100644 index 0000000000..766bd25244 --- /dev/null +++ b/sysdeps/mach/hurd/local_lim.h @@ -0,0 +1,40 @@ +/* Minimum guaranteed maximum values for system limits. Hurd version. + +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* GNU has no arbitrary fixed limits on these things, so we don't + define the macros. Some things are unlimited. Some are in fact + limited but the limit is run-time dependent and fetched with + `sysconf' or `pathconf'. + + POSIX.1 requires that we define NGROUPS_MAX (though none of the others + is required). GNU allows any number of supplementary groups, + dynamically allocated. So we pick a number which seems vaguely + suitable, and `sysconf' will return a number at least as large. */ + +#define NGROUPS_MAX 256 + +/* The maximum number of symbolic links that are allowed in a single file + name resolution. When a further link is encountered, the call returns + ELOOP. This name is a GNU extension; POSIX.1 has no such limit, and BSD + calls it MAXSYMLINKS in <sys/param.h>. */ + +#ifdef __USE_GNU /* 1003.1a defines this */ +#define SYMLOOP_MAX 8 +#endif diff --git a/sysdeps/mach/hurd/lseek.c b/sysdeps/mach/hurd/lseek.c new file mode 100644 index 0000000000..396d2b9e09 --- /dev/null +++ b/sysdeps/mach/hurd/lseek.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Seek to OFFSET on FD, starting from WHENCE. */ +off_t +DEFUN(__lseek, (fd, offset, whence), int fd AND off_t offset AND int whence) +{ + error_t err; + if (err = HURD_DPORT_USE (fd, __io_seek (port, offset, whence, &offset))) + return __hurd_dfail (fd, err); + return offset; +} + +weak_alias (__lseek, lseek) diff --git a/sysdeps/mach/hurd/lstat.c b/sysdeps/mach/hurd/lstat.c new file mode 100644 index 0000000000..21eb448fe8 --- /dev/null +++ b/sysdeps/mach/hurd/lstat.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/stat.h> +#include <stddef.h> +#include <fcntl.h> +#include <hurd.h> + +int +DEFUN(__lstat, (file, buf), CONST char *file AND struct stat *buf) +{ + error_t err; + file_t port = __file_name_lookup (file, O_NOLINK, 0); + if (port == MACH_PORT_NULL) + return -1; + err = __io_stat (port, buf); + __mach_port_deallocate (__mach_task_self (), port); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__lstat, lstat) diff --git a/sysdeps/mach/hurd/mig-reply.c b/sysdeps/mach/hurd/mig-reply.c new file mode 100644 index 0000000000..feb03257dd --- /dev/null +++ b/sysdeps/mach/hurd/mig-reply.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <hurd/threadvar.h> + +#define GETPORT \ + mach_port_t *portloc = \ + (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY) +#define reply_port (use_threadvar ? *portloc : global_reply_port) + +static int use_threadvar; +static mach_port_t global_reply_port; + +/* These functions are called by MiG-generated code. */ + +/* Called by MiG to get a reply port. */ +mach_port_t +__mig_get_reply_port (void) +{ + GETPORT; + + if (reply_port == MACH_PORT_NULL) + reply_port = __mach_reply_port (); + + return reply_port; +} +weak_alias (__mig_get_reply_port, mig_get_reply_port) + +/* Called by MiG to deallocate the reply port. */ +void +__mig_dealloc_reply_port (mach_port_t arg) +{ + mach_port_t port; + + GETPORT; + + port = reply_port; + reply_port = MACH_PORT_NULL; /* So the mod_refs RPC won't use it. */ + __mach_port_mod_refs (__mach_task_self (), port, + MACH_PORT_RIGHT_RECEIVE, -1); +} +weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port) + +/* Called by mig interfaces when done with a port. Used to provide the + same interface as needed when a custom allocator is used. */ +void +__mig_put_reply_port(mach_port_t port) +{ + /* Do nothing. */ +} +weak_alias (__mig_put_reply_port, mig_put_reply_port) + +/* Called at startup with STACK == NULL. When per-thread variables are set + up, this is called again with STACK set to the new stack being switched + to, where per-thread variables should be set up. */ +void +__mig_init (void *stack) +{ + use_threadvar = stack != 0; + + if (use_threadvar) + { + /* Recycle the reply port used before multithreading was enabled. */ + mach_port_t *portloc = (mach_port_t *) + __hurd_threadvar_location_from_sp (_HURD_THREADVAR_MIG_REPLY, stack); + *portloc = global_reply_port; + global_reply_port = MACH_PORT_NULL; + } +} +weak_alias (__mig_init, mig_init) diff --git a/sysdeps/mach/hurd/mips/exc2signal.c b/sysdeps/mach/hurd/mips/exc2signal.c new file mode 100644 index 0000000000..f907c89cf0 --- /dev/null +++ b/sysdeps/mach/hurd/mips/exc2signal.c @@ -0,0 +1,98 @@ +/* Translate Mach exception codes into signal numbers. MIPS version. +Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <mach/exception.h> + +/* Translate the Mach exception codes, as received in an `exception_raise' RPC, + into a signal number and signal subcode. */ + +void +_hurd_exception2signal (int exception, int code, int subcode, + int *signo, long int *sigcode, int *error) +{ + *error = 0; + + switch (exception) + { + default: + *signo = SIGIOT; + *sigcode = exception; + break; + + case EXC_BAD_ACCESS: + if (code == KERN_PROTECTION_FAILURE) + *signo = SIGSEGV; + else + *signo = SIGBUS; + *sigcode = subcode; + *error = code; + break; + + case EXC_BAD_INSTRUCTION: + *signo = SIGILL; + if (code == EXC_MIPS_II) + *sigcode = code; + else + *sigcode = 0; + break; + + case EXC_ARITHMETIC: + switch (code) + { + case EXC_MIPS_OV: /* integer overflow */ + *signo = SIGFPE; + *sigcode = EXC_MIPS_FLT_OVERFLOW; + break; + + default: + *signo = SIGFPE; + *sigcode = 0; + break; + + case EXC_MIPS_INT: + /* Subcode is the fp_status word saved by the hardware. + Give an error code corresponding to the first bit set. */ + if (subcode == EXC_MIPS_FLT_UNIMP) + *signo = SIGILL; + else + *signo = SIGFPE; + *sigcode = subcode; + break; + } + break; + + case EXC_EMULATION: + /* 3.0 doesn't give this one, why, I don't know. */ + *signo = SIGEMT; + *sigcode = 0; + break; + + case EXC_SOFTWARE: + *signo = SIGEMT; + *sigcode = 0; + break; + + case EXC_BREAKPOINT: + *signo = SIGTRAP; + *sigcode = code; + break; + } +} diff --git a/sysdeps/mach/hurd/mips/init-fault.c b/sysdeps/mach/hurd/mips/init-fault.c new file mode 100644 index 0000000000..e6f8acf64d --- /dev/null +++ b/sysdeps/mach/hurd/mips/init-fault.c @@ -0,0 +1,41 @@ +/* Set up a thread_state for proc_handle_exceptions. MIPS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <mach/thread_status.h> +#include <string.h> +#include <setjmp.h> + +extern jmp_buf _hurd_sigthread_fault_env; + +static char fault_stack[32]; +static volatile void +faulted (void) +{ + __longjmp (_hurd_sigthread_fault_env, 1); +} + +void +_hurd_initialize_fault_recovery_state (void *state) +{ + struct mips_thread_state *ts = state; + memset (ts, 0, sizeof (*ts)); + ts->r29 = (int) &fault_stack[sizeof (fault_stack)]; + ts->pc = (int) &faulted; +} diff --git a/sysdeps/mach/hurd/mips/longjmp-ctx.c b/sysdeps/mach/hurd/mips/longjmp-ctx.c new file mode 100644 index 0000000000..0c78f6b4d6 --- /dev/null +++ b/sysdeps/mach/hurd/mips/longjmp-ctx.c @@ -0,0 +1,41 @@ +/* Perform a `longjmp' on a `struct sigcontext'. MIPS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <hurd/signal.h> +#include <string.h> + +void +_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval) +{ + scp->sc_gpr[16] = env[0].__regs[0]; + scp->sc_gpr[17] = env[0].__regs[1]; + scp->sc_gpr[18] = env[0].__regs[2]; + scp->sc_gpr[19] = env[0].__regs[3]; + scp->sc_gpr[20] = env[0].__regs[4]; + scp->sc_gpr[21] = env[0].__regs[5]; + scp->sc_gpr[22] = env[0].__regs[6]; + scp->sc_gpr[23] = env[0].__regs[7]; + + scp->sc_gpr[28] = (int) env[0].__gp; + scp->sc_fp = (int) env[0].__fp; + scp->sc_sp = (int) env[0].__sp; + scp->sc_pc = (int) env[0].__pc; + scp->sc_gpr[2] = retval ?: 1; +} diff --git a/sysdeps/mach/hurd/mips/longjmp-ts.c b/sysdeps/mach/hurd/mips/longjmp-ts.c new file mode 100644 index 0000000000..980a2ceb94 --- /dev/null +++ b/sysdeps/mach/hurd/mips/longjmp-ts.c @@ -0,0 +1,45 @@ +/* Perform a `longjmp' on a Mach thread_state. MIPS version. +Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include <setjmp.h> +#include <mach/thread_status.h> + + +/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ + +void +_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) +{ + struct mips_thread_state *ts = state; + + ts->r16 = env[0].__jmpbuf[0].__regs[0]; + ts->r17 = env[0].__jmpbuf[0].__regs[1]; + ts->r18 = env[0].__jmpbuf[0].__regs[2]; + ts->r19 = env[0].__jmpbuf[0].__regs[3]; + ts->r20 = env[0].__jmpbuf[0].__regs[4]; + ts->r21 = env[0].__jmpbuf[0].__regs[5]; + ts->r22 = env[0].__jmpbuf[0].__regs[6]; + ts->r23 = env[0].__jmpbuf[0].__regs[7]; + ts->r28 = (int) env[0].__jmpbuf[0].__gp; + ts->r29 = (int) env[0].__jmpbuf[0].__sp; + ts->r30 = (int) env[0].__jmpbuf[0].__fp; + ts->pc = (int) env[0].__jmpbuf[0].__pc; + ts->r2 = val ?: 1; +} diff --git a/sysdeps/mach/hurd/mips/sigcontext.h b/sysdeps/mach/hurd/mips/sigcontext.h new file mode 100644 index 0000000000..81d1f25f25 --- /dev/null +++ b/sysdeps/mach/hurd/mips/sigcontext.h @@ -0,0 +1,71 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Signal handlers are actually called: + void handler (int sig, int code, struct sigcontext *scp); */ + +/* State of this thread when the signal was taken. */ +struct sigcontext + { + /* These first members are machine-independent. */ + + int sc_onstack; /* Nonzero if running on sigstack. */ + __sigset_t sc_mask; /* Blocked signals to restore. */ + + /* MiG reply port this thread is using. */ + unsigned int sc_reply_port; + + /* Port this thread is doing an interruptible RPC on. */ + unsigned int sc_intr_port; + + /* Error code associated with this signal (interpreted as `error_t'). */ + int sc_error; + + /* All following members are machine-dependent. The rest of this + structure is written to be laid out identically to: + { + struct mips_thread_state ts; + struct mips_exc_state es; + struct mips_float_state fs; + } + trampoline.c knows this, so it must be changed if this changes. */ +#define sc_mips_thread_state sc_gpr /* Beginning of correspondence. */ + int sc_gpr[31]; /* "General" registers; [0] is r1. */ + int sc_mdlo, sc_mdhi; /* Low and high multiplication results. */ + int sc_pc; /* Instruction pointer. */ + + /* struct mips_exc_state */ +#define sc_mips_exc_state sc_cause + unsigned int sc_cause; /* Machine-level trap code. */ +#define SC_CAUSE_SST 0x00000044 + unsigned int sc_badvaddr; + unsigned int sc_coproc_used; /* Which coprocessors the thread has used. */ +#define SC_COPROC_USE_COP0 1 /* (by definition) */ +#define SC_COPROC_USE_COP1 2 /* FPA */ +#define SC_COPROC_USE_FPU SC_COPROC_USE_COP1 +#define SC_COPROC_USE_COP2 4 +#define SC_COPROC_USE_COP3 8 + + /* struct mips_float_state + This is only filled in if the SC_COPROC_USE_FPU bit + is set in sc_coproc_used. */ +#define sc_mips_float_state sc_fpr + int sc_fpr[32]; /* FP registers. */ + int sc_fpcsr; /* FPU status register. */ + int sc_fpeir; /* FP exception instruction register. */ + }; diff --git a/sysdeps/mach/hurd/mips/sigreturn.c b/sysdeps/mach/hurd/mips/sigreturn.c new file mode 100644 index 0000000000..7396a8bb22 --- /dev/null +++ b/sysdeps/mach/hurd/mips/sigreturn.c @@ -0,0 +1,169 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/threadvar.h> +#include <stdlib.h> + +int +__sigreturn (struct sigcontext *scp) +{ + struct hurd_sigstate *ss; + mach_port_t *reply_port; + + if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) + { + errno = EINVAL; + return -1; + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + + /* Restore the set of blocked signals, and the intr_port slot. */ + ss->blocked = scp->sc_mask; + ss->intr_port = scp->sc_intr_port; + + /* Check for pending signals that were blocked by the old set. */ + if (ss->pending & ~ss->blocked) + { + /* There are pending signals that just became unblocked. Wake up the + signal thread to deliver them. But first, squirrel away SCP where + the signal thread will notice it if it runs another handler, and + arrange to have us called over again in the new reality. */ + ss->context = scp; + /* Clear the intr_port slot, since we are not in fact doing + an interruptible RPC right now. If SS->intr_port is not null, + the SCP context is doing an interruptible RPC, but the signal + thread will examine us while we are blocked in the sig_post RPC. */ + ss->intr_port = MACH_PORT_NULL; + __spin_unlock (&ss->lock); + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + /* If a pending signal was handled, sig_post never returned. */ + __spin_lock (&ss->lock); + } + + if (scp->sc_onstack) + { + ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */ + /* XXX cannot unlock until off sigstack */ + abort (); + } + else + __spin_unlock (&ss->lock); + + /* Destroy the MiG reply port used by the signal handler, and restore the + reply port in use by the thread when interrupted. */ + reply_port = + (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); + if (*reply_port) + __mach_port_destroy (__mach_task_self (), *reply_port); + *reply_port = scp->sc_reply_port; + + if (scp->sc_coproc_used & SC_COPROC_USE_FPU) + { + /* Restore FPU state. */ +#define restore_fpr(n) \ + asm volatile ("l.d $f" #n ",%0" : : "m" (scp->sc_fpr[n])) + + /* Restore floating-point registers. */ + restore_fpr (0); + restore_fpr (2); + restore_fpr (4); + restore_fpr (6); + restore_fpr (8); + restore_fpr (10); + restore_fpr (12); + restore_fpr (14); + restore_fpr (16); + restore_fpr (18); + restore_fpr (20); + restore_fpr (22); + restore_fpr (24); + restore_fpr (26); + restore_fpr (28); + restore_fpr (30); + + /* Restore the floating-point control/status register ($f31). */ + asm volatile ("ctc1 %0,$f31" : : "r" (scp->sc_fpcsr)); + } + + /* Load all the registers from the sigcontext. */ +#define restore_gpr(n) \ + asm volatile ("lw $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1])) + + { + register const struct sigcontext *const scpreg asm ("$1") = scp; + register int *at asm ("$1"); + + /* First restore the multiplication result registers. The compiler + will use some temporary registers, so we do this before restoring + the general registers. */ + asm volatile ("mtlo %0" : : "r" (scpreg->sc_mdlo)); + asm volatile ("mthi %0" : : "r" (scpreg->sc_mdhi)); + + /* In the word after the saved PC, store the saved $1 value. */ + (&scpreg->sc_pc)[1] = scpreg->sc_gpr[0]; + + asm volatile (".set noreorder; .set noat;"); + + /* Restore the normal registers. */ + restore_gpr (2); + restore_gpr (3); + restore_gpr (4); + restore_gpr (5); + restore_gpr (6); + restore_gpr (7); + restore_gpr (8); + restore_gpr (9); + restore_gpr (10); + restore_gpr (11); + restore_gpr (12); + restore_gpr (13); + restore_gpr (14); + restore_gpr (15); + restore_gpr (16); + restore_gpr (17); + restore_gpr (18); + restore_gpr (19); + restore_gpr (20); + restore_gpr (21); + restore_gpr (22); + restore_gpr (23); + restore_gpr (24); + restore_gpr (25); + /* Registers 26-27 are kernel-only. */ + restore_gpr (28); + restore_gpr (29); /* Stack pointer. */ + restore_gpr (30); /* Frame pointer. */ + restore_gpr (31); /* Return address. */ + + at = &scpreg->sc_pc; + /* This is an emulated instruction that will find at the address in $1 + two words: the PC value to restore, and the $1 value to restore. */ + asm volatile (".word op_sigreturn"); + + asm volatile (".set reorder; .set at;"); + } + + /* NOTREACHED */ + return -1; +} + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/mach/hurd/mips/trampoline.c b/sysdeps/mach/hurd/mips/trampoline.c new file mode 100644 index 0000000000..f03ad5852f --- /dev/null +++ b/sysdeps/mach/hurd/mips/trampoline.c @@ -0,0 +1,260 @@ +/* Set thread_state for sighandler, and sigcontext to recover. MIPS version. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd/signal.h> +#include "thread_state.h" + + +struct mach_msg_trap_args + { + /* This is the order of arguments to mach_msg_trap. */ + mach_msg_header_t *msg; + mach_msg_option_t option; + mach_msg_size_t send_size; + mach_msg_size_t rcv_size; + mach_port_t rcv_name; + mach_msg_timeout_t timeout; + mach_port_t notify; + }; + + +struct sigcontext * +_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, + int signo, long int sigcode, + int rpc_wait, + struct machine_thread_all_state *state) +{ + + __label__ trampoline, rpc_wait_trampoline; + void *sigsp; + struct sigcontext *scp; + + if (ss->context) + { + /* We have a previous sigcontext that sigreturn was about + to restore when another signal arrived. We will just base + our setup on that. */ + if (! setjmp (_hurd_sigthread_fault_env)) + { + memcpy (&state->basic, &ss->context->sc_mips_thread_state, + sizeof (state->basic)); + memcpy (&state->exc, &ss->context->sc_mips_exc_state, + sizeof (state->exc)); + state->set = (1 << MIPS_THREAD_STATE) | (1 << MIPS_EXC_STATE); + if (state->exc.coproc_state & SC_COPROC_USE_FPU) + { + memcpy (&state->fpu, &ss->context->sc_mips_float_state, + sizeof (state->fpu)); + state->set |= (1 << MIPS_FLOAT_STATE); + } + assert (! rpc_wait); + /* The intr_port slot was cleared before sigreturn sent us the + sig_post that made us notice this pending signal, so + _hurd_internal_post_signal wouldn't do interrupt_operation. + After we return, our caller will set SCP->sc_intr_port (in the + new context) from SS->intr_port and clear SS->intr_port. Now + that we are restoring this old context recorded by sigreturn, + we want to restore its intr_port too; so store it in + SS->intr_port now, so it will end up in SCP->sc_intr_port + later. */ + ss->intr_port = ss->context->sc_intr_port; + } + /* If the sigreturn context was bogus, just ignore it. */ + ss->context = NULL; + } + else if (! machine_get_basic_state (ss->thread, state)) + return NULL; + + if ((ss->actions[signo].sa_flags & SA_ONSTACK) && + !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK))) + { + sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size; + ss->sigaltstack.ss_flags |= SA_ONSTACK; + /* XXX need to set up base of new stack for + per-thread variables, cthreads. */ + } + else + sigsp = (char *) state->basic.r29; + + /* Set up the sigcontext structure on the stack. This is all the stack + needs, since the args are passed in registers (below). */ + sigsp -= sizeof (*scp); + scp = sigsp; + + if (! setjmp (_hurd_sigthread_fault_env)) + { + /* Set up the sigcontext from the current state of the thread. */ + + scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0; + + /* struct sigcontext is laid out so that starting at sc_gpr + mimics a struct mips_thread_state. */ + memcpy (&scp->sc_mips_thread_state, + &state->basic, sizeof (state->basic)); + + /* struct sigcontext is laid out so that starting at sc_cause + mimics a struct mips_exc_state. */ + if (! machine_get_state (ss->thread, state, MIPS_EXC_STATE, + &state->exc, &scp->sc_cause, + sizeof (state->exc))) + return NULL; + if ((scp->sc_coproc_used & SC_COPROC_USE_FPU) && + /* struct sigcontext is laid out so that starting at sc_fpr + mimics a struct mips_float_state. This state + is only meaningful if the coprocessor was used. */ + ! machine_get_state (ss->thread, state, MIPS_FLOAT_STATE, + &state->fpu, + &scp->sc_mips_float_state, sizeof (state->fpu))) + return NULL; + } + else + /* We got a fault trying to write the stack frame. + We cannot set up the signal handler. + Returning NULL tells our caller, who will nuke us with a SIGILL. */ + return NULL; + + /* Modify the thread state to call the trampoline code on the new stack. */ + if (rpc_wait) + { + /* The signalee thread was blocked in a mach_msg_trap system call, + still waiting for a reply. We will have it run the special + trampoline code which retries the message receive before running + the signal handler. + + To do this we change the OPTION argument in its registers to + enable only message reception, since the request message has + already been sent. */ + + /* The system call arguments are stored in consecutive registers + starting with a0 ($4). */ + struct mach_msg_trap_args *args = (void *) &state->basic.r4; + + assert (args->option & MACH_RCV_MSG); + /* Disable the message-send, since it has already completed. The + calls we retry need only wait to receive the reply message. */ + args->option &= ~MACH_SEND_MSG; + + state->basic.pc = (int) &&rpc_wait_trampoline; + state->basic.r29 = (int) sigsp; /* $29 is the stack pointer register. */ + /* After doing the message receive, the trampoline code will need to + update the v0 ($2) value to be restored by sigreturn. To simplify + the assembly code, we pass the address of its slot in SCP to the + trampoline code in v1 ($3). */ + state->basic.r3 = (int) &scp->sc_gpr[1]; + /* We must preserve the mach_msg_trap args in a0..t2 ($4..$10). + Pass the handler args to the trampoline code in s1..s3 ($17..$19). */ + state->basic.r17 = signo; + state->basic.r18 = sigcode; + state->basic.r19 = (int) scp; + } + else + { + state->basic.pc = (int) &&trampoline; + state->basic.r29 = (int) sigsp; + state->basic.r4 = signo; + state->basic.r5 = sigcode; + state->basic.r6 = (int) scp; + } + + /* We pass the handler function to the trampoline code in at ($1). */ + state->basic.r1 = (int) handler; + /* In the callee-saved register s0 ($16), we save the SCP value to pass + to __sigreturn after the handler returns. */ + state->basic.r16 = (int) scp; + + return scp; + + /* The trampoline code follows. This is not actually executed as part of + this function, it is just convenient to write it that way. */ + + rpc_wait_trampoline: + /* This is the entry point when we have an RPC reply message to receive + before running the handler. The MACH_MSG_SEND bit has already been + cleared in the OPTION argument in our registers. For our convenience, + $3 points to the sc_gpr[1] member of the sigcontext (saved v0 ($2)). */ + asm volatile + (".set noat; .set noreorder; .set nomacro\n" + /* Retry the interrupted mach_msg system call. */ + "li $2, -25\n" /* mach_msg_trap */ + "syscall\n" + /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But + now the message receive has completed and the original caller of + the RPC (i.e. the code running when the signal arrived) needs to + see the final return value of the message receive in v0. So + store the new v0 value into the sc_gpr[1] member of the sigcontext + (whose address is in v1 to make this code simpler). */ + "sw $2, ($3)\n" + /* Since the argument registers needed to have the mach_msg_trap + arguments, we've stored the arguments to the handler function + in registers s1..s3 ($17..$19). */ + "move $4, $17\n" + "move $5, $18\n" + "move $6, $19\n"); + + trampoline: + /* Entry point for running the handler normally. The arguments to the + handler function are already in the standard registers: + + a0 SIGNO + a1 SIGCODE + a2 SCP + */ + asm volatile + ("jal $1; nop\n" /* Call the handler function. */ + /* Call __sigreturn (SCP); this cannot return. */ + "j %0\n" + "move $4, $16" /* Set up arg from saved SCP in delay slot. */ + : : "i" (&__sigreturn)); + + /* NOTREACHED */ + asm volatile (".set reorder; .set at; .set macro"); + + return NULL; +} + +/* STATE describes a thread that had intr_port set (meaning it was inside + HURD_EINTR_RPC), after it has been thread_abort'd. It it looks to have + just completed a mach_msg_trap system call that returned + MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right + being waited on. */ +int +_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state, + mach_port_t *port) +{ + const unsigned int *const pc = (void *) state->basic.pc; + + if (_hurdsig_catch_fault (SIGSEGV)) + assert (_hurdsig_fault_sigcode == (long int) pc); + else + { + if (state->basic.r2 == MACH_RCV_INTERRUPTED && + pc[-1] == 0xc) /* syscall */ + { + /* We did just return from a mach_msg_trap system call + doing a message receive that was interrupted. + Examine the parameters to find the receive right. */ + struct mach_msg_trap_args *args = (void *) &state->basic.r4; + + *port = args->rcv_name; + return 1; + } + } + + return 0; +} diff --git a/sysdeps/mach/hurd/mkdir.c b/sysdeps/mach/hurd/mkdir.c new file mode 100644 index 0000000000..d477815994 --- /dev/null +++ b/sysdeps/mach/hurd/mkdir.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <hurd.h> + +/* Create a directory named FILE_NAME with protections MODE. */ +int +DEFUN(__mkdir, (file_name, mode), CONST char *file_name AND mode_t mode) +{ + error_t err; + const char *name; + file_t parent = __file_name_split (file_name, (char **) &name); + if (parent == MACH_PORT_NULL) + return -1; + err = __dir_mkdir (parent, name, mode); + __mach_port_deallocate (__mach_task_self (), parent); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__mkdir, mkdir) diff --git a/sysdeps/mach/hurd/mknod.c b/sysdeps/mach/hurd/mknod.c new file mode 100644 index 0000000000..cf1b4d021e --- /dev/null +++ b/sysdeps/mach/hurd/mknod.c @@ -0,0 +1,114 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/stat.h> +#include <hurd.h> +#include <hurd/paths.h> +#include <fcntl.h> +#include "stdio/_itoa.h" +#include <string.h> + +/* Temporary hack; this belongs in a header file, probably types.h. */ +#define major(x) ((int)(((unsigned) (x) >> 8) & 0xff)) +#define minor(x) ((int)((x) & 0xff)) + + +/* Create a device file named FILE_NAME, with permission and special bits MODE + and device number DEV (which can be constructed from major and minor + device numbers with the `makedev' macro above). */ +int +DEFUN(__mknod, (file_name, mode, dev), + CONST char *file_name AND mode_t mode AND dev_t dev) +{ + error_t err; + file_t dir, node; + char *name; + char buf[100], *bp; + const char *translator; + size_t len; + + if (S_ISCHR (mode)) + { + translator = _HURD_CHRDEV; + len = sizeof (_HURD_CHRDEV); + } + else if (S_ISBLK (mode)) + { + translator = _HURD_BLKDEV; + len = sizeof (_HURD_BLKDEV); + } + else if (S_ISFIFO (mode)) + { + translator = _HURD_FIFO; + len = sizeof (_HURD_FIFO); + } + else + { + errno = EINVAL; + return -1; + } + + if (! S_ISFIFO (mode)) + { + /* We set the translator to "ifmt\0major\0minor\0", where IFMT + depends on the S_IFMT bits of our MODE argument, and MAJOR and + MINOR are ASCII decimal (octal or hex would do as well) + representations of our arguments. Thus the convention is that + CHRDEV and BLKDEV translators are invoked with two non-switch + arguments, giving the major and minor device numbers in %i format. */ + + bp = buf + sizeof (buf); + *--bp = '\0'; + bp = _itoa (minor (dev), bp, 10, 0); + *--bp = '\0'; + bp = _itoa (major (dev), bp, 10, 0); + memcpy (bp - len, translator, len); + translator = bp - len; + len = buf + sizeof (buf) - translator; + } + + dir = __file_name_split (file_name, &name); + if (dir == MACH_PORT_NULL) + return -1; + + /* Create a new, unlinked node in the target directory. */ + err = __dir_mkfile (dir, O_WRITE, mode & ~S_IFMT & _hurd_umask, &node); + + if (! err) + /* Set the node's translator to make it a device. */ + err = __file_set_translator (node, + FS_TRANS_EXCL | FS_TRANS_SET, + FS_TRANS_EXCL | FS_TRANS_SET, 0, + translator, len, + MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND); + + if (! err) + /* Link the node, now a valid device, into the target directory. */ + err = __dir_link (node, dir, name); + + __mach_port_deallocate (__mach_task_self (), dir); + __mach_port_deallocate (__mach_task_self (), node); + + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__mknod, mknod) diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c new file mode 100644 index 0000000000..e682225ec8 --- /dev/null +++ b/sysdeps/mach/hurd/mmap.c @@ -0,0 +1,105 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +caddr_t +mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + error_t err; + vm_prot_t vmprot; + memory_object_t memobj; + vm_address_t mapaddr; + + vmprot = VM_PROT_NONE; + if (prot & PROT_READ) + vmprot |= VM_PROT_READ; + if (prot & PROT_WRITE) + vmprot |= VM_PROT_WRITE; + if (prot & PROT_EXEC) + vmprot |= VM_PROT_EXECUTE; + + switch (flags & MAP_TYPE) + { + default: + return (caddr_t) (long int) __hurd_fail (EINVAL); + + case MAP_ANON: + memobj = MACH_PORT_NULL; + break; + + case MAP_FILE: + { + mach_port_t robj, wobj; + if (err = HURD_DPORT_USE (fd, __io_map (port, &robj, &wobj))) + return (caddr_t) (long int) __hurd_dfail (fd, err); + switch (prot & (PROT_READ|PROT_WRITE)) + { + case PROT_READ: + memobj = robj; + __mach_port_deallocate (__mach_task_self (), wobj); + break; + case PROT_WRITE: + memobj = wobj; + __mach_port_deallocate (__mach_task_self (), robj); + break; + case PROT_READ|PROT_WRITE: + __mach_port_deallocate (__mach_task_self (), robj); + if (robj == wobj) + memobj = wobj; + else + { + __mach_port_deallocate (__mach_task_self (), wobj); + return ((caddr_t) (long int) + __hurd_fail (EGRATUITOUS)); /* XXX */ + } + break; + } + break; + /* XXX handle MAP_NOEXTEND */ + } + } + + mapaddr = (vm_address_t) addr; + err = __vm_map (__mach_task_self (), + &mapaddr, (vm_size_t) len, (vm_address_t) 0, + flags & MAP_FIXED, + memobj, (vm_offset_t) offset, + flags & (MAP_COPY|MAP_PRIVATE), + vmprot, VM_PROT_ALL, + flags & MAP_INHERIT); + + if (memobj != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), memobj); + + return err ? (caddr_t) (long int) __hurd_fail (err) : (caddr_t) mapaddr; +} + diff --git a/sysdeps/mach/hurd/open.c b/sysdeps/mach/hurd/open.c new file mode 100644 index 0000000000..0d22e7f36d --- /dev/null +++ b/sysdeps/mach/hurd/open.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, + a third argument is the file protection. */ +int +DEFUN(__open, (file, oflag), CONST char *file AND int oflag DOTS) +{ + mode_t mode; + io_t port; + + if (oflag & O_CREAT) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, mode_t); + va_end (arg); + } + else + mode = 0; + + port = __file_name_lookup (file, oflag, mode); + if (port == MACH_PORT_NULL) + return -1; + + return _hurd_intern_fd (port, oflag, 1); +} + +weak_alias (__open, open) diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c new file mode 100644 index 0000000000..d843da8aeb --- /dev/null +++ b/sysdeps/mach/hurd/opendir.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <dirent.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <hurd.h> + + +/* Open a directory stream on NAME. */ +DIR * +DEFUN(opendir, (name), CONST char *name) +{ + DIR *dirp; + file_t port; + + port = __file_name_lookup (name, O_RDONLY, 0); + if (port == MACH_PORT_NULL) + return NULL; + + /* XXX this port should be deallocated on exec */ + + dirp = (DIR *) malloc (sizeof (DIR)); + if (dirp == NULL) + { + __mach_port_deallocate (__mach_task_self (), port); + return NULL; + } + + dirp->__port = port; + dirp->__data = dirp->__ptr = NULL; + dirp->__entry_data = dirp->__entry_ptr = 0; + dirp->__allocation = 0; + dirp->__size = 0; + + return dirp; +} diff --git a/sysdeps/mach/hurd/pipe.c b/sysdeps/mach/hurd/pipe.c new file mode 100644 index 0000000000..07c802f5a0 --- /dev/null +++ b/sysdeps/mach/hurd/pipe.c @@ -0,0 +1,99 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <sys/socket.h> +#include <hurd/socket.h> +#include <fcntl.h> + +/* Create a one-way communication channel (pipe). + If successul, two file descriptors are stored in FDS; + bytes written on FDS[1] can be read from FDS[0]. + Returns 0 if successful, -1 if not. */ +int +DEFUN(__pipe, (fds), int fds[2]) +{ + error_t err; + socket_t server, sock1, sock2; + int d1, d2; + + if (fds == NULL) + return __hurd_fail (EINVAL); + + /* Find the local domain socket server. */ + server = _hurd_socket_server (PF_LOCAL, 0); + if (server == MACH_PORT_NULL) + return -1; + + /* Create two local domain sockets and connect them together. */ + + err = __socket_create (server, SOCK_STREAM, 0, &sock1); + if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + { + /* On the first use of the socket server during the operation, + allow for the old server port dying. */ + server = _hurd_socket_server (PF_LOCAL, 1); + if (server == MACH_PORT_NULL) + return -1; + err = __socket_create (server, SOCK_STREAM, 0, &sock1); + } + if (err) + return __hurd_fail (err); + if (err = __socket_create (server, SOCK_STREAM, 0, &sock2)) + { + __mach_port_deallocate (__mach_task_self (), sock1); + return __hurd_fail (err); + } + if (err = __socket_connect2 (sock1, sock2)) + { + __mach_port_deallocate (__mach_task_self (), sock1); + __mach_port_deallocate (__mach_task_self (), sock2); + return __hurd_fail (err); + } + + /* Shut down the unused sides of the sockets. */ + __socket_shutdown (sock1, 1); + __socket_shutdown (sock2, 0); + + /* Put the sockets into file descriptors. */ + + d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1); + if (d1 < 0) + { + __mach_port_deallocate (__mach_task_self (), sock2); + return -1; + } + d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1); + if (d2 < 0) + { + err = errno; + (void) close (d1); + return __hurd_fail (err); + } + + fds[0] = d1; + fds[1] = d2; + return 0; +} + +weak_alias (__pipe, pipe) diff --git a/sysdeps/mach/hurd/ptrace.c b/sysdeps/mach/hurd/ptrace.c new file mode 100644 index 0000000000..3d8558734f --- /dev/null +++ b/sysdeps/mach/hurd/ptrace.c @@ -0,0 +1,392 @@ +/* Process tracing interface `ptrace' for GNU Hurd. +Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <sys/ptrace.h> +#include <sys/types.h> +#include <stdarg.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/msg.h> +#include <thread_state.h> + +/* Perform process tracing functions. REQUEST is one of the values + in <sys/ptrace.h>, and determines the action to be taken. + For all requests except PTRACE_TRACEME, PID specifies the process to be + traced. + + PID and the other arguments described above for the various requests should + appear (those that are used for the particular request) as: + pid_t PID, void *ADDR, int DATA, void *ADDR2 + after PID. */ +int +ptrace (enum __ptrace_request request, ... ) +{ + pid_t pid; + void *addr, *addr2; + natural_t data; + va_list ap; + + /* Read data from PID's address space, from ADDR for DATA bytes. */ + error_t read_data (task_t task, vm_address_t *ourpage, vm_size_t *size) + { + /* Read the pages containing the addressed range. */ + error_t err; + *size = round_page (addr + data) - trunc_page (addr); + err = __vm_read (task, trunc_page (addr), *size, ourpage, size); + return err; + } + + /* Fetch the thread port for PID's user thread. */ + error_t fetch_user_thread (task_t task, thread_t *thread) + { + thread_t threadbuf[3], *threads = threadbuf; + mach_msg_type_number_t nthreads = 3, i; + error_t err = __task_threads (task, &threads, &nthreads); + if (err) + return err; + if (nthreads == 0) + return EINVAL; + *thread = threads[0]; /* Assume user thread is first. */ + for (i = 1; i < nthreads; ++i) + __mach_port_deallocate (__mach_task_self (), threads[i]); + if (threads != threadbuf) + __vm_deallocate (__mach_task_self (), + (vm_address_t) threads, nthreads * sizeof threads[0]); + return 0; + } + + /* Fetch a thread state structure from PID and store it at ADDR. */ + int get_regs (int flavor, mach_msg_type_number_t count) + { + error_t err; + task_t task = __pid2task (pid); + thread_t thread; + if (task == MACH_PORT_NULL) + return -1; + err = fetch_user_thread (task, &thread); + __mach_port_deallocate (__mach_task_self (), task); + if (!err) + err = __thread_get_state (thread, flavor, addr, &count); + __mach_port_deallocate (__mach_task_self (), thread); + return err ? __hurd_fail (err) : 0; + } + + + switch (request) + { + case PTRACE_TRACEME: + /* Make this process be traced. */ + _hurd_exec_flags |= EXEC_TRACED; + break; + + case PTRACE_CONT: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + data = va_arg (ap, int); + va_end (ap); + { + /* Send a DATA signal to PID, telling it to take the signal + normally even if it's traced. */ + error_t err; task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + if (data == SIGKILL) + err = __task_terminate (task); + else + { + mach_port_t msgport; + err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)); + + if (!err && addr != (void *) 1) + { + /* Move the user thread's PC to ADDR. */ + thread_t thread; + err = fetch_user_thread (task, &thread); + if (!err) + { + struct machine_thread_state state; + mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT; + err = __thread_get_state (thread, + MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, &count); + if (!err) + { + MACHINE_THREAD_STATE_SET_PC (&state, addr); + err = __thread_set_state (thread, + MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state, count); + } + + } + __mach_port_deallocate (__mach_task_self (), thread); + } + + if (! err) + /* Tell the process to take the signal (or just resume if 0). */ + err = __msg_sig_post_untraced (msgport, data, task); + __mach_port_deallocate (__mach_task_self (), msgport); + } + __mach_port_deallocate (__mach_task_self (), task); + return err ? __hurd_fail (err) : 0; + } + + case PTRACE_KILL: + va_start (ap, request); + pid = va_arg (ap, pid_t); + va_end (ap); + /* SIGKILL always just terminates the task, + so normal kill is just the same when traced. */ + return kill (pid, SIGKILL); + + case PTRACE_SINGLESTEP: + /* This is a machine-dependent kernel RPC on + machines that support it. Punt. */ + return EOPNOTSUPP; + + case PTRACE_ATTACH: + case PTRACE_DETACH: + va_start (ap, request); + pid = va_arg (ap, pid_t); + va_end (ap); + { + /* Tell PID to set or clear its trace bit. */ + error_t err; + mach_port_t msgport; + task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)); + if (! err) + { + err = (request == PTRACE_ATTACH ? + __msg_set_some_exec_flags : + __msg_clear_some_exec_flags) (msgport, task, EXEC_TRACED); +#ifdef notyet /* XXX */ + if (! err) + /* Request (or request an end to) SIGCHLD notification + when PID stops or dies, and proc_wait working on PID. */ + err = __USEPORT (PROC, + __proc_trace_pid (port, pid, + request == PTRACE_ATTACH)); +#endif + if (! err) + { + if (request == PTRACE_ATTACH) + /* Now stop the process. */ + err = __msg_sig_post (msgport, SIGSTOP, task); + else + /* Resume the process from tracing stop. */ + err = __msg_sig_post_untraced (msgport, 0, task); + } + __mach_port_deallocate (__mach_task_self (), msgport); + } + __mach_port_deallocate (__mach_task_self (), task); + return err ? __hurd_fail (err) : 0; + } + + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + va_end (ap); + { + /* Read the page (or two pages, if the word lies on a boundary) + containing the addressed word. */ + error_t err; + vm_address_t ourpage; + vm_size_t size; + natural_t word; + task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + data = sizeof word; + ourpage = 0; + size = 0; + err = read_data (task, &ourpage, &size); + __mach_port_deallocate (__mach_task_self (), task); + if (err) + return __hurd_fail (err); + word = *(natural_t *) ((vm_address_t) addr - trunc_page (addr) + + ourpage); + __vm_deallocate (__mach_task_self (), ourpage, size); + return word; + } + + case PTRACE_PEEKUSER: + case PTRACE_POKEUSER: + /* U area, what's that? */ + return EOPNOTSUPP; + + case PTRACE_GETREGS: + case PTRACE_SETREGS: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + va_end (ap); + return get_regs (MACHINE_THREAD_STATE_FLAVOR, + MACHINE_THREAD_STATE_COUNT); + + case PTRACE_GETFPREGS: + case PTRACE_SETFPREGS: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + va_end (ap); +#ifdef MACHINE_THREAD_FLOAT_STATE_FLAVOR + return get_regs (MACHINE_THREAD_FLOAT_STATE_FLAVOR, + MACHINE_THREAD_FLOAT_STATE_COUNT); +#else + return EOPNOTSUPP; +#endif + + case PTRACE_GETFPAREGS: + case PTRACE_SETFPAREGS: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + va_end (ap); +#ifdef MACHINE_THREAD_FPA_STATE_FLAVOR + return get_regs (MACHINE_THREAD_FPA_STATE_FLAVOR, + MACHINE_THREAD_FPA_STATE_COUNT); +#else + return EOPNOTSUPP; +#endif + + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + data = va_arg (ap, int); + va_end (ap); + { + /* Read the page (or two pages, if the word lies on a boundary) + containing the addressed word. */ + error_t err; + vm_address_t ourpage; + vm_size_t size; + task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + data = sizeof (natural_t); + ourpage = 0; + size = 0; + err = read_data (task, &ourpage, &size); + + if (!err) + { + /* Now modify the specified word and write the page back. */ + *(natural_t *) ((vm_address_t) addr - trunc_page (addr) + + ourpage) = data; + err = __vm_write (task, trunc_page (addr), ourpage, size); + __vm_deallocate (__mach_task_self (), ourpage, size); + } + + __mach_port_deallocate (__mach_task_self (), task); + return err ? __hurd_fail (err) : 0; + } + + case PTRACE_READDATA: + case PTRACE_READTEXT: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + data = va_arg (ap, int); + addr2 = va_arg (ap, void *); + va_end (ap); + { + error_t err; + vm_address_t ourpage; + vm_size_t size; + task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + if (((vm_address_t) addr2 + data) % __vm_page_size == 0) + { + /* Perhaps we can write directly to the user's buffer. */ + ourpage = (vm_address_t) addr2; + size = data; + } + else + { + ourpage = 0; + size = 0; + } + err = read_data (task, &ourpage, &size); + __mach_port_deallocate (__mach_task_self (), task); + if (!err && ourpage != (vm_address_t) addr2) + { + memcpy (addr2, (void *) ourpage, data); + __vm_deallocate (__mach_task_self (), ourpage, size); + } + return err ? __hurd_fail (err) : 0; + } + + case PTRACE_WRITEDATA: + case PTRACE_WRITETEXT: + va_start (ap, request); + pid = va_arg (ap, pid_t); + addr = va_arg (ap, void *); + data = va_arg (ap, int); + addr2 = va_arg (ap, void *); + va_end (ap); + { + error_t err; + vm_address_t ourpage; + vm_size_t size; + task_t task = __pid2task (pid); + if (task == MACH_PORT_NULL) + return -1; + if ((vm_address_t) addr % __vm_page_size == 0 && + (vm_address_t) data % __vm_page_size == 0) + { + /* Writing whole pages; can go directly from the user's buffer. */ + ourpage = (vm_address_t) addr2; + size = data; + err = 0; + } + else + { + /* Read the task's pages and modify our own copy. */ + ourpage = 0; + size = 0; + err = read_data (task, &ourpage, &size); + if (!err) + memcpy ((void *) ((vm_address_t) addr - trunc_page (addr) + + ourpage), + addr2, + data); + } + if (!err) + /* Write back the modified pages. */ + err = __vm_write (task, trunc_page (addr), ourpage, size); + __mach_port_deallocate (__mach_task_self (), task); + return err ? __hurd_fail (err) : 0; + } + + default: + errno = EINVAL; + return -1; + } + + return 0; +} diff --git a/sysdeps/mach/hurd/read.c b/sysdeps/mach/hurd/read.c new file mode 100644 index 0000000000..c7fdaf8a4d --- /dev/null +++ b/sysdeps/mach/hurd/read.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +/* Read NBYTES into BUF from FD. Return the number read or -1. */ +ssize_t +DEFUN(__read, (fd, buf, nbytes), + int fd AND PTR buf AND size_t nbytes) +{ + error_t err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes)); + return err ? __hurd_dfail (fd, err) : nbytes; +} + +weak_alias (__read, read) diff --git a/sysdeps/mach/hurd/readdir.c b/sysdeps/mach/hurd/readdir.c new file mode 100644 index 0000000000..185aeee2b1 --- /dev/null +++ b/sysdeps/mach/hurd/readdir.c @@ -0,0 +1,90 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <hurd.h> + + +/* Read a directory entry from DIRP. */ +struct dirent * +DEFUN(readdir, (dirp), DIR *dirp) +{ + struct dirent *dp; + + if (dirp == NULL) + { + errno = EINVAL; + return NULL; + } + + do + { + if (dirp->__ptr - dirp->__data >= dirp->__size) + { + /* We've emptied out our buffer. Refill it. */ + + char *data = dirp->__data; + int nentries; + error_t err; + + if (err = __dir_readdir (dirp->__port, &data, &dirp->__size, + dirp->__entry_ptr, -1, 0, &nentries)) + return __hurd_fail (err), NULL; + + /* DATA now corresponds to entry index DIRP->__entry_ptr. */ + dirp->__entry_data = dirp->__entry_ptr; + + if (data != dirp->__data) + { + /* The data was passed out of line, so our old buffer is no + longer useful. Deallocate the old buffer and reset our + information for the new buffer. */ + __vm_deallocate (__mach_task_self (), + (vm_address_t) dirp->__data, + dirp->__allocation); + dirp->__data = data; + dirp->__allocation = round_page (dirp->__size); + } + + /* Reset the pointer into the buffer. */ + dirp->__ptr = dirp->__data; + + if (nentries == 0) + /* End of file. */ + return NULL; + + /* We trust the filesystem to return correct data and so we + ignore NENTRIES. */ + } + + dp = (struct dirent *) dirp->__ptr; + dirp->__ptr += dp->d_reclen; + ++dirp->__entry_ptr; + + /* Loop to ignore deleted files. */ + } while (dp->d_fileno == 0); + + return dp; +} diff --git a/sysdeps/mach/hurd/readlink.c b/sysdeps/mach/hurd/readlink.c new file mode 100644 index 0000000000..2f51e200b5 --- /dev/null +++ b/sysdeps/mach/hurd/readlink.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/paths.h> +#include <fcntl.h> +#include <string.h> + +/* Read the contents of the symbolic link FILE_NAME into no more than + LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +ssize_t +DEFUN(__readlink, (file_name, buf, len), + CONST char *file_name AND char *buf AND size_t len) +{ + error_t err; + file_t file; + char mybuf[2048], *transp = mybuf; + mach_msg_type_number_t translen = sizeof (mybuf); + + file = __file_name_lookup (file_name, O_NOTRANS, 0); + if (file == MACH_PORT_NULL) + return -1; + + err = __file_get_translator (file, &transp, &translen); + __mach_port_deallocate (__mach_task_self (), file); + + if (err) + return __hurd_fail (err); + + if (translen < sizeof (_HURD_SYMLINK) || + memcmp (transp, _HURD_SYMLINK, sizeof (_HURD_SYMLINK))) + /* The file is not actually a symlink. */ + err = EINVAL; + else + { + /* This is a symlink; its translator is "/hurd/symlink\0target\0". */ + if (len >= translen - sizeof (_HURD_SYMLINK)) + { + len = translen - sizeof (_HURD_SYMLINK); + if (transp[translen - 1] == '\0') + /* Remove the null terminator. */ + --len; + } + if (buf == NULL) + /* This call is just to find out how large a buffer is required. */ + len = translen - sizeof (_HURD_SYMLINK) - 1; + else + /* Copy into the user's buffer. */ + memcpy (buf, transp + sizeof (_HURD_SYMLINK), len); + } + + if (transp != mybuf) + __vm_deallocate (__mach_task_self (), (vm_address_t) transp, translen); + + return err ? __hurd_fail (err) : len; +} + +weak_alias (__readlink, readlink) diff --git a/sysdeps/mach/hurd/reboot.c b/sysdeps/mach/hurd/reboot.c new file mode 100644 index 0000000000..80356fdf5a --- /dev/null +++ b/sysdeps/mach/hurd/reboot.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/startup.h> + +/* Reboot the system. */ +int +DEFUN(reboot, (howto), int howto) +{ + error_t err; + startup_t init; + mach_port_t hostpriv, devmaster; + + if (err = __USEPORT (PROC, __proc_getprivports (port, + &hostpriv, &devmaster))) + return __hurd_fail (err); + __mach_port_deallocate (__mach_task_self (), devmaster); + + err = __USEPORT (PROC, __proc_getmsgport (port, 1, &init)); + if (!err) + { + err = __startup_reboot (init, hostpriv, howto); + __mach_port_deallocate (__mach_task_self (), init); + } + + __mach_port_deallocate (__mach_task_self (), hostpriv); + + if (err) + return __hurd_fail (err); + + return 0; +} diff --git a/sysdeps/mach/hurd/recv.c b/sysdeps/mach/hurd/recv.c new file mode 100644 index 0000000000..7d06919c4b --- /dev/null +++ b/sysdeps/mach/hurd/recv.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1994 Fremach_msg_type_number_t Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <string.h> + +/* Read N bytes into BUF from socket FD. + Returns the number read or -1 for errors. */ +int +DEFUN(recv, (fd, buf, n, flags), + int fd AND PTR buf AND size_t n AND int flags) +{ + error_t err; + mach_port_t addrport; + char *bufp = buf; + mach_msg_type_number_t nread = n; + mach_port_t *ports; + mach_msg_type_number_t nports; + char *cdata = NULL; + mach_msg_type_number_t clen = 0; + + if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport, + flags, &bufp, &nread, + &ports, &nports, + &cdata, &clen, + &flags, + n))) + return __hurd_dfail (fd, err); + + __mach_port_deallocate (__mach_task_self (), addrport); + __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); + + if (bufp != buf) + { + memcpy (buf, bufp, nread); + __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread); + } + + return nread; +} diff --git a/sysdeps/mach/hurd/recvfrom.c b/sysdeps/mach/hurd/recvfrom.c new file mode 100644 index 0000000000..09d45c7cc8 --- /dev/null +++ b/sysdeps/mach/hurd/recvfrom.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <hurd/socket.h> +#include <string.h> + +/* Read N bytes into BUF through socket FD from peer + at address ADDR (which is ADDR_LEN bytes long). + Returns the number read or -1 for errors. */ +int +DEFUN(recvfrom, (fd, buf, n, flags, addr, addr_len), + int fd AND PTR buf AND size_t n AND int flags AND + struct sockaddr *addr AND size_t *addr_len) +{ + error_t err; + mach_port_t addrport; + char *bufp = buf; + mach_msg_type_number_t nread = n; + mach_port_t *ports; + mach_msg_type_number_t nports; + char *cdata = NULL; + mach_msg_type_number_t clen = 0; + + if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport, + flags, &bufp, &nread, + &ports, &nports, + &cdata, &clen, + &flags, + n))) + return __hurd_dfail (fd, err); + + /* Get address data for the returned address port. */ + { + char *buf = (char *) addr; + mach_msg_type_number_t buflen = *addr_len; + int type; + + err = __socket_whatis_address (addrport, &type, &buf, &buflen); + __mach_port_deallocate (__mach_task_self (), addrport); + if (err) + return __hurd_dfail (fd, err); + + if (buf != (char *) addr) + { + if (*addr_len < buflen) + *addr_len = buflen; + memcpy (addr, buf, *addr_len); + __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen); + } + + addr->sa_family = type; + } + + /* Toss control data; we don't care. */ + __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); + + if (bufp != buf) + { + memcpy (buf, bufp, nread); + __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread); + } + + return nread; +} + diff --git a/sysdeps/mach/hurd/rename.c b/sysdeps/mach/hurd/rename.c new file mode 100644 index 0000000000..63efbfb43f --- /dev/null +++ b/sysdeps/mach/hurd/rename.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <hurd.h> + +/* Rename the file OLD to NEW. */ +int +DEFUN(rename, (old, new), CONST char *old AND CONST char *new) +{ + error_t err; + file_t olddir, newdir; + const char *oldname, *newname; + + olddir = __file_name_split (old, (char **) &oldname); + if (olddir == MACH_PORT_NULL) + return -1; + newdir = __file_name_split (new, (char **) &newname); + if (newdir == MACH_PORT_NULL) + { + __mach_port_deallocate (__mach_task_self (), olddir); + return -1; + } + + err = __dir_rename (olddir, oldname, newdir, newname); + __mach_port_deallocate (__mach_task_self (), olddir); + __mach_port_deallocate (__mach_task_self (), newdir); + if (err) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/rewinddir.c b/sysdeps/mach/hurd/rewinddir.c new file mode 100644 index 0000000000..66a11d619f --- /dev/null +++ b/sysdeps/mach/hurd/rewinddir.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <dirent.h> +#include <sys/types.h> +#include <unistd.h> + + +/* Rewind DIRP to the beginning of the directory. */ +void +DEFUN(rewinddir, (dirp), DIR *dirp) +{ + seekdir (dirp, (off_t) 0L); +} diff --git a/sysdeps/mach/hurd/rmdir.c b/sysdeps/mach/hurd/rmdir.c new file mode 100644 index 0000000000..13a199f5ae --- /dev/null +++ b/sysdeps/mach/hurd/rmdir.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> + +/* Remove the directory FILE_NAME. */ +int +DEFUN(__rmdir, (file_name), CONST char *file_name) +{ + error_t err; + const char *name; + file_t parent = __file_name_split (file_name, (char **) &name); + if (parent == MACH_PORT_NULL) + return -1; + err = __dir_rmdir (parent, name); + __mach_port_deallocate (__mach_task_self (), parent); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__rmdir, rmdir) diff --git a/sysdeps/mach/hurd/sbrk.c b/sysdeps/mach/hurd/sbrk.c new file mode 100644 index 0000000000..855cab8a60 --- /dev/null +++ b/sysdeps/mach/hurd/sbrk.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> + +/* Extend the process's data space by INCREMENT. + If INCREMENT is negative, shrink data space by - INCREMENT. + Return the address of the start of the new data space, or -1 for errors. */ +PTR +DEFUN(__sbrk, (increment), int increment) +{ + PTR result; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_brk_lock); + result = (PTR) _hurd_brk; + if (increment != 0 && _hurd_set_brk (_hurd_brk + increment) < 0) + result = (PTR) -1; + __mutex_unlock (&_hurd_brk_lock); + HURD_CRITICAL_END; + + return result; +} + +weak_alias (__sbrk, sbrk) diff --git a/sysdeps/mach/hurd/seekdir.c b/sysdeps/mach/hurd/seekdir.c new file mode 100644 index 0000000000..9f585eba63 --- /dev/null +++ b/sysdeps/mach/hurd/seekdir.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <unistd.h> + +/* Seek to position POS in DIRP. */ +void +DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos) +{ + /* Change our entry index pointer to POS and discard any data already + read. The next `readdir' call will notice the empty block and read + anew from the location in DIRP->__entry_ptr and reset the other state + variables. */ + dirp->__entry_ptr = pos; + dirp->__size = 0; +} diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c new file mode 100644 index 0000000000..d1c5913cb8 --- /dev/null +++ b/sysdeps/mach/hurd/select.c @@ -0,0 +1,275 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <hurd.h> +#include <hurd/fd.h> +#include <stdlib.h> +#include <string.h> + + +/* Check the first NFDS descriptors each in READFDS (if not NULL) for read + readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS + (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out + after waiting the interval specified therein. Returns the number of ready + descriptors, or -1 for errors. */ +int +DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), + int nfds AND fd_set *readfds AND fd_set *writefds AND + fd_set *exceptfds AND struct timeval *timeout) +{ + int i; + mach_port_t port; + int got; + int *types; + struct hurd_userlink *ulink; + mach_port_t *ports; + struct hurd_fd **cells; + error_t err; + fd_set rfds, wfds, xfds; + int firstfd, lastfd; + mach_msg_timeout_t to = (timeout != NULL ? + (timeout->tv_sec * 1000 + + timeout->tv_usec / 1000) : + 0); + + /* Use local copies so we can't crash from user bogosity. */ + if (readfds == NULL) + FD_ZERO (&rfds); + else + rfds = *readfds; + if (writefds == NULL) + FD_ZERO (&wfds); + else + wfds = *writefds; + if (exceptfds == NULL) + FD_ZERO (&xfds); + else + xfds = *exceptfds; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + + if (nfds > _hurd_dtablesize) + nfds = _hurd_dtablesize; + + /* Collect the ports for interesting FDs. */ + cells = __alloca (nfds * sizeof (*cells)); + ports = __alloca (nfds * sizeof (*ports)); + types = __alloca (nfds * sizeof (*types)); + ulink = __alloca (nfds * sizeof (*ulink)); + firstfd = lastfd = -1; + for (i = 0; i < nfds; ++i) + { + int type = 0; + if (readfds != NULL && FD_ISSET (i, &rfds)) + type |= SELECT_READ; + if (writefds != NULL && FD_ISSET (i, &wfds)) + type |= SELECT_WRITE; + if (exceptfds != NULL && FD_ISSET (i, &xfds)) + type |= SELECT_URG; + types[i] = type; + if (type) + { + cells[i] = _hurd_dtable[i]; + ports[i] = _hurd_port_get (&cells[i]->port, &ulink[i]); + if (ports[i] == MACH_PORT_NULL) + { + /* If one descriptor is bogus, we fail completely. */ + while (i-- > 0) + _hurd_port_free (&cells[i]->port, &ulink[i], ports[i]); + errno = EBADF; + break; + } + lastfd = i; + if (firstfd == -1) + firstfd = i; + } + } + + __mutex_unlock (&_hurd_dtable_lock); + HURD_CRITICAL_END; + + if (i < nfds) + return -1; + + /* Get a port to receive the io_select_reply messages on. */ + port = __mach_reply_port (); + + /* Send them all io_select request messages. */ + got = 0; + err = 0; + for (i = firstfd; i <= lastfd; ++i) + if (types[i]) + { + if (!err) + { + int tag = i; + err = __io_select (ports[i], port, + /* Poll for each but the last. */ + (i == lastfd && got == 0) ? to : 0, + &types[i], &tag); + if (!err) + { + if (tag != i) + err = EGRATUITOUS; + else if (types[i] & (SELECT_READ|SELECT_URG|SELECT_WRITE)) + ++got; + } + } + _hurd_port_free (&cells[i]->port, &ulink[i], ports[i]); + } + + /* Now wait for reply messages. */ + if (!err && got == 0 && port != MACH_PORT_NULL) + { + /* Now wait for io_select_reply messages on PORT, + timing out as appropriate. */ + + union + { + mach_msg_header_t head; + struct + { + mach_msg_header_t head; + mach_msg_type_t err_type; + error_t err; + } error; + struct + { + mach_msg_header_t head; + mach_msg_type_t err_type; + error_t err; + mach_msg_type_t result_type; + int result; + mach_msg_type_t tag_type; + int tag; + } success; + } msg; + mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT); + error_t msgerr; + while ((msgerr = __mach_msg (&msg.head, + MACH_RCV_MSG | options, + sizeof msg, 0, port, to, + MACH_PORT_NULL)) == MACH_MSG_SUCCESS) + { + /* We got a message. Decode it. */ +#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */ + const mach_msg_type_t inttype = + { MACH_MSG_TYPE_INTEGER_32, 32, 1, 1, 0, 0 }; + if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID && + msg.head.msgh_size >= sizeof msg.error && + !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) && + *(int *) &msg.error.err_type == *(int *) &inttype) + { + /* This is a properly formatted message so far. + See if it is a success or a failure. */ + if (msg.error.err) + { + err = msg.error.err; + if (msg.head.msgh_size != sizeof msg.error) + __mach_msg_destroy (&msg); + } + else if (msg.head.msgh_size != sizeof msg.success || + *(int *) &msg.success.tag_type != *(int *) &inttype || + *(int *) &msg.success.result_type != *(int *) &inttype) + __mach_msg_destroy (&msg); + else if ((msg.success.result & + (SELECT_READ|SELECT_WRITE|SELECT_URG)) == 0 || + msg.success.tag < firstfd || msg.success.tag > lastfd) + err = EGRATUITOUS; + else + { + /* This is a winning io_select_reply message! + Record the readiness it indicates and send a reply. */ + if (types[msg.success.tag] == 0) + /* This descriptor is ready and it was not before, + so we increment our count of ready descriptors. */ + ++got; + types[msg.success.tag] |= msg.success.result; + } + } + + if (msg.head.msgh_remote_port != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), + msg.head.msgh_remote_port); + + if (got || err == EINTR) + { + /* Poll for another message. */ + to = 0; + options |= MACH_RCV_TIMEOUT; + } + } + + if (err == MACH_RCV_TIMED_OUT) + /* This is the normal value for ERR. We might have timed out and + read no messages. Otherwise, after receiving the first message, + we poll for more messages. We receive with a timeout of 0 to + effect a poll, so ERR is MACH_RCV_TIMED_OUT when the poll finds no + message waiting. */ + err = 0; + + if (got && err == EINTR) + /* Some calls were interrupted, but at least one descriptor + is known to be ready now, so we will return success. */ + err = 0; + } + + if (port != MACH_PORT_NULL) + /* We must destroy the port if we made some select requests + that might send notification on that port after we no longer care. + If the port were reused, that notification could confuse the next + select call to use the port. The notification might be valid, + but the descriptor may have changed to a different server. */ + __mach_port_destroy (__mach_task_self (), port); + + if (timeout && got == 0 && err == MACH_RCV_TIMED_OUT) + /* No io_select call returned success immediately, and the last call + blocked for our full timeout period and then timed out. So the + multiplex times out too. */ + return 0; + + if (err) + return __hurd_fail (err); + + /* Set the user bitarrays. */ + for (i = 0; i < nfds; ++i) + { + if (readfds != NULL) + if (types[i] & SELECT_READ) + FD_SET (i, readfds); + else + FD_CLR (i, readfds); + if (writefds != NULL) + if (types[i] & SELECT_WRITE) + FD_SET (i, writefds); + else + FD_CLR (i, writefds); + if (exceptfds != NULL) + if (types[i] & SELECT_URG) + FD_SET (i, exceptfds); + else + FD_CLR (i, exceptfds); + } + + return got; +} + +weak_alias (__select, select) diff --git a/sysdeps/mach/hurd/send.c b/sysdeps/mach/hurd/send.c new file mode 100644 index 0000000000..153ee93701 --- /dev/null +++ b/sysdeps/mach/hurd/send.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> + +/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ +int +DEFUN(send, (fd, buf, n, flags), + int fd AND PTR buf AND size_t n AND int flags) +{ + error_t err; + int wrote; + + err = HURD_DPORT_USE (fd, __socket_send (port, MACH_PORT_NULL, + flags, buf, n, + NULL, MACH_MSG_TYPE_COPY_SEND, 0, + NULL, 0, &wrote)); + + return err ? __hurd_dfail (fd, err) : wrote; +} diff --git a/sysdeps/mach/hurd/sendto.c b/sysdeps/mach/hurd/sendto.c new file mode 100644 index 0000000000..c3d4a4e121 --- /dev/null +++ b/sysdeps/mach/hurd/sendto.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> + +/* Send N bytes of BUF on socket FD to peer at address ADDR (which is + ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ +int +DEFUN(sendto, (fd, buf, n, flags, addr, addr_len), + int fd AND PTR buf AND size_t n AND int flags AND + struct sockaddr *addr AND size_t addr_len) +{ + addr_port_t aport; + error_t err; + int wrote; + + /* Get an address port for the desired destination address. */ + err = HURD_DPORT_USE (fd, + ({ + err = __socket_create_address (port, + addr->sa_family, + (char *) addr, + addr_len, + &aport, 1); + if (! err) + { + /* Send the data. */ + err = __socket_send (port, aport, + flags, buf, n, + NULL, + MACH_MSG_TYPE_COPY_SEND, 0, + NULL, 0, &wrote); + __mach_port_deallocate (__mach_task_self (), + aport); + } + err; + })); + + return err ? __hurd_dfail (fd, err) : wrote; +} diff --git a/sysdeps/mach/hurd/setegid.c b/sysdeps/mach/hurd/setegid.c new file mode 100644 index 0000000000..8ca4abee06 --- /dev/null +++ b/sysdeps/mach/hurd/setegid.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <sys/types.h> +#include <hurd/id.h> +#include <string.h> + +/* Set the effective user ID of the calling process to GID. */ +int +DEFUN(setegid, (gid), gid_t gid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has EGID as the first element in the + list of effective gids. */ + + size_t ngen = _hurd_id.gen.ngids < 1 ? 1 : _hurd_id.gen.ngids; + gid_t newgen[ngen]; + + newgen[0] = gid; + memcpy (&newgen[1], _hurd_id.gen.gids, (ngen - 1) * sizeof (gid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + _hurd_id.gen.uids, _hurd_id.gen.nuids, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + newgen, ngen, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} diff --git a/sysdeps/mach/hurd/seteuid.c b/sysdeps/mach/hurd/seteuid.c new file mode 100644 index 0000000000..9c44c4d275 --- /dev/null +++ b/sysdeps/mach/hurd/seteuid.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <sys/types.h> +#include <hurd/id.h> +#include <string.h> + +/* Set the effective user ID of the calling process to UID. */ +int +DEFUN(seteuid, (uid), uid_t uid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has EUID as the first element in the + list of effective uids. */ + + size_t ngen = _hurd_id.gen.nuids < 1 ? 1 : _hurd_id.gen.nuids; + uid_t newgen[ngen]; + + newgen[0] = uid; + memcpy (&newgen[1], _hurd_id.gen.uids, (ngen - 1) * sizeof (uid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + newgen, ngen, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + _hurd_id.gen.gids, _hurd_id.gen.ngids, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} diff --git a/sysdeps/mach/hurd/setgid.c b/sysdeps/mach/hurd/setgid.c new file mode 100644 index 0000000000..726b4130be --- /dev/null +++ b/sysdeps/mach/hurd/setgid.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +/* Set the group ID of the calling process to UID. + If the calling process is the super-user, the real + and effective group IDs, and the saved set-group-ID to UID; + if not, the effective group ID is set to GID. */ +int +DEFUN(__setgid, (gid), gid_t gid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has GID as the real gid, + and as the first element in the list of effective gids. */ + + gid_t newgen[_hurd_id.gen.ngids + 1]; + gid_t newaux[_hurd_id.aux.ngids]; + + newgen[0] = gid; + memcpy (&newgen[1], _hurd_id.gen.gids, + _hurd_id.gen.ngids * sizeof (gid_t)); + newaux[0] = gid; + memcpy (&newaux[1], _hurd_id.aux.gids, + (_hurd_id.aux.ngids - 1) * sizeof (gid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, 0, MACH_MSG_TYPE_COPY_SEND, + _hurd_id.gen.uids, _hurd_id.gen.nuids, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + newgen, 1 + _hurd_id.gen.ngids, + newaux, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} + +weak_alias (__setgid, setgid) diff --git a/sysdeps/mach/hurd/setgroups.c b/sysdeps/mach/hurd/setgroups.c new file mode 100644 index 0000000000..c3431477fb --- /dev/null +++ b/sysdeps/mach/hurd/setgroups.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <grp.h> +#include <hurd.h> +#include <hurd/id.h> + +/* Set the group set for the current user to GROUPS (N of them). */ +int +DEFUN(setgroups, (n, groups), size_t n AND CONST gid_t *groups) +{ + error_t err; + auth_t newauth; + size_t i; + gid_t new[n]; + + /* Fault before taking locks. */ + for (i = 0; i < n; ++i) + new[i] = groups[i]; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + if (! err) + { + /* Get a new auth port using those IDs. */ + err = __USEPORT (AUTH, + __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + _hurd_id.gen.uids, _hurd_id.gen.nuids, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + new, n, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new auth port and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} diff --git a/sysdeps/mach/hurd/sethostid.c b/sysdeps/mach/hurd/sethostid.c new file mode 100644 index 0000000000..dc8153caa6 --- /dev/null +++ b/sysdeps/mach/hurd/sethostid.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Set the current machine's Internet number to ID. + This call is restricted to the super-user. */ +int +DEFUN(sethostid, (id), long int id) +{ + error_t err = __USEPORT (PROC, __proc_sethostid (port, id)); + return err ? __hurd_fail (err) : 0; +} diff --git a/sysdeps/mach/hurd/sethostname.c b/sysdeps/mach/hurd/sethostname.c new file mode 100644 index 0000000000..2c019cf99e --- /dev/null +++ b/sysdeps/mach/hurd/sethostname.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Set the name of the current host to NAME, which is LEN bytes long. + This call is restricted to the super-user. */ +int +DEFUN(sethostname, (name, len), + CONST char *name AND size_t len) +{ + error_t err = __USEPORT (PROC, __proc_sethostname (port, name, len)); + if (err) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c new file mode 100644 index 0000000000..4351c5ea99 --- /dev/null +++ b/sysdeps/mach/hurd/setitimer.c @@ -0,0 +1,332 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/time.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/msg_request.h> +#include <mach/message.h> + +/* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM. */ + +spin_lock_t _hurd_itimer_lock = SPIN_LOCK_INITIALIZER; +struct itimerval _hurd_itimerval; /* Current state of the timer. */ +mach_port_t _hurd_itimer_port; /* Port the timer thread blocks on. */ +thread_t _hurd_itimer_thread; /* Thread waiting for timeout. */ +int _hurd_itimer_thread_suspended; /* Nonzero if that thread is suspended. */ +vm_address_t _hurd_itimer_thread_stack_base; /* Base of its stack. */ +vm_address_t _hurd_itimer_thread_stack_size; /* Size of its stack. */ +struct timeval _hurd_itimer_started; /* Time the thread started waiting. */ + +static inline void +subtract_timeval (struct timeval *from, const struct timeval *subtract) +{ + from->tv_usec -= subtract->tv_usec; + from->tv_sec -= subtract->tv_sec; + while (from->tv_usec < 0) + { + --from->tv_sec; + from->tv_usec += 1000000; + } +} + +/* Function run by the itimer thread. + This code must be very careful not ever to require a MiG reply port. */ + +static void +timer_thread (void) +{ + while (1) + { + error_t err; + /* The only message we ever expect to receive is the reply from the + signal thread to a sig_post call we did. We never examine the + contents. */ + struct + { + mach_msg_header_t header; + error_t return_code; + } msg; + + /* Wait for a message on a port that noone sends to. The purpose is + the receive timeout. Notice interrupts so that if we are + thread_abort'd, we will loop around and fetch new values from + _hurd_itimerval. */ + err = __mach_msg (&msg.header, + MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, _hurd_itimer_port, + _hurd_itimerval.it_value.tv_sec * 1000 + + _hurd_itimerval.it_value.tv_usec / 1000, + MACH_PORT_NULL); + switch (err) + { + case MACH_RCV_TIMED_OUT: + /* We got the expected timeout. Send a message to the signal + thread to tell it to post a SIGALRM signal. We use + _hurd_itimer_port as the reply port just so we will block until + the signal thread has frobnicated things to reload the itimer or + has terminated this thread. */ + __msg_sig_post_request (_hurd_msgport, + _hurd_itimer_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + SIGALRM, __mach_task_self ()); + break; + + case MACH_RCV_INTERRUPTED: + /* We were thread_abort'd. This is to tell us that + _hurd_itimerval has changed and we need to reexamine it + and start waiting with the new timeout value. */ + break; + + case MACH_MSG_SUCCESS: + /* We got the reply message from the sig_post_request above. + Ignore it and reexamine the timer value. */ + __mach_msg_destroy (&msg.header); /* Just in case. */ + break; + + default: + /* Unexpected lossage. Oh well, keep trying. */ + break; + } + } +} + +/* Forward declaration. */ +static sighandler_t preempt_sigalrm (thread_t thread, int signo, + long int sigcode, int sigerror); + +/* Called before any normal SIGALRM signal is delivered. + Reload the itimer, or disable the itimer. */ + +static int +setitimer_locked (const struct itimerval *new, struct itimerval *old, + void *crit) +{ + struct itimerval newval = *new; + struct timeval now, remaining, elapsed; + struct timeval old_interval; + error_t err; + + inline void kill_itimer_thread (void) + { + __thread_terminate (_hurd_itimer_thread); + __vm_deallocate (__mach_task_self (), + _hurd_itimer_thread_stack_base, + _hurd_itimer_thread_stack_size); + _hurd_itimer_thread = MACH_PORT_NULL; + } + + if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0) + { + /* Make sure the itimer thread is set up. */ + + if (_hurd_signal_preempt[SIGALRM] == NULL) + { + static struct hurd_signal_preempt preempt = + { preempt_sigalrm, 0, 0, NULL }; + _hurd_signal_preempt[SIGALRM] = &preempt; + } + + if (_hurd_itimer_port == MACH_PORT_NULL) + { + /* Allocate a receive right that the itimer thread will + block waiting for a message on. */ + if (err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, + &_hurd_itimer_port)) + goto out; + } + + if (_hurd_itimer_thread == MACH_PORT_NULL) + { + /* Start up the itimer thread running `timer_thread' (below). */ + if (err = __thread_create (__mach_task_self (), + &_hurd_itimer_thread)) + return __hurd_fail (err); + _hurd_itimer_thread_stack_base = 0; /* Anywhere. */ + _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack. */ + if (err = __mach_setup_thread (__mach_task_self (), + _hurd_itimer_thread, + &timer_thread, + &_hurd_itimer_thread_stack_base, + &_hurd_itimer_thread_stack_size)) + { + __thread_terminate (_hurd_itimer_thread); + _hurd_itimer_thread = MACH_PORT_NULL; + goto out; + } + _hurd_itimer_thread_suspended = 1; + } + } + + if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0 || old != NULL) + { + /* Calculate how much time is remaining for the pending alarm. */ + if (__gettimeofday (&now, NULL) < 0) + { + __spin_unlock (&_hurd_itimer_lock); + _hurd_critical_section_unlock (crit); + return -1; + } + elapsed = now; + subtract_timeval (&elapsed, &_hurd_itimer_started); + remaining = _hurd_itimerval.it_value; + if (timercmp (&remaining, &elapsed, <)) + { + /* Hmm. The timer should have just gone off, but has not been reset. + This is a possible timing glitch. The alarm will signal soon. */ + /* XXX wrong */ + remaining.tv_sec = 0; + remaining.tv_usec = 0; + } + else + subtract_timeval (&remaining, &elapsed); + + /* Remember the old reload interval before changing it. */ + old_interval = _hurd_itimerval.it_interval; + + /* Record the starting time that the timer interval relates to. */ + _hurd_itimer_started = now; + } + + /* Load the new itimer value. */ + _hurd_itimerval = newval; + + if ((newval.it_value.tv_sec | newval.it_value.tv_usec) == 0) + { + /* Disable the itimer. */ + if (_hurd_itimer_thread && !_hurd_itimer_thread_suspended) + { + /* Suspend the itimer thread so it does nothing. Then abort its + kernel context so that when the thread is resumed, mach_msg + will return to timer_thread (below) and it will fetch new + values from _hurd_itimerval. */ + if ((err = __thread_suspend (_hurd_itimer_thread)) || + (err = __thread_abort (_hurd_itimer_thread))) + /* If we can't save it for later, nuke it. */ + kill_itimer_thread (); + else + _hurd_itimer_thread_suspended = 1; + } + } + /* See if the timeout changed. If so, we must alert the itimer thread. */ + else if (remaining.tv_sec != new->it_value.tv_sec || + remaining.tv_usec != new->it_value.tv_usec) + { + /* The timeout value is changing. Tell the itimer thread to + reexamine it and start counting down. If the itimer thread is + marked as suspended, either we just created it, or it was + suspended and thread_abort'd last time the itimer was disabled; + either way it will wake up and start waiting for the new timeout + value when we resume it. If it is not suspended, the itimer + thread is waiting to deliver a pending alarm that we will override + (since it would come later than the new alarm being set); + thread_abort will make mach_msg return MACH_RCV_INTERRUPTED, so it + will loop around and use the new timeout value. */ + if (err = (_hurd_itimer_thread_suspended + ? __thread_resume : __thread_abort) (_hurd_itimer_thread)) + { + kill_itimer_thread (); + goto out; + } + _hurd_itimer_thread_suspended = 0; + } + + __spin_unlock (&_hurd_itimer_lock); + _hurd_critical_section_unlock (crit); + + if (old != NULL) + { + old->it_value = remaining; + old->it_interval = old_interval; + } + return 0; + + out: + __spin_unlock (&_hurd_itimer_lock); + _hurd_critical_section_unlock (crit); + return __hurd_fail (err); +} + +/* Set the timer WHICH to *NEW. If OLD is not NULL, + set *OLD to the old value of timer WHICH. + Returns 0 on success, -1 on errors. */ +int +DEFUN(__setitimer, (which, new, old), + enum __itimer_which which AND + struct itimerval *new AND struct itimerval *old) +{ + void *crit; + + switch (which) + { + default: + return __hurd_fail (EINVAL); + + case ITIMER_VIRTUAL: + case ITIMER_PROF: + return __hurd_fail (ENOSYS); + + case ITIMER_REAL: + break; + } + + crit = _hurd_critical_section_lock (); + __spin_lock (&_hurd_itimer_lock); + return setitimer_locked (new, old, crit); +} + +static sighandler_t +preempt_sigalrm (thread_t thread, int signo, long int sigcode, int sigerror) +{ + struct itimerval it; + + if (thread != _hurd_sigthread || signo != SIGALRM || sigcode != 0) + /* Too much monkey business. */ + return SIG_DFL; + + /* Either reload or disable the itimer. */ + __spin_lock (&_hurd_itimer_lock); + it = _hurd_itimerval; + it.it_value = it.it_interval; + setitimer_locked (&it, NULL, NULL); + + /* Continue with normal delivery of SIGALRM. */ + return SIG_DFL; +} + +static void +fork_itimer (void) +{ + /* We must restart the itimer in the child. */ + + struct itimerval it; + + __spin_lock (&_hurd_itimer_lock); + _hurd_itimer_thread = MACH_PORT_NULL; + it = _hurd_itimerval; + it.it_value = it.it_interval; + + setitimer_locked (&it, NULL, NULL); +} +text_set_element (_hurd_fork_child_hook, fork_itimer); + +weak_alias (__setitimer, setitimer) diff --git a/sysdeps/mach/hurd/setlogin.c b/sysdeps/mach/hurd/setlogin.c new file mode 100644 index 0000000000..867d8e25c9 --- /dev/null +++ b/sysdeps/mach/hurd/setlogin.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Set the login name returned by `getlogin'. */ +int +DEFUN(setlogin, (name), CONST char *name) +{ + error_t err; + if (err = __USEPORT (PROC, __proc_setlogin (port, name))) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/setpgid.c b/sysdeps/mach/hurd/setpgid.c new file mode 100644 index 0000000000..7c74ef8a4c --- /dev/null +++ b/sysdeps/mach/hurd/setpgid.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> + +/* Set the process group ID of the process matching PID to PGID. + If PID is zero, the current process's process group ID is set. + If PGID is zero, the process ID of the process is used. */ +int +DEFUN(__setpgid, (pid, pgid), pid_t pid AND pid_t pgid) +{ + error_t err; + unsigned int stamp; + + stamp = _hurd_pids_changed_stamp; /* Atomic fetch. */ + + if (err = __USEPORT (PROC, __proc_setpgrp (port, pid, pgid))) + return __hurd_fail (err); + + if (pid == 0 || pid == _hurd_pid) + /* Synchronize with the signal thread to make sure we have + received and processed proc_newids before returning to the user. */ + while (_hurd_pids_changed_stamp == stamp) + { +#ifdef noteven + /* XXX we have no need for a mutex, but cthreads demands one. */ + __condition_wait (&_hurd_pids_changed_sync, NULL); +#else + __swtch_pri(0); +#endif + } + + return 0; + +} + +weak_alias (__setpgid, setpgid) +weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/mach/hurd/setpriority.c b/sysdeps/mach/hurd/setpriority.c new file mode 100644 index 0000000000..644bfdf6fe --- /dev/null +++ b/sysdeps/mach/hurd/setpriority.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <hurd/resource.h> + +/* Set the priority of all processes specified by WHICH and WHO + to PRIO. Returns 0 on success, -1 on errors. */ +int +setpriority (enum __priority_which which, int who, int prio) +{ + error_t err; + error_t pidloser, priloser; + unsigned int npids, ntasks, nwin, nperm, nacces; + + error_t setonepriority (pid_t pid, struct procinfo *pi) + { + task_t task; + error_t piderr = __USEPORT (PROC, __proc_pid2task (port, pid, &task)); + if (piderr == EPERM) + ++nperm; + if (piderr != ESRCH) + { + ++npids; + if (piderr && piderr != EPERM) + pidloser = piderr; + } + if (! piderr) + { + error_t prierr; + ++ntasks; + prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1); + __mach_port_deallocate (__mach_task_self (), task); + switch (prierr) + { + case KERN_FAILURE: + ++nacces; + break; + case KERN_SUCCESS: + ++nwin; + break; + case KERN_INVALID_ARGUMENT: /* Task died. */ + --npids; + --ntasks; + break; + default: + priloser = prierr; + } + } + return 0; + } + + npids = ntasks = nwin = nperm = nacces = 0; + pidloser = priloser = 0; + err = _hurd_priority_which_map (which, who, setonepriority); + + if (!err && npids == 0) + /* No error, but no pids found. */ + err = ESRCH; + else if (nperm == npids) + /* Got EPERM from proc_task2pid for every process. */ + err = EPERM; + else if (nacces == ntasks) + /* Got KERN_FAILURE from task_priority for every task. */ + err = EACCES; + else if (nwin == 0) + err = pidloser ?: priloser; + + return err ? __hurd_fail (err) : 0; +} diff --git a/sysdeps/mach/hurd/setregid.c b/sysdeps/mach/hurd/setregid.c new file mode 100644 index 0000000000..8b76f7008a --- /dev/null +++ b/sysdeps/mach/hurd/setregid.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +int +__setregid (gid_t rgid, gid_t egid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has RGID as the real gid, + and EGID as the first element in the list of effective gids. */ + + size_t ngen = _hurd_id.gen.ngids < 1 ? 1 : _hurd_id.gen.ngids; + size_t naux = _hurd_id.aux.ngids < 1 ? 1 : _hurd_id.aux.ngids; + gid_t newaux[naux], newgen[ngen]; + + newgen[0] = egid; + memcpy (&newgen[1], _hurd_id.gen.gids, (ngen - 1) * sizeof (gid_t)); + newaux[0] = rgid; + memcpy (&newaux[1], _hurd_id.aux.gids, (naux - 1) * sizeof (gid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + _hurd_id.gen.gids, _hurd_id.gen.ngids, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + newgen, ngen, + newaux, naux, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} + +weak_alias (__setregid, setregid) diff --git a/sysdeps/mach/hurd/setreuid.c b/sysdeps/mach/hurd/setreuid.c new file mode 100644 index 0000000000..1dcbf0ee82 --- /dev/null +++ b/sysdeps/mach/hurd/setreuid.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +int +__setreuid (uid_t ruid, uid_t euid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has RUID as the real uid, + and EUID as the first element in the list of effective uids. */ + + size_t ngen = _hurd_id.gen.nuids < 1 ? 1 : _hurd_id.gen.nuids; + size_t naux = _hurd_id.aux.nuids < 1 ? 1 : _hurd_id.aux.nuids; + uid_t newaux[naux], newgen[ngen]; + + newgen[0] = euid; + memcpy (&newgen[1], _hurd_id.gen.uids, (ngen - 1) * sizeof (uid_t)); + newaux[0] = ruid; + memcpy (&newaux[1], _hurd_id.aux.uids, (naux - 1) * sizeof (uid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + newgen, ngen, + newaux, naux, + _hurd_id.gen.gids, _hurd_id.gen.ngids, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} + +weak_alias (__setreuid, setreuid) diff --git a/sysdeps/mach/hurd/setrlimit.c b/sysdeps/mach/hurd/setrlimit.c new file mode 100644 index 0000000000..6d60d6dd57 --- /dev/null +++ b/sysdeps/mach/hurd/setrlimit.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <hurd.h> +#include <hurd/resource.h> +#include <errno.h> +#include <hurd/fd.h> + + +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int +DEFUN(setrlimit, (resource, rlimits), + enum __rlimit_resource resource AND struct rlimit *rlimits) +{ + struct rlimit lim; + + if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS) + { + errno = EINVAL; + return -1; + } + + lim = *rlimits; + + if (lim.rlim_max != RLIM_INFINITY) + { + /* We have no enforceable resource limits. */ + errno = ENOSYS; + return -1; + } + + if (lim.rlim_cur > lim.rlim_max) + lim.rlim_cur = lim.rlim_max; + + __mutex_lock (&_hurd_rlimit_lock); + _hurd_rlimits[resource] = lim; + __mutex_unlock (&_hurd_rlimit_lock); + + return 0; +} diff --git a/sysdeps/mach/hurd/setsid.c b/sysdeps/mach/hurd/setsid.c new file mode 100644 index 0000000000..22dc965344 --- /dev/null +++ b/sysdeps/mach/hurd/setsid.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/port.h> + + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +int +DEFUN_VOID(__setsid) +{ + error_t err; + unsigned int stamp; + + stamp = _hurd_pids_changed_stamp; /* Atomic fetch. */ + + /* Tell the proc server we want to start a new session. */ + if (err = __USEPORT (PROC, __proc_setsid (port))) + return __hurd_fail (err); + + /* Punt our current ctty. */ + _hurd_setcttyid (MACH_PORT_NULL); + + /* Synchronize with the signal thread to make sure we have + received and processed proc_newids before returning to the user. */ + while (_hurd_pids_changed_stamp == stamp) + { +#ifdef noteven + /* XXX we have no need for a mutex, but cthreads demands one. */ + __condition_wait (&_hurd_pids_changed_sync, NULL); +#else + __swtch_pri(0); +#endif + } + + return 0; +} + +weak_alias (__setsid, setsid) diff --git a/sysdeps/mach/hurd/setsockopt.c b/sysdeps/mach/hurd/setsockopt.c new file mode 100644 index 0000000000..4d527696fe --- /dev/null +++ b/sysdeps/mach/hurd/setsockopt.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> + +/* Set socket FD's option OPTNAME at protocol level LEVEL + to *OPTVAL (which is OPTLEN bytes long). + Returns 0 on success, -1 for errors. */ +int +DEFUN(setsockopt, (fd, level, optname, optval, optlen), + int fd AND int level AND int optname AND + PTR optval AND size_t optlen) +{ + error_t err = HURD_DPORT_USE (fd, __socket_setopt (port, + level, optname, + optval, optlen)); + if (err) + return __hurd_dfail (fd, err); + return 0; +} diff --git a/sysdeps/mach/hurd/settimeofday.c b/sysdeps/mach/hurd/settimeofday.c new file mode 100644 index 0000000000..1747a443a4 --- /dev/null +++ b/sysdeps/mach/hurd/settimeofday.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> +#include <hurd.h> +#include <hurd/port.h> + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +int +DEFUN(__settimeofday, (tv, tz), + CONST struct timeval *tv AND CONST struct timezone *tz) +{ + error_t err; + mach_port_t hostpriv, devmaster; + + if (tz != NULL) + { + errno = ENOSYS; + return -1; + } + + if (err = __USEPORT (PROC, __proc_getprivports (port, + &hostpriv, &devmaster))) + return __hurd_fail (err); + __mach_port_deallocate (__mach_task_self (), devmaster); + + /* `time_value_t' and `struct timeval' are in fact identical with the + names changed. */ + err = __host_set_time (hostpriv, *(time_value_t *) tv); + __mach_port_deallocate (__mach_task_self (), hostpriv); + + if (err) + return __hurd_fail (err); + + return 0; +} + +weak_alias (__settimeofday, settimeofday) diff --git a/sysdeps/mach/hurd/setuid.c b/sysdeps/mach/hurd/setuid.c new file mode 100644 index 0000000000..7084038b0b --- /dev/null +++ b/sysdeps/mach/hurd/setuid.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <hurd.h> +#include <hurd/id.h> +#include <string.h> + +/* Set the user ID of the calling process to UID. + If the calling process is the super-user, the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID. */ +int +DEFUN(__setuid, (uid), uid_t uid) +{ + auth_t newauth; + error_t err; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); + err = _hurd_check_ids (); + + if (!err) + { + /* Make a new auth handle which has UID as the real uid, + and as the first element in the list of effective uids. */ + + uid_t newgen[_hurd_id.gen.nuids + 1]; + uid_t newaux[_hurd_id.aux.nuids]; + + newgen[0] = uid; + memcpy (&newgen[1], _hurd_id.gen.uids, + _hurd_id.gen.nuids * sizeof (uid_t)); + newaux[0] = uid; + memcpy (&newaux[1], _hurd_id.aux.uids, + (_hurd_id.aux.nuids - 1) * sizeof (uid_t)); + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, 0, MACH_MSG_TYPE_COPY_SEND, + _hurd_id.gen.uids, _hurd_id.gen.nuids, + _hurd_id.aux.uids, _hurd_id.aux.nuids, + newgen, 1 + _hurd_id.gen.nuids, + newaux, _hurd_id.aux.nuids, + &newauth)); + } + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + + if (err) + return __hurd_fail (err); + + /* Install the new handle and reauthenticate everything. */ + err = __setauth (newauth); + __mach_port_deallocate (__mach_task_self (), newauth); + return err; +} + +weak_alias (__setuid, setuid) diff --git a/sysdeps/mach/hurd/shutdown.c b/sysdeps/mach/hurd/shutdown.c new file mode 100644 index 0000000000..685057b709 --- /dev/null +++ b/sysdeps/mach/hurd/shutdown.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> + +/* Shut down all or part of the connection open on socket FD. + HOW determines what to shut down: + 0 = No more receptions; + 1 = No more transmissions; + 2 = No more receptions or transmissions. + Returns 0 on success, -1 for errors. */ +int +DEFUN(shutdown, (fd, how), + int fd AND int how) +{ + error_t err = HURD_DPORT_USE (fd, __socket_shutdown (port, how)); + if (err) + return __hurd_dfail (fd, err); + return 0; +} diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c new file mode 100644 index 0000000000..91de02cd17 --- /dev/null +++ b/sysdeps/mach/hurd/sigaction.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <hurd.h> +#include <hurd/signal.h> + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +DEFUN(__sigaction, (sig, act, oact), + int sig AND CONST struct sigaction *act AND struct sigaction *oact) +{ + struct hurd_sigstate *ss; + struct sigaction a, old; + sigset_t pending; + + if (sig <= 0 || sig >= NSIG || + (act != NULL && act->sa_handler != SIG_DFL && + ((__sigmask (sig) & _SIG_CANT_MASK) || + act->sa_handler == SIG_ERR))) + { + errno = EINVAL; + return -1; + } + + /* Copy so we fault before taking locks. */ + if (act != NULL) + a = *act; + + ss = _hurd_self_sigstate (); + + __spin_lock (&ss->lock); + old = ss->actions[sig]; + if (act != NULL) + ss->actions[sig] = a; + + if (act != NULL && sig == SIGCHLD) + { + ss->critical_section = 1; + __spin_unlock (&ss->lock); + + /* Inform the proc server whether or not it should send us SIGCHLD for + stopped children. We do this in a critical section so that no + SIGCHLD can arrive in the middle and be of indeterminate status. */ + __USEPORT (PROC, + __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP))); + + __spin_lock (&ss->lock); + ss->critical_section = 0; + pending = ss->pending & ~ss->blocked; + } + else + pending = 0; + + __spin_unlock (&ss->lock); + + if (pending) + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + + if (oact != NULL) + *oact = old; + + return 0; +} + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/mach/hurd/sigaltstack.c b/sysdeps/mach/hurd/sigaltstack.c new file mode 100644 index 0000000000..c4a905213c --- /dev/null +++ b/sysdeps/mach/hurd/sigaltstack.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/signal.h> + +/* Run signals handlers on the stack specified by SS (if not NULL). + If OSS is not NULL, it is filled in with the old signal stack status. */ +int +DEFUN(sigaltstack, (ss, oss), + CONST struct sigaltstack *argss AND struct sigaltstack *oss) +{ + struct hurd_sigstate *s; + struct sigaltstack ss, old; + + /* Fault before taking any locks. */ + if (argss != NULL) + ss = *argss; + if (oss != NULL) + *(volatile struct sigaltstack *) oss = *oss; + + s = _hurd_self_sigstate (); + __spin_lock (&s->lock); + + if (argss != NULL && + (ss.ss_flags & SA_DISABLE) && (s->sigaltstack.ss_flags & SA_ONSTACK)) + { + /* Can't disable a stack that is in use. */ + __spin_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + old = s->sigaltstack; + + if (argss != NULL) + s->sigaltstack = ss; + + __spin_unlock (&s->lock); + + if (oss != NULL) + *oss = old; + + return 0; +} diff --git a/sysdeps/mach/hurd/sigpending.c b/sysdeps/mach/hurd/sigpending.c new file mode 100644 index 0000000000..8c12ed0bbf --- /dev/null +++ b/sysdeps/mach/hurd/sigpending.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <hurd.h> +#include <hurd/signal.h> + + +/* Store in SET all signals that are blocked and pending. */ +int +DEFUN(sigpending, (set), sigset_t *set) +{ + struct hurd_sigstate *ss; + sigset_t pending; + + if (set == NULL) + { + errno = EINVAL; + return -1; + } + + ss = _hurd_self_sigstate (); + __spin_lock (&ss->lock); + pending = ss->pending; + __spin_unlock (&ss->lock); + + *set = pending; + return 0; +} diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c new file mode 100644 index 0000000000..bae3266708 --- /dev/null +++ b/sysdeps/mach/hurd/sigprocmask.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/msg.h> + + +/* If SET is not NULL, modify the current set of blocked signals + according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK. + If OSET is not NULL, store the old set of blocked signals in *OSET. */ +int +DEFUN(__sigprocmask, (how, set, oset), + int how AND CONST sigset_t *set AND sigset_t *oset) +{ + struct hurd_sigstate *ss; + sigset_t old, new; + sigset_t pending; + + if (set != NULL) + new = *set; + + ss = _hurd_self_sigstate (); + + __spin_lock (&ss->lock); + + old = ss->blocked; + + if (set != NULL) + { + switch (how) + { + case SIG_BLOCK: + ss->blocked |= new; + break; + + case SIG_UNBLOCK: + ss->blocked &= ~new; + break; + + case SIG_SETMASK: + ss->blocked = new; + break; + + default: + __spin_unlock (&ss->lock); + errno = EINVAL; + return -1; + } + + ss->blocked &= ~_SIG_CANT_MASK; + } + + pending = ss->pending & ~ss->blocked; + + __spin_unlock (&ss->lock); + + if (oset != NULL) + *oset = old; + + if (pending) + /* Send a message to the signal thread so it + will wake up and check for pending signals. */ + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + + return 0; +} + +weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/mach/hurd/sigstack.c b/sysdeps/mach/hurd/sigstack.c new file mode 100644 index 0000000000..77803ab012 --- /dev/null +++ b/sysdeps/mach/hurd/sigstack.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <hurd.h> + +/* Run signals handlers on the stack specified by SS (if not NULL). + If OSS is not NULL, it is filled in with the old signal stack status. */ +int +DEFUN(sigstack, (ss, oss), + CONST struct sigstack *ss AND struct sigstack *oss) +{ + struct sigaltstack as, oas; + + as.ss_sp = ss->ss_sp; + as.ss_size = 0; + as.ss_flags = 0; + + if (sigaltstack (&as, &oas) < 0) + return -1; + + if (oss != NULL) + { + oss->ss_sp = oas.ss_sp; + oss->ss_onstack = oas.ss_flags & SA_ONSTACK; + } + + return 0; +} diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c new file mode 100644 index 0000000000..aa0b2876a4 --- /dev/null +++ b/sysdeps/mach/hurd/sigsuspend.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/signal.h> +#include <hurd/msg.h> + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +int +DEFUN(sigsuspend, (set), CONST sigset_t *set) +{ + struct hurd_sigstate *ss; + sigset_t newmask, oldmask, pending; + mach_port_t wait; + mach_msg_header_t msg; + + if (set != NULL) + /* Crash before locking. */ + newmask = *set; + + /* Get a fresh port we will wait on. */ + wait = __mach_reply_port (); + + ss = _hurd_self_sigstate (); + + __spin_lock (&ss->lock); + + oldmask = ss->blocked; + if (set != NULL) + /* Change to the new blocked signal mask. */ + ss->blocked = newmask & ~_SIG_CANT_MASK; + + /* Notice if any pending signals just became unblocked. */ + pending = ss->pending & ~ss->blocked; + + /* Tell the signal thread to message us when a signal arrives. */ + ss->suspended = wait; + __spin_unlock (&ss->lock); + + if (pending) + /* Tell the signal thread to check for pending signals. */ + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + + /* Wait for the signal thread's message. */ + __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __mach_port_destroy (__mach_task_self (), wait); + + __spin_lock (&ss->lock); + ss->blocked = oldmask; /* Restore the old mask. */ + pending = ss->pending & ~ss->blocked; /* Again check for pending signals. */ + __spin_unlock (&ss->lock); + + if (pending) + /* Tell the signal thread to check for pending signals. */ + __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + + /* We've been interrupted! And a good thing, too. + Otherwise we'd never return. + That's right; this function always returns an error. */ + errno = EINTR; + return -1; +} diff --git a/sysdeps/mach/hurd/socket.c b/sysdeps/mach/hurd/socket.c new file mode 100644 index 0000000000..b779360780 --- /dev/null +++ b/sysdeps/mach/hurd/socket.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> +#include <fcntl.h> + +/* Create a new socket of type TYPE in domain DOMAIN, using + protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. + Returns a file descriptor for the new socket, or -1 for errors. */ +int +DEFUN(socket, (domain, type, protocol), + int domain AND enum __socket_type type AND int protocol) +{ + error_t err; + socket_t sock, server; + + /* Find the socket server for DOMAIN. */ + server = _hurd_socket_server (domain, 0); + if (server == MACH_PORT_NULL) + return -1; + + err = __socket_create (server, type, protocol, &sock); + if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + { + /* On the first use of the socket server during the operation, + allow for the old server port dying. */ + server = _hurd_socket_server (domain, 1); + if (server == MACH_PORT_NULL) + return -1; + err = __socket_create (server, type, protocol, &sock); + } + + if (err) + return __hurd_fail (err); + + return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1); +} diff --git a/sysdeps/mach/hurd/socketpair.c b/sysdeps/mach/hurd/socketpair.c new file mode 100644 index 0000000000..c4d09c707a --- /dev/null +++ b/sysdeps/mach/hurd/socketpair.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> +#include <hurd.h> +#include <hurd/socket.h> +#include <hurd/fd.h> +#include <unistd.h> +#include <fcntl.h> + +/* Create two new sockets, of type TYPE in domain DOMAIN and using + protocol PROTOCOL, which are connected to each other, and put file + descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, + one will be chosen automatically. Returns 0 on success, -1 for errors. */ +int +DEFUN(socketpair, (domain, type, protocol, fds), + int domain AND enum __socket_type type AND int protocol AND int fds[2]) +{ + error_t err; + socket_t server, sock1, sock2; + int d1, d2; + + if (fds == NULL) + return __hurd_fail (EINVAL); + + /* Find the domain's socket server. */ + server = _hurd_socket_server (domain, 0); + if (server == MACH_PORT_NULL) + return -1; + + /* Create two sockets and connect them together. */ + + err = __socket_create (server, type, protocol, &sock1); + if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + { + /* On the first use of the socket server during the operation, + allow for the old server port dying. */ + server = _hurd_socket_server (domain, 1); + if (server == MACH_PORT_NULL) + return -1; + err = __socket_create (server, type, protocol, &sock1); + } + if (err) + return __hurd_fail (err); + if (err = __socket_create (server, type, protocol, &sock2)) + { + __mach_port_deallocate (__mach_task_self (), sock1); + return __hurd_fail (err); + } + if (err = __socket_connect2 (sock1, sock2)) + { + __mach_port_deallocate (__mach_task_self (), sock1); + __mach_port_deallocate (__mach_task_self (), sock2); + return __hurd_fail (err); + } + + /* Put the sockets into file descriptors. */ + + d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1); + if (d1 < 0) + { + __mach_port_deallocate (__mach_task_self (), sock2); + return -1; + } + d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1); + if (d2 < 0) + { + err = errno; + (void) close (d1); + return __hurd_fail (err); + } + + fds[0] = d1; + fds[1] = d2; + return 0; +} diff --git a/sysdeps/mach/hurd/start.c b/sysdeps/mach/hurd/start.c new file mode 100644 index 0000000000..91be7eaefe --- /dev/null +++ b/sysdeps/mach/hurd/start.c @@ -0,0 +1,316 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <hurd.h> +#include <hurd/exec.h> +#include <sysdep.h> +#include <hurd/threadvar.h> +#include "set-hooks.h" +#include "hurdmalloc.h" /* XXX */ + +/* The first piece of initialized data. */ +int __data_start = 0; +weak_alias (__data_start, data_start) + +mach_port_t *_hurd_init_dtable; +mach_msg_type_number_t _hurd_init_dtablesize; + +unsigned int __hurd_threadvar_max; +unsigned long int __hurd_threadvar_stack_mask; +unsigned long int __hurd_threadvar_stack_offset; + +/* These are set up by _hurdsig_init. */ +unsigned long int __hurd_sigthread_stack_base; +unsigned long int __hurd_sigthread_stack_end; +unsigned long int *__hurd_sigthread_variables; + +vm_address_t _hurd_stack_base; +vm_size_t _hurd_stack_size; + +char **__environ; +weak_alias (__environ, environ) + +/* Things that want to be run before _hurd_init or much anything else. + Importantly, these are called before anything tries to use malloc. */ +DEFINE_HOOK (_hurd_preinit_hook, (void)); + +extern void __mach_init (void); +extern void __libc_init (int argc, char **argv, char **envp); +extern int main (int argc, char **argv, char **envp); + +void *(*_cthread_init_routine) (void); /* Returns new SP to use. */ +void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__)); + +int _hurd_split_args (char *, size_t, char **); + +/* These communicate values from _start to start1, + where we cannot use the stack for anything. */ +static char *args, *env; +static mach_port_t *portarray; +static int *intarray; +static mach_msg_type_number_t argslen, envlen, portarraysize, intarraysize; +static int flags; +static char **argv, **envp; +static int argc; + + +static void start1 (void) __attribute__ ((__noreturn__)); + + +/* Entry point. This is the first thing in the text segment. + + The exec server started the initial thread in our task with this spot the + PC, and a stack that is presumably big enough. We do basic Mach + initialization so mig-generated stubs work, and then do an exec_startup + RPC on our bootstrap port, to which the exec server responds with the + information passed in the exec call, as well as our original bootstrap + port, and the base address and size of the preallocated stack. + + If using cthreads, we are given a new stack by cthreads initialization and + deallocate the stack set up by the exec server. On the new stack we call + `start1' (above) to do the rest of the startup work. Since the stack may + disappear out from under us in a machine-dependent way, we use a pile of + static variables to communicate the information from exec_startup to start1. + This is unfortunate but preferable to machine-dependent frobnication to copy + the state from the old stack to the new one. */ + +#ifndef START_ARGS +#define START_ARGS void +#endif +#ifdef START_MACHDEP +START_MACHDEP +#define _start _start0 +#endif + +void +_start (START_ARGS) +{ + error_t err; + mach_port_t in_bootstrap; + + /* Basic Mach initialization, must be done before RPCs can be done. */ + __mach_init (); + + /* Run things that want to do initialization as soon as possible. We do + this before exec_startup so that no out of line data arrives and + clutters up the address space before brk initialization. */ + + RUN_HOOK (_hurd_preinit_hook, ()); + + if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, + &in_bootstrap)) + LOSE; + + if (in_bootstrap != MACH_PORT_NULL) + { + /* Call the exec server on our bootstrap port and + get all our standard information from it. */ + + argslen = envlen = 0; + _hurd_init_dtablesize = portarraysize = intarraysize = 0; + + err = __exec_startup (in_bootstrap, + &_hurd_stack_base, &_hurd_stack_size, + &flags, + &args, &argslen, &env, &envlen, + &_hurd_init_dtable, &_hurd_init_dtablesize, + &portarray, &portarraysize, + &intarray, &intarraysize); + __mach_port_deallocate (__mach_task_self (), in_bootstrap); + } + + if (err || in_bootstrap == MACH_PORT_NULL) + { + /* Either we have no bootstrap port, or the RPC to the exec server + failed. Try to snarf the args in the canonical Mach way. + Hopefully either they will be on the stack as expected, or the + stack will be zeros so we don't crash. Set all our other + variables to have empty information. */ + + /* SNARF_ARGS (ARGC, ARGV, ENVP) snarfs the arguments and environment + from the stack, assuming they were put there by the microkernel. */ + SNARF_ARGS (argc, argv, envp); + + flags = 0; + args = env = NULL; + argslen = envlen = 0; + _hurd_init_dtable = NULL; + _hurd_init_dtablesize = 0; + portarray = NULL; + portarraysize = 0; + intarray = NULL; + intarraysize = 0; + } + else + argv = envp = NULL; + + + /* The user might have defined a value for this, to get more variables. + Otherwise it will be zero on startup. We must make sure it is set + properly before before cthreads initialization, so cthreads can know + how much space to leave for thread variables. */ + if (__hurd_threadvar_max < _HURD_THREADVAR_MAX) + __hurd_threadvar_max = _HURD_THREADVAR_MAX; + + /* Do cthreads initialization and switch to the cthread stack. */ + + if (_cthread_init_routine != NULL) + CALL_WITH_SP (start1, (*_cthread_init_routine) ()); + else + start1 (); + + /* Should never get here. */ + LOSE; +} + + +static void +start1 (void) +{ + register int envc = 0; + + { + /* Check if the stack we are now on is different from + the one described by _hurd_stack_{base,size}. */ + + char dummy; + const vm_address_t newsp = (vm_address_t) &dummy; + + if (_hurd_stack_size != 0 && (newsp < _hurd_stack_base || + newsp - _hurd_stack_base > _hurd_stack_size)) + /* The new stack pointer does not intersect with the + stack the exec server set up for us, so free that stack. */ + __vm_deallocate (__mach_task_self (), + _hurd_stack_base, _hurd_stack_size); + } + + if (__hurd_threadvar_stack_mask == 0) + { + /* We are not using cthreads, so we will have just a single allocated + area for the per-thread variables of the main user thread. */ + unsigned long int i; + __hurd_threadvar_stack_offset + = (unsigned long int) malloc (__hurd_threadvar_max * + sizeof (unsigned long int)); + if (__hurd_threadvar_stack_offset == 0) + __libc_fatal ("Can't allocate single-threaded per-thread variables."); + for (i = 0; i < __hurd_threadvar_max; ++i) + ((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0; + } + + + /* Turn the block of null-separated strings we were passed for the + arguments and environment into vectors of pointers to strings. */ + + if (! argv) + { + if (args) + /* Count up the arguments so we can allocate ARGV. */ + argc = _hurd_split_args (args, argslen, NULL); + if (! args || argc == 0) + { + /* No arguments passed; set argv to { NULL }. */ + argc = 0; + args = NULL; + argv = (char **) &args; + } + } + + if (! envp) + { + if (env) + /* Count up the environment variables so we can allocate ENVP. */ + envc = _hurd_split_args (env, envlen, NULL); + if (! env || envc == 0) + { + /* No environment passed; set __environ to { NULL }. */ + env = NULL; + envp = (char **) &env; + } + } + + if (! argv) + { + /* There were some arguments. + Allocate space for the vectors of pointers and fill them in. */ + argv = __alloca ((argc + 1) * sizeof (char *)); + _hurd_split_args (args, argslen, argv); + } + + if (! envp) + { + /* There was some environment. + Allocate space for the vectors of pointers and fill them in. */ + envp = __alloca ((envc + 1) * sizeof (char *)); + _hurd_split_args (env, envlen, envp); + } + + __environ = envp; + + if (portarray || intarray) + /* Initialize library data structures, start signal processing, etc. */ + _hurd_init (flags, argv, portarray, portarraysize, intarray, intarraysize); + + /* Random library initialization. These functions may assume that + _hurd_init has already run (if it is going to), and POSIX.1 facilities + are initialized and available. */ + __libc_init (argc, argv, __environ); + + /* Finally, run the user program. */ + (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit) + (main (argc, argv, __environ)); + + /* Should never get here. */ + LOSE; +} + +/* Split ARGSLEN bytes at ARGS into words, breaking at NUL characters. If + ARGV is not a null pointer, store a pointer to the start of each word in + ARGV[n], and null-terminate ARGV. Return the number of words split. */ + +int +_hurd_split_args (char *args, size_t argslen, char **argv) +{ + char *p = args; + size_t n = argslen; + int argc = 0; + + while (n > 0) + { + char *end = memchr (p, '\0', n); + + if (argv) + argv[argc] = p; + ++argc; + + if (end == NULL) + /* The last argument is unterminated. */ + break; + + n -= end + 1 - p; + p = end + 1; + } + + if (argv) + argv[argc] = NULL; + return argc; +} diff --git a/sysdeps/mach/hurd/stat.c b/sysdeps/mach/hurd/stat.c new file mode 100644 index 0000000000..e6df5e66eb --- /dev/null +++ b/sysdeps/mach/hurd/stat.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/stat.h> +#include <stddef.h> +#include <hurd.h> + +/* Get file information about FILE in BUF. */ +int +DEFUN(__stat, (file, buf), CONST char *file AND struct stat *buf) +{ + error_t err; + file_t port = __file_name_lookup (file, 0, 0); + if (port == MACH_PORT_NULL) + return -1; + err = __io_stat (port, buf); + __mach_port_deallocate (__mach_task_self (), port); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__stat, stat) diff --git a/sysdeps/mach/hurd/statbuf.h b/sysdeps/mach/hurd/statbuf.h new file mode 100644 index 0000000000..4d97dc1c55 --- /dev/null +++ b/sysdeps/mach/hurd/statbuf.h @@ -0,0 +1,119 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H + +#define _STATBUF_H 1 + +#include <gnu/types.h> + +/* NOTE: The size of this structure (32 ints) is known in + <hurd/hurd_types.defs>, since it is used in the `io_stat' RPC. MiG + does not cope at all well with the passed C structure not being of + the expected size. There are some filler words at the end to allow + for future expansion. To increase the size of the structure used + in the RPC and retain binary compatibility, we would need to assign + a new message number. */ + +struct stat + { + int st_fstype; /* File system type. */ + __fsid_t st_fsid; /* File system ID. */ +#define st_dev st_fsid + + __ino_t st_ino; /* File number. */ + unsigned int st_gen; /* To detect reuse of file numbers. */ + __dev_t st_rdev; /* Device if special file. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Number of links. */ + + __uid_t st_uid; /* Owner. */ + __gid_t st_gid; /* Owning group. */ + + __off_t st_size; /* Size in bytes. */ + + __time_t st_atime; /* Access time, seconds */ + unsigned long int st_atime_usec; /* and microseconds. */ + __time_t st_mtime; /* Modification time, seconds */ + unsigned long int st_mtime_usec; /* and microseconds. */ + __time_t st_ctime; /* Status change time, seconds */ + unsigned long int st_ctime_usec; /* and microseconds. */ + + unsigned int st_blksize; /* Optimal size for I/O. */ + +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + + unsigned int st_blocks; /* Number of 512-byte blocks allocated. + Not related to `st_blksize'. */ + + __uid_t st_author; /* File author. */ + + unsigned int st_flags; /* User-defined flags. + High 16 bits can be set only by root. */ + + int st_spare[11]; /* Room for future expansion. */ + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 00400 /* Read by owner. */ +#define __S_IWRITE 00200 /* Write by owner. */ +#define __S_IEXEC 00100 /* Execute by owner. */ + + +#ifdef __USE_GNU +/* If set, there is no benefit in caching the contents of this file. */ +#define S_INOCACHE 000000200000 + +/* If the S_IUSEUNK bit is set, then the S_IUNKNOWN bits (see below) + control access for unknown users. If S_IUSEUNK is clear, then unknown + users are treated as "others" for purposes of access control. */ +#define S_IUSEUNK 000000400000 +/* Mask of protection bits for unknown users (no effective IDs at all). */ +#define S_IUNKNOWN 000007000000 +/* Shift S_IREAD, S_IWRITE, S_IEXEC left this many bits to produce the + protection bits for unknown users. */ +#define S_IUNKSHIFT 12 + +/* All the unused bits. */ +#define S_ISPARE (~(S_IFMT|S_INOCACHE|S_IUNKNOWN|07777)) +#endif + +/* Default file creation mask (umask). */ +#ifdef __USE_BSD +#define CMASK 0022 +#endif + + +#endif /* statbuf.h */ diff --git a/sysdeps/mach/hurd/stdio_init.c b/sysdeps/mach/hurd/stdio_init.c new file mode 100644 index 0000000000..f083ee85dc --- /dev/null +++ b/sysdeps/mach/hurd/stdio_init.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <hurd/fd.h> +#include <hurd/io.h> +#include <hurd/term.h> + +/* Initialize STREAM as necessary. + This may change I/O functions, give a buffer, etc. + If no buffer is allocated, but the bufsize is set, + the bufsize will be used to allocate the buffer. */ +void +DEFUN(__stdio_init_stream, (stream), FILE *stream) +{ + struct hurd_fd *const d = stream->__cookie; + struct stat statb; + error_t err; + + if (stream->__buffer != NULL || stream->__userbuf) + /* If's unbuffered by request, we can't do anything useful. */ + return; + + /* Find out what sort of file this is. */ + if (err = HURD_FD_PORT_USE (d, __io_stat (port, &statb))) + return; + + if (S_ISCHR (statb.st_mode)) + { + /* It's a character device. + Make it line-buffered if it's a terminal. */ + mach_port_t cttyid; + err = HURD_FD_PORT_USE (d, __term_getctty (port, &cttyid)); + if (! err) + { + __mach_port_deallocate (__mach_task_self (), cttyid); + stream->__linebuf = 1; + } + } + + /* Use the block-size field to determine + the system's optimal buffering size. */ + stream->__bufsize = statb.st_blksize; +} diff --git a/sysdeps/mach/hurd/symlink.c b/sysdeps/mach/hurd/symlink.c new file mode 100644 index 0000000000..5e67c4e452 --- /dev/null +++ b/sysdeps/mach/hurd/symlink.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/paths.h> +#include <fcntl.h> + +/* Make a link to FROM called TO. */ +int +DEFUN(__symlink, (from, to), CONST char *from AND CONST char *to) +{ + error_t err; + file_t dir, node; + char *name; + const size_t len = strlen (from) + 1; + char buf[sizeof (_HURD_SYMLINK) + len]; + + /* A symlink is a file whose translator is "/hurd/symlink\0target\0". */ + + memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK)); + memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len); + + dir = __file_name_split (to, &name); + if (dir == MACH_PORT_NULL) + return -1; + + /* Create a new, unlinked node in the target directory. */ + err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node); + + if (! err) + /* Set the node's translator to make it a symlink. */ + err = __file_set_translator (node, + FS_TRANS_EXCL|FS_TRANS_SET, + FS_TRANS_EXCL|FS_TRANS_SET, 0, + buf, sizeof (_HURD_SYMLINK) + len, + MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND); + + if (! err) + /* Link the node, now a valid symlink, into the target directory. */ + err = __dir_link (node, dir, name); + + __mach_port_deallocate (__mach_task_self (), dir); + __mach_port_deallocate (__mach_task_self (), node); + + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__symlink, symlink) diff --git a/sysdeps/mach/hurd/sync.c b/sysdeps/mach/hurd/sync.c new file mode 100644 index 0000000000..af207e6cdf --- /dev/null +++ b/sysdeps/mach/hurd/sync.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> + +/* Make all changes done to all files actually appear on disk. */ +int +DEFUN_VOID(sync) +{ + /* This is not actually synchronous; we don't wait. */ + error_t err = __USEPORT (CRDIR, __file_syncfs (port, 0, 1)); + if (err) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/sys/param.h b/sysdeps/mach/hurd/sys/param.h new file mode 100644 index 0000000000..79f3b0503a --- /dev/null +++ b/sysdeps/mach/hurd/sys/param.h @@ -0,0 +1,135 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file is deprecated and is provided only for compatibility with + Unix systems. It is unwise to include this file on programs which + are intended only for GNU systems. + + Parts from: + + * Copyright (c) 1982, 1986, 1989 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. + * + * @(#)param.h 7.23 (Berkeley) 5/6/91 + */ + + +#ifndef _SYS_PARAM_H + +#define _SYS_PARAM_H 1 +#include <features.h> + +#define __need_NULL +#include <stddef.h> + +#include <sys/types.h> +#include <errno.h> +#include <signal.h> +#include <endian.h> +#include <limits.h> +#ifdef notyet +#include <ufs/param.h> +#endif + + +/* What versions of BSD we are compatible with. */ +#define BSD 199306 /* System version (year & month). */ +#define BSD4_3 1 +#define BSD4_4 1 + +#define GNU 1994100 /* GNU version (year, month, and release). */ + + +/* BSD names for some <limits.h> values. We do not define the BSD names + for the values which are not statically limited, such as NOFILE. */ + +#define NGROUPS NGROUPS_MAX +#define MAXSYMLINKS SYMLOOP_MAX +#define CANBSIZ MAX_CANON /* XXX ? */ + +/* ARG_MAX is unlimited, but we define NCARGS for BSD programs that want to + compare against some fixed limit. */ +#define NCARGS INT_MAX + +/* There is nothing quite equivalent in GNU to Unix "mounts", but there is + no limit on the number of simultaneously attached filesystems. */ +#define NMOUNT INT_MAX + + +/* Magical constants. */ +#define NOGROUP 65535 /* Marker for empty group set member. */ +#define NODEV ((dev_t) -1) /* Non-existent device. */ + + +/* Bit map related macros. */ +#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) + +/* Macros for counting and rounding. */ +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define powerof2(x) ((((x)-1)&(x))==0) + +/* Macros for min/max. */ +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + + +/* Scale factor for scaled integers used to count %cpu time and load avgs. + + The number of CPU `tick's that map to a unique `%age' can be expressed + by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that + can be calculated (assuming 32 bits) can be closely approximated using + the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). */ + +#define FSHIFT 11 /* Bits to right of fixed binary point. */ +#define FSCALE (1<<FSHIFT) + +#endif /* sys/param.h */ diff --git a/sysdeps/mach/hurd/sysd-stdio.c b/sysdeps/mach/hurd/sysd-stdio.c new file mode 100644 index 0000000000..85dd04bad4 --- /dev/null +++ b/sysdeps/mach/hurd/sysd-stdio.c @@ -0,0 +1,237 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <hurd.h> +#include <fcntl.h> +#include <hurd/fd.h> + + +/* Check ERR for wanting to generate a signal. */ + +int __stdio_fileno (void *); + +static inline int +fd_fail (struct hurd_fd *fd, error_t err) +{ + int signo = _hurd_fd_error_signal (err); + if (signo) + _hurd_raise_signal (NULL, signo, __stdio_fileno (fd), err); + errno = err; + return -1; +} + + +/* Read up to N chars into BUF from COOKIE. + Return how many chars were read, 0 for EOF or -1 for error. */ +ssize_t +DEFUN(__stdio_read, (cookie, buf, n), + PTR cookie AND register char *buf AND size_t n) +{ + error_t err; + struct hurd_fd *fd = cookie; + + if (! fd) + return __hurd_fail (EBADF); + + if (err = _hurd_fd_read (fd, buf, &n)) + return fd_fail (fd, err); + + return n; +} + +/* Write up to N chars from BUF to COOKIE. + Return how many chars were written or -1 for error. */ +ssize_t +DEFUN(__stdio_write, (cookie, buf, n), + PTR cookie AND register CONST char *buf AND size_t n) +{ + error_t err; + size_t wrote, nleft; + struct hurd_fd *fd = cookie; + + if (! fd) + return __hurd_fail (EBADF); + + nleft = n; + do + { + wrote = nleft; + if (err = _hurd_fd_write (fd, buf, &wrote)) + return fd_fail (fd, err); + buf += wrote; + nleft -= wrote; + } while (nleft > 0); + + return wrote; +} + +/* Move COOKIE's file position *POS bytes, according to WHENCE. + The current file position is stored in *POS. + Returns zero if successful, nonzero if not. */ +int +DEFUN(__stdio_seek, (cookie, pos, whence), + PTR cookie AND fpos_t *pos AND int whence) +{ + error_t err; + struct hurd_fd *fd = cookie; + if (! fd) + return __hurd_fail (EBADF); + err = HURD_FD_PORT_USE (fd, __io_seek (port, *pos, whence, pos)); + return err ? fd_fail (fd, err) : 0; +} + +/* Close the file associated with COOKIE. + Return 0 for success or -1 for failure. */ +int +DEFUN(__stdio_close, (cookie), PTR cookie) +{ + error_t error = cookie ? _hurd_fd_close (cookie) : EBADF; + return error ? fd_fail (cookie, error) : 0; +} + + +static inline int +modeflags (__io_mode m) +{ + int flags = 0; + if (m.__read) + flags |= O_READ; + if (m.__write) + flags |= O_WRITE; + if (m.__append) + flags |= O_APPEND; + if (m.__create) + flags |= O_CREAT; + if (m.__truncate) + flags |= O_TRUNC; + if (m.__exclusive) + flags |= O_EXCL; + return flags; +} + +/* Open FILENAME with the mode in M. */ +int +DEFUN(__stdio_open, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND PTR *cookieptr) +{ + int flags; + file_t port; + struct hurd_fd *d; + + flags = modeflags (m); + port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask); + if (port == MACH_PORT_NULL) + return -1; + + HURD_CRITICAL_BEGIN; + d = _hurd_alloc_fd (NULL, 0); + if (d != NULL) + { + _hurd_port2fd (d, port, flags); + __spin_unlock (&d->port.lock); + } + HURD_CRITICAL_END; + + *cookieptr = d; + return 0; +} + + +/* Open FILENAME with the mode in M. Use the same magic cookie + already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */ +int +DEFUN(__stdio_reopen, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND + PTR *cookieptr AND __io_close_fn closefn) +{ + int flags; + file_t port; + struct hurd_fd *d; + + if (closefn != __stdio_close) + { + /* The old cookie is Not Of The Body. + Just close it and do a normal open. */ + (*closefn) (*cookieptr); + return __stdio_open (filename, m, cookieptr); + } + + /* Open a new port on the file. */ + flags = modeflags (m); + port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask); + + /* Install the new port in the same file descriptor slot the old cookie + points to. If opening the file failed, PORT will be MACH_PORT_NULL + and installing it in the descriptor will have the effect of closing + the old descriptor. */ + + d = *cookieptr; + HURD_CRITICAL_BEGIN; + __spin_lock (&d->port.lock); + _hurd_port2fd (d, port, flags); + __spin_unlock (&d->port.lock); + HURD_CRITICAL_END; + + return port == MACH_PORT_NULL ? -1 : 0; +} + + +/* Write a message to the error output. + Try hard to make it really get out. */ +void +DEFUN(__stdio_errmsg, (msg, len), CONST char *msg AND size_t len) +{ + io_t server; + mach_msg_type_number_t wrote; + + server = __getdport (2); + __io_write (server, msg, len, -1, &wrote); + __mach_port_deallocate (__mach_task_self (), server); +} + + +/* Return the POSIX.1 file descriptor associated with COOKIE, + or -1 for errors. If COOKIE does not relate to any POSIX.1 file + descriptor, this should return -1 with errno set to EOPNOTSUPP. */ +int +DEFUN(__stdio_fileno, (cookie), PTR cookie) +{ + int fd; + + if (! cookie) + return __hurd_fail (EBADF); + + __mutex_lock (&_hurd_dtable_lock); + for (fd = 0; fd < _hurd_dtablesize; ++fd) + if (_hurd_dtable[fd] == cookie) + { + __mutex_unlock (&_hurd_dtable_lock); + return fd; + } + __mutex_unlock (&_hurd_dtable_lock); + + /* This should never happen, because this function should not be + installed as a stream's __fileno function unless that stream's cookie + points to a file descriptor. */ + errno = EGRATUITOUS; + return -1; +} diff --git a/sysdeps/mach/hurd/telldir.c b/sysdeps/mach/hurd/telldir.c new file mode 100644 index 0000000000..7ce8d1f061 --- /dev/null +++ b/sysdeps/mach/hurd/telldir.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> + +/* Return the current position of DIRP. */ +off_t +DEFUN(telldir, (dirp), DIR *dirp) +{ + return dirp->__entry_ptr; +} diff --git a/sysdeps/mach/hurd/truncate.c b/sysdeps/mach/hurd/truncate.c new file mode 100644 index 0000000000..7453bfb3a9 --- /dev/null +++ b/sysdeps/mach/hurd/truncate.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> +#include <hurd.h> +#include <fcntl.h> + +/* Truncate FILE_NAME to LENGTH bytes. */ +int +DEFUN(truncate, (file_name, length), + CONST char *file_name AND off_t length) +{ + error_t err; + file_t file = __file_name_lookup (file_name, O_WRITE, 0); + + if (file == MACH_PORT_NULL) + return -1; + + err = __file_truncate (file, length); + __mach_port_deallocate (__mach_task_self (), file); + + if (err) + return __hurd_fail (err); + return 0; +} diff --git a/sysdeps/mach/hurd/ttyname.c b/sysdeps/mach/hurd/ttyname.c new file mode 100644 index 0000000000..5b8be3c629 --- /dev/null +++ b/sysdeps/mach/hurd/ttyname.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/term.h> +#include <hurd/fd.h> + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +char * +ttyname (int fd) +{ + error_t err; + static char nodename[1024]; /* XXX */ + + nodename[0] = '\0'; + if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename))) + return __hurd_dfail (fd, err), NULL; + + return nodename; +} diff --git a/sysdeps/mach/hurd/umask.c b/sysdeps/mach/hurd/umask.c new file mode 100644 index 0000000000..0848dd77cd --- /dev/null +++ b/sysdeps/mach/hurd/umask.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/stat.h> +#include <hurd.h> + +/* Set the file creation mask to MASK, returning the old mask. */ +mode_t +DEFUN(__umask, (mask), mode_t mask) +{ + mode_t omask; + mask &= 0777; + omask = _hurd_umask; + _hurd_umask = mask; + return omask; +} + +weak_alias (__umask, umask) diff --git a/sysdeps/mach/hurd/uname.c b/sysdeps/mach/hurd/uname.c new file mode 100644 index 0000000000..74d9d3799f --- /dev/null +++ b/sysdeps/mach/hurd/uname.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/utsname.h> +#include <hurd.h> +#include <hurd/startup.h> + +int +uname (struct utsname *uname) +{ + error_t err; + + err = __USEPORT (PROC, __proc_uname (port, uname)); + + return err ? __hurd_fail (err) : 0; +} diff --git a/sysdeps/mach/hurd/unlink.c b/sysdeps/mach/hurd/unlink.c new file mode 100644 index 0000000000..b71d7f9f54 --- /dev/null +++ b/sysdeps/mach/hurd/unlink.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <hurd.h> + + +/* Remove the link named NAME. */ +int +DEFUN(__unlink, (name), CONST char *name) +{ + error_t err; + file_t dir; + CONST char *file; + + dir = __file_name_split (name, (char **) &file); + if (dir == MACH_PORT_NULL) + return -1; + + err = __dir_unlink (dir, file); + __mach_port_deallocate (__mach_task_self (), dir); + + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__unlink, unlink) diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c new file mode 100644 index 0000000000..f8f042598b --- /dev/null +++ b/sysdeps/mach/hurd/utimes.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/time.h> +#include <errno.h> +#include <stddef.h> +#include <hurd.h> + +/* Change the access time of FILE to TVP[0] and + the modification time of FILE to TVP[1]. */ +int +DEFUN(__utimes, (file, tvp), + CONST char *file AND struct timeval tvp[2]) +{ + error_t err; + file_t f = __file_name_lookup (file, 0, 0); + if (f == MACH_PORT_NULL) + return -1; + err = __file_utimes (f, + *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]); + __mach_port_deallocate (__mach_task_self (), f); + if (err) + return __hurd_fail (err); + return 0; +} + +weak_alias (__utimes, utimes) diff --git a/sysdeps/mach/hurd/wait4.c b/sysdeps/mach/hurd/wait4.c new file mode 100644 index 0000000000..61e985505e --- /dev/null +++ b/sysdeps/mach/hurd/wait4.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <hurd.h> +#include <hurd/port.h> + +pid_t +__wait4 (pid_t pid, __WAIT_STATUS_DEFN stat_loc, + int options, struct rusage *usage) +{ + pid_t dead; + error_t err; + struct rusage ignored; + + err = __USEPORT (PROC, __proc_wait (port, pid, options, stat_loc, + usage ?: &ignored, &dead)); + + return err ? (pid_t) __hurd_fail (err) : dead; +} + +weak_alias (__wait4, wait4) diff --git a/sysdeps/mach/hurd/write.c b/sysdeps/mach/hurd/write.c new file mode 100644 index 0000000000..c6c3e6c668 --- /dev/null +++ b/sysdeps/mach/hurd/write.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <hurd.h> +#include <hurd/fd.h> + +ssize_t +DEFUN(__write, (fd, buf, nbytes), + int fd AND CONST PTR buf AND size_t nbytes) +{ + error_t err = HURD_FD_USE (fd, _hurd_fd_write (descriptor, buf, &nbytes)); + return err ? __hurd_dfail (fd, err) : nbytes; +} + + + +weak_alias (__write, write) diff --git a/sysdeps/mach/i386/machine-lock.h b/sysdeps/mach/i386/machine-lock.h new file mode 100644 index 0000000000..bdc57e0997 --- /dev/null +++ b/sysdeps/mach/i386/machine-lock.h @@ -0,0 +1,66 @@ +/* Machine-specific definition for spin locks. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef __volatile int __spin_lock_t; + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER 0 + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + register int __unlocked; + __asm__ __volatile ("xchgl %0, %1" + : "=&r" (__unlocked), "=m" (*__lock) : "0" (0)); +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (__spin_lock_t *__lock) +{ + register int __locked; + __asm__ __volatile ("xchgl %0, %1" + : "=&r" (__locked), "=m" (*__lock) : "0" (1)); + return !__locked; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + return *__lock != 0; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/mach/i386/machine-sp.h b/sysdeps/mach/i386/machine-sp.h new file mode 100644 index 0000000000..7fd15413f5 --- /dev/null +++ b/sysdeps/mach/i386/machine-sp.h @@ -0,0 +1,38 @@ +/* Machine-specific function to return the stack pointer. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +_EXTERN_INLINE void * +__thread_stack_pointer (void) +{ + void *__sp__; + __asm__ ("movl %%esp, %0" : "=r" (__sp__)); + return __sp__; +} + +#endif /* machine-sp.h */ + diff --git a/sysdeps/mach/i386/syscall.S b/sysdeps/mach/i386/syscall.S new file mode 100644 index 0000000000..1e9fbb81e8 --- /dev/null +++ b/sysdeps/mach/i386/syscall.S @@ -0,0 +1,26 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (syscall) + popl %ecx /* Pop return address into %ecx. */ + popl %eax /* Pop syscall number into %eax. */ + pushl %ecx /* Push back return address. */ + .byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- gas bug */ + ret diff --git a/sysdeps/mach/i386/sysdep.h b/sysdeps/mach/i386/sysdep.h new file mode 100644 index 0000000000..8d482a0485 --- /dev/null +++ b/sysdeps/mach/i386/sysdep.h @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define MOVE(x,y) movl x , y + +#define LOSE asm volatile ("hlt") + +#define SNARF_ARGS(argc, argv, envp) \ + do \ + { \ + int *entry_sp; \ + register char **p; \ + \ + asm ("leal 4(%%ebp), %0" : "=r" (entry_sp)); \ + \ + argc = *entry_sp; \ + argv = (char **) (entry_sp + 1); \ + p = argv; \ + while (*p++ != NULL) \ + ; \ + if (p >= (char **) argv[0]) \ + --p; \ + envp = p; \ + } while (0) + +#define CALL_WITH_SP(fn, sp) \ + asm volatile ("movl %0, %%esp; jmp %1" : : \ + "g" (sp), "m" (*(long int *) (fn)) : "%esp") + +#define STACK_GROWTH_DOWN + +#include_next <sysdep.h> diff --git a/sysdeps/mach/i386/thread_state.h b/sysdeps/mach/i386/thread_state.h new file mode 100644 index 0000000000..89779b60ed --- /dev/null +++ b/sysdeps/mach/i386/thread_state.h @@ -0,0 +1,38 @@ +/* Mach thread state definitions for machine-independent code. i386 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach/machine/thread_status.h> + +#define MACHINE_THREAD_STATE_FLAVOR i386_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT + +#define machine_thread_state i386_thread_state + +#define PC eip +#define SP uesp +#define SYSRETURN eax + +struct machine_thread_all_state + { + int set; /* Mask of bits (1 << FLAVOR). */ + struct i386_thread_state basic; + struct i386_float_state fpu; + }; + +#include_next <thread_state.h> diff --git a/sysdeps/mach/mips/Dist b/sysdeps/mach/mips/Dist new file mode 100644 index 0000000000..f2699bf887 --- /dev/null +++ b/sysdeps/mach/mips/Dist @@ -0,0 +1 @@ +cacheflush.c diff --git a/sysdeps/mach/mips/Makefile b/sysdeps/mach/mips/Makefile new file mode 100644 index 0000000000..a890ae7b46 --- /dev/null +++ b/sysdeps/mach/mips/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),gnulib) +sysdep_routines += cacheflush +endif diff --git a/sysdeps/mach/mips/cacheflush.c b/sysdeps/mach/mips/cacheflush.c new file mode 100644 index 0000000000..5325e6fd1e --- /dev/null +++ b/sysdeps/mach/mips/cacheflush.c @@ -0,0 +1,44 @@ +/* Flush the insn cache after GCC writes a closure on the stack. Mach/MIPS. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <mach/vm_attributes.h> + +/* Stupid name, but this is what GCC generates (config/mips/mips.h). */ +void +cacheflush (void *addr, size_t size, int flag) +{ + vm_machine_attribute_val_t val; + + switch (flag) + { + case 0: /* ? */ + val = MATTR_VAL_DCACHE_FLUSH; + case 1: /* This is the only value GCC uses. */ + val = MATTR_VAL_ICACHE_FLUSH; + break; + default: + val = MATTR_VAL_CACHE_FLUSH; + } + + __vm_machine_attribute (__mach_task_self (), + (vm_address_t) addr, size, + MATTR_CACHE, + &val); +} diff --git a/sysdeps/mach/mips/machine-lock.h b/sysdeps/mach/mips/machine-lock.h new file mode 100644 index 0000000000..628aae41bb --- /dev/null +++ b/sysdeps/mach/mips/machine-lock.h @@ -0,0 +1,73 @@ +/* Machine-specific definition for spin locks. MIPS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef __volatile int __spin_lock_t; + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER 0 + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + *__lock = 0; +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (register __spin_lock_t *__lock) +{ + register int __rtn; + __asm__ __volatile (".set noreorder"); +#if 0 + __asm__ __volatile ("lw %0,0(%1)": "=r" (__rtn) : "r" (__lock)); + __asm__ __volatile ("sw %0,0(%0)": : "r" (__lock)); + __asm__ __volatile ("xor %0,%1,%0": "=r" (__rtn) : "r" (__lock)); +#else + /* Use the Mach microkernel's emulated TAS pseudo-instruction. */ + register int __rtn __asm__ ("a0"); + __asm__ __volatile (".word 0xf ! %0 " : "=r" (__rtn) : "0" (__lock)); +#endif + __asm__ __volatile (".set reorder"); + return __rtn ^ (int) __lock; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + return *__lock != 0; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/mach/mips/machine-sp.h b/sysdeps/mach/mips/machine-sp.h new file mode 100644 index 0000000000..7406658f53 --- /dev/null +++ b/sysdeps/mach/mips/machine-sp.h @@ -0,0 +1,38 @@ +/* Machine-specific function to return the stack pointer. MIPS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +_EXTERN_INLINE void * +__thread_stack_pointer (void) +{ + void *__sp__; + __asm__ ("move %0,$29" : "=r" (__sp__)); + return __sp__; +} + +#endif /* machine-sp.h */ + diff --git a/sysdeps/mach/mips/syscall.S b/sysdeps/mach/mips/syscall.S new file mode 100644 index 0000000000..bf56b401dd --- /dev/null +++ b/sysdeps/mach/mips/syscall.S @@ -0,0 +1,37 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (syscall) + .frame sp,0,ra + move v0, a0 /* Load system call number from first arg. */ + move a0, a1 /* Move the next three args up a register. */ + move a1, a2 + move a2, a3 + /* Load the remaining possible args (up to 11) from the stack. */ + lw t0,16(sp) + lw t1,20(sp) + lw t2,24(sp) + lw t3,28(sp) + lw t4,32(sp) + lw t5,36(sp) + lw t6,40(sp) + syscall /* Do the system call. */ + j ra /* Return to caller. */ + .end syscall diff --git a/sysdeps/mach/mips/sysdep.h b/sysdeps/mach/mips/sysdep.h new file mode 100644 index 0000000000..7609be5931 --- /dev/null +++ b/sysdeps/mach/mips/sysdep.h @@ -0,0 +1,69 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define MOVE(x,y) move y , x + +#if 0 +#define LOSE asm volatile ("1: b 1b") +#endif + +#define SNARF_ARGS(argc, argv, envp) \ + do \ + { \ + int *entry_sp; \ + register char **p; \ + \ + asm ("addu %0,$30,4" : "=r" (entry_sp)); \ + \ + argc = *entry_sp; \ + argv = (char **) (entry_sp + 1); \ + p = argv; \ + while (*p++ != NULL) \ + ; \ + if (p >= (char **) argv[0]) \ + --p; \ + envp = p; \ + } while (0) + +#define CALL_WITH_SP(fn, sp) \ + ({ register int __fn = fn, __sp = (int) sp; \ + asm volatile ("move $sp,%0; j %1" : : "r" (__sp), "r" (__fn));}) + +#define STACK_GROWTH_DOWN + +#ifdef P40 +#include <syscall.h> + +#define SYSCALL(name, args) \ + .globl syscall_error; \ + kernel_trap(name,SYS_##name,args); \ + beq $1,$0,1f; \ + j syscall_error; \ +1: + +#define SYSCALL__(name, args) \ + .globl syscall_error; \ + kernel_trap(__##name,SYS_##name,args); \ + beq $1,$0,1f; \ + j syscall_error; \ +1: + +#define ret j ra; nop +#endif + +#include_next <sysdep.h> diff --git a/sysdeps/mach/mips/thread_state.h b/sysdeps/mach/mips/thread_state.h new file mode 100644 index 0000000000..f4f4b429cf --- /dev/null +++ b/sysdeps/mach/mips/thread_state.h @@ -0,0 +1,37 @@ +/* Mach thread state definitions for machine-independent code. MIPS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define MACHINE_THREAD_STATE_FLAVOR MIPS_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT MIPS_THREAD_STATE_COUNT + +#define machine_thread_state mips_thread_state + +#define PC pc +#define SP r29 +#define SYSRETURN r2 + +struct machine_thread_all_state + { + int set; /* Mask of bits (1 << FLAVOR). */ + struct mips_thread_state basic; + struct mips_exc_state exc; + struct mips_float_state fpu; + }; + +#include_next <thread_state.h> diff --git a/sysdeps/mach/mprotect.c b/sysdeps/mach/mprotect.c new file mode 100644 index 0000000000..5f1dbe8b5c --- /dev/null +++ b/sysdeps/mach/mprotect.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> +#include <mach.h> + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ + +int +mprotect (caddr_t addr, size_t len, int prot) +{ + kern_return_t err; + vm_prot_t vmprot; + + vmprot = VM_PROT_NONE; + if (prot & PROT_READ) + vmprot |= VM_PROT_READ; + if (prot & PROT_WRITE) + vmprot |= VM_PROT_WRITE; + if (prot & PROT_EXEC) + vmprot |= VM_PROT_EXECUTE; + + if (err = __vm_protect (__mach_task_self (), + (vm_address_t) addr, (vm_size_t) len, + 0, vmprot)) + { + errno = err; + return -1; + } + return 0; +} diff --git a/sysdeps/mach/munmap.c b/sysdeps/mach/munmap.c new file mode 100644 index 0000000000..5ca11298f3 --- /dev/null +++ b/sysdeps/mach/munmap.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> +#include <mach.h> + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ + +int +munmap (caddr_t addr, size_t len) +{ + kern_return_t err; + if (err = __vm_deallocate (__mach_task_self (), + (vm_address_t) addr, (vm_size_t) len)) + { + errno = err; + return -1; + } + return 0; +} + diff --git a/sysdeps/mach/sleep.c b/sysdeps/mach/sleep.c new file mode 100644 index 0000000000..0e613d3eec --- /dev/null +++ b/sysdeps/mach/sleep.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <time.h> +#include <unistd.h> +#include <mach.h> + +/* Make the process sleep for SECONDS seconds, or until a signal arrives + and is not ignored. The function returns the number of seconds less + than SECONDS which it actually slept (zero if it slept the full time). + There is no return value to indicate error, but if `sleep' returns + SECONDS, it probably didn't work. */ +unsigned int +DEFUN(sleep, (seconds), unsigned int seconds) +{ + time_t before, after; + mach_port_t recv; + + recv = __mach_reply_port (); + + before = time ((time_t *) NULL); + (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, recv, seconds * 1000, MACH_PORT_NULL); + after = time ((time_t *) NULL); + __mach_port_destroy (__mach_task_self (), recv); + + return seconds - (after - before); +} diff --git a/sysdeps/mach/start.c b/sysdeps/mach/start.c new file mode 100644 index 0000000000..26abc23f53 --- /dev/null +++ b/sysdeps/mach/start.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stddef.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <sysdep.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* The first piece of initialized data. */ +int __data_start = 0; + +volatile int errno; + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif +char **__environ; + +extern void __mach_init (void); +extern void __libc_init (int argc, char **argv, char **envp); +extern int main (int argc, char **argv, char **envp); + +/* These are uninitialized common definitions so they will be zero + by default. If the user links in C threads, that will provide initialized + definitions that override these. */ +void *(*_cthread_init_routine) (void); /* Returns new SP to use. */ +void (*_cthread_exit_routine) (int status); + + +/* These are for communication from _start to start1, + where we cannot use the stack for anything. */ +static int start_argc; +static char **start_argv; + +/* _start calls this on the new stack. */ +static volatile void +start1 (void) +{ + __libc_init (start_argc, start_argv, __environ); + + (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit) + (main (start_argc, start_argv, __environ)); + + /* Should never get here. */ + LOSE; +} + +#ifndef START_ARGS +#define START_ARGS void +#ifdef START_MACHDEP +START_MACHDEP +#define _start _start0 +#endif + +void +_start (START_ARGS) +{ + SNARF_ARGS (start_argc, start_argv, __environ); + + __mach_init (); + + if (_cthread_init_routine != NULL) + CALL_WITH_SP (start1, (*_cthread_init_routine) ()); + else + start1 (); + + /* Should never get here. */ + LOSE; +} diff --git a/sysdeps/mach/sys/reboot.h b/sysdeps/mach/sys/reboot.h new file mode 100644 index 0000000000..6435fea00c --- /dev/null +++ b/sysdeps/mach/sys/reboot.h @@ -0,0 +1,153 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * HISTORY + * $Log$ + * Revision 1.1 1993/08/03 22:25:15 roland + * entered into RCS + * + * Revision 1.1 1993/08/03 22:25:15 roland + * entered into RCS + * + * Revision 2.8 93/03/11 13:46:40 danner + * u_long -> u_int. + * [93/03/09 danner] + * + * Revision 2.7 92/05/21 17:25:11 jfriedl + * Appended 'U' to constants that would otherwise be signed. + * [92/05/16 jfriedl] + * + * Revision 2.6 91/06/19 11:59:44 rvb + * Second byte of boothowto is flags for "startup" program. + * [91/06/18 rvb] + * Add ifndef ASSEMBLER so that vax_init.s can include it. + * [91/06/11 rvb] + * + * Revision 2.5 91/05/14 17:40:11 mrt + * Correcting copyright + * + * Revision 2.4 91/02/05 17:56:48 mrt + * Changed to new Mach copyright + * [91/02/01 17:49:12 mrt] + * + * Revision 2.3 90/08/27 22:12:56 dbg + * Added definitions used by Mach Kernel: RB_DEBUGGER, RB_UNIPROC, + * RB_NOBOOTRC, RB_ALTBOOT. Moved RB_KDB to 0x04 (Mach value). + * Removed RB_RDONLY, RB_DUMP, RB_NOSYNC. + * [90/08/14 dbg] + * + */ + +/* + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)reboot.h 7.5 (Berkeley) 6/27/88 + */ + +#ifndef _SYS_REBOOT_H_ +#define _SYS_REBOOT_H_ + +/* + * Arguments to reboot system call. + * These are converted to switches, and passed to startup program, + * and on to init. + */ +#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#define RB_ASKNAME 0x01 /* -a: ask for file name to reboot from */ +#define RB_SINGLE 0x02 /* -s: reboot to single user only */ +#define RB_KDB 0x04 /* -d: kernel debugger symbols loaded */ +#define RB_HALT 0x08 /* -h: enter KDB at bootup */ + /* for host_reboot(): don't reboot, + just halt */ +#define RB_INITNAME 0x10 /* -i: name given for /etc/init (unused) */ +#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */ +#define RB_NOBOOTRC 0x20 /* -b: don't run /etc/rc.boot */ +#define RB_ALTBOOT 0x40 /* use /boot.old vs /boot */ +#define RB_UNIPROC 0x80 /* -u: start only one processor */ + +#define RB_SHIFT 8 /* second byte is for ux */ + +#define RB_DEBUGGER 0x1000 /* for host_reboot(): enter kernel + debugger from user level */ + +/* + * Constants for converting boot-style device number to type, + * adaptor (uba, mba, etc), unit number and partition number. + * Type (== major device number) is in the low byte + * for backward compatibility. Except for that of the "magic + * number", each mask applies to the shifted value. + * Format: + * (4) (4) (4) (4) (8) (8) + * -------------------------------- + * |MA | AD| CT| UN| PART | TYPE | + * -------------------------------- + */ +#define B_ADAPTORSHIFT 24 +#define B_ADAPTORMASK 0x0f +#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK) +#define B_CONTROLLERSHIFT 20 +#define B_CONTROLLERMASK 0xf +#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK) +#define B_UNITSHIFT 16 +#define B_UNITMASK 0xf +#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK) +#define B_PARTITIONSHIFT 8 +#define B_PARTITIONMASK 0xff +#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK) +#define B_TYPESHIFT 0 +#define B_TYPEMASK 0xff +#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK) + +#define B_MAGICMASK ((u_int)0xf0000000U) +#define B_DEVMAGIC ((u_int)0xa0000000U) + +#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \ + (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \ + ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \ + ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC) + + +#ifdef KERNEL +#ifndef ASSEMBLER +extern int boothowto; +#endif ASSEMBLER +#endif + +#endif /* _SYS_REBOOT_H_ */ diff --git a/sysdeps/mach/syscall.h b/sysdeps/mach/syscall.h new file mode 100644 index 0000000000..6e4ed4d64e --- /dev/null +++ b/sysdeps/mach/syscall.h @@ -0,0 +1 @@ +/* The Mach syscalls are in <mach/syscall_sw.h>. */ diff --git a/sysdeps/mach/sysdep.h b/sysdeps/mach/sysdep.h new file mode 100644 index 0000000000..9a8dbd5163 --- /dev/null +++ b/sysdeps/mach/sysdep.h @@ -0,0 +1,82 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef ASSEMBLER + +/* Get the Mach definitions of ENTRY and kernel_trap. */ +#include <mach/machine/syscall_sw.h> + +/* The Mach definitions assume underscores should be prepended to + symbol names. Redefine them to do so only when appropriate. */ +#undef EXT +#undef LEXT +#define EXT(x) C_SYMBOL_NAME(x) +#define LEXT(x) C_SYMBOL_NAME(x##:) + +#endif + +/* This is invoked by things run when there is random lossage, before they + try to do anything else. Just to be safe, deallocate the reply port so + bogons arriving on it don't foul up future RPCs. */ + +#ifndef ASSEMBLER +#define FATAL_PREPARE_INCLUDE <mach/mig_support.h> +#define FATAL_PREPARE __mig_dealloc_reply_port (MACH_PORT_NULL) +#endif + +/* sysdeps/mach/MACHINE/sysdep.h should define the following macros. */ + +/* Produce a text assembler label for the C global symbol NAME. */ +#ifndef ENTRY +#define ENTRY(name) .error ENTRY not defined by sysdeps/mach/MACHINE/sysdep.h +/* This is not used on all machines. */ +#endif + +/* Set variables ARGC, ARGV, and ENVP for the arguments + left on the stack by the microkernel. */ +#ifndef SNARF_ARGS +#define SNARF_ARGS(argc, argv, envp) +#error SNARF_ARGS not defined by sysdeps/mach/MACHINE/sysdep.h +#endif + +/* Call the C function FN with no arguments, + on a stack starting at SP (as returned by *_cthread_init_routine). + You don't need to deal with FN returning; it shouldn't. */ +#ifndef CALL_WITH_SP +#define CALL_WITH_SP(fn, sp) +#error CALL_WITH_SP not defined by sysdeps/mach/MACHINE/sysdep.h +#endif + +/* LOSE can be defined as the `halt' instruction or something + similar which will cause the process to die in a characteristic + way suggesting a bug. */ +#ifndef LOSE +#define LOSE ({ volatile int zero = 0; zero / zero; }) +#endif + +/* One of these should be defined to specify the stack direction. */ +#if !defined (STACK_GROWTH_UP) && !defined (STACK_GROWTH_DOWN) +#error stack direction unspecified +#endif + +/* Used by some assembly code. */ +#ifdef NO_UNDERSCORES +#define C_SYMBOL_NAME(name) name +#else +#define C_SYMBOL_NAME(name) _##name +#endif diff --git a/sysdeps/mach/thread_state.h b/sysdeps/mach/thread_state.h new file mode 100644 index 0000000000..06f168bb55 --- /dev/null +++ b/sysdeps/mach/thread_state.h @@ -0,0 +1,87 @@ +/* Generic definitions for dealing with Mach thread states. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + + +/* Everything else is called `thread_state', but CMU's header file is + called `thread_status'. Oh boy. */ +#include <mach/thread_status.h> + +/* The machine-dependent thread_state.h file can either define these + macros, or just define PC and SP to the register names. */ + +#ifndef MACHINE_THREAD_STATE_SET_PC +#define MACHINE_THREAD_STATE_SET_PC(ts, pc) \ + ((ts)->PC = (unsigned long int) (pc)) +#endif +#ifndef MACHINE_THREAD_STATE_SET_SP +#ifdef STACK_GROWTH_UP +#define MACHINE_THREAD_STATE_SET_SP(ts, stack, size) \ + ((ts)->SP = (unsigned long int) (stack)) +#else +#define MACHINE_THREAD_STATE_SET_SP(ts, stack, size) \ + ((ts)->SP = (unsigned long int) (stack) + (size)) +#endif +#endif + +/* These functions are of use in machine-dependent signal trampoline + implementations. */ + +#include <string.h> /* size_t, memcpy */ +#include <mach/mach_interface.h> /* __thread_get_state */ + +static inline int +machine_get_state (thread_t thread, struct machine_thread_all_state *state, + int flavor, void *stateptr, void *scpptr, size_t size) +{ + if (state->set & (1 << flavor)) + { + /* Copy the saved state. */ + memcpy (scpptr, stateptr, size); + return 1; + } + else + { + /* Noone asked about this flavor of state before; fetch the state + directly from the kernel into the sigcontext. */ + mach_msg_type_number_t got = (size / sizeof (int)); + return (! __thread_get_state (thread, flavor, scpptr, &got) + && got == (size / sizeof (int))); + } +} + +static inline int +machine_get_basic_state (thread_t thread, + struct machine_thread_all_state *state) +{ + mach_msg_type_number_t count; + + if (state->set & (1 << MACHINE_THREAD_STATE_FLAVOR)) + return 1; + + count = MACHINE_THREAD_STATE_COUNT; + if (__thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &state->basic, + &count) != KERN_SUCCESS || + count != MACHINE_THREAD_STATE_COUNT) + /* What kind of thread?? */ + return 0; /* XXX */ + + state->set |= 1 << MACHINE_THREAD_STATE_FLAVOR; + return 1; +} diff --git a/sysdeps/mach/usleep.c b/sysdeps/mach/usleep.c new file mode 100644 index 0000000000..90d47d8c24 --- /dev/null +++ b/sysdeps/mach/usleep.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <mach.h> +#include <sys/time.h> + +/* Sleep USECONDS microseconds, or until a previously set timer goes off. */ +unsigned int +DEFUN(usleep, (useconds), unsigned int useconds) +{ + mach_port_t recv; + struct timeval before, after; + + recv = __mach_reply_port (); + + if (__gettimeofday (&before, NULL) < 0) + return useconds; + (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, recv, (useconds + 999) / 1000, MACH_PORT_NULL); + __mach_port_destroy (mach_task_self (), recv); + if (__gettimeofday (&after, NULL) < 0) + return 0; + + return useconds - (((after.tv_sec - before.tv_sec) * 1000000) + + (after.tv_usec - before.tv_usec)); +} diff --git a/sysdeps/mips/.cvsignore b/sysdeps/mips/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/sysdeps/mips/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/sysdeps/mips/Dist b/sysdeps/mips/Dist new file mode 100644 index 0000000000..ad6ea0313a --- /dev/null +++ b/sysdeps/mips/Dist @@ -0,0 +1 @@ +setjmp_aux.c diff --git a/sysdeps/mips/Implies b/sysdeps/mips/Implies new file mode 100644 index 0000000000..60732cef94 --- /dev/null +++ b/sysdeps/mips/Implies @@ -0,0 +1,2 @@ +# MIPS uses IEEE 754 floating point. +ieee754 diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile new file mode 100644 index 0000000000..736414197a --- /dev/null +++ b/sysdeps/mips/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),setjmp) +sysdep_routines := $(sysdep_routines) setjmp_aux +endif diff --git a/sysdeps/mips/__longjmp.c b/sysdeps/mips/__longjmp.c new file mode 100644 index 0000000000..7ea3df2827 --- /dev/null +++ b/sysdeps/mips/__longjmp.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <setjmp.h> +#include <stdlib.h> + +#undef __longjmp + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +void +DEFUN(__longjmp, (env, val_arg), CONST __jmp_buf env AND int val_arg) +{ + /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before + the hack around it); force it to use $a1 for the longjmp value. + Without this it saves $a1 in a register which gets clobbered + along the way. */ + register int val asm ("a1"); + + /* Pull back the floating point callee-saved registers. */ + asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0])); + asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1])); + asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2])); + asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3])); + asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); + asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5])); + + /* Restore the stack pointer. */ + asm volatile ("lw $29, %0" : : "m" (env[0].__sp)); + + /* Get and reconstruct the floating point csr. */ + asm volatile ("lw $2, %0" : : "m" (env[0].__fpc_csr)); + asm volatile ("ctc1 $2, $31"); + + /* Get the FP. */ + asm volatile ("lw $30, %0" : : "m" (env[0].__fp)); + + /* Get the GP. */ + asm volatile ("lw $gp, %0" : : "m" (env[0].__gp)); + + /* Get the callee-saved registers. */ + asm volatile ("lw $16, %0" : : "m" (env[0].__regs[0])); + asm volatile ("lw $17, %0" : : "m" (env[0].__regs[1])); + asm volatile ("lw $18, %0" : : "m" (env[0].__regs[2])); + asm volatile ("lw $19, %0" : : "m" (env[0].__regs[3])); + asm volatile ("lw $20, %0" : : "m" (env[0].__regs[4])); + asm volatile ("lw $21, %0" : : "m" (env[0].__regs[5])); + asm volatile ("lw $22, %0" : : "m" (env[0].__regs[6])); + asm volatile ("lw $23, %0" : : "m" (env[0].__regs[7])); + + /* Get the PC. */ + asm volatile ("lw $31, %0" : : "m" (env[0].__pc)); + + /* Give setjmp 1 if given a 0, or what they gave us if non-zero. */ + if (val == 0) + asm volatile ("li $2, 1"); + else + asm volatile ("move $2, %0" : : "r" (val)); + + asm volatile ("j $31"); + + abort (); +} diff --git a/sysdeps/mips/bsd-_setjmp.S b/sysdeps/mips/bsd-_setjmp.S new file mode 100644 index 0000000000..6e6844cc52 --- /dev/null +++ b/sysdeps/mips/bsd-_setjmp.S @@ -0,0 +1,28 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. MIPS version. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + j C_SYMBOL_NAME (__sigsetjmp) + li a1, zero /* Pass a second argument of zero. */ diff --git a/sysdeps/mips/bsd-setjmp.S b/sysdeps/mips/bsd-setjmp.S new file mode 100644 index 0000000000..5cd090a31c --- /dev/null +++ b/sysdeps/mips/bsd-setjmp.S @@ -0,0 +1,28 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. MIPS version. +Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + j C_SYMBOL_NAME (__sigsetjmp) + li a1, 1 /* Pass a second argument of one. */ diff --git a/sysdeps/mips/dec/bytesex.h b/sysdeps/mips/dec/bytesex.h new file mode 100644 index 0000000000..157bc44d06 --- /dev/null +++ b/sysdeps/mips/dec/bytesex.h @@ -0,0 +1,4 @@ +/* The MIPS architecture has selectable endianness. + The DECstation uses little-endian mode. */ + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/sysdeps/mips/jmp_buf.h b/sysdeps/mips/jmp_buf.h new file mode 100644 index 0000000000..eed47dce7f --- /dev/null +++ b/sysdeps/mips/jmp_buf.h @@ -0,0 +1,47 @@ +/* Define the machine-dependent type `jmp_buf'. Mips version. + Copyright (C) 1992, 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +typedef struct + { + /* Program counter. */ + __ptr_t __pc; + + /* Stack pointer. */ + __ptr_t __sp; + + /* Callee-saved registers s0 through s7. */ + int __regs[8]; + + /* The frame pointer. */ + __ptr_t __fp; + + /* The global pointer. */ + __ptr_t __gp; + + /* Floating point status register. */ + int __fpc_csr; + + /* Callee-saved floating point registers. */ + double __fpregs[6]; + } __jmp_buf[1]; + +#ifdef __USE_MISC +/* Offset to the program counter in `jmp_buf'. */ +#define JB_PC 0 +#endif diff --git a/sysdeps/mips/mips64/gmp-mparam.h b/sysdeps/mips/mips64/gmp-mparam.h new file mode 100644 index 0000000000..a801b35d7a --- /dev/null +++ b/sysdeps/mips/mips64/gmp-mparam.h @@ -0,0 +1,26 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define BITS_PER_MP_LIMB 64 +#define BYTES_PER_MP_LIMB 8 +#define BITS_PER_LONGINT 32 +#define BITS_PER_INT 32 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 diff --git a/sysdeps/mips/mipsel/bytesex.h b/sysdeps/mips/mipsel/bytesex.h new file mode 100644 index 0000000000..5da5965cb2 --- /dev/null +++ b/sysdeps/mips/mipsel/bytesex.h @@ -0,0 +1,4 @@ +/* The MIPS architecture has selectable endianness. + This file is for a machine using little-endian mode. */ + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/sysdeps/mips/p40/bytesex.h b/sysdeps/mips/p40/bytesex.h new file mode 100644 index 0000000000..e4b0119433 --- /dev/null +++ b/sysdeps/mips/p40/bytesex.h @@ -0,0 +1,4 @@ +/* The MIPS has selectable endianness. + The Japanese homebrew P40 architecture uses big-endian mode. */ + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/mips/setjmp.S b/sysdeps/mips/setjmp.S new file mode 100644 index 0000000000..b3c0247468 --- /dev/null +++ b/sysdeps/mips/setjmp.S @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* The function __sigsetjmp_aux saves all the registers, but it can't + reliably access the stack or frame pointers, so we pass them in as + extra arguments. */ +ENTRY (__sigsetjmp) + move a2, sp +#ifdef __sgi__ + move a3, fp +#else + move a3, $fp +#endif + j __sigsetjmp_aux diff --git a/sysdeps/mips/setjmp_aux.c b/sysdeps/mips/setjmp_aux.c new file mode 100644 index 0000000000..d478e3fdc9 --- /dev/null +++ b/sysdeps/mips/setjmp_aux.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> + +/* This function is only called via the assembly language routine + __sigsetjmp, which arranges to pass in the stack pointer and the frame + pointer. We do things this way because it's difficult to reliably + access them in C. */ + +int +__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp) +{ + /* Store the floating point callee-saved registers... */ + asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1])); + asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2])); + asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3])); + asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4])); + asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5])); + + /* .. and the PC; */ + asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc)); + + /* .. and the stack pointer; */ + env[0].__jmpbuf[0].__sp = sp; + + /* .. and the FP; it'll be in s8. */ + env[0].__jmpbuf[0].__fp = fp; + + /* .. and the GP; */ + asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp)); + + /* .. and the callee-saved registers; */ + asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0])); + asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1])); + asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2])); + asm volatile ("sw $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3])); + asm volatile ("sw $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4])); + asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5])); + asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6])); + asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7])); + + /* .. and finally get and reconstruct the floating point csr. */ + asm ("cfc1 %0, $31" : "=r" (env[0].__jmpbuf[0].__fpc_csr)); + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/sysdeps/posix/Dist b/sysdeps/posix/Dist new file mode 100644 index 0000000000..d003c6e781 --- /dev/null +++ b/sysdeps/posix/Dist @@ -0,0 +1 @@ +mk-stdiolim.c diff --git a/sysdeps/posix/Makefile b/sysdeps/posix/Makefile new file mode 100644 index 0000000000..fd1b3f257a --- /dev/null +++ b/sysdeps/posix/Makefile @@ -0,0 +1,40 @@ +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +$(common-objpfx)stdio_lim.h: $(common-objpfx)mk-stdiolim + $(dir $<)$(notdir $<) > $@-t + mv $@-t $@ + +ifdef subdir +objdir-CPPFLAGS = $(CPPFLAGS) # Already has appropriate `..'s. +else +objdir-CPPFLAGS = $(patsubst -I/..//%,-I/%,$(CPPFLAGS:-I%=-I../%)) +endif +# Turn into a version that works when cd'd into $(objdir). +cded-objdir-CPPFLAGS = $(patsubst -I$$cwd//%,-I/%,\ + $(patsubst -I%,-I$$cwd/%,$(CPPFLAGS))) +# $(BUILD_CFLAGS) needs to come last because it contains unwanted -Is. +$(common-objpfx)mk-stdiolim: $(sysdep_dir)/posix/mk-stdiolim.c \ + posix1_lim.h local_lim.h + cwd=`pwd`; cd $(common-objdir); \ + $(BUILD_CC) $(cded-objdir-CPPFLAGS) $(BUILD_CFLAGS) \ + $$cwd/$< -o $(patsubst $(common-objpfx)%,%,$@) + + +common-generated := $(common-generated) stdio_lim.h mk-stdiolim +before-compile := $(before-compile) $(common-objpfx)stdio_lim.h diff --git a/sysdeps/posix/clock.c b/sysdeps/posix/clock.c new file mode 100644 index 0000000000..c34593b9eb --- /dev/null +++ b/sysdeps/posix/clock.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/times.h> +#include <time.h> + +/* Return the time used by the program so far (user time + system time). */ +clock_t +DEFUN_VOID(clock) +{ + struct tms buf; + + if (__times(&buf) < 0) + return (clock_t) -1; + + return ((buf.tms_utime + buf.tms_stime) * CLK_TCK * CLOCKS_PER_SEC); +} diff --git a/sysdeps/posix/ctermid.c b/sysdeps/posix/ctermid.c new file mode 100644 index 0000000000..8e96694841 --- /dev/null +++ b/sysdeps/posix/ctermid.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> + + +/* Return the name of the controlling terminal. + If S is not NULL, the name is copied into it (it should be at + least L_ctermid bytes long), otherwise a static buffer is used. */ +char * +DEFUN(ctermid, (s), char *s) +{ + static char name[L_ctermid]; + + if (name[0] == '\0') + (void) strcpy(name, "/dev/tty"); + + if (s == NULL) + return(name); + + return(strcpy(s, name)); +} diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c new file mode 100644 index 0000000000..b874e909ce --- /dev/null +++ b/sysdeps/posix/cuserid.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> + +extern int EXFUN(geteuid, (NOARGS)); + + +/* Return the username of the caller. + If S is not NULL, it points to a buffer of at least L_cuserid bytes + into which the name is copied; otherwise, a static buffer is used. */ +char * +DEFUN(cuserid, (s), char *s) +{ + static char name[L_cuserid]; + struct passwd *pwent = getpwuid(geteuid()); + + if (pwent == NULL) + { + if (s != NULL) + s[0] = '\0'; + return NULL; + } + + if (s == NULL) + s = name; + return strcpy(s, pwent->pw_name); +} diff --git a/sysdeps/posix/defs.c b/sysdeps/posix/defs.c new file mode 100644 index 0000000000..fcbaf16f69 --- /dev/null +++ b/sysdeps/posix/defs.c @@ -0,0 +1,76 @@ +/* Definitions of global stdio data structures. + +Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <unistd.h> + +/* This file defines all the global internal variables for stdio. */ + +/* Standard streams. */ +#define READ 1, 0 +#define WRITE 0, 1 +#define BUFFERED 0 +#define UNBUFFERED 1 +#define stdstream(name, next, fd, readwrite, unbuffered) \ + { \ + _IOMAGIC, \ + NULL, NULL, NULL, NULL, 0, \ + (PTR) fd, \ + { readwrite, /* ... */ }, \ + { NULL, NULL, NULL, NULL, NULL }, \ + { NULL, NULL }, \ + -1, -1, \ + (next), \ + NULL, '\0', 0, \ + 0, 0, unbuffered, 0, 0, 0, 0 \ + } +static FILE stdstreams[3] = + { + stdstream (&stdstreams[0], &stdstreams[1], STDIN_FILENO, READ, BUFFERED), + stdstream (&stdstreams[1], &stdstreams[2], STDOUT_FILENO, WRITE, BUFFERED), + stdstream (&stdstreams[2], NULL, STDERR_FILENO, WRITE, UNBUFFERED), + }; +FILE *stdin = &stdstreams[0]; +FILE *stdout = &stdstreams[1]; +FILE *stderr = &stdstreams[2]; + +/* Pointer to the first stream in the list. */ +FILE *__stdio_head = &stdstreams[0]; + +/* This function MUST be in this file! + This is because we want _cleanup to go into the __libc_atexit set + when any stdio code is used (and to use any stdio code, one must reference + something defined in this file), and since only local symbols can be made + set elements, having the set element stab entry here and _cleanup elsewhere + loses; and having them both elsewhere loses because there is no reference + to cause _cleanup to be linked in. */ + +void +DEFUN_VOID(_cleanup) +{ + (void) fclose((FILE *) NULL); +} + + +#ifdef HAVE_GNU_LD +text_set_element(__libc_atexit, _cleanup); +#endif diff --git a/sysdeps/posix/dup.c b/sysdeps/posix/dup.c new file mode 100644 index 0000000000..73c5900f9c --- /dev/null +++ b/sysdeps/posix/dup.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + + +/* Duplicate FD, returning a new file descriptor open on the same file. */ +int +DEFUN(__dup, (fd), int fd) +{ + return fcntl(fd, F_DUPFD, 0); +} + +weak_alias (__dup, dup) diff --git a/sysdeps/posix/dup2.c b/sysdeps/posix/dup2.c new file mode 100644 index 0000000000..c0c6b2a0f6 --- /dev/null +++ b/sysdeps/posix/dup2.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <unistd.h> + + +/* Duplicate FD to FD2, closing the old FD2 and making FD2 be + open the same file as FD is. Return FD2 or -1. */ +int +DEFUN(__dup2, (fd, fd2), int fd AND int fd2) +{ + int save; + + if (fd2 < 0 +#ifdef OPEN_MAX + || fd2 >= OPEN_MAX +#endif +) + { + errno = EBADF; + return -1; + } + + /* Check if FD is kosher. */ + if (fcntl (fd, F_GETFL) < 0) + return -1; + + if (fd == fd2) + return fd2; + + /* This is not atomic. */ + + save = errno; + (void) close (fd2); + errno = save; + + return fcntl (fd, F_DUPFD, fd2); +} + +weak_alias (__dup2, dup2) diff --git a/sysdeps/posix/fdopen.c b/sysdeps/posix/fdopen.c new file mode 100644 index 0000000000..ad746ec371 --- /dev/null +++ b/sysdeps/posix/fdopen.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> + +/* Defined in fopen.c. */ +extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr)); + +/* Open a new stream on a given system file descriptor. */ +FILE * +DEFUN(fdopen, (fd, mode), int fd AND CONST char *mode) +{ + register FILE *stream; + __io_mode m; + int dflags; + + if (!__getmode (mode, &m)) + return NULL; + + /* Verify the FD is valid and allows the access MODE specifies. */ + + dflags = __fcntl (fd, F_GETFL); + if (dflags == -1) + /* FD was invalid; fcntl has already set errno. */ + return NULL; + + /* Check the access mode. */ + switch (dflags & O_ACCMODE) + { + case O_RDONLY: + if (!m.__read) + { + errno = EBADF; + return NULL; + } + break; + case O_WRONLY: + if (!m.__write) + { + errno = EBADF; + return NULL; + } + break; + } + + stream = __newstream (); + if (stream == NULL) + return NULL; + + stream->__cookie = (PTR) fd; + stream->__mode = m; + + return stream; +} diff --git a/sysdeps/posix/flock.c b/sysdeps/posix/flock.c new file mode 100644 index 0000000000..b4c9fc3b79 --- /dev/null +++ b/sysdeps/posix/flock.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file implements the `flock' function in terms of the POSIX.1 `fcntl' + locking mechanism. In 4BSD, these are two incompatible locking mechanisms, + perhaps with different semantics? */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/file.h> + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +int +DEFUN(__flock, (fd, operation), int fd AND int operation) +{ + struct flock lbuf; + + switch (operation & ~LOCK_NB) + { + case LOCK_SH: + lbuf.l_type = F_RDLCK; + break; + case LOCK_EX: + lbuf.l_type = F_WRLCK; + break; + case LOCK_UN: + lbuf.l_type = F_UNLCK; + break; + default: + errno = EINVAL; + return -1; + } + + lbuf.l_whence = SEEK_SET; + lbuf.l_start = lbuf.l_len = 0L; /* Lock the whole file. */ + + return __fcntl (fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lbuf); +} + +weak_alias (__flock, flock) diff --git a/sysdeps/posix/fpathconf.c b/sysdeps/posix/fpathconf.c new file mode 100644 index 0000000000..b339990b57 --- /dev/null +++ b/sysdeps/posix/fpathconf.c @@ -0,0 +1,116 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <limits.h> + + +/* Get file-specific information about descriptor FD. */ +long int +DEFUN(__fpathconf, (fd, name), int fd AND int name) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + switch (name) + { + default: + errno = EINVAL; + return -1; + + case _PC_LINK_MAX: +#ifdef LINK_MAX + return LINK_MAX; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_MAX_CANON: +#ifdef MAX_CANON + return MAX_CANON; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_MAX_INPUT: +#ifdef MAX_INPUT + return MAX_INPUT; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_NAME_MAX: +#ifdef NAME_MAX + return NAME_MAX; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_PATH_MAX: +#ifdef PATH_MAX + return PATH_MAX; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_PIPE_BUF: +#ifdef PIPE_BUF + return PIPE_BUF; +#else + errno = ENOSYS; + return -1; +#endif + + case _PC_CHOWN_RESTRICTED: +#ifdef _POSIX_CHOWN_RESTRICTED + return _POSIX_CHOWN_RESTRICTED; +#else + return -1; +#endif + + case _PC_NO_TRUNC: +#ifdef _POSIX_NO_TRUNC + return _POSIX_NO_TRUNC; +#else + return -1; +#endif + + case _PC_VDISABLE: +#ifdef _POSIX_VDISABLE + return _POSIX_VDISABLE; +#else + return -1; +#endif + } + + errno = ENOSYS; + return -1; +} + +weak_alias (__fpathconf, fpathconf) diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c new file mode 100644 index 0000000000..7b992a9f43 --- /dev/null +++ b/sysdeps/posix/getcwd.c @@ -0,0 +1,366 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Wants: + AC_STDC_HEADERS + AC_DIR_HEADER + AC_UNISTD_H + AC_MEMORY_H + AC_CONST + AC_ALLOCA + */ + +/* AIX requires this to be the first thing in the file. */ +#if defined (_AIX) && !defined (__GNUC__) + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef STDC_HEADERS +#include <stddef.h> +#endif + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#if defined (USGr3) && !defined (DIRENT) +#define DIRENT +#endif /* USGr3 */ +#if defined (Xenix) && !defined (SYSNDIR) +#define SYSNDIR +#endif /* Xenix */ + +#if defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__) +#include <dirent.h> +#ifndef __GNU_LIBRARY__ +#define D_NAMLEN(d) strlen((d)->d_name) +#else +#define HAVE_D_NAMLEN +#define D_NAMLEN(d) ((d)->d_namlen) +#endif +#else /* not POSIX or DIRENT */ +#define dirent direct +#define D_NAMLEN(d) ((d)->d_namlen) +#define HAVE_D_NAMLEN +#if defined (USG) && !defined (sgi) +#if defined (SYSNDIR) +#include <sys/ndir.h> +#else /* Not SYSNDIR */ +#include "ndir.h" +#endif /* SYSNDIR */ +#else /* not USG */ +#include <sys/dir.h> +#endif /* USG */ +#endif /* POSIX or DIRENT or __GNU_LIBRARY__ */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) \ + || defined (POSIX)) +#include <stdlib.h> +#include <string.h> +#define ANSI_STRING +#else /* No standard headers. */ + +#ifdef USG + +#include <string.h> +#ifdef NEED_MEMORY_H +#include <memory.h> +#endif +#define ANSI_STRING + +#else /* Not USG. */ + +#ifdef NeXT + +#include <string.h> + +#else /* Not NeXT. */ + +#include <strings.h> + +#ifndef bcmp +extern int bcmp (); +#endif +#ifndef bzero +extern void bzero (); +#endif +#ifndef bcopy +extern void bcopy (); +#endif + +#endif /* NeXT. */ + +#endif /* USG. */ + +extern char *malloc (), *realloc (); +extern void free (); + +#endif /* Standard headers. */ + +#ifndef ANSI_STRING +#define memcpy(d, s, n) bcopy((s), (d), (n)) +#define memmove memcpy +#endif /* Not ANSI_STRING. */ + +#if !defined(__alloca) && !defined(__GNU_LIBRARY__) + +#ifdef __GNUC__ +#undef alloca +#define alloca(n) __builtin_alloca (n) +#else /* Not GCC. */ +#if defined (sparc) || defined (HAVE_ALLOCA_H) +#include <alloca.h> +#else /* Not sparc or HAVE_ALLOCA_H. */ +#ifndef _AIX +extern char *alloca (); +#endif /* Not _AIX. */ +#endif /* sparc or HAVE_ALLOCA_H. */ +#endif /* GCC. */ + +#define __alloca alloca + +#endif + +#if (defined (HAVE_LIMITS_H) || defined (STDC_HEADERS) || \ + defined (__GNU_LIBRARY__)) +#include <limits.h> +#else +#include <sys/param.h> +#endif + +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif + +#ifndef STDC_HEADERS +#undef size_t +#define size_t unsigned int +#endif + +#if !__STDC__ && !defined (const) +#define const +#endif + +#ifndef __GNU_LIBRARY__ +#define __lstat stat +#endif + +/* Get the pathname of the current working directory, and put it in SIZE + bytes of BUF. Returns NULL if the directory couldn't be determined or + SIZE was too small. If successful, returns BUF. In GNU, if BUF is + NULL, an array is allocated with `malloc'; the array is SIZE bytes long, + unless SIZE <= 0, in which case it is as big as necessary. */ + +char * +getcwd (buf, size) + char *buf; + size_t size; +{ + static const char dots[] + = "../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../.."; + const char *dotp, *dotlist; + size_t dotsize; + dev_t rootdev, thisdev; + ino_t rootino, thisino; + char *path; + register char *pathp; + struct stat st; + + if (size == 0) + { + if (buf != NULL) + { + errno = EINVAL; + return NULL; + } + + size = PATH_MAX + 1; + } + + if (buf != NULL) + path = buf; + else + { + path = malloc (size); + if (path == NULL) + return NULL; + } + + pathp = path + size; + *--pathp = '\0'; + + if (__lstat (".", &st) < 0) + return NULL; + thisdev = st.st_dev; + thisino = st.st_ino; + + if (__lstat ("/", &st) < 0) + return NULL; + rootdev = st.st_dev; + rootino = st.st_ino; + + dotsize = sizeof (dots) - 1; + dotp = &dots[sizeof (dots)]; + dotlist = dots; + while (!(thisdev == rootdev && thisino == rootino)) + { + register DIR *dirstream; + register struct dirent *d; + dev_t dotdev; + ino_t dotino; + char mount_point; + + /* Look at the parent directory. */ + if (dotp == dotlist) + { + /* My, what a deep directory tree you have, Grandma. */ + char *new; + if (dotlist == dots) + { + new = malloc (dotsize * 2 + 1); + if (new == NULL) + return NULL; + memcpy (new, dots, dotsize); + } + else + { + new = realloc ((__ptr_t) dotlist, dotsize * 2 + 1); + if (new == NULL) + goto lose; + } + memcpy (&new[dotsize], new, dotsize); + dotp = &new[dotsize]; + dotsize *= 2; + new[dotsize] = '\0'; + dotlist = new; + } + + dotp -= 3; + + /* Figure out if this directory is a mount point. */ + if (__lstat (dotp, &st) < 0) + goto lose; + dotdev = st.st_dev; + dotino = st.st_ino; + mount_point = dotdev != thisdev; + + /* Search for the last directory. */ + dirstream = opendir (dotp); + if (dirstream == NULL) + goto lose; + while ((d = readdir (dirstream)) != NULL) + { + if (d->d_name[0] == '.' && + (d->d_namlen == 1 || (d->d_namlen == 2 && d->d_name[1] == '.'))) + continue; + if (mount_point || d->d_ino == thisino) + { + char *name = __alloca (dotlist + dotsize - dotp + + 1 + d->d_namlen + 1); + memcpy (name, dotp, dotlist + dotsize - dotp); + name[dotlist + dotsize - dotp] = '/'; + memcpy (&name[dotlist + dotsize - dotp + 1], + d->d_name, d->d_namlen + 1); + if (__lstat (name, &st) < 0) + { + int save = errno; + (void) closedir (dirstream); + errno = save; + goto lose; + } + if (st.st_dev == thisdev && st.st_ino == thisino) + break; + } + } + if (d == NULL) + { + int save = errno; + (void) closedir (dirstream); + errno = save; + goto lose; + } + else + { + if (pathp - path < d->d_namlen + 1) + { + if (buf != NULL) + { + errno = ERANGE; + return NULL; + } + else + { + size *= 2; + buf = realloc (path, size); + if (buf == NULL) + { + (void) closedir (dirstream); + free (path); + errno = ENOMEM; /* closedir might have changed it. */ + return NULL; + } + pathp = &buf[pathp - path]; + path = buf; + } + } + pathp -= d->d_namlen; + (void) memcpy (pathp, d->d_name, d->d_namlen); + *--pathp = '/'; + (void) closedir (dirstream); + } + + thisdev = dotdev; + thisino = dotino; + } + + if (pathp == &path[size - 1]) + *--pathp = '/'; + + if (dotlist != dots) + free ((__ptr_t) dotlist); + + memmove (path, pathp, path + size - pathp); + return path; + + lose: + if (dotlist != dots) + free ((__ptr_t) dotlist); + return NULL; +} diff --git a/sysdeps/posix/getdtsz.c b/sysdeps/posix/getdtsz.c new file mode 100644 index 0000000000..2080dc7c51 --- /dev/null +++ b/sysdeps/posix/getdtsz.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> + +extern long int EXFUN(__sysconf, (int)); + +/* Return the maximum number of file descriptors + the current process could possibly have. */ +int +DEFUN_VOID(__getdtablesize) +{ + return __sysconf (_SC_OPEN_MAX); +} + +weak_alias (__getdtablesize, getdtablesize) diff --git a/sysdeps/posix/getpagesize.c b/sysdeps/posix/getpagesize.c new file mode 100644 index 0000000000..4deb208633 --- /dev/null +++ b/sysdeps/posix/getpagesize.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@cygnus.com). + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <unistd.h> + +extern long int EXFUN(__sysconf, (int)); + +/* Return the system page size. */ +size_t +DEFUN_VOID(__getpagesize) +{ + return __sysconf (_SC_PAGESIZE); +} + +weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c new file mode 100644 index 0000000000..a4bb38a41c --- /dev/null +++ b/sysdeps/posix/gettimeofday.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <time.h> +#include <sys/time.h> + +#ifndef HAVE_GNU_LD +#define __daylight daylight +#define __timezone timezone +#define __tzname tzname +#endif + + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. */ +int +DEFUN(__gettimeofday, (tv, tz), + struct timeval *tv AND struct timezone *tz) +{ + if (tv == NULL) + { + errno = EINVAL; + return -1; + } + + tv->tv_sec = (long int) time ((time_t *) NULL); + tv->tv_usec = 0L; + + if (tz != NULL) + { + CONST time_t timer = tv->tv_sec; + CONST struct tm *tm; + + CONST long int save_timezone = __timezone; + CONST long int save_daylight = __daylight; + char *save_tzname[2]; + save_tzname[0] = __tzname[0]; + save_tzname[1] = __tzname[1]; + + tm = localtime (&timer); + + tz->tz_minuteswest = __timezone / 60; + tz->tz_dsttime = __daylight; + + __timezone = save_timezone; + __daylight = save_daylight; + __tzname[0] = save_tzname[0]; + __tzname[1] = save_tzname[1]; + + if (tm == NULL) + return -1; + } + + return 0; +} + +weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/posix/isatty.c b/sysdeps/posix/isatty.c new file mode 100644 index 0000000000..7536b1eeed --- /dev/null +++ b/sysdeps/posix/isatty.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <termios.h> + +/* Return 1 if FD is a terminal, 0 if not. */ +int +DEFUN(__isatty, (fd), int fd) +{ + int save; + int is_tty; + struct termios term; + + save = errno; + is_tty = __tcgetattr(fd, &term) == 0; + errno = save; + + return is_tty; +} + +weak_alias (__isatty, isatty) diff --git a/sysdeps/posix/killpg.c b/sysdeps/posix/killpg.c new file mode 100644 index 0000000000..0c70dd2164 --- /dev/null +++ b/sysdeps/posix/killpg.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* Send SIG to all processes in process group PGRP. + If PGRP is zero, send SIG to all processes in + the current process's process group. */ +int +DEFUN(killpg, (pgrp, sig), __pid_t pgrp AND int sig) +{ + if (pgrp < 0) + { + errno = EINVAL; + return -1; + } + + return __kill (- pgrp, sig); +} diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c new file mode 100644 index 0000000000..5539516733 --- /dev/null +++ b/sysdeps/posix/libc_fatal.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <sysdep.h> + +#ifdef FATAL_PREPARE_INCLUDE +#include FATAL_PREPARE_INCLUDE +#endif + +/* Abort with an error message. */ +void +DEFUN(__libc_fatal, (message), CONST char *message) +{ + size_t len = strlen (message); + +#ifdef FATAL_PREPARE + FATAL_PREPARE; +#endif + + while (len > 0) + { + register int count = __write (STDERR_FILENO, message, len); + if (count > 0) + { + message += count; + len -= count; + } + else if (count < 0 +#ifdef EINTR + && errno != EINTR +#endif + ) + break; + } + + abort (); +} diff --git a/sysdeps/posix/mk-stdiolim.c b/sysdeps/posix/mk-stdiolim.c new file mode 100644 index 0000000000..da78a98394 --- /dev/null +++ b/sysdeps/posix/mk-stdiolim.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <posix1_lim.h> + +int +main() +{ + /* These values correspond to the code in sysdeps/posix/tempname.c. + Change the values here if you change that code. */ + printf("#define L_tmpnam %u\n", sizeof("/usr/tmp/") + 8); + printf("#define TMP_MAX %u\n", 62 * 62 * 62); + + puts ("#ifdef __USE_POSIX"); + printf("#define L_ctermid %u\n", sizeof("/dev/tty")); + printf("#define L_cuserid 9\n"); + puts ("#endif"); + + /* POSIX does not require that OPEN_MAX and PATH_MAX be defined, so + <local_lim.h> will not define them if they are run-time variant (which + is the case in the Hurd). ANSI still requires that FOPEN_MAX and + FILENAME_MAX be defined, however. */ + + printf("#define FOPEN_MAX %u\n", +#ifdef OPEN_MAX + + OPEN_MAX +#else + /* This is the minimum number of files that the implementation + guarantees can be open simultaneously. OPEN_MAX not being + defined means the maximum is run-time variant; but POSIX.1 + requires that it never be less than _POSIX_OPEN_MAX, so that is + a good minimum to use. */ + _POSIX_OPEN_MAX +#endif + + ); + + printf("#define FILENAME_MAX %u\n", +#ifdef PATH_MAX + PATH_MAX +#else + /* This is supposed to be the size needed to hold the longest file + name string the implementation guarantees can be opened. + PATH_MAX not being defined means the actual limit on the length + of a file name is runtime-variant (or it is unlimited). ANSI + says in such a case FILENAME_MAX should be a good size to + allocate for a file name string. POSIX.1 guarantees that a + file name up to _POSIX_PATH_MAX chars long can be opened, so + this value must be at least that. */ + 1024 /* _POSIX_PATH_MAX is 255. */ +#endif + ); + + exit(0); +} diff --git a/sysdeps/posix/mkstemp.c b/sysdeps/posix/mkstemp.c new file mode 100644 index 0000000000..9f4f68d72d --- /dev/null +++ b/sysdeps/posix/mkstemp.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns a file descriptor open on the file for reading and writing. */ +int +DEFUN(mkstemp, (template), char *template) +{ + static CONST char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + size_t len; + size_t i; + + len = strlen (template); + if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) + { + errno = EINVAL; + return -1; + } + + if (sprintf (&template[len - 5], "%.5u", + (unsigned int) getpid () % 100000) != 5) + /* Inconceivable lossage. */ + return -1; + + for (i = 0; i < sizeof (letters); ++i) + { + int fd; + + template[len - 6] = letters[i]; + + fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0666); + if (fd >= 0) + return fd; + } + + /* We return the null string if we can't find a unique file name. */ + template[0] = '\0'; + return -1; +} diff --git a/sysdeps/posix/mktemp.c b/sysdeps/posix/mktemp.c new file mode 100644 index 0000000000..c3aae36a7b --- /dev/null +++ b/sysdeps/posix/mktemp.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. */ +char * +DEFUN(mktemp, (template), char *template) +{ + static CONST char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + size_t len; + size_t i; + + len = strlen (template); + if (len < 6 || strcmp (&template[len - 6], "XXXXXX")) + { + errno = EINVAL; + return NULL; + } + + if (sprintf (&template[len - 5], "%.5u", + (unsigned int) getpid () % 100000) != 5) + /* Inconceivable lossage. */ + return NULL; + + for (i = 0; i < sizeof (letters); ++i) + { + struct stat ignored; + + template[len - 6] = letters[i]; + + if (stat (template, &ignored) < 0 && errno == ENOENT) + /* The file does not exist. So return this name. */ + return template; + } + + /* We return the null string if we can't find a unique file name. */ + template[0] = '\0'; + return template; +} diff --git a/sysdeps/posix/pipestream.c b/sysdeps/posix/pipestream.c new file mode 100644 index 0000000000..53595f5b54 --- /dev/null +++ b/sysdeps/posix/pipestream.c @@ -0,0 +1,223 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <fcntl.h> + +#define SH_PATH "/bin/sh" /* Shell to run. */ +#define SH_NAME "sh" /* Name to give it. */ + +/* Structure describing a popen child. */ +struct child + { + pid_t pid; /* PID of the child. */ + __ptr_t cookie; /* Original cookie from fdopen. */ + __io_functions funcs; /* Original functions from fdopen. */ + }; + +/* io_functions for pipe streams. + These all simply call the corresponding + original function with the original cookie. */ + +#define FUNC(type, name, args) \ + static type DEFUN(__CONCAT(child_,name), args, __CONCAT(name,decl)) \ + { \ + struct child *c = (struct child *) cookie; \ + { \ + __ptr_t cookie = c->cookie; \ + return (*c->funcs.__CONCAT(__,name)) args; \ + } \ + } + +#define readdecl PTR cookie AND register char *buf AND register size_t n +FUNC (int, read, (cookie, buf, n)) +#define writedecl PTR cookie AND register CONST char *buf AND register size_t n +FUNC (int, write, (cookie, buf, n)) +#define seekdecl PTR cookie AND fpos_t *pos AND int whence +FUNC (int, seek, (cookie, pos, whence)) +#define closedecl PTR cookie +FUNC (int, close, (cookie)) +#define filenodecl PTR cookie +FUNC (int, fileno, (cookie)) + +static const __io_functions child_funcs + = { child_read, child_write, child_seek, child_close, child_fileno }; + +/* Open a new stream that is a one-way pipe to a + child process running the given shell command. */ +FILE * +DEFUN(popen, (command, mode), CONST char *command AND CONST char *mode) +{ + pid_t pid; + int pipedes[2]; + FILE *stream; + struct child *child; + + if (command == NULL || mode == NULL || (*mode != 'r' && *mode != 'w')) + { + errno = EINVAL; + return NULL; + } + + /* Create the pipe. */ + if (pipe(pipedes) < 0) + return NULL; + + /* Fork off the child. */ + pid = __vfork (); + if (pid == (pid_t) -1) + { + /* The fork failed. */ + (void) close (pipedes[0]); + (void) close (pipedes[1]); + return NULL; + } + else if (pid == (pid_t) 0) + { + /* We are the child side. Make the write side of + the pipe be stdin or the read side be stdout. */ + + CONST char *new_argv[4]; + + if ((*mode == 'w' ? dup2(pipedes[STDIN_FILENO], STDIN_FILENO) : + dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO)) < 0) + _exit(127); + + /* Close the pipe descriptors. */ + (void) close(pipedes[STDIN_FILENO]); + (void) close(pipedes[STDOUT_FILENO]); + + /* Exec the shell. */ + new_argv[0] = SH_NAME; + new_argv[1] = "-c"; + new_argv[2] = command; + new_argv[3] = NULL; + (void) execve(SH_PATH, (char *CONST *) new_argv, environ); + /* Die if it failed. */ + _exit(127); + } + + /* We are the parent side. */ + + /* Close the irrelevant side of the pipe and open the relevant side as a + new stream. Mark our side of the pipe to close on exec, so new children + won't see it. */ + if (*mode == 'r') + { + (void) close (pipedes[STDOUT_FILENO]); + (void) fcntl (pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC); + stream = fdopen (pipedes[STDIN_FILENO], mode); + } + else + { + (void) close (pipedes[STDIN_FILENO]); + (void) fcntl (pipedes[STDOUT_FILENO], F_SETFD, FD_CLOEXEC); + stream = fdopen (pipedes[STDOUT_FILENO], mode); + } + + if (stream == NULL) + goto error; + + child = (struct child *) malloc (sizeof (struct child)); + if (child == NULL) + goto error; + + { + /* Make sure STREAM has its functions set before + we try to squirrel them away in CHILD. */ + extern void __stdio_check_funcs __P ((FILE *)); + __stdio_check_funcs (stream); + } + + child->pid = pid; + child->cookie = stream->__cookie; + child->funcs = stream->__io_funcs; + stream->__cookie = (PTR) child; + stream->__io_funcs = child_funcs; + stream->__ispipe = 1; + return stream; + + error: + { + /* The stream couldn't be opened or the child structure couldn't be + allocated. Kill the child and close the other side of the pipe. */ + int save = errno; + (void) kill (pid, SIGKILL); + if (stream == NULL) + (void) close (pipedes[*mode == 'r' ? STDOUT_FILENO : STDIN_FILENO]); + else + (void) fclose (stream); +#ifndef NO_WAITPID + (void) waitpid (pid, (int *) NULL, 0); +#else + { + pid_t dead; + do + dead = wait ((int *) NULL); + while (dead > 0 && dead != pid); + } +#endif + errno = save; + return NULL; + } +} + +/* Close a stream opened by popen and return its status. + Returns -1 if the stream was not opened by popen. */ +int +DEFUN(pclose, (stream), register FILE *stream) +{ + struct child *c; + pid_t pid, dead; + int status; + + if (!__validfp(stream) || !stream->__ispipe) + { + errno = EINVAL; + return -1; + } + + c = (struct child *) stream->__cookie; + pid = c->pid; + stream->__cookie = c->cookie; + stream->__io_funcs = c->funcs; + free ((PTR) c); + stream->__ispipe = 0; + if (fclose (stream)) + return -1; + +#ifndef NO_WAITPID + dead = waitpid (pid, &status, 0); +#else + do + dead = wait (&status); + while (dead > 0 && dead != pid); +#endif + if (dead != pid) + status = -1; + + return status; +} diff --git a/sysdeps/posix/raise.c b/sysdeps/posix/raise.c new file mode 100644 index 0000000000..159fdd5cb9 --- /dev/null +++ b/sysdeps/posix/raise.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <unistd.h> + +/* Raise the signal SIG. */ +int +DEFUN(raise, (sig), int sig) +{ + return __kill(__getpid(), sig); +} diff --git a/sysdeps/posix/readv.c b/sysdeps/posix/readv.c new file mode 100644 index 0000000000..5f61e61b9f --- /dev/null +++ b/sysdeps/posix/readv.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/uio.h> + +/* Read data from file descriptor FD, and put the result in the + buffers described by VECTOR, which is a vector of COUNT `struct iovec's. + The buffers are filled in the order specified. + Operates just like `read' (see <unistd.h>) except that data are + put in VECTOR instead of a contiguous buffer. */ +int +DEFUN(readv, (fd, vector, count), + int fd AND CONST struct iovec *vector AND size_t count) +{ + char *buffer; + size_t bytes; + int bytes_read; + register size_t i; + + /* Find the total number of bytes to be read. */ + bytes = 0; + for (i = 0; i < count; ++i) + bytes += vector[i].iov_len; + + /* Allocate a temporary buffer to hold the data. */ + buffer = (char *) __alloca(bytes); + + /* Read the data. */ + bytes_read = read(fd, buffer, bytes); + if (bytes_read <= 0) + return -1; + + /* Copy the data from BUFFER into the memory specified by VECTOR. */ + bytes = bytes_read; + for (i = 0; i < count; ++i) + { +#define min(a, b) ((a) > (b) ? (b) : (a)) + size_t copy = min(vector[i].iov_len, bytes); + + (void) memcpy((PTR) vector[i].iov_base, (PTR) buffer, copy); + + buffer += copy; + bytes -= copy; + if (bytes == 0) + break; + } + + return bytes_read; +} diff --git a/sysdeps/posix/remove.c b/sysdeps/posix/remove.c new file mode 100644 index 0000000000..66414c9039 --- /dev/null +++ b/sysdeps/posix/remove.c @@ -0,0 +1,40 @@ +/* ANSI C `remove' function to delete a file or directory. POSIX.1 version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +int +remove (file) + const char *file; +{ + int save; + + save = errno; + if (__rmdir (file) == 0) + return 0; + else if (errno == ENOTDIR && __unlink (file) == 0) + { + errno = save; + return 0; + } + + return -1; +} diff --git a/sysdeps/posix/rename.c b/sysdeps/posix/rename.c new file mode 100644 index 0000000000..3245f9cf9c --- /dev/null +++ b/sysdeps/posix/rename.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +/* Rename the file OLD to NEW. */ +int +DEFUN(rename, (old, new), CONST char *old AND CONST char *new) +{ + int save = errno; + if (__link(old, new) < 0) + { + if (errno == EEXIST) + { + errno = save; + /* Race condition, required for 1003.1 conformance. */ + if (__unlink(new) < 0 || + __link(old, new) < 0) + return -1; + } + else + return -1; + } + if (__unlink(old) < 0) + { + save = errno; + if (__unlink(new) == 0) + errno = save; + return -1; + } + return 0; +} diff --git a/sysdeps/posix/sigblock.c b/sysdeps/posix/sigblock.c new file mode 100644 index 0000000000..411a952bc3 --- /dev/null +++ b/sysdeps/posix/sigblock.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Block signals in MASK, returning the old mask. */ +int +DEFUN(__sigblock, (mask), int mask) +{ + register int sig; + sigset_t set, oset; + + if (__sigemptyset(&set) < 0) + return -1; + + if (sizeof (mask) == sizeof (set)) + *(int *) &set = mask; + else + for (sig = 1; sig < NSIG; ++sig) + if ((mask & sigmask(sig)) && + __sigaddset(&set, sig) < 0) + return -1; + + if (sigprocmask(SIG_BLOCK, &set, &oset) < 0) + return -1; + + mask = 0; + if (sizeof (mask) == sizeof (oset)) + mask = *(int *) &oset; + else + for (sig = 1; sig < NSIG; ++sig) + if (__sigismember(&oset, sig)) + mask |= sigmask(sig); + + return mask; +} + +weak_alias (__sigblock, sigblock) diff --git a/sysdeps/posix/sigintr.c b/sysdeps/posix/sigintr.c new file mode 100644 index 0000000000..441c643df8 --- /dev/null +++ b/sysdeps/posix/sigintr.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <signal.h> +#include <errno.h> + +/* If INTERRUPT is nonzero, make signal SIG interrupt system calls + (causing them to fail with EINTR); if INTERRUPT is zero, make system + calls be restarted after signal SIG. */ +int +DEFUN(siginterrupt, (sig, interrupt), + int sig AND int interrupt) +{ +#ifdef SA_RESTART + extern sigset_t _sigintr; /* Defined in signal.c. */ + struct sigaction action; + + if (__sigaction (sig, (struct sigaction *) NULL, &action) < 0) + return -1; + + if (interrupt) + { + __sigaddset (&_sigintr, sig); + action.sa_flags &= ~SA_RESTART; + } + else + { + __sigdelset (&_sigintr, sig); + action.sa_flags |= SA_RESTART; + } + + if (__sigaction (sig, &action, (struct sigaction *) NULL) < 0) + return -1; + + return 0; +#else + errno = ENOSYS; + return -1; +#endif +} diff --git a/sysdeps/posix/signal.c b/sysdeps/posix/signal.c new file mode 100644 index 0000000000..f9ae47b6bb --- /dev/null +++ b/sysdeps/posix/signal.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +sigset_t _sigintr; /* Set by siginterrupt. */ + +/* Set the handler for the signal SIG to HANDLER, + returning the old handler, or SIG_ERR on error. */ +__sighandler_t +DEFUN(signal, (sig, handler), int sig AND __sighandler_t handler) +{ + struct sigaction act, oact; + + if (handler == SIG_ERR) + { + errno = EINVAL; + return SIG_ERR; + } + + act.sa_handler = handler; + if (__sigemptyset (&act.sa_mask) < 0) + return SIG_ERR; + act.sa_flags = __sigismember (&_sigintr, sig) ? 0 : SA_RESTART; + if (__sigaction (sig, &act, &oact) < 0) + return SIG_ERR; + + return oact.sa_handler; +} diff --git a/sysdeps/posix/sigpause.c b/sysdeps/posix/sigpause.c new file mode 100644 index 0000000000..97716d352b --- /dev/null +++ b/sysdeps/posix/sigpause.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Set the mask of blocked signals to MASK, + wait for a signal to arrive, and then restore the mask. */ +int +DEFUN(__sigpause, (mask), int mask) +{ + sigset_t set; + int sig; + + if (__sigemptyset (&set) < 0) + return -1; + + if (sizeof (mask) == sizeof (set)) + *(int *) &set = mask; + else + for (sig = 1; sig < NSIG; ++sig) + if ((mask & sigmask(sig)) && + __sigaddset(&set, sig) < 0) + return -1; + + return sigsuspend (&set); +} + +weak_alias (__sigpause, sigpause) diff --git a/sysdeps/posix/sigsetmask.c b/sysdeps/posix/sigsetmask.c new file mode 100644 index 0000000000..12e77a619d --- /dev/null +++ b/sysdeps/posix/sigsetmask.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Set the mask of blocked signals to MASK, returning the old mask. */ +int +DEFUN(__sigsetmask, (mask), int mask) +{ + register int sig; + sigset_t set, oset; + + if (__sigemptyset(&set) < 0) + return -1; + + if (sizeof (mask) == sizeof (set)) + *(int *) &set = mask; + else + for (sig = 1; sig < NSIG; ++sig) + if ((mask & sigmask(sig)) && + __sigaddset(&set, sig) < 0) + return -1; + + if (sigprocmask(SIG_SETMASK, &set, &oset) < 0) + return -1; + + mask = 0; + if (sizeof (mask) == sizeof (oset)) + mask = *(int *) &oset; + else + for (sig = 1; sig < NSIG; ++sig) + if (__sigismember(&oset, sig)) + mask |= sigmask(sig); + + return mask; +} + +weak_alias (__sigsetmask, sigsetmask) diff --git a/sysdeps/posix/sigsuspend.c b/sysdeps/posix/sigsuspend.c new file mode 100644 index 0000000000..771315333a --- /dev/null +++ b/sysdeps/posix/sigsuspend.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <unistd.h> + + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +int +DEFUN(sigsuspend, (set), CONST sigset_t *set) +{ + sigset_t oset; + int save; + + if (set == NULL) + { + errno = EINVAL; + return -1; + } + + if (sigprocmask(SIG_SETMASK, set, &oset) < 0) + return -1; + + (void) pause(); + save = errno; + + if (sigprocmask(SIG_SETMASK, &oset, (sigset_t *) NULL) < 0) + return -1; + + errno = save; + return -1; +} diff --git a/sysdeps/posix/sigvec.c b/sysdeps/posix/sigvec.c new file mode 100644 index 0000000000..4aef22ae32 --- /dev/null +++ b/sysdeps/posix/sigvec.c @@ -0,0 +1,162 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <errno.h> +#include <stddef.h> + + +/* We use a wrapper handler to support SV_RESETHAND. */ + +static __sighandler_t wrapped_handlers[NSIG]; +static sigset_t wrapped_masks[NSIG]; + +static void +DEFUN(wrapper_handler, (sig), int sig) +{ + int save; + struct sigaction act; + + act.sa_handler = SIG_DFL; + act.sa_mask = wrapped_masks[sig]; + act.sa_flags = 0; + save = errno; + (void) __sigaction(sig, &act, (struct sigaction *) NULL); + errno = save; + + (*wrapped_handlers[sig])(sig); +} + +static +#ifdef __GNUC__ +inline +#endif +int +DEFUN(convert_mask, (set, mask), sigset_t *set AND CONST int mask) +{ + register int sig; + + if (sizeof(*set) == sizeof(mask)) + { + *(int *) set = mask; + return 0; + } + + if (__sigemptyset(set) < 0) + return -1; + + for (sig = 1; sig < NSIG; ++sig) + if (mask & sigmask(sig)) + if (__sigaddset(set, sig) < 0) + return -1; + + return 0; +} + +/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member + of VEC. The signals in `sv_mask' will be blocked while the handler runs. + If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be + reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, + it is filled in with the old information for SIG. */ +int +DEFUN(__sigvec, (sig, vec, ovec), + int sig AND CONST struct sigvec *vec AND struct sigvec *ovec) +{ + struct sigaction old; + + if (vec == NULL || !(vec->sv_flags & SV_RESETHAND)) + { + struct sigaction new, *n; + + if (vec == NULL) + n = NULL; + else + { + n = &new; + n->sa_handler = vec->sv_handler; + if (convert_mask (&n->sa_mask, vec->sv_mask) < 0) + return -1; + n->sa_flags = 0; + + if (vec->sv_flags & SV_ONSTACK) + { +#ifdef SA_ONSTACK + n->sa_flags |= SA_ONSTACK; +#else + errno = ENOSYS; + return -1; +#endif + } +#ifdef SA_RESTART + if (!(vec->sv_flags & SV_INTERRUPT)) + n->sa_flags |= SA_RESTART; +#endif + } + + if (__sigaction (sig, n, &old) < 0) + return -1; + } + else + { + struct sigaction wrapper; + + wrapper.sa_handler = wrapper_handler; + wrapped_handlers[sig] = vec->sv_handler; + if (convert_mask (&wrapped_masks[sig], vec->sv_mask) < 0) + return -1; + + if (__sigaction (sig, &wrapper, &old) < 0) + return -1; + } + + if (ovec != NULL) + { + register int i; + int mask = 0; + + if (sizeof (int) == sizeof (sigset_t)) + mask = *(int *) &old.sa_mask; + else + for (i = 1; i < NSIG; ++i) + if (__sigismember(&old.sa_mask, i)) + mask |= sigmask(i); + + ovec->sv_mask = mask; + ovec->sv_flags = 0; +#ifdef SA_ONSTACK + if (old.sa_flags & SA_ONSTACK) + ovec->sv_flags |= SV_ONSTACK; +#endif +#ifdef SA_RESTART + if (!(old.sa_flags & SA_RESTART)) +#endif + ovec->sv_flags |= SV_INTERRUPT; + if (old.sa_handler == wrapper_handler) + { + ovec->sv_flags |= SV_RESETHAND; + ovec->sv_handler = wrapped_handlers[sig]; + } + else + ovec->sv_handler = old.sa_handler; + } + + return 0; +} + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c new file mode 100644 index 0000000000..36864cbf6e --- /dev/null +++ b/sysdeps/posix/sleep.c @@ -0,0 +1,106 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> + + +/* SIGALRM signal handler for `sleep'. This does nothing but return, + but SIG_IGN isn't supposed to break `pause'. */ +static void +DEFUN(sleep_handler, (sig), int sig) +{ + return; +} + +/* Make the process sleep for SECONDS seconds, or until a signal arrives + and is not ignored. The function returns the number of seconds less + than SECONDS which it actually slept (zero if it slept the full time). + If a signal handler does a `longjmp' or modifies the handling of the + SIGALRM signal while inside `sleep' call, the handling of the SIGALRM + signal afterwards is undefined. There is no return value to indicate + error, but if `sleep' returns SECONDS, it probably didn't work. */ +unsigned int +DEFUN(sleep, (seconds), unsigned int seconds) +{ + unsigned int remaining, slept; + time_t before, after; + sigset_t set, oset; + struct sigaction act, oact; + int save = errno; + + if (seconds == 0) + return 0; + + /* Block SIGALRM signals while frobbing the handler. */ + if (sigemptyset (&set) < 0 || + sigaddset (&set, SIGALRM) < 0 || + sigprocmask (SIG_BLOCK, &set, &oset)) + return seconds; + + act.sa_handler = sleep_handler; + act.sa_flags = 0; + if (sigemptyset (&act.sa_mask) < 0 || + sigaction (SIGALRM, &act, &oact) < 0) + return seconds; + + before = time ((time_t *) NULL); + remaining = alarm (seconds); + + if (remaining > 0 && remaining < seconds) + { + /* The user's alarm will expire before our own would. + Restore the user's signal action state and let his alarm happen. */ + (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL); + alarm (remaining); /* Restore sooner alarm. */ + sigsuspend (&oset); /* Wait for it to go off. */ + after = time ((time_t *) NULL); + } + else + { + /* Atomically restore the old signal mask + (which had better not block SIGALRM), + and wait for a signal to arrive. */ + sigsuspend (&oset); + + after = time ((time_t *) NULL); + + /* Restore the old signal action state. */ + (void) sigaction (SIGALRM, &oact, (struct sigaction *) NULL); + } + + /* Notice how long we actually slept. */ + slept = after - before; + + /* Restore the user's alarm if we have not already past it. + If we have, be sure to turn off the alarm in case a signal + other than SIGALRM was what woke us up. */ + (void) alarm (remaining > slept ? remaining - slept : 0); + + /* Restore the original signal mask. */ + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + + /* Restore the `errno' value we started with. + Some of the calls we made might have failed, but we didn't care. */ + errno = save; + + return slept > seconds ? 0 : seconds - slept; +} diff --git a/sysdeps/posix/stdio_init.c b/sysdeps/posix/stdio_init.c new file mode 100644 index 0000000000..422d9b69ef --- /dev/null +++ b/sysdeps/posix/stdio_init.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +/* Initialize STREAM as necessary. + This may change I/O functions, give a buffer, etc. + If no buffer is allocated, but the bufsize is set, + the bufsize will be used to allocate the buffer. */ +void +DEFUN(__stdio_init_stream, (stream), FILE *stream) +{ + register CONST int fd = (int) stream->__cookie; + struct stat statb; + + if (stream->__buffer != NULL || stream->__userbuf) + /* If's unbuffered by request, we can't do anything useful. */ + return; + + /* Find out what sort of file this is. */ + if (__fstat (fd, &statb) < 0) + return; + + if (S_ISCHR (statb.st_mode)) + { + /* It's a character device. + Make it line-buffered if it's a terminal. */ + if (__isatty (fd)) + { + stream->__linebuf = 1; + + /* Unix terminal devices have the bad habit of claiming to be + seekable. On systems I have tried, seeking on a terminal + device seems to set its file position as specified, such that + a later tell says the same thing. This is in no way related + to actual seekability--the ability to seek back and read old + data. Unix terminal devices will let you "seek back", and + then read more new data from the terminal. I can think of + nothing to do about this lossage except to preemptively disable + seeking on terminal devices. */ + + stream->__io_funcs.__seek = NULL; /* Seeks get ESPIPE. */ + } + } + +#ifdef _STATBUF_ST_BLKSIZE + /* Use the block-size field to determine + the system's optimal buffering size. */ + stream->__bufsize = statb.st_blksize; +#endif +} diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c new file mode 100644 index 0000000000..7f4fbb7261 --- /dev/null +++ b/sysdeps/posix/sysconf.c @@ -0,0 +1,183 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <unistd.h> +#include <stddef.h> +#include <stdio.h> +#include <time.h> + +extern int EXFUN(__getdtablesize, (NOARGS)); +extern size_t EXFUN(__getpagesize, (NOARGS)); + +/* Get the value of the system variable NAME. */ +long int +DEFUN(__sysconf, (name), int name) +{ + switch (name) + { + default: + errno = EINVAL; + return -1; + + case _SC_ARG_MAX: +#ifdef ARG_MAX + return ARG_MAX; +#else + return -1; +#endif + + case _SC_CHILD_MAX: +#ifdef CHILD_MAX + return CHILD_MAX; +#else + return -1; +#endif + + case _SC_CLK_TCK: + return 60; + + case _SC_NGROUPS_MAX: +#ifdef NGROUPS_MAX + return NGROUPS_MAX; +#else + return -1; +#endif + + case _SC_OPEN_MAX: + return __getdtablesize (); + + case _SC_STREAM_MAX: + return FOPEN_MAX; + + case _SC_TZNAME_MAX: + return __tzname_max (); + + case _SC_JOB_CONTROL: +#ifdef _POSIX_JOB_CONTROL + return 1; +#else + return -1; +#endif + case _SC_SAVED_IDS: +#ifdef _POSIX_SAVED_IDS + return 1; +#else + return -1; +#endif + case _SC_VERSION: + return _POSIX_VERSION; + + case _SC_PAGESIZE: + return __getpagesize (); + + case _SC_BC_BASE_MAX: +#ifdef BC_BASE_MAX + return BC_BASE_MAX; +#else + return -1; +#endif + + case _SC_BC_DIM_MAX: +#ifdef BC_DIM_MAX + return BC_DIM_MAX; +#else + return -1; +#endif + + case _SC_BC_SCALE_MAX: +#ifdef BC_SCALE_MAX + return BC_SCALE_MAX; +#else + return -1; +#endif + + case _SC_BC_STRING_MAX: +#ifdef BC_STRING_MAX + return BC_STRING_MAX; +#else + return -1; +#endif + + case _SC_EQUIV_CLASS_MAX: +#ifdef EQUIV_CLASS_MAX + return EQUIV_CLASS_MAX; +#else + return -1; +#endif + + case _SC_EXPR_NEST_MAX: +#ifdef EXPR_NEST_MAX + return EXPR_NEST_MAX; +#else + return -1; +#endif + + case _SC_LINE_MAX: +#ifdef LINE_MAX + return LINE_MAX; +#else + return -1; +#endif + + case _SC_RE_DUP_MAX: +#ifdef RE_DUP_MAX + return RE_DUP_MAX; +#else + return -1; +#endif + + + case _SC_2_VERSION: + /* This is actually supposed to return the version + of the 1003.2 utilities on the system {POSIX2_VERSION}. */ + return _POSIX2_C_VERSION; + + case _SC_2_C_BIND: +#ifdef _POSIX2_C_BIND + return _POSIX2_C_BIND; +#else + return -1; +#endif + + case _SC_2_C_DEV: +#ifdef _POSIX2_C_DEV + return _POSIX2_C_DEV; +#else + return -1; +#endif + + case _SC_2_FORT_DEV: +#ifdef _POSIX2_FORT_DEV + return _POSIX2_FORT_DEV; +#else + return -1; +#endif + + case _SC_2_SW_DEV: +#ifdef _POSIX2_SW_DEV + return _POSIX2_SW_DEV; +#else + return -1; +#endif + } +} + +weak_alias (__sysconf, sysconf) diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c new file mode 100644 index 0000000000..69b004bb41 --- /dev/null +++ b/sysdeps/posix/system.c @@ -0,0 +1,145 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> +#include <sys/types.h> + + +#ifndef HAVE_GNU_LD +#define __environ environ +#endif + +#define SHELL_PATH "/bin/sh" /* Path of the shell. */ +#define SHELL_NAME "sh" /* Name to give it. */ + +/* Execute LINE as a shell command, returning its status. */ +int +DEFUN(system, (line), register CONST char *line) +{ + int status, save; + pid_t pid; + struct sigaction sa, intr, quit; +#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD + sigset_t block, omask; +#endif + + if (line == NULL) + return 1; + + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + __sigemptyset (&sa.sa_mask); + + if (__sigaction (SIGINT, &sa, &intr) < 0) + return -1; + if (__sigaction (SIGQUIT, &sa, &quit) < 0) + { + save = errno; + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + errno = save; + return -1; + } + +#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD + +/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is + blocked. This makes it impossible for `system' to be implemented in + compliance with POSIX.2-1992. They have acknowledged that this is a bug + but I have not seen nor heard of any forthcoming fix. */ + + __sigemptyset (&block); + __sigaddset (&block, SIGCHLD); + save = errno; + if (__sigprocmask (SIG_BLOCK, &block, &omask) < 0) + { + if (errno == ENOSYS) + errno = save; + else + { + save = errno; + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + errno = save; + return -1; + } + } +#define UNBLOCK __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) +#else +#define UNBLOCK 0 +#endif + + pid = __vfork (); + if (pid == (pid_t) 0) + { + /* Child side. */ + CONST char *new_argv[4]; + new_argv[0] = SHELL_NAME; + new_argv[1] = "-c"; + new_argv[2] = line; + new_argv[3] = NULL; + + /* Restore the signals. */ + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) UNBLOCK; + + /* Exec the shell. */ + (void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ); + _exit (127); + } + else if (pid < (pid_t) 0) + /* The fork failed. */ + status = -1; + else + /* Parent side. */ +#ifdef NO_WAITPID + { + pid_t child; + do + { + child = __wait (&status); + if (child <= -1) + { + status = -1; + break; + } + } while (child != pid); + } +#else + if (__waitpid (pid, &status, 0) != pid) + status = -1; +#endif + + save = errno; + if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) | + __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) | + UNBLOCK) != 0) + { + if (errno == ENOSYS) + errno = save; + else + return -1; + } + + return status; +} diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c new file mode 100644 index 0000000000..f2da66a211 --- /dev/null +++ b/sysdeps/posix/tempname.c @@ -0,0 +1,208 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +/* Return nonzero if DIR is an existent directory. */ +static int +DEFUN(diraccess, (dir), CONST char *dir) +{ + struct stat buf; + return __stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode); +} + +/* Return nonzero if FILE exists. */ +static int +DEFUN(exists, (file), CONST char *file) +{ + /* We can stat the file even if we can't read its data. */ + struct stat st; + int save = errno; + if (__stat (file, &st) == 0) + return 1; + else + { + /* We report that the file exists if stat failed for a reason other + than nonexistence. In this case, it may or may not exist, and we + don't know; but reporting that it does exist will never cause any + trouble, while reporting that it doesn't exist when it does would + violate the interface of __stdio_gen_tempname. */ + int exists = errno != ENOENT; + errno = save; + return exists; + } +} + + +/* These are the characters used in temporary filenames. */ +static CONST char letters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* Generate a temporary filename and return it (in a static buffer). If + STREAMPTR is not NULL, open a stream "w+b" on the file and set + *STREAMPTR to it. If DIR_SEARCH is nonzero, DIR and PFX are used as + described for tempnam. If not, a temporary filename in P_tmpdir with no + special prefix is generated. If LENPTR is not NULL, *LENPTR is set the + to length (including the terminating '\0') of the resultant filename, + which is returned. This goes through a cyclic pattern of all possible + filenames consisting of five decimal digits of the current pid and three + of the characters in `letters'. Data for tempnam and tmpnam is kept + separate, but when tempnam is using P_tmpdir and no prefix (i.e, it is + identical to tmpnam), the same data is used. Each potential filename is + tested for an already-existing file of the same name, and no name of an + existing file will be returned. When the cycle reaches its end + (12345ZZZ), NULL is returned. */ +char * +DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr, streamptr), + CONST char *dir AND CONST char *pfx AND + int dir_search AND size_t *lenptr AND + FILE **streamptr) +{ + int saverrno = errno; + static CONST char tmpdir[] = P_tmpdir; + static size_t indices[2]; + size_t *idx; + static char buf[FILENAME_MAX]; + static pid_t oldpid = (pid_t) 0; + pid_t pid = __getpid(); + register size_t len, plen, dlen; + + if (dir_search) + { + register CONST char *d = getenv ("TMPDIR"); + if (d != NULL && !diraccess (d)) + d = NULL; + if (d == NULL && dir != NULL && diraccess (dir)) + d = dir; + if (d == NULL && diraccess (tmpdir)) + d = tmpdir; + if (d == NULL && diraccess ("/tmp")) + d = "/tmp"; + if (d == NULL) + { + errno = ENOENT; + return NULL; + } + dir = d; + } + else + dir = tmpdir; + + dlen = strlen (dir); + + /* Remove trailing slashes from the directory name. */ + while (dlen > 1 && dir[dlen - 1] == '/') + --dlen; + + if (pfx != NULL && *pfx != '\0') + { + plen = strlen (pfx); + if (plen > 5) + plen = 5; + } + else + plen = 0; + + if (dir != tmpdir && !strcmp (dir, tmpdir)) + dir = tmpdir; + idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0]; + + if (pid != oldpid) + { + oldpid = pid; + indices[0] = indices[1] = 0; + } + + len = dlen + 1 + plen + 5 + 3; + while (*idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) * + (sizeof (letters) - 1))) + { + const size_t i = (*idx)++; + + /* Construct a file name and see if it already exists. + + We use a single counter in *IDX to cycle each of three + character positions through each of 62 possible letters. */ + + if (sizeof (buf) < len || + sprintf (buf, "%.*s/%.*s%.5d%c%c%c", + (int) dlen, dir, (int) plen, + pfx, pid % 100000, + letters[i % (sizeof (letters) - 1)], + letters[(i / (sizeof (letters) - 1)) + % (sizeof (letters) - 1)], + letters[(i / ((sizeof (letters) - 1) * + (sizeof (letters) - 1))) + % (sizeof (letters) - 1)] + ) != (int) len) + return NULL; + + if (streamptr != NULL) + { + /* Try to create the file atomically. */ + int fd = __open (buf, O_RDWR|O_CREAT|O_EXCL, 0666); + if (fd >= 0) + { + /* We got a new file that did not previously exist. + Create a stream for it. */ + *streamptr = __newstream (); + if (*streamptr == NULL) + { + /* We lost trying to create a stream (out of memory?). + Nothing to do but remove the file, close the descriptor, + and return failure. */ + const int save = errno; + (void) remove (buf); + (void) __close (fd); + errno = save; + return NULL; + } + (*streamptr)->__cookie = (PTR) (long int) fd; + (*streamptr)->__mode.__write = 1; + (*streamptr)->__mode.__read = 1; + (*streamptr)->__mode.__binary = 1; + } + else + continue; + } + else if (exists (buf)) + continue; + + /* If the file already existed we have continued the loop above, + so we only get here when we have a winning name to return. */ + + errno = saverrno; + + if (lenptr != NULL) + *lenptr = len + 1; + return buf; + } + + /* We got out of the loop because we ran out of combinations to try. */ + errno = EEXIST; /* ? */ + return NULL; +} diff --git a/sysdeps/posix/truncate.c b/sysdeps/posix/truncate.c new file mode 100644 index 0000000000..9fe0d86a0a --- /dev/null +++ b/sysdeps/posix/truncate.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> +#include <unistd.h> + +/* Truncate PATH to LENGTH bytes. */ +int +DEFUN(truncate, (path, length), + CONST char *path AND off_t length) +{ + int fd, ret, save; + + fd = open (path, O_WRONLY); + if (fd < 0) + return -1; + + ret = ftruncate (fd, length); + save = errno; + (void) close (fd); + if (ret < 0) + errno = save; + return ret; +} diff --git a/sysdeps/posix/ttyname.c b/sysdeps/posix/ttyname.c new file mode 100644 index 0000000000..50e3c79341 --- /dev/null +++ b/sysdeps/posix/ttyname.c @@ -0,0 +1,82 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> + +char *__ttyname = NULL; + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +char * +DEFUN(ttyname, (fd), int fd) +{ + static CONST char dev[] = "/dev"; + static char *name; + static size_t namelen = 0; + struct stat st; + dev_t mydev; + ino_t myino; + DIR *dirstream; + struct dirent *d; + int save = errno; + + if (fstat (fd, &st) < 0) + return NULL; + mydev = st.st_dev; + myino = st.st_ino; + + dirstream = opendir (dev); + if (dirstream == NULL) + return NULL; + + while ((d = readdir (dirstream)) != NULL) + if (d->d_fileno == myino) + { + if (sizeof (dev) + d->d_namlen + 1 > namelen) + { + free (name); + namelen = 2 * (sizeof (dev) + d->d_namlen + 1); /* Big enough. */ + name = malloc (namelen); + if (! name) + return NULL; + (void) memcpy (name, dev, sizeof (dev) - 1); + name[sizeof (dev) - 1] = '/'; + } + (void) memcpy (&name[sizeof (dev)], d->d_name, d->d_namlen + 1); + if (stat (name, &st) == 0 && st.st_dev == mydev) + { + (void) closedir (dirstream); + __ttyname = name; + errno = save; + return name; + } + } + + (void) closedir (dirstream); + errno = save; + return NULL; +} diff --git a/sysdeps/posix/wait.c b/sysdeps/posix/wait.c new file mode 100644 index 0000000000..38891c7e01 --- /dev/null +++ b/sysdeps/posix/wait.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/wait.h> + + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +__pid_t +DEFUN(__wait, (stat_loc), __WAIT_STATUS_DEFN stat_loc) +{ + return __waitpid(WAIT_ANY, (int *) stat_loc, 0); +} + +weak_alias (__wait, wait) diff --git a/sysdeps/posix/wait3.c b/sysdeps/posix/wait3.c new file mode 100644 index 0000000000..5eb084a7c9 --- /dev/null +++ b/sysdeps/posix/wait3.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <stddef.h> + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not nil, + store information about the child's resource usage (as a `struct rusage') + there. If the WUNTRACED bit is set in OPTIONS, return status for stopped + children; otherwise don't. */ +pid_t +DEFUN(__wait3, (stat_loc, options, usage), + __WAIT_STATUS_DEFN stat_loc AND int options AND struct rusage *usage) +{ + if (usage != NULL) + { + errno = ENOSYS; + return (pid_t) -1; + } + return __waitpid (WAIT_ANY, stat_loc, options); +} + +weak_alias (__wait3, wait3) diff --git a/sysdeps/posix/writev.c b/sysdeps/posix/writev.c new file mode 100644 index 0000000000..56e29a64b9 --- /dev/null +++ b/sysdeps/posix/writev.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/uio.h> + +/* Write data pointed by the buffers described by VECTOR, which + is a vector of COUNT `struct iovec's, to file descriptor FD. + The data is written in the order specified. + Operates just like `write' (see <unistd.h>) except that the data + are taken from VECTOR instead of a contiguous buffer. */ +int +DEFUN(writev, (fd, vector, count), + int fd AND CONST struct iovec *vector AND size_t count) +{ + char *buffer; + register char *bp; + size_t bytes, to_copy; + register size_t i; + + /* Find the total number of bytes to be written. */ + bytes = 0; + for (i = 0; i < count; ++i) + bytes += vector[i].iov_len; + + /* Allocate a temporary buffer to hold the data. */ + buffer = (char *) __alloca(bytes); + + /* Copy the data into BUFFER. */ + to_copy = bytes; + bp = buffer; + for (i = 0; i < count; ++i) + { +#define min(a, b) ((a) > (b) ? (b) : (a)) + size_t copy = min(vector[i].iov_len, to_copy); + + (void) memcpy((PTR) bp, (PTR) vector[i].iov_base, copy); + + bp += copy; + to_copy -= copy; + if (bytes == 0) + break; + } + + return write(fd, buffer, bytes); +} diff --git a/sysdeps/rs6000/ffs.c b/sysdeps/rs6000/ffs.c new file mode 100644 index 0000000000..44e7a434d2 --- /dev/null +++ b/sysdeps/rs6000/ffs.c @@ -0,0 +1,39 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For IBM rs6000. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <bstring.h> + +#undef ffs + +#ifdef __GNUC__ + +int +DEFUN(ffs, (x), int x) +{ + int cnt; + + asm ("cntlz %0,%1" : "=r" (cnt) : "r" (x & -x)); + return 32 - cnt; +} + +#else +#include <sysdeps/generic/ffs.c> +#endif diff --git a/sysdeps/rs6000/memcopy.h b/sysdeps/rs6000/memcopy.h new file mode 100644 index 0000000000..873b31200b --- /dev/null +++ b/sysdeps/rs6000/memcopy.h @@ -0,0 +1,86 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/generic/memcopy.h> + +#undef OP_T_THRES +#define OP_T_THRES 32 + +#undef BYTE_COPY_FWD +#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \ + do \ + { \ + size_t __nbytes = nbytes; \ + asm volatile("mtspr 1,%2\n" \ + "lsx 6,0,%1\n" \ + "stsx 6,0,%0" : /* No outputs. */ : \ + "b" (dst_bp), "b" (src_bp), "r" (__nbytes) : \ + "6", "7", "8", "9", "10", "11", "12", "13"); \ + dst_bp += __nbytes; \ + src_bp += __nbytes; \ + } while (0) + +#undef BYTE_COPY_BWD +#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \ + do \ + { \ + size_t __nbytes = (nbytes); \ + dst_ep -= __nbytes; \ + src_ep -= __nbytes; \ + asm volatile("mtspr 1,%2\n" \ + "lsx 6,0,%1\n" \ + "stsx 6,0,%0" : /* No outputs. */ : \ + "b" (dst_ep), "b" (src_ep), "r" (__nbytes) : \ + "6", "7", "8", "9", "10", "11", "12", "13"); \ + } while (0) + +#undef WORD_COPY_FWD +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + size_t __nblocks = (nbytes) / 32; \ + if (__nblocks != 0) \ + asm volatile("mtctr %4\n" \ + "lsi 6,%1,32\n" \ + "ai %1,%1,32\n" \ + "stsi 6,%0,32\n" \ + "ai %0,%0,32\n" \ + "bdn $-16" : \ + "=b" (dst_bp), "=b" (src_bp) : \ + "0" (dst_bp), "1" (src_bp), "r" (__nblocks) : \ + "6", "7", "8", "9", "10", "11", "12", "13"); \ + (nbytes_left) = (nbytes) % 32; \ + } while (0) + +#undef WORD_COPY_BWD +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + size_t __nblocks = (nbytes) / 32; \ + if (__nblocks != 0) \ + asm volatile("mtctr %4\n" \ + "ai %1,%1,-32\n" \ + "lsi 6,%1,32\n" \ + "ai %0,%0,-32\n" \ + "stsi 6,%0,32\n" \ + "bdn $-16" : \ + "=b" (dst_ep), "=b" (src_ep) : \ + "0" (dst_ep), "1" (src_ep), "r" (__nblocks) : \ + "6", "7", "8", "9", "10", "11", "12", "13"); \ + (nbytes_left) = (nbytes) % 32; \ + } while (0) diff --git a/sysdeps/sparc/DEFS.h b/sysdeps/sparc/DEFS.h new file mode 100644 index 0000000000..ef6966319f --- /dev/null +++ b/sysdeps/sparc/DEFS.h @@ -0,0 +1,4 @@ +#define FUNC(name) \ + .global name; \ + .align 4; \ + name: diff --git a/sysdeps/sparc/Dist b/sysdeps/sparc/Dist new file mode 100644 index 0000000000..49cd4dc7e0 --- /dev/null +++ b/sysdeps/sparc/Dist @@ -0,0 +1,4 @@ +DEFS.h +mul.S umul.S +divrem.m4 sdiv.S udiv.S rem.S urem.S +alloca.S diff --git a/sysdeps/sparc/Implies b/sysdeps/sparc/Implies new file mode 100644 index 0000000000..da719e1707 --- /dev/null +++ b/sysdeps/sparc/Implies @@ -0,0 +1,2 @@ +# SPARC uses IEEE 754 floating point. +ieee754 diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile new file mode 100644 index 0000000000..1154d05480 --- /dev/null +++ b/sysdeps/sparc/Makefile @@ -0,0 +1,57 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),gnulib) +routines = mul umul $(divrem) alloca +endif # gnulib + +# We distribute these files, even though they are generated, +# so as to avoid the need for a functioning m4 to build the library. +divrem := sdiv udiv rem urem + ++divrem-NAME-sdiv := div ++divrem-NAME-udiv := udiv ++divrem-NAME-rem := rem ++divrem-NAME-urem := urem ++divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@))) ++divrem-OP-div := div ++divrem-OP-udiv := div ++divrem-OP-rem := rem ++divrem-OP-urem := rem ++divrem-S-div := true ++divrem-S-rem := true ++divrem-S-udiv := false ++divrem-S-urem := false +$(divrem:%=$(sysdep_dir)/sparc/%.S): $(sysdep_dir)/sparc/divrem.m4 + (echo "define(NAME,\`.$(+divrem-NAME)')\ + define(OP,\`$(+divrem-OP-$(+divrem-NAME))')\ + define(S,\`$(+divrem-S-$(+divrem-NAME))')\ + /* This file is generated from divrem.m4; DO NOT EDIT! */"; \ + cat $<) | $(M4) > $@-tmp +# Make it unwritable so noone will edit it by mistake. + -chmod a-w $@-tmp + mv -f $@-tmp $@ + test -d CVS && cvs commit -m'Regenerated from $<' $@ + +sysdep-realclean := $(sysdep-realclean) $(divrem:%=sysdeps/sparc/%.S) + +ifeq ($(subdir),crypt) + +crypt := crypt.sparc # Use crypt/crypt.sparc.S. + +endif # crypt diff --git a/sysdeps/sparc/__longjmp.S b/sysdeps/sparc/__longjmp.S new file mode 100644 index 0000000000..adff06e349 --- /dev/null +++ b/sysdeps/sparc/__longjmp.S @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +/* NOTE: This code depends on the definition of `__jmp_buf' in <jmp_buf.h>. */ + +ENTRY (__longjmp) + /* Do a "flush register windows trap". The trap handler in the + kernel writes all the register windows to their stack slots, and + marks them all as invalid (needing to be sucked up from the + stack when used). This ensures that all information needed to + unwind to these callers is in memory, not in the register + windows. */ + ta ST_FLUSH_WINDOWS + ld [%o0], %o7 /* Return PC. */ + ld [%o0 + 4], %fp /* Saved SP. */ + sub %fp, 64, %sp /* Allocate a register save area. */ + + /* if (%o1 == 0) %o1 = 1; */ + tst %o1 + be,a Ldone + mov 1, %o1 + +Ldone: retl + /* On the way out, put the return value in %o0. */ + restore %o1, 0, %o0 diff --git a/sysdeps/sparc/add_n.S b/sysdeps/sparc/add_n.S new file mode 100644 index 0000000000..3be3e39b86 --- /dev/null +++ b/sysdeps/sparc/add_n.S @@ -0,0 +1,134 @@ +! sparc __mpn_add_n -- Add two limb vectors of the same length > 0 and store +! sum in a third limb vector. + +! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr %o0 +! s1_ptr %o1 +! s2_ptr %o2 +! size %o3 + +#include "sysdep.h" + + .text + .align 4 + .global C_SYMBOL_NAME(__mpn_add_n) +C_SYMBOL_NAME(__mpn_add_n): + ld [%o1+0],%o4 ! read first limb from s1_ptr + srl %o3,4,%g1 + ld [%o2+0],%o5 ! read first limb from s2_ptr + + sub %g0,%o3,%o3 + andcc %o3,(16-1),%o3 + be Lzero + nop + + sll %o3,2,%o3 ! multiply by 4 + sub %o0,%o3,%o0 ! adjust res_ptr + sub %o1,%o3,%o1 ! adjust s1_ptr + sub %o2,%o3,%o2 ! adjust s2_ptr + + mov %o4,%g2 + + sethi %hi(Lbase),%g3 + or %g3,%lo(Lbase),%g3 + sll %o3,2,%o3 ! multiply by 4 + jmp %g3+%o3 + mov %o5,%g3 + +Loop: addxcc %g2,%g3,%o3 + add %o1,64,%o1 + st %o3,[%o0+60] + add %o2,64,%o2 + ld [%o1+0],%o4 + add %o0,64,%o0 + ld [%o2+0],%o5 +Lzero: sub %g1,1,%g1 ! add 0 + 16r limbs (adjust loop counter) +Lbase: ld [%o1+4],%g2 + addxcc %o4,%o5,%o3 + ld [%o2+4],%g3 + st %o3,[%o0+0] + ld [%o1+8],%o4 ! add 15 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+8],%o5 + st %o3,[%o0+4] + ld [%o1+12],%g2 ! add 14 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+12],%g3 + st %o3,[%o0+8] + ld [%o1+16],%o4 ! add 13 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+16],%o5 + st %o3,[%o0+12] + ld [%o1+20],%g2 ! add 12 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+20],%g3 + st %o3,[%o0+16] + ld [%o1+24],%o4 ! add 11 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+24],%o5 + st %o3,[%o0+20] + ld [%o1+28],%g2 ! add 10 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+28],%g3 + st %o3,[%o0+24] + ld [%o1+32],%o4 ! add 9 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+32],%o5 + st %o3,[%o0+28] + ld [%o1+36],%g2 ! add 8 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+36],%g3 + st %o3,[%o0+32] + ld [%o1+40],%o4 ! add 7 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+40],%o5 + st %o3,[%o0+36] + ld [%o1+44],%g2 ! add 6 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+44],%g3 + st %o3,[%o0+40] + ld [%o1+48],%o4 ! add 5 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+48],%o5 + st %o3,[%o0+44] + ld [%o1+52],%g2 ! add 4 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+52],%g3 + st %o3,[%o0+48] + ld [%o1+56],%o4 ! add 3 + 16r limbs + addxcc %g2,%g3,%o3 + ld [%o2+56],%o5 + st %o3,[%o0+52] + ld [%o1+60],%g2 ! add 2 + 16r limbs + addxcc %o4,%o5,%o3 + ld [%o2+60],%g3 + st %o3,[%o0+56] + addx %g0,%g0,%o4 + tst %g1 + bne Loop + subcc %g0,%o4,%g0 ! restore cy (delay slot) + + addxcc %g2,%g3,%o3 + st %o3,[%o0+60] ! store most significant limb + + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb diff --git a/sysdeps/sparc/addmul_1.S b/sysdeps/sparc/addmul_1.S new file mode 100644 index 0000000000..63e7db0ce2 --- /dev/null +++ b/sysdeps/sparc/addmul_1.S @@ -0,0 +1,146 @@ +! SPARC __mpn_addmul_1 -- Multiply a limb vector with a limb and add +! the result to a second limb vector. + +! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include "sysdep.h" + +.text + .align 4 + .global C_SYMBOL_NAME(__mpn_addmul_1) +C_SYMBOL_NAME(__mpn_addmul_1): + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu Large + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b L0 + add %o4,-4,%o4 +Loop0: + addcc %o5,%g1,%g1 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g1,[%o4+%o2] +L0: wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne Loop0 + ld [%o4+%o2],%o5 + + addcc %o5,%g1,%g1 + addx %o0,%g0,%o0 + retl + st %g1,[%o4+%o2] + + +Large: ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b L1 + add %o4,-4,%o4 +Loop: + addcc %o5,%g3,%g3 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g3,[%o4+%o2] +L1: wr %g0,%o5,%y + and %o5,%g4,%g2 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 + addcc %o2,4,%o2 + bne Loop + ld [%o4+%o2],%o5 + + addcc %o5,%g3,%g3 + addx %o0,%g0,%o0 + retl + st %g3,[%o4+%o2] diff --git a/sysdeps/sparc/alloca.S b/sysdeps/sparc/alloca.S new file mode 100644 index 0000000000..0a8718de31 --- /dev/null +++ b/sysdeps/sparc/alloca.S @@ -0,0 +1,32 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "DEFS.h" + +/* Code produced by Sun's C compiler calls this function with two extra + arguments which it makes relocatable symbols but seem always to be + the constant 96; I have no idea what they are for. */ + +#ifndef NO_UNDERSCORES +#define __builtin_alloca ___builtin_alloca +#endif + +FUNC (__builtin_alloca) + sub %sp, %o0, %sp /* Push some stack space. */ + retl /* Return; the returned buffer leaves 96 */ + add %sp, 96, %o0 /* bytes of register save area at the top. */ diff --git a/sysdeps/sparc/bsd-_setjmp.S b/sysdeps/sparc/bsd-_setjmp.S new file mode 100644 index 0000000000..5b685d5496 --- /dev/null +++ b/sysdeps/sparc/bsd-_setjmp.S @@ -0,0 +1,26 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Sparc version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (setjmp) + sethi %hi(C_SYMBOL_NAME (__sigsetjmp)), %g1 + or %lo(C_SYMBOL_NAME (__sigsetjmp)), %g1, %g1 + jmp %g1 + mov %g0, %o1 /* Pass second argument of zero. */ diff --git a/sysdeps/sparc/bsd-setjmp.S b/sysdeps/sparc/bsd-setjmp.S new file mode 100644 index 0000000000..b0a6326a2c --- /dev/null +++ b/sysdeps/sparc/bsd-setjmp.S @@ -0,0 +1,26 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Sparc version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (setjmp) + sethi %hi(C_SYMBOL_NAME (__sigsetjmp)), %g1 + or %lo(C_SYMBOL_NAME (__sigsetjmp)), %g1, %g1 + jmp %g1 + mov 1, %o1 /* Pass second argument of one. */ diff --git a/sysdeps/sparc/bytesex.h b/sysdeps/sparc/bytesex.h new file mode 100644 index 0000000000..f1a75c0652 --- /dev/null +++ b/sysdeps/sparc/bytesex.h @@ -0,0 +1,3 @@ +/* SPARC is big-endian. */ + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/sparc/divrem.m4 b/sysdeps/sparc/divrem.m4 new file mode 100644 index 0000000000..bde8a21e29 --- /dev/null +++ b/sysdeps/sparc/divrem.m4 @@ -0,0 +1,234 @@ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * NAME name of function to generate + * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1 + * S S=true => signed; S=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top `decade' of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + +define(N, `4')dnl +define(WORDSIZE, `32')dnl +define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N)))dnl +dnl +define(dividend, `%o0')dnl +define(divisor, `%o1')dnl +define(Q, `%o2')dnl +define(R, `%o3')dnl +define(ITER, `%o4')dnl +define(V, `%o5')dnl +dnl +dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d +define(T, `%g1')dnl +define(SC, `%g7')dnl +ifelse(S, `true', `define(SIGN, `%g6')')dnl + +dnl +dnl This is the recursive definition for developing quotient digits. +dnl +dnl Parameters: +dnl $1 the current depth, 1 <= $1 <= N +dnl $2 the current accumulation of quotient bits +dnl N max depth +dnl +dnl We add a new bit to $2 and either recurse or insert the bits in +dnl the quotient. R, Q, and V are inputs and outputs as defined above; +dnl the condition codes are expected to reflect the input R, and are +dnl modified to reflect the output R. +dnl +define(DEVELOP_QUOTIENT_BITS, +` ! depth $1, accumulated bits $2 + bl L.$1.eval(2**N+$2) + srl V,1,V + ! remainder is positive + subcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2+1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') +L.$1.eval(2**N+$2): + ! remainder is negative + addcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2-1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') + ifelse($1, 1, `9:')')dnl + +#include "DEFS.h" +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +FUNC(NAME) +ifelse(S, `true', +` ! compute sign of result; if neither is negative, no problem + orcc divisor, dividend, %g0 ! either negative? + bge 2f ! no, go do the divide +ifelse(OP, `div', +` xor divisor, dividend, SIGN ! compute sign in any case', +` mov dividend, SIGN ! sign of remainder matches dividend') + tst divisor + bge 1f + tst dividend + ! divisor is definitely negative; dividend might also be negative + bge 2f ! if dividend not negative... + sub %g0, divisor, divisor ! in any case, make divisor nonneg +1: ! dividend is negative, divisor is nonnegative + sub %g0, dividend, dividend ! make dividend nonnegative +2: +') + ! Ready to divide. Compute size of quotient; scale comparand. + orcc divisor, %g0, V + bne 1f + mov dividend, R + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp R, V ! if divisor exceeds dividend, done + blu Lgot_result ! (and algorithm fails otherwise) + clr Q + sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T + cmp R, T + blu Lnot_really_big + clr ITER + + ! `Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R.' + 1: + cmp V, T + bgeu 3f + mov 1, SC + sll V, N, V + b 1b + add ITER, 1, ITER + + ! Now compute SC. + 2: addcc V, V, V + bcc Lnot_too_big + add SC, 1, SC + + ! We get here if the divisor overflowed while shifting. + ! This means that R has the high-order bit set. + ! Restore V and subtract from R. + sll T, TOPBITS, T ! high order bit + srl V, 1, V ! rest of V + add V, T, V + b Ldo_single_div + sub SC, 1, SC + + Lnot_too_big: + 3: cmp V, R + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! V > R: went too far: back up 1 step + ! srl V, 1, V + ! dec SC + ! do single-bit divide steps + ! + ! We have to be careful here. We know that R >= V, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if R >= 0. Because both R and V may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc SC, 1, SC + bl Lend_regular_divide + nop + sub R, V, R + mov 1, Q + b Lend_single_divloop + nop + Lsingle_divloop: + sll Q, 1, Q + bl 1f + srl V, 1, V + ! R >= 0 + sub R, V, R + b 2f + add Q, 1, Q + 1: ! R < 0 + add R, V, R + sub Q, 1, Q + 2: + Lend_single_divloop: + subcc SC, 1, SC + bge Lsingle_divloop + tst R + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll V, N, V + cmp V, R + bleu 1b + addcc ITER, 1, ITER + be Lgot_result + sub ITER, 1, ITER + + tst R ! set up for initial iteration +Ldivloop: + sll Q, N, Q + DEVELOP_QUOTIENT_BITS(1, 0) +Lend_regular_divide: + subcc ITER, 1, ITER + bge Ldivloop + tst R + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) +ifelse(OP, `div', +` sub Q, 1, Q +', ` add R, divisor, R +') + +Lgot_result: +ifelse(S, `true', +` ! check to see if answer should be < 0 + tst SIGN + bl,a 1f + ifelse(OP, `div', `sub %g0, Q, Q', `sub %g0, R, R') +1:') + retl + ifelse(OP, `div', `mov Q, %o0', `mov R, %o0') diff --git a/sysdeps/sparc/jmp_buf.h b/sysdeps/sparc/jmp_buf.h new file mode 100644 index 0000000000..a5a592fd47 --- /dev/null +++ b/sysdeps/sparc/jmp_buf.h @@ -0,0 +1,14 @@ +/* Define the machine-dependent type `jmp_buf'. SPARC version. */ + +/* NOTE: The assembly code in __longjmp.S and setjmp.S knows the layout + of this structure. You must hack the assembly code if you want to change + the order of the members. */ + +typedef struct + { + /* Return PC (register o7). */ + __ptr_t __pc; + + /* Saved FP. */ + __ptr_t __fp; + } __jmp_buf[1]; diff --git a/sysdeps/sparc/memcopy.h b/sysdeps/sparc/memcopy.h new file mode 100644 index 0000000000..3fd4f3dfbc --- /dev/null +++ b/sysdeps/sparc/memcopy.h @@ -0,0 +1,21 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/generic/memcopy.h> +#undef reg_char +#define reg_char int diff --git a/sysdeps/sparc/mul_1.S b/sysdeps/sparc/mul_1.S new file mode 100644 index 0000000000..84aa12bb41 --- /dev/null +++ b/sysdeps/sparc/mul_1.S @@ -0,0 +1,198 @@ +! SPARC __mpn_mul_1 -- Multiply a limb vector with a limb and store +! the result in a second limb vector. + +! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +! ADD CODE FOR SMALL MULTIPLIERS! +!1: ld +! st +! +!2: ld ,a +! addxcc a,a,x +! st x, +! +!3_unrolled: +! ld ,a +! addxcc a,a,x1 ! 2a + cy +! addx %g0,%g0,x2 +! addcc a,x1,x ! 3a + c +! st x, +! +! ld ,a +! addxcc a,a,y1 +! addx %g0,%g0,y2 +! addcc a,y1,x +! st x, +! +!4_unrolled: +! ld ,a +! srl a,2,x1 ! 4a +! addxcc y2,x1,x +! sll a,30,x2 +! st x, +! +! ld ,a +! srl a,2,y1 +! addxcc x2,y1,y +! sll a,30,y2 +! st x, +! +!5_unrolled: +! ld ,a +! srl a,2,x1 ! 4a +! addxcc a,x1,x ! 5a + c +! sll a,30,x2 +! addx %g0,x2,x2 +! st x, +! +! ld ,a +! srl a,2,y1 +! addxcc a,y1,x +! sll a,30,y2 +! addx %g0,y2,y2 +! st x, +! +!8_unrolled: +! ld ,a +! srl a,3,x1 ! 8a +! addxcc y2,x1,x +! sll a,29,x2 +! st x, +! +! ld ,a +! srl a,3,y1 +! addxcc x2,y1,y +! sll a,29,y2 +! st x, + +#include "sysdep.h" + +.text + .align 4 + .global C_SYMBOL_NAME(__mpn_mul_1) +C_SYMBOL_NAME(__mpn_mul_1): + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu Large + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b L0 + add %o4,-4,%o4 +Loop0: + st %g1,[%o4+%o2] +L0: wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne,a Loop0 + ld [%o1+%o2],%o5 + + retl + st %g1,[%o4+%o2] + + +Large: ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b L1 + add %o4,-4,%o4 +Loop: + st %g3,[%o4+%o2] +L1: wr %g0,%o5,%y + and %o5,%g4,%g2 ! g2 = S1_LIMB iff S2_LIMB < 0, else 0 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne,a Loop + ld [%o1+%o2],%o5 + + retl + st %g3,[%o4+%o2] diff --git a/sysdeps/sparc/rem.S b/sysdeps/sparc/rem.S new file mode 100644 index 0000000000..17662f7fd4 --- /dev/null +++ b/sysdeps/sparc/rem.S @@ -0,0 +1,365 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .rem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include "DEFS.h" +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +FUNC(.rem) + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + mov %o0, %g6 ! sign of remainder matches %o0 + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: cmp %o5, %o3 + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + + +Lgot_result: + ! check to see if answer should be < 0 + tst %g6 + bl,a 1f + sub %g0, %o3, %o3 +1: + retl + mov %o3, %o0 diff --git a/sysdeps/sparc/sdiv.S b/sysdeps/sparc/sdiv.S new file mode 100644 index 0000000000..dadbb36b0a --- /dev/null +++ b/sysdeps/sparc/sdiv.S @@ -0,0 +1,365 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .div name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * true true=true => signed; true=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include "DEFS.h" +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +FUNC(.div) + ! compute sign of result; if neither is negative, no problem + orcc %o1, %o0, %g0 ! either negative? + bge 2f ! no, go do the divide + xor %o1, %o0, %g6 ! compute sign in any case + tst %o1 + bge 1f + tst %o0 + ! %o1 is definitely negative; %o0 might also be negative + bge 2f ! if %o0 not negative... + sub %g0, %o1, %o1 ! in any case, make %o1 nonneg +1: ! %o0 is negative, %o1 is nonnegative + sub %g0, %o0, %o0 ! make %o0 nonnegative +2: + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: cmp %o5, %o3 + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + + +Lgot_result: + ! check to see if answer should be < 0 + tst %g6 + bl,a 1f + sub %g0, %o2, %o2 +1: + retl + mov %o2, %o0 diff --git a/sysdeps/sparc/setjmp.S b/sysdeps/sparc/setjmp.S new file mode 100644 index 0000000000..3c9c18d00d --- /dev/null +++ b/sysdeps/sparc/setjmp.S @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* NOTE: This code depends on the definition of `__jmp_buf' in <jmp_buf.h>. */ + +ENTRY (__sigsetjmp) + /* Save our return PC and SP (second store in the jmp delay slot). */ + st %o7, [%o0] + /* Save the signal mask if requested. We do this as a tail-call + for simplicity; it always returns zero. */ + sethi %hi(C_SYMBOL_NAME (__sigjmp_save)), %g1 + or %lo(C_SYMBOL_NAME (__sigjmp_save)), %g1, %g1 + jmp %g1 + st %sp, [%o0 + 4] diff --git a/sysdeps/sparc/sparc8/addmul_1.S b/sysdeps/sparc/sparc8/addmul_1.S new file mode 100644 index 0000000000..fbaacfda4f --- /dev/null +++ b/sysdeps/sparc/sparc8/addmul_1.S @@ -0,0 +1,116 @@ +! SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and +! add the result to a second limb vector. + +! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include "sysdep.h" + +.text + .align 4 + .global C_SYMBOL_NAME(__mpn_addmul_1) +C_SYMBOL_NAME(__mpn_addmul_1): + orcc %g0,%g0,%g2 + ld [%o1+0],%o4 ! 1 + + sll %o2,4,%g1 + and %g1,(4-1)<<4,%g1 + sethi %hi(LL),%g3 + or %g3,%lo(LL),%g3 + jmp %g3+%g1 + nop +LL: +LL00: add %o0,-4,%o0 + b Loop00 /* 4, 8, 12, ... */ + add %o1,-4,%o1 + nop +LL01: b Loop01 /* 1, 5, 9, ... */ + nop + nop + nop +LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ + b Loop10 + add %o1,4,%o1 + nop +LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ + b Loop11 + add %o1,-8,%o1 + nop + +1: addcc %g3,%g2,%g3 ! 1 + ld [%o1+4],%o4 ! 2 + rd %y,%g2 ! 1 + addx %g0,%g2,%g2 + ld [%o0+0],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+0] ! 1 +Loop00: umul %o4,%o3,%g3 ! 2 + ld [%o0+4],%g1 ! 2 + addxcc %g3,%g2,%g3 ! 2 + ld [%o1+8],%o4 ! 3 + rd %y,%g2 ! 2 + addx %g0,%g2,%g2 + nop + addcc %g1,%g3,%g3 + st %g3,[%o0+4] ! 2 +Loop11: umul %o4,%o3,%g3 ! 3 + addxcc %g3,%g2,%g3 ! 3 + ld [%o1+12],%o4 ! 4 + rd %y,%g2 ! 3 + add %o1,16,%o1 + addx %g0,%g2,%g2 + ld [%o0+8],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+8] ! 3 +Loop10: umul %o4,%o3,%g3 ! 4 + addxcc %g3,%g2,%g3 ! 4 + ld [%o1+0],%o4 ! 1 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 + ld [%o0+12],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+12] ! 4 + add %o0,16,%o0 + addx %g0,%g2,%g2 +Loop01: addcc %o2,-4,%o2 + bg 1b + umul %o4,%o3,%g3 ! 1 + + addcc %g3,%g2,%g3 ! 4 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 + ld [%o0+0],%g1 ! 2 + addcc %g1,%g3,%g3 + st %g3,[%o0+0] ! 4 + addx %g0,%g2,%o0 + + retl + nop + + +! umul, ld, addxcc, rd, st + +! umul, ld, addxcc, rd, ld, addcc, st, addx + diff --git a/sysdeps/sparc/sparc8/mul_1.S b/sysdeps/sparc/sparc8/mul_1.S new file mode 100644 index 0000000000..9c21768eb1 --- /dev/null +++ b/sysdeps/sparc/sparc8/mul_1.S @@ -0,0 +1,91 @@ +! SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and +! store the product in a second limb vector. + +! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include "sysdep.h" + +.text + .align 8 + .global C_SYMBOL_NAME(__mpn_mul_1) +C_SYMBOL_NAME(__mpn_mul_1): + sll %o2,4,%g1 + and %g1,(4-1)<<4,%g1 + sethi %hi(LL),%g3 + or %g3,%lo(LL),%g3 + jmp %g3+%g1 + ld [%o1+0],%o4 ! 1 +LL: +LL00: add %o0,-4,%o0 + add %o1,-4,%o1 + b Loop00 /* 4, 8, 12, ... */ + orcc %g0,%g0,%g2 +LL01: b Loop01 /* 1, 5, 9, ... */ + orcc %g0,%g0,%g2 + nop + nop +LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ + add %o1,4,%o1 + b Loop10 + orcc %g0,%g0,%g2 + nop +LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ + add %o1,-8,%o1 + b Loop11 + orcc %g0,%g0,%g2 + +Loop: addcc %g3,%g2,%g3 ! 1 + ld [%o1+4],%o4 ! 2 + st %g3,[%o0+0] ! 1 + rd %y,%g2 ! 1 +Loop00: umul %o4,%o3,%g3 ! 2 + addxcc %g3,%g2,%g3 ! 2 + ld [%o1+8],%o4 ! 3 + st %g3,[%o0+4] ! 2 + rd %y,%g2 ! 2 +Loop11: umul %o4,%o3,%g3 ! 3 + addxcc %g3,%g2,%g3 ! 3 + ld [%o1+12],%o4 ! 4 + add %o1,16,%o1 + st %g3,[%o0+8] ! 3 + rd %y,%g2 ! 3 +Loop10: umul %o4,%o3,%g3 ! 4 + addxcc %g3,%g2,%g3 ! 4 + ld [%o1+0],%o4 ! 1 + st %g3,[%o0+12] ! 4 + add %o0,16,%o0 + rd %y,%g2 ! 4 + addx %g0,%g2,%g2 +Loop01: addcc %o2,-4,%o2 + bg Loop + umul %o4,%o3,%g3 ! 1 + + addcc %g3,%g2,%g3 ! 4 + st %g3,[%o0+0] ! 4 + rd %y,%g2 ! 4 + + retl + addx %g0,%g2,%o0 diff --git a/sysdeps/sparc/sparc8/submul_1.S b/sysdeps/sparc/sparc8/submul_1.S new file mode 100644 index 0000000000..5c4d688ee8 --- /dev/null +++ b/sysdeps/sparc/sparc8/submul_1.S @@ -0,0 +1,57 @@ +! SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and +! subtract the result from a second limb vector. + +! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include "sysdep.h" + +.text + .align 4 + .global C_SYMBOL_NAME(__mpn_submul_1) +C_SYMBOL_NAME(__mpn_submul_1): + sub %g0,%o2,%o2 ! negate ... + sll %o2,2,%o2 ! ... and scale size + sub %o1,%o2,%o1 ! o1 is offset s1_ptr + sub %o0,%o2,%g1 ! g1 is offset res_ptr + + mov 0,%o0 ! clear cy_limb + +Loop: ld [%o1+%o2],%o4 + ld [%g1+%o2],%g2 + umul %o4,%o3,%o5 + rd %y,%g3 + addcc %o5,%o0,%o5 + addx %g3,0,%o0 + subcc %g2,%o5,%g2 + addx %o0,0,%o0 + st %g2,[%g1+%o2] + + addcc %o2,4,%o2 + bne Loop + nop + + retl + nop diff --git a/sysdeps/sparc/sparc8/udiv_qrnnd.S b/sysdeps/sparc/sparc8/udiv_qrnnd.S new file mode 100644 index 0000000000..49c2398806 --- /dev/null +++ b/sysdeps/sparc/sparc8/udiv_qrnnd.S @@ -0,0 +1,186 @@ +! SPARC __udiv_qrnnd division support, used from longlong.h. + +! Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! rem_ptr o0 +! n1 o1 +! n0 o2 +! d o3 + +#include "sysdep.h" + + .text + .align 4 + .global C_SYMBOL_NAME(__udiv_qrnnd) +C_SYMBOL_NAME(__udiv_qrnnd): + tst %o3 + bneg Largedivisor + mov 8,%g1 + + b Lp1 + addxcc %o2,%o2,%o2 + +Lplop: bcc Ln1 + addxcc %o2,%o2,%o2 +Lp1: addx %o1,%o1,%o1 + subcc %o1,%o3,%o4 + bcc Ln2 + addxcc %o2,%o2,%o2 +Lp2: addx %o1,%o1,%o1 + subcc %o1,%o3,%o4 + bcc Ln3 + addxcc %o2,%o2,%o2 +Lp3: addx %o1,%o1,%o1 + subcc %o1,%o3,%o4 + bcc Ln4 + addxcc %o2,%o2,%o2 +Lp4: addx %o1,%o1,%o1 + addcc %g1,-1,%g1 + bne Lplop + subcc %o1,%o3,%o4 + bcc Ln5 + addxcc %o2,%o2,%o2 +Lp5: st %o1,[%o0] + retl + xnor %g0,%o2,%o0 + +Lnlop: bcc Lp1 + addxcc %o2,%o2,%o2 +Ln1: addx %o4,%o4,%o4 + subcc %o4,%o3,%o1 + bcc Lp2 + addxcc %o2,%o2,%o2 +Ln2: addx %o4,%o4,%o4 + subcc %o4,%o3,%o1 + bcc Lp3 + addxcc %o2,%o2,%o2 +Ln3: addx %o4,%o4,%o4 + subcc %o4,%o3,%o1 + bcc Lp4 + addxcc %o2,%o2,%o2 +Ln4: addx %o4,%o4,%o4 + addcc %g1,-1,%g1 + bne Lnlop + subcc %o4,%o3,%o1 + bcc Lp5 + addxcc %o2,%o2,%o2 +Ln5: st %o4,[%o0] + retl + xnor %g0,%o2,%o0 + +Largedivisor: + and %o2,1,%o5 ! %o5 = n0 & 1 + + srl %o2,1,%o2 + sll %o1,31,%g2 + or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1) + srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1) + + and %o3,1,%g2 + srl %o3,1,%g3 ! %g3 = floor(d / 2) + add %g3,%g2,%g3 ! %g3 = ceil(d / 2) + + b LLp1 + addxcc %o2,%o2,%o2 + +LLplop: bcc LLn1 + addxcc %o2,%o2,%o2 +LLp1: addx %o1,%o1,%o1 + subcc %o1,%g3,%o4 + bcc LLn2 + addxcc %o2,%o2,%o2 +LLp2: addx %o1,%o1,%o1 + subcc %o1,%g3,%o4 + bcc LLn3 + addxcc %o2,%o2,%o2 +LLp3: addx %o1,%o1,%o1 + subcc %o1,%g3,%o4 + bcc LLn4 + addxcc %o2,%o2,%o2 +LLp4: addx %o1,%o1,%o1 + addcc %g1,-1,%g1 + bne LLplop + subcc %o1,%g3,%o4 + bcc LLn5 + addxcc %o2,%o2,%o2 +LLp5: add %o1,%o1,%o1 ! << 1 + tst %g2 + bne Oddp + add %o5,%o1,%o1 + st %o1,[%o0] + retl + xnor %g0,%o2,%o0 + +LLnlop: bcc LLp1 + addxcc %o2,%o2,%o2 +LLn1: addx %o4,%o4,%o4 + subcc %o4,%g3,%o1 + bcc LLp2 + addxcc %o2,%o2,%o2 +LLn2: addx %o4,%o4,%o4 + subcc %o4,%g3,%o1 + bcc LLp3 + addxcc %o2,%o2,%o2 +LLn3: addx %o4,%o4,%o4 + subcc %o4,%g3,%o1 + bcc LLp4 + addxcc %o2,%o2,%o2 +LLn4: addx %o4,%o4,%o4 + addcc %g1,-1,%g1 + bne LLnlop + subcc %o4,%g3,%o1 + bcc LLp5 + addxcc %o2,%o2,%o2 +LLn5: add %o4,%o4,%o4 ! << 1 + tst %g2 + bne Oddn + add %o5,%o4,%o4 + st %o4,[%o0] + retl + xnor %g0,%o2,%o0 + +Oddp: xnor %g0,%o2,%o2 + ! q' in %o2. r' in %o1 + addcc %o1,%o2,%o1 + bcc LLp6 + addx %o2,0,%o2 + sub %o1,%o3,%o1 +LLp6: subcc %o1,%o3,%g0 + bcs LLp7 + subx %o2,-1,%o2 + sub %o1,%o3,%o1 +LLp7: st %o1,[%o0] + retl + mov %o2,%o0 + +Oddn: xnor %g0,%o2,%o2 + ! q' in %o2. r' in %o4 + addcc %o4,%o2,%o4 + bcc LLn6 + addx %o2,0,%o2 + sub %o4,%o3,%o4 +LLn6: subcc %o4,%o3,%g0 + bcs LLn7 + subx %o2,-1,%o2 + sub %o4,%o3,%o4 +LLn7: st %o4,[%o0] + retl + mov %o2,%o0 diff --git a/sysdeps/sparc/sqrt.c b/sysdeps/sparc/sqrt.c new file mode 100644 index 0000000000..bff46e1644 --- /dev/null +++ b/sysdeps/sparc/sqrt.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* Return the square root of X. */ +double +DEFUN(sqrt, (x), double x) +{ + register double result; + asm("fsqrtd %1, %0" : "=f" (result) : "f" (x)); + return result; +} diff --git a/sysdeps/sparc/sub_n.S b/sysdeps/sparc/sub_n.S new file mode 100644 index 0000000000..7a167b2ac1 --- /dev/null +++ b/sysdeps/sparc/sub_n.S @@ -0,0 +1,134 @@ +! sparc __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and +! store difference in a third limb vector. + +! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr %o0 +! s1_ptr %o1 +! s2_ptr %o2 +! size %o3 + +#include "sysdep.h" + + .text + .align 4 + .global C_SYMBOL_NAME(__mpn_sub_n) +C_SYMBOL_NAME(__mpn_sub_n): + ld [%o1+0],%o4 ! read first limb from s1_ptr + srl %o3,4,%g1 + ld [%o2+0],%o5 ! read first limb from s2_ptr + + sub %g0,%o3,%o3 + andcc %o3,(16-1),%o3 + be Lzero + nop + + sll %o3,2,%o3 ! multiply by 4 + sub %o0,%o3,%o0 ! adjust res_ptr + sub %o1,%o3,%o1 ! adjust s1_ptr + sub %o2,%o3,%o2 ! adjust s2_ptr + + mov %o4,%g2 + + sethi %hi(Lbase),%g3 + or %g3,%lo(Lbase),%g3 + sll %o3,2,%o3 ! multiply by 4 + jmp %g3+%o3 + mov %o5,%g3 + +Loop: subxcc %g2,%g3,%o3 + add %o1,64,%o1 + st %o3,[%o0+60] + add %o2,64,%o2 + ld [%o1+0],%o4 + add %o0,64,%o0 + ld [%o2+0],%o5 +Lzero: sub %g1,1,%g1 ! add 0 + 16r limbs (adjust loop counter) +Lbase: ld [%o1+4],%g2 + subxcc %o4,%o5,%o3 + ld [%o2+4],%g3 + st %o3,[%o0+0] + ld [%o1+8],%o4 ! add 15 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+8],%o5 + st %o3,[%o0+4] + ld [%o1+12],%g2 ! add 14 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+12],%g3 + st %o3,[%o0+8] + ld [%o1+16],%o4 ! add 13 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+16],%o5 + st %o3,[%o0+12] + ld [%o1+20],%g2 ! add 12 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+20],%g3 + st %o3,[%o0+16] + ld [%o1+24],%o4 ! add 11 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+24],%o5 + st %o3,[%o0+20] + ld [%o1+28],%g2 ! add 10 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+28],%g3 + st %o3,[%o0+24] + ld [%o1+32],%o4 ! add 9 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+32],%o5 + st %o3,[%o0+28] + ld [%o1+36],%g2 ! add 8 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+36],%g3 + st %o3,[%o0+32] + ld [%o1+40],%o4 ! add 7 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+40],%o5 + st %o3,[%o0+36] + ld [%o1+44],%g2 ! add 6 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+44],%g3 + st %o3,[%o0+40] + ld [%o1+48],%o4 ! add 5 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+48],%o5 + st %o3,[%o0+44] + ld [%o1+52],%g2 ! add 4 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+52],%g3 + st %o3,[%o0+48] + ld [%o1+56],%o4 ! add 3 + 16r limbs + subxcc %g2,%g3,%o3 + ld [%o2+56],%o5 + st %o3,[%o0+52] + ld [%o1+60],%g2 ! add 2 + 16r limbs + subxcc %o4,%o5,%o3 + ld [%o2+60],%g3 + st %o3,[%o0+56] + subx %g0,%g0,%o4 + tst %g1 + bne Loop + subcc %g0,%o4,%g0 ! restore cy (delay slot) + + subxcc %g2,%g3,%o3 + st %o3,[%o0+60] ! store most significant limb + + retl + addx %g0,%g0,%o0 ! return carry-out from most sign. limb diff --git a/sysdeps/sparc/submul_1.S b/sysdeps/sparc/submul_1.S new file mode 100644 index 0000000000..ed67c99d29 --- /dev/null +++ b/sysdeps/sparc/submul_1.S @@ -0,0 +1,146 @@ +! SPARC __mpn_submul_1 -- Multiply a limb vector with a limb and subtract +! the result from a second limb vector. + +! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! res_ptr o0 +! s1_ptr o1 +! size o2 +! s2_limb o3 + +#include "sysdep.h" + +.text + .align 4 + .global C_SYMBOL_NAME(__mpn_submul_1) +C_SYMBOL_NAME(__mpn_submul_1): + ! Make S1_PTR and RES_PTR point at the end of their blocks + ! and put (- 4 x SIZE) in index/loop counter. + sll %o2,2,%o2 + add %o0,%o2,%o4 ! RES_PTR in o4 since o0 is retval + add %o1,%o2,%o1 + sub %g0,%o2,%o2 + + cmp %o3,0xfff + bgu Large + nop + + ld [%o1+%o2],%o5 + mov 0,%o0 + b L0 + add %o4,-4,%o4 +Loop0: + subcc %o5,%g1,%g1 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g1,[%o4+%o2] +L0: wr %g0,%o3,%y + sra %o5,31,%g2 + and %o3,%g2,%g2 + andcc %g1,0,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,%o5,%g1 + mulscc %g1,0,%g1 + sra %g1,20,%g4 + sll %g1,12,%g1 + rd %y,%g3 + srl %g3,20,%g3 + or %g1,%g3,%g1 + + addcc %g1,%o0,%g1 + addx %g2,%g4,%o0 ! add sign-compensation and cy to hi limb + addcc %o2,4,%o2 ! loop counter + bne Loop0 + ld [%o4+%o2],%o5 + + subcc %o5,%g1,%g1 + addx %o0,%g0,%o0 + retl + st %g1,[%o4+%o2] + + +Large: ld [%o1+%o2],%o5 + mov 0,%o0 + sra %o3,31,%g4 ! g4 = mask of ones iff S2_LIMB < 0 + b L1 + add %o4,-4,%o4 +Loop: + subcc %o5,%g3,%g3 + ld [%o1+%o2],%o5 + addx %o0,%g0,%o0 + st %g3,[%o4+%o2] +L1: wr %g0,%o5,%y + and %o5,%g4,%g2 + andcc %g0,%g0,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%o3,%g1 + mulscc %g1,%g0,%g1 + rd %y,%g3 + addcc %g3,%o0,%g3 + addx %g2,%g1,%o0 + addcc %o2,4,%o2 + bne Loop + ld [%o4+%o2],%o5 + + subcc %o5,%g3,%g3 + addx %o0,%g0,%o0 + retl + st %g3,[%o4+%o2] diff --git a/sysdeps/sparc/udiv.S b/sysdeps/sparc/udiv.S new file mode 100644 index 0000000000..826d01183d --- /dev/null +++ b/sysdeps/sparc/udiv.S @@ -0,0 +1,348 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .udiv name of function to generate + * div div=div => %o0 / %o1; div=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include "DEFS.h" +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +FUNC(.udiv) + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: cmp %o5, %o3 + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + sub %o2, 1, %o2 + + +Lgot_result: + + retl + mov %o2, %o0 diff --git a/sysdeps/sparc/udiv_qrnnd.S b/sysdeps/sparc/udiv_qrnnd.S new file mode 100644 index 0000000000..4cd4f051b3 --- /dev/null +++ b/sysdeps/sparc/udiv_qrnnd.S @@ -0,0 +1,143 @@ +! SPARC __udiv_qrnnd division support, used from longlong.h. + +! Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +! This file is part of the GNU MP Library. + +! The GNU MP Library is free software; you can redistribute it and/or modify +! it under the terms of the GNU Library General Public License as published by +! the Free Software Foundation; either version 2 of the License, or (at your +! option) any later version. + +! The GNU MP Library is distributed in the hope that it will be useful, but +! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +! License for more details. + +! You should have received a copy of the GNU Library General Public License +! along with the GNU MP Library; see the file COPYING.LIB. If not, write to +! the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +! INPUT PARAMETERS +! rem_ptr i0 +! n1 i1 +! n0 i2 +! d i3 + +#include "sysdep.h" +#undef ret /* Kludge for glibc */ + + .text + .align 8 +LC0: .double 0r4294967296 +LC1: .double 0r2147483648 + + .align 4 + .global C_SYMBOL_NAME(__udiv_qrnnd) +C_SYMBOL_NAME(__udiv_qrnnd): + !#PROLOGUE# 0 + save %sp,-104,%sp + !#PROLOGUE# 1 + st %i1,[%fp-8] + ld [%fp-8],%f10 + sethi %hi(LC0),%o7 + fitod %f10,%f4 + ldd [%o7+%lo(LC0)],%f8 + cmp %i1,0 + bge L248 + mov %i0,%i5 + faddd %f4,%f8,%f4 +L248: + st %i2,[%fp-8] + ld [%fp-8],%f10 + fmuld %f4,%f8,%f6 + cmp %i2,0 + bge L249 + fitod %f10,%f2 + faddd %f2,%f8,%f2 +L249: + st %i3,[%fp-8] + faddd %f6,%f2,%f2 + ld [%fp-8],%f10 + cmp %i3,0 + bge L250 + fitod %f10,%f4 + faddd %f4,%f8,%f4 +L250: + fdivd %f2,%f4,%f2 + sethi %hi(LC1),%o7 + ldd [%o7+%lo(LC1)],%f4 + fcmped %f2,%f4 + nop + fbge,a L251 + fsubd %f2,%f4,%f2 + fdtoi %f2,%f2 + st %f2,[%fp-8] + b L252 + ld [%fp-8],%i4 +L251: + fdtoi %f2,%f2 + st %f2,[%fp-8] + ld [%fp-8],%i4 + sethi %hi(-2147483648),%g2 + xor %i4,%g2,%i4 +L252: + wr %g0,%i4,%y + sra %i3,31,%g2 + and %i4,%g2,%g2 + andcc %g0,0,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,%i3,%g1 + mulscc %g1,0,%g1 + add %g1,%g2,%i0 + rd %y,%g3 + subcc %i2,%g3,%o7 + subxcc %i1,%i0,%g0 + be L253 + cmp %o7,%i3 + + add %i4,-1,%i0 + add %o7,%i3,%o7 + st %o7,[%i5] + ret + restore +L253: + blu L246 + mov %i4,%i0 + add %i4,1,%i0 + sub %o7,%i3,%o7 +L246: + st %o7,[%i5] + ret + restore diff --git a/sysdeps/sparc/umul.S b/sysdeps/sparc/umul.S new file mode 100644 index 0000000000..7a26c295cb --- /dev/null +++ b/sysdeps/sparc/umul.S @@ -0,0 +1,153 @@ +/* + * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the + * upper 32 bits of the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. Short + * multiplies require 25 instruction cycles, and long ones require + * 45 instruction cycles. + * + * On return, overflow has occurred (%o1 is not zero) if and only if + * the Z condition code is clear, allowing, e.g., the following: + * + * call .umul + * nop + * bnz overflow (or tnz) + */ + +#include "DEFS.h" +FUNC(.umul) + or %o0, %o1, %o4 + mov %o0, %y ! multiplier -> Y + andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args + be Lmul_shortway ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + + /* + * Normally, with the shift-and-add approach, if both numbers are + * positive you get the correct result. With 32-bit two's-complement + * numbers, -x is represented as + * + * x 32 + * ( 2 - ------ ) mod 2 * 2 + * 32 + * 2 + * + * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, + * we can treat this as if the radix point were just to the left + * of the sign bit (multiply by 2^32), and get + * + * -x = (2 - x) mod 2 + * + * Then, ignoring the `mod 2's for convenience: + * + * x * y = xy + * -x * y = 2y - xy + * x * -y = 2x - xy + * -x * -y = 4 - 2x - 2y + xy + * + * For signed multiplies, we subtract (x << 32) from the partial + * product to fix this problem for negative multipliers (see mul.s). + * Because of the way the shift into the partial product is calculated + * (N xor V), this term is automatically removed for the multiplicand, + * so we don't have to adjust. + * + * But for unsigned multiplies, the high order bit wasn't a sign bit, + * and the correction is wrong. So for unsigned multiplies where the + * high order bit is one, we end up with xy - (y << 32). To fix it + * we add y << 32. + */ +#if 0 + tst %o1 + bl,a 1f ! if %o1 < 0 (high order bit = 1), + add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) +1: rd %y, %o0 ! get lower half of product + retl + addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 +#else + /* Faster code from tege@sics.se. */ + sra %o1, 31, %o2 ! make mask from sign bit + and %o0, %o2, %o2 ! %o2 = 0 or %o0, depending on sign of %o1 + rd %y, %o0 ! get lower half of product + retl + addcc %o4, %o2, %o1 ! add compensation and put upper half in place +#endif + +Lmul_shortway: + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above), + * and overflow is impossible (the answer is at most 24 bits long). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the result; %y has + * the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * -----result----- + * + * The 12 bits of %o4 left of the `result' area are all zero; + * in fact, all top 20 bits of %o4 are zero. + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20 + or %o5, %o0, %o0 + retl + addcc %g0, %g0, %o1 ! %o1 = zero, and set Z diff --git a/sysdeps/sparc/urem.S b/sysdeps/sparc/urem.S new file mode 100644 index 0000000000..9f64c8859e --- /dev/null +++ b/sysdeps/sparc/urem.S @@ -0,0 +1,348 @@ + /* This file is generated from divrem.m4; DO NOT EDIT! */ +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * .urem name of function to generate + * rem rem=div => %o0 / %o1; rem=rem => %o0 % %o1 + * false false=true => signed; false=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TOPBITS number of bits in the top decade of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + + + +#include "DEFS.h" +#ifdef __svr4__ +#include <sys/trap.h> +#else +#include <machine/trap.h> +#endif + +FUNC(.urem) + + ! Ready to divide. Compute size of quotient; scale comparand. + orcc %o1, %g0, %o5 + bne 1f + mov %o0, %o3 + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + ta ST_DIV0 + retl + clr %o0 + +1: + cmp %o3, %o5 ! if %o1 exceeds %o0, done + blu Lgot_result ! (and algorithm fails otherwise) + clr %o2 + sethi %hi(1 << (32 - 4 - 1)), %g1 + cmp %o3, %g1 + blu Lnot_really_big + clr %o4 + + ! Here the dividend is >= 2**(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R. + 1: + cmp %o5, %g1 + bgeu 3f + mov 1, %g7 + sll %o5, 4, %o5 + b 1b + add %o4, 1, %o4 + + ! Now compute %g7. + 2: addcc %o5, %o5, %o5 + bcc Lnot_too_big + add %g7, 1, %g7 + + ! We get here if the %o1 overflowed while shifting. + ! This means that %o3 has the high-order bit set. + ! Restore %o5 and subtract from %o3. + sll %g1, 4, %g1 ! high order bit + srl %o5, 1, %o5 ! rest of %o5 + add %o5, %g1, %o5 + b Ldo_single_div + sub %g7, 1, %g7 + + Lnot_too_big: + 3: cmp %o5, %o3 + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! %o5 > %o3: went too far: back up 1 step + ! srl %o5, 1, %o5 + ! dec %g7 + ! do single-bit divide steps + ! + ! We have to be careful here. We know that %o3 >= %o5, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + subcc %g7, 1, %g7 + bl Lend_regular_divide + nop + sub %o3, %o5, %o3 + mov 1, %o2 + b Lend_single_divloop + nop + Lsingle_divloop: + sll %o2, 1, %o2 + bl 1f + srl %o5, 1, %o5 + ! %o3 >= 0 + sub %o3, %o5, %o3 + b 2f + add %o2, 1, %o2 + 1: ! %o3 < 0 + add %o3, %o5, %o3 + sub %o2, 1, %o2 + 2: + Lend_single_divloop: + subcc %g7, 1, %g7 + bge Lsingle_divloop + tst %o3 + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll %o5, 4, %o5 + cmp %o5, %o3 + bleu 1b + addcc %o4, 1, %o4 + be Lgot_result + sub %o4, 1, %o4 + + tst %o3 ! set up for initial iteration +Ldivloop: + sll %o2, 4, %o2 + ! depth 1, accumulated bits 0 + bl L.1.16 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 2, accumulated bits 1 + bl L.2.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits 3 + bl L.3.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 7 + bl L.4.23 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (7*2+1), %o2 + +L.4.23: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (7*2-1), %o2 + + +L.3.19: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 5 + bl L.4.21 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (5*2+1), %o2 + +L.4.21: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (5*2-1), %o2 + + + +L.2.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits 1 + bl L.3.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits 3 + bl L.4.19 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (3*2+1), %o2 + +L.4.19: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (3*2-1), %o2 + + +L.3.17: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits 1 + bl L.4.17 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (1*2+1), %o2 + +L.4.17: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (1*2-1), %o2 + + + + +L.1.16: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 2, accumulated bits -1 + bl L.2.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 3, accumulated bits -1 + bl L.3.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -1 + bl L.4.15 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2+1), %o2 + +L.4.15: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-1*2-1), %o2 + + +L.3.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -3 + bl L.4.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2+1), %o2 + +L.4.13: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-3*2-1), %o2 + + + +L.2.15: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 3, accumulated bits -3 + bl L.3.13 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + ! depth 4, accumulated bits -5 + bl L.4.11 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2+1), %o2 + +L.4.11: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-5*2-1), %o2 + + +L.3.13: + ! remainder is negative + addcc %o3,%o5,%o3 + ! depth 4, accumulated bits -7 + bl L.4.9 + srl %o5,1,%o5 + ! remainder is positive + subcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2+1), %o2 + +L.4.9: + ! remainder is negative + addcc %o3,%o5,%o3 + b 9f + add %o2, (-7*2-1), %o2 + + + + + 9: +Lend_regular_divide: + subcc %o4, 1, %o4 + bge Ldivloop + tst %o3 + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) + add %o3, %o1, %o3 + + +Lgot_result: + + retl + mov %o3, %o0 diff --git a/sysdeps/standalone/Dist b/sysdeps/standalone/Dist new file mode 100644 index 0000000000..b6b12b709a --- /dev/null +++ b/sysdeps/standalone/Dist @@ -0,0 +1,2 @@ +filedesc.h +standalone.h diff --git a/sysdeps/standalone/Subdirs b/sysdeps/standalone/Subdirs new file mode 100644 index 0000000000..4125ae86db --- /dev/null +++ b/sysdeps/standalone/Subdirs @@ -0,0 +1,4 @@ +# The `bare' subdirectory defines some structure for a target-specific +# library of functions which are actually implemented in +# sysdeps/standalone/CPU/TARGET. +bare diff --git a/sysdeps/standalone/brk.c b/sysdeps/standalone/brk.c new file mode 100644 index 0000000000..67fbf771a0 --- /dev/null +++ b/sysdeps/standalone/brk.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> + +PTR __curbrk; +PTR __rorig; +PTR __rlimit; + +int +DEFUN(__brk, (inaddr), PTR inaddr) +{ + + if ( ( (void *)inaddr > (void *)__rlimit ) || + ( (void *)inaddr < (void *)__rorig ) ) + return -1; + + __curbrk = inaddr; + return 0; +} + +/* Initialization Code for Memory Allocation */ + +PTR __C_heap_start; +int __C_heap_size; + +#ifdef HAVE_GNU_LD +static +#endif +void +DEFUN(__NONE_set_memvals, (argc, argv, envp), + int argc AND char **argv AND char **envp) +{ + + __rorig = + __curbrk = __C_heap_start; + __rlimit = __curbrk + __C_heap_size; + + (void) &__NONE_set_memvals; /* Avoid "defined but not used" warning. */ +} + +#ifdef HAVE_GNU_LD +text_set_element (__libc_subinit, __NONE_set_memvals); +#endif + +weak_alias (__brk, brk) diff --git a/sysdeps/standalone/close.c b/sysdeps/standalone/close.c new file mode 100644 index 0000000000..59b607305f --- /dev/null +++ b/sysdeps/standalone/close.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +#include <stdio_lim.h> +#include "filedesc.h" + +/* Close the file descriptor FD. */ +int +DEFUN(__close, (fd), int fd) +{ + if ( !__FD_Is_valid( fd ) || !__FD_Table[ fd ].in_use ) + { + errno = EBADF; + return -1; + } + + __FD_Table[ fd ].in_use = 0; + return 0; +} + + +weak_alias (__close, close) diff --git a/sysdeps/standalone/dirstream.h b/sysdeps/standalone/dirstream.h new file mode 100644 index 0000000000..20c4922fb9 --- /dev/null +++ b/sysdeps/standalone/dirstream.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + +#define __need_size_t +#include <stddef.h> + +/* Directory stream type. + + The miscellaneous Unix `readdir' implementations read directory data + into a buffer and fill in a `struct dirent' copy in the `DIR' object. */ + +typedef struct + { + int __fd; /* File descriptor. */ + + char *__data; /* Directory block. */ + size_t __allocation; /* Space allocated for the block. */ + size_t __offset; /* Current offset into the block. */ + size_t __size; /* Total valid data in the block. */ + + struct dirent __entry; /* Returned by `readdir'. */ + } DIR; + +#endif /* dirstream.h */ diff --git a/sysdeps/standalone/filedesc.h b/sysdeps/standalone/filedesc.h new file mode 100644 index 0000000000..bf3b6a9f0c --- /dev/null +++ b/sysdeps/standalone/filedesc.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * This is the file descriptor used by the no OS implementation + * of __open, __read, __write, and __close. + */ + +#ifndef __FILEDESC_h +#define __FILEDESC_h + +#include <stdio_lim.h> + +#ifndef __DECLARE_FILE_DESCRIPTORS__ +#define FILEDESC_EXTERN extern +#else +#define FILEDESC_EXTERN +#endif + +typedef struct { + int in_use; /* 1 if in use, 0 otherwise */ + int flags; /* Flags from open */ +} __no_os_file_descriptor; + +#define __FD_Is_valid( _fd ) \ + ( (_fd) >= 0 && (_fd) < FOPEN_MAX ) + +FILEDESC_EXTERN __no_os_file_descriptor __FD_Table[ FOPEN_MAX ]; + +#endif diff --git a/sysdeps/standalone/i386/Dist b/sysdeps/standalone/i386/Dist new file mode 100644 index 0000000000..98d13be9af --- /dev/null +++ b/sysdeps/standalone/i386/Dist @@ -0,0 +1 @@ +i386.h diff --git a/sysdeps/standalone/i386/force_cpu386/Dist b/sysdeps/standalone/i386/force_cpu386/Dist new file mode 100644 index 0000000000..8b7b09e10a --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/Dist @@ -0,0 +1 @@ +target.ld diff --git a/sysdeps/standalone/i386/force_cpu386/Makefile b/sysdeps/standalone/i386/force_cpu386/Makefile new file mode 100644 index 0000000000..8483724ee3 --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/Makefile @@ -0,0 +1,24 @@ +# Copyright (C) 1994 Free Software Foundation, Inc. +# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), +# On-Line Applications Research Corporation. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq (bare,$(subdir)) +install-others += $(libdir)/force_cpu386.ld +$(libdir)/force_cpu386.ld: $(sysdep_dir)/standalone/i386/target.ld + $(do-install) +endif diff --git a/sysdeps/standalone/i386/force_cpu386/_exit.c b/sysdeps/standalone/i386/force_cpu386/_exit.c new file mode 100644 index 0000000000..011bb8bda9 --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/_exit.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdlib.h> + +/* This returns control to FORCEbug. */ + +void DEFUN_VOID(Bsp_cleanup); + +/* The function `_exit' should take a status argument and simply + terminate program execution, using the low-order 8 bits of the + given integer as status. */ + +__NORETURN void +DEFUN(_exit, (status), int status) +{ + /* status is ignored */ + Bsp_cleanup(); +} + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(_exit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/standalone/i386/force_cpu386/brdinit.c b/sysdeps/standalone/i386/force_cpu386/brdinit.c new file mode 100644 index 0000000000..0d27218121 --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/brdinit.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "i386.h" + +/* _Board_Initialize() + +This routine initializes the FORCE CPU386 board. */ + +void DEFUN_VOID(_Console_Initialize); + +void +DEFUN_VOID(_Board_Initialize) +{ + /* + * FORCE documentation incorrectly states that the bus request + * level is initialized to 3. It is actually initialized by + * FORCEbug to 0. + */ + + outport_byte( 0x00, 0x3f ); /* resets VMEbus request level */ + + _Console_Initialize(); +} diff --git a/sysdeps/standalone/i386/force_cpu386/console.c b/sysdeps/standalone/i386/force_cpu386/console.c new file mode 100644 index 0000000000..5d56f768ea --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/console.c @@ -0,0 +1,163 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "i386.h" + +/* Console IO routines for a FORCE CPU386 board. */ + +/* Force CPU/386 specific IO addressing + * + * The following determines whether Port B or the Console should + * be used for console I/O. Setting ONE (and only ONE) of these to 1 + * enables I/O on that port. + * + * PORT A - DUSCC MC68562 Channel A (*** not supported here ***) + * PORT B - DUSCC MC68562 Channel B + * PORT C - MFP MC68901 Channel (*** FORCEbug console ***) + */ + +#define PORTB 1 /* use port b as console */ +#define PORTC 0 /* use console port as console */ + +#if ( PORTB == 1 ) +#define TX_STATUS 0x1b6 /* DUSCC General Status Register */ +#define RX_STATUS 0x1b6 /* DUSCC General Status Register */ +#define TX_BUFFER 0x1e0 /* DUSCC Transmitter Channel B */ +#define RX_BUFFER 0x1e8 /* DUSCC Receiver Channel B */ +#define Is_tx_ready( _status ) ( (_status) & 0x20 ) +#define Is_rx_ready( _status ) ( (_status) & 0x10 ) +#endif + +#if ( PORTC == 1 ) +#define TX_STATUS 0x12c /* MFP Transmit Status Register */ +#define RX_STATUS 0x12a /* MFP Receive Status Register */ +#define TX_BUFFER 0x12e /* MFP Transmitter Channel */ +#define RX_BUFFER 0x12e /* MFP Receiver Channel */ +#define Is_tx_ready( _status ) ( (_status) & 0x80 ) +#define Is_rx_ready( _status ) ( (_status) & 0x80 ) +#endif + +/* _Console_Initialize + +On the Force board the console require some initialization. */ + +void +DEFUN_VOID(_Console_Initialize) +{ + register unsigned8 ignored; + + /* FORCE technical support mentioned that it may be necessary to + read the DUSCC RX_BUFFER port four times to remove all junk. + This code is a little more paranoid. */ + + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); +} + +/* Miscellaneous support for console IO */ + +static inline int _Force386_is_rx_ready() +{ + register unsigned8 status; + + inport_byte( RX_STATUS, status ); + + if ( Is_rx_ready( status ) ) return 1; + else return 0; +} + +static inline int _Force386_is_tx_ready() +{ + register unsigned8 status; + + inport_byte( TX_STATUS, status ); + + if ( Is_tx_ready( status ) ) return 1; + else return 0; +} + + +static inline int _Force386_read_data() +{ + register unsigned8 ch; + +#if ( PORTB == 1 ) + /* Force example code resets the Channel B Receiver here. + * It appears to cause XON's to be lost. + */ + + /* outport_byte( RX_STATUS, 0x10 ); */ +#endif + + inport_byte( RX_BUFFER, ch ); + + return ch; +} + +/* _Console_Putc + +This routine transmits a character. It supports XON/XOFF flow control. */ + +#define XON 0x11 /* control-Q */ +#define XOFF 0x13 /* control-S */ + +int +DEFUN( _Console_Putc, (ch), char ch ) +{ + register unsigned8 inch; + + while ( !_Force386_is_tx_ready() ); + + while ( _Force386_is_rx_ready() == 1 ) { /* must be an XOFF */ + inch = _Force386_read_data(); + if ( inch == XOFF ) + do { + while ( _Force386_is_rx_ready() == 0 ); + inch = _Force386_read_data(); + } while ( inch != XON ); + } + + outport_byte( TX_BUFFER, ch ); + return( 0 ); +} + +/* _Console_Getc + +This routine reads a character from the UART and returns it. */ + +int +DEFUN( _Console_Getc, (poll), int poll ) +{ + if ( poll ) { + if ( !_Force386_is_rx_ready() ) + return -1; + else + return _Force386_read_data(); + } else { + while ( !_Force386_is_rx_ready() ); + return _Force386_read_data(); + } +} diff --git a/sysdeps/standalone/i386/force_cpu386/strtsupp.S b/sysdeps/standalone/i386/force_cpu386/strtsupp.S new file mode 100644 index 0000000000..6b78a8c343 --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/strtsupp.S @@ -0,0 +1,89 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file assists the board independent startup code by + * loading the proper segment register values. The values + * loaded are dependent on the FORCEBUG. + * + * NOTE: No stack has been established when this routine + * is invoked. It returns by jumping back to the start code. + * + */ + +/* + * FORCEBUG loads us into a virtual address space which + * really starts at PHYSICAL_ADDRESS_BASE. + * + */ + +.set PHYSICAL_ADDRESS_BASE, 0x00002000 + +/* + * At reset time, FORCEBUG normally has the segment selectors preloaded. + * If a human resets the instruction pointer, this will not have occurred. + * However, no guarantee can be made of the other registers if cs:ip was + * modified to restart the program. Because of this, the BSP reloads all + * segment registers (except cs) with the values they have following + * a reset. + */ + + +.set RESET_SS, 0x40 # initial value of stack segment register +.set RESET_DS, 0x40 # initial value of data segment register +.set RESET_ES, 0x40 # initial value of extra segment register +.set RESET_FS, 0x40 # initial value of "f" segment register +.set RESET_GS, 0x30 # initial value of "g" segment register + + +#define LOAD_SEGMENTS(_value,_segreg) \ + movw $_value##,%ax ; \ + movw %ax,##_segreg + + + .global _load_segments + + .global _establish_stack + +_load_segments: + + LOAD_SEGMENTS( RESET_SS, %ss ) + LOAD_SEGMENTS( RESET_DS, %ds ) + LOAD_SEGMENTS( RESET_ES, %es ) + LOAD_SEGMENTS( RESET_FS, %fs ) + LOAD_SEGMENTS( RESET_GS, %gs ) + + jmp _establish_stack # return to the bsp entry code + + .global _return_to_monitor +_return_to_monitor: + + movb $0,%al + int $0x20 # restart FORCEbug + jmp start # FORCEbug does not reset PC + + .data + + .global _Do_Load_IDT +_Do_Load_IDT: .byte 1 + + .global _Do_Load_GDT +_Do_Load_GDT: .byte 0 + diff --git a/sysdeps/standalone/i386/force_cpu386/target.ld b/sysdeps/standalone/i386/force_cpu386/target.ld new file mode 100644 index 0000000000..056da10d55 --- /dev/null +++ b/sysdeps/standalone/i386/force_cpu386/target.ld @@ -0,0 +1,59 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file contains directives for the GNU linker which are specific +to the FORCE CPU386 board. */ + +MEMORY + { + ram : org = 0x0, l = 1M + } + +/* This value is also when the space is allocated. If you change +this one, change the other one!!! */ + +heap_size = 0x20000; + +SECTIONS +{ + .text 0x0 : + { + _text_start = ABSOLUTE(.) ; + *(.text) + _etext = ALIGN( 0x10 ) ; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + _data_start = . ; + *(.data) + _edata = ALIGN( 0x10 ) ; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + _bss_start = . ; + *(.bss) + *(COMMON) + heap_memory = .; + . += 0x20000; + _end = . ; + __end = . ; + } +} diff --git a/sysdeps/standalone/i386/i386.h b/sysdeps/standalone/i386/i386.h new file mode 100644 index 0000000000..8302773709 --- /dev/null +++ b/sysdeps/standalone/i386/i386.h @@ -0,0 +1,327 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* i386.h + * + * This file contains macros which are used to access i80386 + * registers which are not addressable by C. This file contains + * functions which are useful to those developing target + * specific support routines. + */ + +#ifndef i386_h__ +#define i386_h__ + +typedef unsigned char unsigned8; +typedef unsigned short unsigned16; +typedef unsigned int unsigned32; + +#define disable_intr( isrlevel ) \ + { (isrlevel) = 0; \ + asm volatile ( "pushf ; \ + pop %0 ; \ + cli " \ + : "=r" ((isrlevel)) : "0" ((isrlevel)) ); \ + } + + +#define enable_intr( isrlevel ) \ + { asm volatile ( "push %0 ; \ + popf " \ + : "=r" ((isrlevel)) : "0" ((isrlevel)) ); \ + } + +#define delay( _microseconds ) \ + { \ + unsigned32 _counter; \ + \ + _counter = (_microseconds); \ + \ + asm volatile ( "0: nop;" \ + " mov %0,%0 ;" \ + " loop 0" : "=c" (_counter) \ + : "0" (_counter) \ + ); \ + \ + } + +/* segment access functions */ + +static inline unsigned16 get_cs() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned16 get_ds() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned16 get_es() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned16 get_ss() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned16 get_fs() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned16 get_gs() +{ + register unsigned16 segment = 0; + + asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +/* i80x86 I/O instructions */ + +#define outport_byte( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned8 __value = _value; \ + \ + asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define outport_word( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned16 __value = _value; \ + \ + asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define outport_long( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned32 __value = _value; \ + \ + asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define inport_byte( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned8 __value = 0; \ + \ + asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +#define inport_word( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned16 __value = 0; \ + \ + asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +#define inport_long( _port, _value ) \ + { register unsigned16 __port = _port; \ + register unsigned32 __value = 0; \ + \ + asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +/* structures */ + +/* See Chapter 5 - Memory Management in i386 manual */ + +struct GDT_slot { + unsigned16 limit_0_15; + unsigned16 base_0_15; + unsigned8 base_16_23; + unsigned8 type_dt_dpl_p; + unsigned8 limit_16_19_granularity; + unsigned8 base_24_31; +}; + +/* See Chapter 9 - Exceptions and Interrupts in i386 manual + * + * NOTE: This is the IDT entry for interrupt gates ONLY. + */ + +struct IDT_slot { + unsigned16 offset_0_15; + unsigned16 segment_selector; + unsigned8 reserved; + unsigned8 p_dpl; + unsigned16 offset_16_31; +}; + +struct DTR_load_save_format { + unsigned16 limit; + unsigned32 physical_address; +}; + +/* variables */ + +extern struct IDT_slot Interrupt_descriptor_table[ 256 ]; +extern struct GDT_slot Global_descriptor_table[ 8192 ]; + +/* functions */ + +#ifdef CPU_INITIALIZE +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +void *Logical_to_physical( + unsigned16 segment, + void *address +); + +void *Physical_to_logical( + unsigned16 segment, + void *address +); + +/* complicated static inline functions */ + +#define get_GDTR( _gdtr_address ) \ + { \ + void *_gdtr = (_gdtr_address); \ + \ + asm volatile( "sgdt (%0)" : "=r" (_gdtr) : "0" (_gdtr) ); \ + } + +#define get_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + { \ + register unsigned32 _gdt_slot = (_gdtr_base) + (_segment); \ + register volatile void *_slot = (_slot_address); \ + register unsigned32 _temporary = 0; \ + \ + asm volatile( "movl %%gs:(%0),%1 ; \ + movl %1,(%2) ; \ + movl %%gs:4(%0),%1 ; \ + movl %1,4(%2)" \ + : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ + : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ + ); \ + } + +#define set_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + { \ + register unsigned32 _gdt_slot = (_gdtr_base) + (_segment); \ + register volatile void *_slot = (_slot_address); \ + register unsigned32 _temporary = 0; \ + \ + asm volatile( "movl (%2),%1 ; \ + movl %1,%%gs:(%0) ; \ + movl 4(%2),%1 ; \ + movl %1,%%gs:4(%0) \ + " \ + : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ + : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ + ); \ + } + +static inline void set_segment( + unsigned16 segment, + unsigned32 base, + unsigned32 limit +) +{ + struct DTR_load_save_format gdtr; + volatile struct GDT_slot Gdt_slot; + volatile struct GDT_slot *gdt_slot = &Gdt_slot; + unsigned16 tmp_segment = 0; + unsigned32 limit_adjusted; + + + /* load physical address of the GDT */ + + get_GDTR( &gdtr ); + + gdt_slot->type_dt_dpl_p = 0x92; /* present, dpl=0, */ + /* application=1, */ + /* type=data read/write */ + gdt_slot->limit_16_19_granularity = 0x40; /* 32 bit segment */ + + limit_adjusted = limit; + if ( limit > 4095 ) { + gdt_slot->limit_16_19_granularity |= 0x80; /* set granularity bit */ + limit_adjusted /= 4096; + } + + gdt_slot->limit_16_19_granularity |= (limit_adjusted >> 16) & 0xff; + gdt_slot->limit_0_15 = limit_adjusted & 0xffff; + + gdt_slot->base_0_15 = base & 0xffff; + gdt_slot->base_16_23 = (base >> 16) & 0xff; + gdt_slot->base_24_31 = (base >> 24); + + set_GDT_slot( gdtr.physical_address, segment, gdt_slot ); + + /* Now, reload all segment registers so the limit takes effect. */ + + asm volatile( "movw %%ds,%0 ; movw %0,%%ds + movw %%es,%0 ; movw %0,%%es + movw %%fs,%0 ; movw %0,%%fs + movw %%gs,%0 ; movw %0,%%gs + movw %%ss,%0 ; movw %0,%%ss" + : "=r" (tmp_segment) + : "0" (tmp_segment) + ); + +} + +#endif +/* end of include file */ diff --git a/sysdeps/standalone/i386/start.S b/sysdeps/standalone/i386/start.S new file mode 100644 index 0000000000..8331a331c1 --- /dev/null +++ b/sysdeps/standalone/i386/start.S @@ -0,0 +1,323 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* entry.s + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + * + */ + + .data + .global _Do_Load_IDT + .global _Do_Load_GDT + + .text + .global start # GNU default entry point + .global _establish_stack + + .global _bsp_start + .global _load_segments + .global __exit + +start: + nop + cli # DISABLE INTERRUPTS!!! +# +# Load the segment registers +# +# NOTE: Upon return, gs will contain the segment descriptor for +# a segment which maps directly to all of physical memory. +# + jmp _load_segments # load board dependent segments + +# +# Set up the stack +# + +_establish_stack: + + movl $stack_end,%esp # set stack pointer + movl $stack_end,%ebp # set base pointer + +# +# Zero out the BSS segment +# +zero_bss: + cld # make direction flag count up + movl $_end,%ecx # find end of .bss + movl $_bss_start,%edi # edi = beginning of .bss + subl %edi,%ecx # ecx = size of .bss in bytes + shrl $2,%ecx # size of .bss in longs + xorl %eax,%eax # value to clear out memory + repne # while ecx != 0 + stosl # clear a long in the bss + +# +# Set the C heap information for malloc +# + movl $heap_size,___C_heap_size # set ___C_heap_size + movl $heap_memory,___C_heap_start # set ___C_heap_start + +# +# Copy the Global Descriptor Table to our space +# + + sgdt _Original_GDTR # save original GDT + movzwl _Original_GDTR_limit,%ecx # size of GDT in bytes; limit + # is 8192 entries * 8 bytes per + + # make ds:esi point to the original GDT + + movl _Original_GDTR_base,%esi + push %ds # save ds + movw %gs,%ax + movw %ax,%ds + + # make es:edi point to the new (our copy) GDT + movl $_Global_descriptor_table,%edi + + rep + movsb # copy the GDT (ds:esi -> es:edi) + + pop %ds # restore ds + + # Build and load new contents of GDTR + movw _Original_GDTR_limit,%ecx # set new limit + movw %cx,_New_GDTR_limit + + push $_Global_descriptor_table + push %es + call _Logical_to_physical + addl $6,%esp + movl %eax,_New_GDTR_base # set new base + + cmpb $0,_Do_Load_GDT # Should the new GDT be loaded? + je no_gdt_load # NO, then branch + lgdt _New_GDTR # load the new GDT +no_gdt_load: + +# +# Copy the Interrupt Descriptor Table to our space +# + + sidt _Original_IDTR # save original IDT + movzwl _Original_IDTR_limit,%ecx # size of IDT in bytes; limit + # is 256 entries * 8 bytes per + + + # make ds:esi point to the original IDT + movl _Original_IDTR_base,%esi + + push %ds # save ds + movw %gs,%ax + movw %ax,%ds + + # make es:edi point to the new (our copy) IDT + movl $_Interrupt_descriptor_table,%edi + + rep + movsb # copy the IDT (ds:esi -> es:edi) + pop %ds # restore ds + + # Build and load new contents of IDTR + movw _Original_IDTR_limit,%ecx # set new limit + movw %cx,_New_IDTR_limit + + push $_Interrupt_descriptor_table + push %es + call _Logical_to_physical + addl $6,%esp + movl %eax,_New_IDTR_base # set new base + + cmpb $0,_Do_Load_IDT # Should the new IDT be loaded? + je no_idt_load # NO, then branch + lidt _New_IDTR # load the new IDT +no_idt_load: + +# +# Initialize the i387. +# +# Using the NO WAIT form of the instruction insures that if +# it is not present the board will not lock up or get an +# exception. +# + + fninit # MUST USE NO-WAIT FORM + + call __Board_Initialize # initialize the board + + pushl $0 # envp = NULL + pushl $0 # argv = NULL + pushl $0 # argc = NULL + call ___libc_init # initialize the library and + # call main + addl $12,%esp + + pushl $0 # argc = NULL + call __exit # call the Board specific exit + addl $4,%esp + +# +# Clean up +# + + + .global _Bsp_cleanup + + .global _return_to_monitor + +_Bsp_cleanup: + cmpb $0,_Do_Load_IDT # Was the new IDT loaded? + je no_idt_restore # NO, then branch + lidt _Original_IDTR # restore the new IDT +no_idt_restore: + + cmpb $0,_Do_Load_GDT # Was the new GDT loaded? + je no_gdt_restore # NO, then branch + lgdt _Original_GDTR # restore the new GDT +no_gdt_restore: + jmp _return_to_monitor + +# +# void *Logical_to_physical( +# rtems_unsigned16 segment, +# void *address +# ); +# +# Returns thirty-two bit physical address for segment:address. +# + + .global _Logical_to_physical + +.set SEGMENT_ARG, 4 +.set ADDRESS_ARG, 8 + +_Logical_to_physical: + + xorl %eax,%eax # clear eax + movzwl SEGMENT_ARG(%esp),%ecx # ecx = segment value + movl $_Global_descriptor_table,%edx # edx = address of our GDT + addl %ecx,%edx # edx = address of desired entry + movb 7(%edx),%ah # ah = base 31:24 + movb 4(%edx),%al # al = base 23:16 + shll $16,%eax # move ax into correct bits + movw 2(%edx),%ax # ax = base 0:15 + movl ADDRESS_ARG(%esp),%ecx # ecx = address to convert + addl %eax,%ecx # ecx = physical address equivalent + movl %ecx,%eax # eax = ecx + ret + +# +# void *Physical_to_logical( +# rtems_unsigned16 segment, +# void *address +# ); +# +# Returns thirty-two bit physical address for segment:address. +# + + .global _Physical_to_logical + +#.set SEGMENT_ARG, 4 +#.set ADDRESS_ARG, 8 -- use sets from above + +_Physical_to_logical: + + xorl %eax,%eax # clear eax + movzwl SEGMENT_ARG(%esp),%ecx # ecx = segment value + movl $_Global_descriptor_table,%edx # edx = address of our GDT + addl %ecx,%edx # edx = address of desired entry + movb 7(%edx),%ah # ah = base 31:24 + movb 4(%edx),%al # al = base 23:16 + shll $16,%eax # move ax into correct bits + movw 2(%edx),%ax # ax = base 0:15 + movl ADDRESS_ARG(%esp),%ecx # ecx = address to convert + subl %eax,%ecx # ecx = logical address equivalent + movl %ecx,%eax # eax = ecx + ret + + +/* + * Data Declarations. Start with a macro which helps declare space. + */ + + .bss + +#define DECLARE_SPACE(_name,_space,_align) \ + .globl _name ; \ + .align _align ; \ +_name##: .space _space + +#define DECLARE_LABEL(_name) \ + .globl _name ; \ +_name##: + +#define DECLARE_PTR(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U32(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U16(_name) DECLARE_SPACE(_name,2,1) + +/* + * Require environment stuff + */ + +DECLARE_LABEL(_environ) +DECLARE_PTR(environ) + +DECLARE_LABEL(_errno) +DECLARE_U32(errno) + +/* + * Miscellaneous Variables used to restore the CPU state. + * + * Start with a macro to declare the space for the contents of + * a Descriptor Table register. + */ + +#define DECLARE_DTR_SPACE(_name) \ + .global _name ; \ + .align 4 ; \ +_name##: ; \ +_name##_limit: .space 2 ; \ +_name##_base: .space 4 + +DECLARE_SPACE(_Interrupt_descriptor_table,256*8,4) +DECLARE_SPACE(_Global_descriptor_table,8192*8,4) + +DECLARE_DTR_SPACE(_Original_IDTR) +DECLARE_DTR_SPACE(_New_IDTR) +DECLARE_DTR_SPACE(_Original_GDTR) +DECLARE_DTR_SPACE(_New_GDTR) + +DECLARE_SPACE(_Physical_base_of_ds,4,4) +DECLARE_SPACE(_Physical_base_of_cs,4,4) + +/* + * Stack Size and Space + */ + + .set stack_size, 0x20000 + +DECLARE_SPACE(stack_memory,stack_size,4) +DECLARE_LABEL(stack_end) + diff --git a/sysdeps/standalone/i960/Dist b/sysdeps/standalone/i960/Dist new file mode 100644 index 0000000000..e1747ef91e --- /dev/null +++ b/sysdeps/standalone/i960/Dist @@ -0,0 +1 @@ +i960ca.h diff --git a/sysdeps/standalone/i960/i960ca.h b/sysdeps/standalone/i960/i960ca.h new file mode 100644 index 0000000000..21012b4ccc --- /dev/null +++ b/sysdeps/standalone/i960/i960ca.h @@ -0,0 +1,207 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* i960ca.h + * + * This file contains macros which are used to access i80960CA + * registers which are not addressable by C. The functions + * in this file sould be useful to the developer of target + * specific code. + */ + +#ifndef i960ca_h__ +#define i960ca_h__ + +typedef unsigned char unsigned8; +typedef unsigned short unsigned16; +typedef unsigned int unsigned32; + +/* + * Intel i80960CA Processor Control Block + */ + +struct i80960ca_prcb { + unsigned32 *fault_tbl; /* fault table base address */ + struct i80960ca_ctltbl + *control_tbl; /* control table base address */ + unsigned32 initial_ac; /* AC register initial value */ + unsigned32 fault_config; /* fault configuration word */ + void *intr_tbl; /* interrupt table base address */ + void *sys_proc_tbl; /* system procedure table */ + /* base address */ + unsigned32 reserved; /* reserved */ + unsigned32 *intr_stack; /* interrupt stack pointer */ + unsigned32 ins_cache_cfg; /* instruction cache */ + /* configuration word */ + unsigned32 reg_cache_cfg; /* register cache */ + /* configuration word */ +}; + +/* + * Intel i80960CA Control Table + */ + +struct i80960ca_ctltbl { + /* Control Group 0 */ + unsigned32 ipb0; /* IP breakpoint 0 */ + unsigned32 ipb1; /* IP breakpoint 1 */ + unsigned32 dab0; /* data address breakpoint 0 */ + unsigned32 dab1; /* data address breakpoint 1 */ + /* Control Group 1 */ + unsigned32 imap0; /* interrupt map 0 */ + unsigned32 imap1; /* interrupt map 1 */ + unsigned32 imap2; /* interrupt map 2 */ + unsigned32 icon; /* interrupt control */ + /* Control Group 2 */ + unsigned32 mcon0; /* memory region 0 configuration */ + unsigned32 mcon1; /* memory region 1 configuration */ + unsigned32 mcon2; /* memory region 2 configuration */ + unsigned32 mcon3; /* memory region 3 configuration */ + /* Control Group 3 */ + unsigned32 mcon4; /* memory region 4 configuration */ + unsigned32 mcon5; /* memory region 5 configuration */ + unsigned32 mcon6; /* memory region 6 configuration */ + unsigned32 mcon7; /* memory region 7 configuration */ + /* Control Group 4 */ + unsigned32 mcon8; /* memory region 8 configuration */ + unsigned32 mcon9; /* memory region 9 configuration */ + unsigned32 mcon10; /* memory region 10 configuration */ + unsigned32 mcon11; /* memory region 11 configuration */ + /* Control Group 5 */ + unsigned32 mcon12; /* memory region 12 configuration */ + unsigned32 mcon13; /* memory region 13 configuration */ + unsigned32 mcon14; /* memory region 14 configuration */ + unsigned32 mcon15; /* memory region 15 configuration */ + /* Control Group 6 */ + unsigned32 bpcon; /* breakpoint control */ + unsigned32 tc; /* trace control */ + unsigned32 bcon; /* bus configuration control */ + unsigned32 reserved; /* reserved */ +}; + +#define disable_intr( oldlevel ) \ + { (oldlevel) = 0x1f0000; \ + asm volatile ( "modpc 0,%1,%1" \ + : "=d" ((oldlevel)) \ + : "0" ((oldlevel)) ); \ + } + +#define enable_intr( oldlevel ) \ + { unsigned32 _mask = 0x1f0000; \ + asm volatile ( "modpc 0,%0,%1" \ + : "=d" (_mask), "=d" ((oldlevel)) \ + : "0" (_mask), "1" ((oldlevel)) ); \ + } + +#define flash_intr( oldlevel ) \ + { unsigned32 _mask = 0x1f0000; \ + asm volatile ( "modpc 0,%0,%1 ; \ + mov %0,%1 ; \ + modpc 0,%0,%1" \ + : "=d" (_mask), "=d" ((oldlevel)) \ + : "0" (_mask), "1" ((oldlevel)) ); \ + } + +#define atomic_modify( mask, addr, prev ) \ + { register unsigned32 _mask = (mask); \ + register unsigned32 *_addr = (unsigned32 *)(addr); \ + asm volatile( "atmod %0,%1,%1" \ + : "=d" (_addr), "=d" (_mask) \ + : "0" (_addr), "1" (_mask) ); \ + (prev) = _mask; \ + } + +#define delay( microseconds ) \ + { register unsigned32 _delay=(microseconds); \ + register unsigned32 _tmp; \ + asm volatile( "delay0: \ + remo 3,31,%0 ; \ + cmpo 0,%0 ; \ + subo 1,%1,%1 ; \ + cmpobne.t 0,%1,delay0 " \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +#define enable_tracing() \ + { register unsigned32 _pc = 0x1; \ + asm volatile( "modpc 0,%0,%0" : "=d" (_pc) : "0" (_pc) ); \ + } + +#define unmask_intr( xint ) \ + { register unsigned32 _mask= (1<<(xint)); \ + asm volatile( "or sf1,%0,sf1" : "=d" (_mask) : "0" (_mask) ); \ + } + +#define mask_intr( xint ) \ + { register unsigned32 _mask= (1<<(xint)); \ + asm volatile( "andnot %0,sf1,sf1" : "=d" (_mask) : "0" (_mask) ); \ + } + +#define clear_intr( xint ) \ + { register unsigned32 _xint=(xint); \ + asm volatile( "loop_til_cleared: + clrbit %0,sf0,sf0 ; \ + bbs %0,sf0,loop_til_cleared" \ + : "=d" (_xint) : "0" (_xint) ); \ + } + +#define reload_ctl_group( group ) \ + { register int _cmd = ((group)|0x400) ; \ + asm volatile( "sysctl %0,%0,%0" : "=d" (_cmd) : "0" (_cmd) ); \ + } + +#define cause_intr( intr ) \ + { register int _intr = (intr); \ + asm volatile( "sysctl %0,%0,%0" : "=d" (_intr) : "0" (_intr) ); \ + } + +#define soft_reset( prcb ) \ + { register struct i80960ca_prcb *_prcb = (prcb); \ + register unsigned32 *_next=0; \ + register unsigned32 _cmd = 0x30000; \ + asm volatile( "lda next,%1; \ + sysctl %0,%1,%2; \ + next: mov g0,g0" \ + : "=d" (_cmd), "=d" (_next), "=d" (_prcb) \ + : "0" (_cmd), "1" (_next), "2" (_prcb) ); \ + } + +static inline unsigned32 pend_intrs() +{ register unsigned32 _intr=0; + asm volatile( "mov sf0,%0" : "=d" (_intr) : "0" (_intr) ); + return ( _intr ); +} + +static inline unsigned32 mask_intrs() +{ register unsigned32 _intr=0; + asm volatile( "mov sf1,%0" : "=d" (_intr) : "0" (_intr) ); + return( _intr ); +} + +static inline unsigned32 get_fp() +{ register unsigned32 _fp=0; + asm volatile( "mov fp,%0" : "=d" (_fp) : "0" (_fp) ); + return ( _fp ); +} + +#endif +/* end of include file */ diff --git a/sysdeps/standalone/i960/nindy960/Makefile b/sysdeps/standalone/i960/nindy960/Makefile new file mode 100644 index 0000000000..e6e65ea064 --- /dev/null +++ b/sysdeps/standalone/i960/nindy960/Makefile @@ -0,0 +1,23 @@ +# Copyright (C) 1993 Free Software Foundation, Inc. +# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), +# On-Line Applications Research Corporation. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + + +# The nindy960 support has only been tested on the following boards: +# +# + Cyclone CVME961 VMEbus single board computer. diff --git a/sysdeps/standalone/i960/nindy960/_exit.c b/sysdeps/standalone/i960/nindy960/_exit.c new file mode 100644 index 0000000000..33553a7a2c --- /dev/null +++ b/sysdeps/standalone/i960/nindy960/_exit.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdlib.h> + +/* The function `_exit' should take a status argument and simply + terminate program execution, using the low-order 8 bits of the + given integer as status. */ + +/* This returns control to Nindy. */ + +__NORETURN void +DEFUN(_exit, (status), int status) +{ + /* status is ignored */ + + asm volatile( "mov 0,g0; \ + fmark ; \ + syncf ; \ + .word 0xfeedface ; \ + bx start" : : ); + /* The constant 0xfeedface is a magic word for break which + * is defined by NINDY. The branch extended restarts the + * application if the user types "go". + */ +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(_exit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/standalone/i960/nindy960/brdinit.c b/sysdeps/standalone/i960/nindy960/brdinit.c new file mode 100644 index 0000000000..c16adcd390 --- /dev/null +++ b/sysdeps/standalone/i960/nindy960/brdinit.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "i960ca.h" + +/* _Board_Initialize() + +This routine initializes the board. + +NOTE: Only tested on a Cyclone CVME961 but should be OK on any i960ca board. */ + +void +DEFUN_VOID(_Board_Initialize) +{ + struct i80960ca_prcb *prcb; /* ptr to processor control block */ + struct i80960ca_ctltbl *ctl_tbl; /* ptr to control table */ + + static inline struct i80960ca_prcb *get_prcb() + { register struct i80960ca_prcb *_prcb = 0; + asm volatile( "calls 5; \ + mov g0,%0" \ + : "=d" (_prcb) \ + : "0" (_prcb) ); + return ( _prcb ); + } + + prcb = get_prcb(); + ctl_tbl = prcb->control_tbl; + + /* The following configures the data breakpoint (which must be set + * before this is executed) to break on writes only. + */ + + ctl_tbl->bpcon &= ~0x00cc0000; + reload_ctl_group( 6 ); + + /* bit 31 of the Register Cache Control can be set to + * enable an alternative caching algorithm. It does + * not appear to help our applications. + */ + + /* Configure Number of Register Caches */ + + prcb->reg_cache_cfg = 8; + soft_reset( prcb ); +} diff --git a/sysdeps/standalone/i960/nindy960/console.c b/sysdeps/standalone/i960/nindy960/console.c new file mode 100644 index 0000000000..821514458a --- /dev/null +++ b/sysdeps/standalone/i960/nindy960/console.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "i960ca.h" + +/* Console IO routines for a NINDY960 board. */ + +/* + * NINDY_IO( ... ) + * + * Interface to NINDY. + */ + +#define NINDY_INPUT 0 +#define NINDY_OUTPUT 1 + +void ___NINDY_IO_WRAPPER( void ) /* never called */ +{ + asm volatile ( " .text" ); + asm volatile ( " .align 4" ); + asm volatile ( " .globl _NINDY_IO" ); + asm volatile ( "_NINDY_IO:" ); + asm volatile ( " calls 0 /* call console routines */" ); + asm volatile ( " ret" ); +} + +/***** !!!! HOW DO I EXFUN NINDY_IO? !!!! *****/ + +/* _Console_Putc + +This routine transmits a character using NINDY. */ + +int +DEFUN( _Console_Putc, (ch), char ch ) +{ + NINDY_IO( NINDY_OUTPUT, ch ); + return( 0 ); +} + +/* _Console_Getc + +This routine reads a character from NINDY and returns it. */ + +int +DEFUN( _Console_Getc, (poll), int poll ) +{ + char ch; + + if ( poll ) { + /* I don't know how to poll with NINDY */ + return -1; + } else { + NINDY_IO( NINDY_INPUT, &ch ); + return ch; + } +} diff --git a/sysdeps/standalone/i960/start.S b/sysdeps/standalone/i960/start.S new file mode 100644 index 0000000000..c14449d3ff --- /dev/null +++ b/sysdeps/standalone/i960/start.S @@ -0,0 +1,137 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* entry.s + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + * + */ + + .text + .globl start # GNU960 default entry point + +start: + mov 3, r12 + modpc r12, r12, r12 # enable tracing/trace faults + mov g5, g5 # NOP + mov 0, g14 # initialize constant for C + + /* + * zero out uninitialized data area + */ +zerobss: + lda _end, r4 /* find end of .bss */ + lda _bss_start, r5 /* find beginning of .bss */ + ldconst 0, r6 + +loop: st r6, (r5) /* to zero out uninitialized */ + addo 4, r5, r5 /* data area */ + cmpobl r5, r4, loop /* loop until _end reached */ + + + lda heap_memory, r12 /* tell C lib where heap is */ + st r12,___C_heap_start + lda heap_size, r12 /* tell C lib how big heap is */ + st r12,___C_heap_size + lda stack_memory,r12 /* set up stack pointer: */ + mov r12, sp + mov 0, g14 /* initialize constant for C */ + + call init_frames + ret /* return to monitor */ + +init_frames: + ldconst 0x3b001000, g0 + ldconst 0x00009107, g1 + modac g1, g0, g0 /* set AC controls */ + + /* + * Call application mainline. + * Someday, real values of argc and argv will be set up. + * For now, they are set to 0. + */ + + callx __Board_Initialize /* Initialize the board */ + + ldconst 0,g0 + ldconst 0,g1 + ldconst 0,g2 + callx ___libc_init /* initialize the library and */ + /* call main */ + /* + * if we return from main, we have "fallen" off the end + * of the program, therefore status is 0 + * so move 0 to g0 (exit parameter) + */ + + mov 0, g0 + callx __exit + ret + + +/* + * Data Declarations. Start with a macro which helps declare space. + */ + +#define DECLARE_SPACE(_name,_space,_align) \ + .globl _name ; \ + .align _align ; \ +.comm _name##,_space + +#define DECLARE_LABEL(_name) \ + .globl _name ; \ +_name##: + +#define DECLARE_PTR(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U32(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U16(_name) DECLARE_SPACE(_name,2,1) + +/* + * Require environment stuff + */ + +DECLARE_LABEL(_environ) +DECLARE_PTR(environ) + +DECLARE_LABEL(_errno) +DECLARE_U32(errno) + +/* + * Stack Size and Space + */ + + .set stack_size, 0x20000 + +DECLARE_SPACE(stack_memory,stack_size,4) +DECLARE_LABEL(stack_end) + +/* + * Heap Size and Space + */ + + .set heap_size, 0x20000 + +DECLARE_SPACE(heap_memory,heap_size,4) +DECLARE_LABEL(heap_end) + diff --git a/sysdeps/standalone/m68k/m68020/Dist b/sysdeps/standalone/m68k/m68020/Dist new file mode 100644 index 0000000000..90b37b40eb --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/Dist @@ -0,0 +1 @@ +m68020.h diff --git a/sysdeps/standalone/m68k/m68020/m68020.h b/sysdeps/standalone/m68k/m68020/m68020.h new file mode 100644 index 0000000000..e9e6f7d875 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/m68020.h @@ -0,0 +1,88 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* m68020.h + * + * This file contains macros which are used to access MC68020 + * registers which are not addressable by C. These are + * useful when developing the board specific support. + */ + +#ifndef m68020_h__ +#define m68020_h__ + +typedef void ( *mc68020_isr )( void ); + +#define disable_intr( level ) \ + { (level) = 0; \ + asm volatile ( "movew %%sr,%0 ; \ + orw #0x0700,%%sr" \ + : "=d" ((level)) : "0" ((level)) ); \ + } + +#define enable_intr( level ) \ + { asm volatile ( "movew %0,%%sr " \ + : "=d" ((level)) : "0" ((level)) ); \ + } + +#define flash_intr( level ) \ + { asm volatile ( "movew %0,%%sr ; \ + orw #0x0700,%%sr" \ + : "=d" ((level)) : "0" ((level)) ); \ + } + +#define get_vbr( vbr ) \ + { (vbr) = 0; \ + asm volatile ( "movec %%vbr,%0 " \ + : "=a" (vbr) : "0" (vbr) ); \ + } + +#define set_vbr( vbr ) \ + { register mc68020_isr *_vbr= (mc68020_isr *)(vbr); \ + asm volatile ( "movec %0,%%vbr " \ + : "=a" (_vbr) : "0" (_vbr) ); \ + } + +#define enable_caching() \ + { register unsigned int _ctl=0x01; \ + asm volatile ( "movec %0,%%cacr" \ + : "=d" (_ctl) : "0" (_ctl) ); \ + } + +#define delay( microseconds ) \ + { register unsigned int _delay=(microseconds); \ + register unsigned int _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0 " \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +#define enable_tracing() +#define cause_intr( X ) +#define clear_intr( X ) + +extern mc68020_isr M68Kvec[]; /* vector table address */ + +#endif +/* end of include file */ diff --git a/sysdeps/standalone/m68k/m68020/mvme135/Implies b/sysdeps/standalone/m68k/m68020/mvme135/Implies new file mode 100644 index 0000000000..7142fe2985 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme135/Implies @@ -0,0 +1,2 @@ +# Motorola MVME135 and MVME136 are compatible. +standalone/m68k/m68020/mvme136 diff --git a/sysdeps/standalone/m68k/m68020/mvme136/Dist b/sysdeps/standalone/m68k/m68020/mvme136/Dist new file mode 100644 index 0000000000..97b90583eb --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/Dist @@ -0,0 +1 @@ +mvme136.ld diff --git a/sysdeps/standalone/m68k/m68020/mvme136/Makefile b/sysdeps/standalone/m68k/m68020/mvme136/Makefile new file mode 100644 index 0000000000..33f049c58c --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/Makefile @@ -0,0 +1,22 @@ +# Copyright (C) 1993 Free Software Foundation, Inc. +# Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), +# On-Line Applications Research Corporation. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq (bare,$(subdir)) +install-lib += mvme136.ld +endif diff --git a/sysdeps/standalone/m68k/m68020/mvme136/_exit.c b/sysdeps/standalone/m68k/m68020/mvme136/_exit.c new file mode 100644 index 0000000000..d13b4d9770 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/_exit.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdlib.h> +#include "m68020.h" + +/* Return control to 135Bug */ + +void +DEFUN_VOID(__exit_trap) +{ + set_vbr( 0 ); /* restore 135Bug vectors */ + asm volatile( "trap #15" ); /* trap to 135Bug */ + asm volatile( ".short 0x63" ); /* return to 135Bug (.RETURN) */ + asm volatile( "jmp main" ); /* restart program */ +} + +/* The function `_exit' should take a status argument and simply + terminate program execution, using the low-order 8 bits of the + given integer as status. */ + +__NORETURN void +DEFUN(_exit, (status), int status) +{ + /* status is ignored */ + + M68Kvec[ 45 ] = __exit_trap; /* install exit_trap handler */ + asm volatile( "trap #13" ); /* insures SUPV mode */ +} diff --git a/sysdeps/standalone/m68k/m68020/mvme136/brdinit.c b/sysdeps/standalone/m68k/m68020/mvme136/brdinit.c new file mode 100644 index 0000000000..0c4801a49b --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/brdinit.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "m68020.h" + +/* _Board_Initialize() + +This routine initializes the Motorola MVME135/MVME136. */ + +void +DEFUN_VOID(_Board_Initialize) +{ + mc68020_isr *monitors_vector_table; + int index; + + monitors_vector_table = (mc68020_isr *)0; /* 135Bug Vectors are at 0 */ + set_vbr( monitors_vector_table ); + + for ( index=2 ; index<=255 ; index++ ) + M68Kvec[ index ] = monitors_vector_table[ 32 ]; + + M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */ + M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */ + M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */ + M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */ + + set_vbr( &M68Kvec ); + + (*(unsigned char *)0xfffb0067) = 0x7f; /* make VME access round-robin */ + + enable_caching(); + +} diff --git a/sysdeps/standalone/m68k/m68020/mvme136/console.c b/sysdeps/standalone/m68k/m68020/mvme136/console.c new file mode 100644 index 0000000000..159070bab9 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/console.c @@ -0,0 +1,101 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> +#include "m68020.h" + +/* Console IO routines for a Motorola MVME135/MVME136 board. + +They currently use the B port. It should be possible to +use the A port by filling in the reset of the chip structure, +adding an ifdef for PORTA/PORTB, and switching the addresses, +and maybe the macroes based on the macro. */ + +/* M68681 DUART chip register structures and constants */ + +typedef struct { + volatile unsigned char fill1[ 5 ]; /* channel A regs ( not used ) */ + volatile unsigned char isr; /* interrupt status reg */ + volatile unsigned char fill2[ 2 ]; /* counter regs (not used) */ + volatile unsigned char mr1mr2b; /* MR1B and MR2B regs */ + volatile unsigned char srb; /* status reg channel B */ + volatile unsigned char fill3; /* do not access */ + volatile unsigned char rbb; /* receive buffer channel B */ + volatile unsigned char ivr; /* interrupt vector register */ +} r_m681_info; + +typedef struct { + volatile unsigned char fill1[ 4 ]; /* channel A regs (not used) */ + volatile unsigned char acr; /* auxillary control reg */ + volatile unsigned char imr; /* interrupt mask reg */ + volatile unsigned char fill2[ 2 ]; /* counter regs (not used) */ + volatile unsigned char mr1mr2b; /* MR1B and MR2B regs */ + volatile unsigned char csrb; /* clock select reg */ + volatile unsigned char crb; /* command reg */ + volatile unsigned char tbb; /* transmit buffer channel B */ + volatile unsigned char ivr; /* interrupt vector register */ +} w_m681_info; + +#define RD_M68681 ((r_m681_info *)0xfffb0040) /* ptr to the M68681 */ +#define WR_M68681 ((w_m681_info *)0xfffb0040) /* ptr to the M68681 */ +#define RXRDYB 0x01 /* status reg recv ready mask */ +#define TXRDYB 0x04 /* status reg trans ready mask */ + +/* _Console_Putc + +This routine transmits a character out the M68681. It supports +XON/XOFF flow control. */ + +#define XON 0x11 /* control-Q */ +#define XOFF 0x13 /* control-S */ + +int +DEFUN( _Console_Putc, (ch), char ch ) +{ + while ( ! (RD_M68681->srb & TXRDYB) ) ; + while ( RD_M68681->srb & RXRDYB ) /* must be an XOFF */ + if ( RD_M68681->rbb == XOFF ) + do { + while ( ! (RD_M68681->srb & RXRDYB) ) ; + } while ( RD_M68681->rbb != XON ); + + WR_M68681->tbb = ch; + return( 0 ); +} + +/* _Console_Getc + +This routine reads a character from the UART and returns it. */ + +int +DEFUN( _Console_Getc, (poll), int poll ) +{ + if ( poll ) { + if ( !(RD_M68681->srb & RXRDYB) ) + return -1; + else + return RD_M68681->rbb; + } else { + while ( !(RD_M68681->srb & RXRDYB) ); + return RD_M68681->rbb; + } +} diff --git a/sysdeps/standalone/m68k/m68020/mvme136/mvme136.ld b/sysdeps/standalone/m68k/m68020/mvme136/mvme136.ld new file mode 100644 index 0000000000..0f68330241 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/mvme136/mvme136.ld @@ -0,0 +1,62 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file contains directives for the GNU linker which are specific +to the Motorola MVME136/MVME135 boards. */ + +MEMORY + { + ram : org = 0x3000, l = 1M + } + +/* This value is also when the space is allocated. If you change +this one, change the other one!!! */ + +heap_size = 0x20000; + +SECTIONS +{ + .text 0x3000 : + { + text_start = ABSOLUTE(.) ; + *(.text) + etext = ALIGN( 0x10 ) ; + } + + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + *(.data) + edata = ALIGN( 0x10 ) ; + } + + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + heap_memory = .; + . += 0x20000; + end = . ; + _end = . ; + } +} diff --git a/sysdeps/standalone/m68k/m68020/start.S b/sysdeps/standalone/m68k/m68020/start.S new file mode 100644 index 0000000000..cbabf5bf07 --- /dev/null +++ b/sysdeps/standalone/m68k/m68020/start.S @@ -0,0 +1,155 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* entry.s + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + */ + + .text + .globl start | Default entry point + .globl _start | Default entry point + .globl M68Kvec | Vector Table + .globl _M68Kvec | Vector Table + +start: +_start: +M68Kvec: | standard location for vectors +_M68Kvec: | standard location for vectors + nop | for linkers with problem + | using location zero as entry + jmp around + .space 4088 | to avoid initial intr stack + | from 135BUG on MVME13? as entry + | and start code at 0x4000 +around: + move.w %sr,initial_sr | save initial values + movec %isp,%a0 + movel %a0,initial_isp + movec %usp,%a0 + movel %a0,initial_usp + movec %msp,%a0 + movel %a0,initial_msp + oriw #0x0700,%sr | INTERRUPTS OFF!!! + + + + | + | zero out uninitialized data area + | +zerobss: + moveal #end,%a0 | find end of .bss + moveal #_bss_start,%a1 | find beginning of .bss + movel #0,%d0 + +loop: movel #0,%a1@+ | to zero out uninitialized + cmpal %a0,%a1 + jlt loop | loop until _end reached + + movel #heap_size,__C_heap_size | set ___C_heap_size + movel #heap_memory,__C_heap_start | set ___C_heap_start + moveal #interrupt_stack_end,%a0 | set interrupt stack pointer + movec %a0,%isp + moveal #stack_end,%a0 | set master stack pointer + movec %a0,%msp + moveal #stack_end,%a6 | set base pointer + movw #0x3000,%sr | SUPV MODE,INTERRUPTS ON!!! + +#ifdef NEED_UNDERSCORES + jsr __Board_Initialize | initialize the board +#else + jsr _Board_Initialize | initialize the board +#endif + + move.l #0,%sp@- | envp = NULL + move.l #0,%sp@- | argv = NULL + move.l #0,%sp@- | argc = NULL +#ifdef NEED_UNDERSCORES + jsr ___libc_init | initialize the library and + | call main +#else + jsr __libc_init | initialize the library and + | call main +#endif + add.l #12,%sp + + move.l #0,%sp@- | argc = NULL + jsr __exit | call the Board specific exit + addq.l #4,%sp + + move.l initial_isp,%a0 | if __exit returns then we can + movec %a0,%isp | restore the initial values + move.l initial_usp,%a0 + movec %a0,%usp + move.l initial_msp,%a0 + movec %a0,%msp + move.w initial_sr,%sr + rts + + + .bss + +/* + * So initial stack registers and status register can be saved. + */ + +#define DECLARE_SPACE(_name,_space,_align) \ + .globl _name ; \ + .align _align ; \ +_name##: .space _space + +#define DECLARE_LABEL(_name) \ + .globl _name ; \ +_name##: + +#define DECLARE_PTR(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U32(_name) DECLARE_SPACE(_name,4,2) +#define DECLARE_U16(_name) DECLARE_SPACE(_name,2,1) + +DECLARE_U32(initial_isp) +DECLARE_U32(initial_msp) +DECLARE_U32(initial_usp) +DECLARE_U16(initial_sr) + +/* + * Require environment stuff + */ + +DECLARE_LABEL(_environ) +DECLARE_PTR(environ) + +DECLARE_LABEL(_errno) +DECLARE_U32(errno) + +/* + * Stack Size and Space + */ + + .set stack_size, 0x20000 + +DECLARE_SPACE(stack_memory,stack_size,4) +DECLARE_LABEL(stack_end) + +DECLARE_SPACE(interrupt_stack_memory,0x1000,4) +DECLARE_LABEL(interrupt_stack_end) diff --git a/sysdeps/standalone/open.c b/sysdeps/standalone/open.c new file mode 100644 index 0000000000..910e7933e7 --- /dev/null +++ b/sysdeps/standalone/open.c @@ -0,0 +1,122 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stddef.h> + +#include <stdio.h> +#include <stdio_lim.h> +#include <unistd.h> + +#define __DECLARE_FILE_DESCRIPTORS__ + +#include "filedesc.h" + +/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, + a third argument is the file protection. */ +int +DEFUN(__open, (file, oflag), CONST char *file AND int oflag DOTS) +{ + int mode; + int newfd; + int index; + + if (file == NULL) + { + errno = EINVAL; + return -1; + } + + if (oflag & O_CREAT) + { + va_list arg; + va_start(arg, oflag); + mode = va_arg(arg, int); + va_end(arg); + } + + /* + * Find an open slot. + */ + + newfd = -1; + + for ( index=0 ; index< FOPEN_MAX ; index++ ) + if ( !__FD_Table[ index ].in_use ) { + newfd = index; + break; + } + + if ( newfd == -1 ) { + errno = ENFILE; + return -1; + } + + /* + * Initialize the open slot + */ + + __FD_Table[ newfd ].in_use = 1; + __FD_Table[ newfd ].flags = oflag; + + return newfd; +} + +/* Initialization Code for Console I/O */ + +#ifdef HAVE_GNU_LD +static +#endif +void +DEFUN(__NONE_init_console_io, (argc, argv, envp), + int argc AND char **argv AND char **envp) +{ + int index; + + for ( index=0 ; index< FOPEN_MAX ; index++ ) + __FD_Table[ index ].in_use = 0; + + stdin = fopen( "", "r" ); + + stdout = fopen( "", "w" ); + + stderr = fopen( "", "w" ); + + /* + * Line buffer the standard input and output and use no buffering for + * standard error. + */ + + setvbuf( stdin, NULL, _IOLBF, BUFSIZ ); + setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); + setvbuf( stderr, NULL, _IONBF, BUFSIZ ); + + (void) &__NONE_init_console_io; /* Avoid "defined but not used" warning. */ +} + +#ifdef HAVE_GNU_LD +text_set_element (__libc_subinit, __NONE_init_console_io); +#endif + +weak_alias (__open, open) diff --git a/sysdeps/standalone/read.c b/sysdeps/standalone/read.c new file mode 100644 index 0000000000..284321d717 --- /dev/null +++ b/sysdeps/standalone/read.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +#include "filedesc.h" +#include <fcntl.h> +#include <standalone.h> + +/* Read NBYTES into BUF from FD. Return the number read or -1. */ +ssize_t +DEFUN(__read, (fd, buf, nbytes), + int fd AND PTR buf AND size_t nbytes) +{ + char *buffer = (char *) buf; + int data; + int poll; + + errno = 0; + + if (nbytes == 0) + return 0; + + if ( !__FD_Is_valid( fd ) || !__FD_Table[ fd ].in_use ) + { + errno = EBADF; + return -1; + } + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + if ( __FD_Table[ fd ].flags & O_WRONLY ) /* is it write only? */ + { + errno = EBADF; + return -1; + } + + /* If this is a non-blocking fd, then we want to poll the console. */ + + poll = ( __FD_Table[ fd ].flags & O_NONBLOCK ) ? 1 : 0; + + /* Read a single character. This is a cheap way to insure that the + upper layers get every character because _Console_Getc can't timeout + or otherwise know when to stop. */ + + + data = _Console_Getc(poll); + + if ( data == -1 ) /* if no data return */ + return -1; + + (void) _Console_Putc(data); /* echo the character */ + + if ( data == '\r' ) { /* translate CR -> CR/LF */ + (void) _Console_Putc('\n'); + data = '\n'; + } + + *buffer = data; + return 1; +} + +weak_alias (__read, read) diff --git a/sysdeps/standalone/standalone.h b/sysdeps/standalone/standalone.h new file mode 100644 index 0000000000..13d58f03e8 --- /dev/null +++ b/sysdeps/standalone/standalone.h @@ -0,0 +1,32 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STANDALONE_H +#define _STANDALONE_H + +#include <sys/cdefs.h> + +extern void _Board_Initialize __P ((void)); + +extern int _Console_Putc __P ((char c)); +extern int _Console_Getc __P ((int poll)); + +#endif diff --git a/sysdeps/standalone/stdio_lim.h b/sysdeps/standalone/stdio_lim.h new file mode 100644 index 0000000000..5552bc4325 --- /dev/null +++ b/sysdeps/standalone/stdio_lim.h @@ -0,0 +1,27 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define L_tmpnam 1 +#define TMPMAX 0 +#define L_ctermid 1 +#define L_cuserid 1 +#define FOPEN_MAX 16 +#define FILENAME_MAX 14 diff --git a/sysdeps/standalone/write.c b/sysdeps/standalone/write.c new file mode 100644 index 0000000000..f0ae3888f6 --- /dev/null +++ b/sysdeps/standalone/write.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Ported to standalone by Joel Sherrill jsherril@redstone-emh2.army.mil, + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +#include "filedesc.h" +#include <fcntl.h> +#include <standalone.h> + +/* Write NBYTES of BUF to FD. Return the number written, or -1. */ +ssize_t +DEFUN(__write, (fd, buf, nbytes), + int fd AND CONST PTR buf AND size_t nbytes) +{ + int count; + CONST char *data = buf; + + if (nbytes == 0) + return 0; + if ( !__FD_Is_valid( fd ) || !__FD_Table[ fd ].in_use ) + { + errno = EBADF; + return -1; + } + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + if ( !(__FD_Table[ fd ].flags & (O_WRONLY|O_RDWR)) ) /* is it writeable? */ + { + errno = EBADF; + return -1; + } + + /* + * All open file descriptors are mapped to the console. + */ + + for ( count=0 ; count != nbytes ; count++ ) { + if ( _Console_Putc(data[ count ]) == -1 ) + return -1; + if ( data[count] == '\n' && _Console_Putc('\r') == -1 ) + return -1; + } + + return count; +} + + +weak_alias (__write, write) diff --git a/sysdeps/stub/__longjmp.c b/sysdeps/stub/__longjmp.c new file mode 100644 index 0000000000..3cc4c4b5a0 --- /dev/null +++ b/sysdeps/stub/__longjmp.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <setjmp.h> + + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +__NORETURN +void +DEFUN(__longjmp, (env, val), CONST __jmp_buf env AND int val) +{ + if (val == 0) + val = 1; + + errno = ENOSYS; + /* No way to signal failure. */ +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(longjmp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/__math.h b/sysdeps/stub/__math.h new file mode 100644 index 0000000000..8159c89b94 --- /dev/null +++ b/sysdeps/stub/__math.h @@ -0,0 +1,6 @@ +/* This file should provide inline versions of math functions. + + Surround GCC-specific parts with #ifdef __GNUC__, and use `extern __inline'. + + This file should define __MATH_INLINES if functions are actually defined as + inlines. */ diff --git a/sysdeps/stub/_exit.c b/sysdeps/stub/_exit.c new file mode 100644 index 0000000000..d72a430150 --- /dev/null +++ b/sysdeps/stub/_exit.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <stdlib.h> + +/* The function `_exit' should take a status argument and simply + terminate program execution, using the low-order 8 bits of the + given integer as status. */ +__NORETURN void +DEFUN(_exit, (status), int status) +{ + status &= 0xff; + abort (); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(_exit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/accept.c b/sysdeps/stub/accept.c new file mode 100644 index 0000000000..d3a30c2844 --- /dev/null +++ b/sysdeps/stub/accept.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Await a connection on socket FD. + When a connection arrives, open a new socket to communicate with it, + set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting + peer and *ADDR_LEN to the address's actual length, and return the + new socket's descriptor, or -1 for errors. */ +int +DEFUN(accept, (fd, addr, addr_len), + int fd AND struct sockaddr *addr AND size_t *addr_len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(accept); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/access.c b/sysdeps/stub/access.c new file mode 100644 index 0000000000..06ddbb5c12 --- /dev/null +++ b/sysdeps/stub/access.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + +/* Test for access to FILE. */ +int +DEFUN(__access, (file, type), CONST char *file AND int type) +{ + if (file == NULL || (type & ~(R_OK|W_OK|X_OK|F_OK)) != 0) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} +stub_warning (access) + +weak_alias (__access, access) diff --git a/sysdeps/stub/acct.c b/sysdeps/stub/acct.c new file mode 100644 index 0000000000..1b547f3ec4 --- /dev/null +++ b/sysdeps/stub/acct.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Turn accounting on if NAME is an existing file. The system will then write + a record for each process as it terminates, to this file. If NAME is NULL, + turn accounting off. This call is restricted to the super-user. */ +int +DEFUN(acct, (name), CONST char *name) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (acct) diff --git a/sysdeps/stub/acos.c b/sysdeps/stub/acos.c new file mode 100644 index 0000000000..2ba05b5573 --- /dev/null +++ b/sysdeps/stub/acos.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the inverse cosine of X. */ +double +DEFUN(acos, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(acos); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/adjtime.c b/sysdeps/stub/adjtime.c new file mode 100644 index 0000000000..933e2ef7a3 --- /dev/null +++ b/sysdeps/stub/adjtime.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> + +/* Adjust the current time of day by the amount in DELTA. + If OLDDELTA is not NULL, it is filled in with the amount + of time adjustment remaining to be done from the last `__adjtime' call. + This call is restricted to the super-user. */ +int +DEFUN(__adjtime, (delta, olddelta), + CONST struct timeval *delta AND + struct timeval *olddelta) +{ + errno = ENOSYS; + return -1; +} +stub_warning (adjtime) + +weak_alias (__adjtime, adjtime) diff --git a/sysdeps/stub/alarm.c b/sysdeps/stub/alarm.c new file mode 100644 index 0000000000..861d624a03 --- /dev/null +++ b/sysdeps/stub/alarm.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Schedule an alarm. In SECONDS seconds, the process will get a SIGALRM. + If SECONDS is zero, any currently scheduled alarm will be cancelled. + The function returns the number of seconds remaining until the last + alarm scheduled would have signaled, or zero if there wasn't one. + There is no return value to indicate an error, but you can set `errno' + to 0 and check its value after calling `alarm', and this might tell you. + The signal may come late due to processor scheduling. */ +unsigned int +DEFUN(alarm, (seconds), unsigned int seconds) +{ + errno = ENOSYS; + return 0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(alarm); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/asin.c b/sysdeps/stub/asin.c new file mode 100644 index 0000000000..e645d48640 --- /dev/null +++ b/sysdeps/stub/asin.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the inverse sine of X. */ +double +DEFUN(asin, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(asin); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/asm-syntax.h b/sysdeps/stub/asm-syntax.h new file mode 100644 index 0000000000..a36150984f --- /dev/null +++ b/sysdeps/stub/asm-syntax.h @@ -0,0 +1,3 @@ +/* On some machines the mpn function from GNU MP use a file called + "asm-syntax.h" to define macros for assembly source code to use. */ + diff --git a/sysdeps/stub/atan2.c b/sysdeps/stub/atan2.c new file mode 100644 index 0000000000..c6ed43f625 --- /dev/null +++ b/sysdeps/stub/atan2.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return the inverse tangent of Y/X. */ +double +DEFUN(atan2, (y, x), double y AND double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(atan2); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/bind.c b/sysdeps/stub/bind.c new file mode 100644 index 0000000000..8ee50234a4 --- /dev/null +++ b/sysdeps/stub/bind.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Give the socket FD the local address ADDR (which is LEN bytes long). */ +int +DEFUN(bind, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(bind); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/brdinit.c b/sysdeps/stub/brdinit.c new file mode 100644 index 0000000000..50c92877f9 --- /dev/null +++ b/sysdeps/stub/brdinit.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> + +/* This file is only required when a "bare" board is configured. */ + +/* _Board_Initialize + +This routine normally performs board specific initialization. */ + +void +DEFUN_VOID(_Board_Initialize) +{ +} diff --git a/sysdeps/stub/brk.c b/sysdeps/stub/brk.c new file mode 100644 index 0000000000..3a48ea2e17 --- /dev/null +++ b/sysdeps/stub/brk.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> + +/* Set the end of the process's data space to ADDR. + Return 0 if successful, -1 if not. */ +int +DEFUN(__brk, (addr), PTR addr) +{ + errno = ENOSYS; + return -1; +} +stub_warning (brk) + +weak_alias (__brk, brk) diff --git a/sysdeps/stub/bsd-_setjmp.c b/sysdeps/stub/bsd-_setjmp.c new file mode 100644 index 0000000000..afb4908dd6 --- /dev/null +++ b/sysdeps/stub/bsd-_setjmp.c @@ -0,0 +1,33 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 0)'. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#undef setjmp + +/* This implementation in C will not usually work, because the call + really needs to be a tail-call so __sigsetjmp saves the state of + the caller, not the state of this `setjmp' frame which then + immediate unwinds. */ + +int +setjmp (jmp_buf env) +{ + return __sigsetjmp (env, 0); +} diff --git a/sysdeps/stub/bsd-setjmp.c b/sysdeps/stub/bsd-setjmp.c new file mode 100644 index 0000000000..80ff8b163f --- /dev/null +++ b/sysdeps/stub/bsd-setjmp.c @@ -0,0 +1,33 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#undef setjmp + +/* This implementation in C will not usually work, because the call + really needs to be a tail-call so __sigsetjmp saves the state of + the caller, not the state of this `setjmp' frame which then + immediate unwinds. */ + +int +setjmp (jmp_buf env) +{ + return __sigsetjmp (env, 1); +} diff --git a/sysdeps/stub/bytesex.h b/sysdeps/stub/bytesex.h new file mode 100644 index 0000000000..238a082bad --- /dev/null +++ b/sysdeps/stub/bytesex.h @@ -0,0 +1,9 @@ +/* This file should define __BYTE_ORDER as appropriate for the machine + in question. See string/endian.h for how to define it. + + If only the stub bytesex.h applies to a particular configuration, + bytesex.h is generated by running a program on the host machine. + So if cross-compiling to a machine with a different byte order, + the bytesex.h file for that machine must exist. */ + +#error Machine byte order unknown. diff --git a/sysdeps/stub/cbrt.c b/sysdeps/stub/cbrt.c new file mode 100644 index 0000000000..8835bead9b --- /dev/null +++ b/sysdeps/stub/cbrt.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the cube root of X. */ +double +DEFUN(cbrt, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(cbrt); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/chdir.c b/sysdeps/stub/chdir.c new file mode 100644 index 0000000000..f73c98142a --- /dev/null +++ b/sysdeps/stub/chdir.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + +/* Change the current directory to PATH. */ +int +DEFUN(__chdir, (path), CONST char *path) +{ + if (path == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} +stub_warning (chdir) + +weak_alias (__chdir, chdir) diff --git a/sysdeps/stub/chflags.c b/sysdeps/stub/chflags.c new file mode 100644 index 0000000000..a906e1b323 --- /dev/null +++ b/sysdeps/stub/chflags.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +/* Change the flags of FILE to FLAGS. */ +int +DEFUN(chflags, (file, flags), CONST char *file AND int flags) +{ + if (file == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + +stub_warning (chflags) diff --git a/sysdeps/stub/chmod.c b/sysdeps/stub/chmod.c new file mode 100644 index 0000000000..3259d3e121 --- /dev/null +++ b/sysdeps/stub/chmod.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> + +/* Change the protections of FILE to MODE. */ +int +DEFUN(__chmod, (file, mode), CONST char *file AND mode_t mode) +{ + if (file == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (chmod) + +weak_alias (__chmod, chmod) diff --git a/sysdeps/stub/chown.c b/sysdeps/stub/chown.c new file mode 100644 index 0000000000..e9db1ed86f --- /dev/null +++ b/sysdeps/stub/chown.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <sys/types.h> + +/* Change the owner and group of FILE. */ +int +DEFUN(__chown, (file, owner, group), + CONST char *file AND uid_t owner AND gid_t group) +{ + if (file == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (chown) + +weak_alias (__chown, chown) diff --git a/sysdeps/stub/chroot.c b/sysdeps/stub/chroot.c new file mode 100644 index 0000000000..637784accd --- /dev/null +++ b/sysdeps/stub/chroot.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Make PATH be the root directory (the starting point for absolute paths). + This call is restricted to the super-user. */ +int +DEFUN(chroot, (path), CONST char *path) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(chroot); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/clock.c b/sysdeps/stub/clock.c new file mode 100644 index 0000000000..151022db4e --- /dev/null +++ b/sysdeps/stub/clock.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/times.h> +#include <time.h> +#include <errno.h> + +/* Return the time used by the program so far (user time + system time). */ +clock_t +DEFUN_VOID(clock) +{ + errno = ENOSYS; + return (clock_t) -1; +} diff --git a/sysdeps/stub/close.c b/sysdeps/stub/close.c new file mode 100644 index 0000000000..efa80a708d --- /dev/null +++ b/sysdeps/stub/close.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Close the file descriptor FD. */ +int +DEFUN(__close, (fd), int fd) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (close) + +weak_alias (__close, close) diff --git a/sysdeps/stub/closedir.c b/sysdeps/stub/closedir.c new file mode 100644 index 0000000000..4595d47ecb --- /dev/null +++ b/sysdeps/stub/closedir.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +int +DEFUN(closedir, (dirp), DIR *dirp) +{ + errno = ENOSYS; + return(-1); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(closedir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/confstr.h b/sysdeps/stub/confstr.h new file mode 100644 index 0000000000..988ec88c0c --- /dev/null +++ b/sysdeps/stub/confstr.h @@ -0,0 +1,4 @@ +/* This file should define values for the strings returned by `confstr'. + If _NAME is passed to `confstr', define NAME. */ + +#define CS_PATH "" diff --git a/sysdeps/stub/connect.c b/sysdeps/stub/connect.c new file mode 100644 index 0000000000..5fae8dd23a --- /dev/null +++ b/sysdeps/stub/connect.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Open a connection on socket FD to peer at ADDR (which LEN bytes long). + For connectionless socket types, just set the default address to send to + and the only address from which to accept transmissions. + Return 0 on success, -1 for errors. */ +int +DEFUN(connect, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(connect); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/console.c b/sysdeps/stub/console.c new file mode 100644 index 0000000000..ca556110b5 --- /dev/null +++ b/sysdeps/stub/console.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> + +/* This file is only required when a "bare" board is configured. */ + +/* These routines provide console IO routines for your embedded target. */ + +int +DEFUN( _Console_Putc, (ch), char ch ) +{ + /* eat the character */ + + return( 0 ); +} + +int +DEFUN( _Console_Getc, (poll), int poll ) +{ + /* boring user, never types anything */ + return -1; +} diff --git a/sysdeps/stub/cos.c b/sysdeps/stub/cos.c new file mode 100644 index 0000000000..675855ce56 --- /dev/null +++ b/sysdeps/stub/cos.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the cosine of X. */ +double +DEFUN(cos, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(cos); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/cosh.c b/sysdeps/stub/cosh.c new file mode 100644 index 0000000000..ce1a0e241d --- /dev/null +++ b/sysdeps/stub/cosh.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the hyperbolic cosine of X. */ +double +DEFUN(cosh, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(cosh); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/ctermid.c b/sysdeps/stub/ctermid.c new file mode 100644 index 0000000000..0e74518fab --- /dev/null +++ b/sysdeps/stub/ctermid.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Return the name of the controlling terminal. + If S is not NULL, the name is copied into it (it should be at + least L_ctermid bytes long), otherwise a static buffer is used. */ +char * +DEFUN(ctermid, (s), char *s) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(ctermid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/cuserid.c b/sysdeps/stub/cuserid.c new file mode 100644 index 0000000000..e2c0eb77f1 --- /dev/null +++ b/sysdeps/stub/cuserid.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <errno.h> + +/* Return the username of the caller. + If S is not NULL, it points to a buffer of at least L_cuserid bytes + into which the name is copied; otherwise, a static buffer is used. */ +char * +DEFUN(cuserid, (s), char *s) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(cuserid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/dbl2mpn.c b/sysdeps/stub/dbl2mpn.c new file mode 100644 index 0000000000..a5bca3f3f1 --- /dev/null +++ b/sysdeps/stub/dbl2mpn.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Convert a `double' to a multi-precision integer representing the + significand scaled up by the highest possible number of significant bits + of fraction (DBL_MANT_DIG), and an integral power of two (MPN frexp). */ + +mp_size_t +__mpn_extract_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + double value) +{ +#error "__mpn_extract_double is not implemented for this floating point format" +} diff --git a/sysdeps/stub/defs.c b/sysdeps/stub/defs.c new file mode 100644 index 0000000000..56d1871e52 --- /dev/null +++ b/sysdeps/stub/defs.c @@ -0,0 +1,51 @@ +/* Definitions of global stdio data structures. + +Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +/* This file should define the following + variables as appropriate for the system. */ + +FILE *stdin, *stdout, *stderr; + +/* Pointer to the first stream in the list. */ +FILE *__stdio_head; + +/* This function MUST be in this file! + This is because we want _cleanup to go into the __libc_atexit set + when any stdio code is used (and to use any stdio code, one must reference + something defined in this file), and since only local symbols can be made + set elements, having the set element stab entry here and _cleanup elsewhere + loses; and having them both elsewhere loses because there is no reference + to cause _cleanup to be linked in. */ + +void +DEFUN_VOID(_cleanup) +{ + (void) fclose((FILE *) NULL); +} + + +#ifdef HAVE_GNU_LD +#include <gnu-stabs.h> + +text_set_element(__libc_atexit, _cleanup); +#endif diff --git a/sysdeps/stub/direct.h b/sysdeps/stub/direct.h new file mode 100644 index 0000000000..7205130571 --- /dev/null +++ b/sysdeps/stub/direct.h @@ -0,0 +1,5 @@ +/* This file should define `struct direct' on Unix systems. + This is the type of actual records in directory files. + See readdir.c. */ + +#error No struct dirent definition. diff --git a/sysdeps/stub/dirstream.h b/sysdeps/stub/dirstream.h new file mode 100644 index 0000000000..9a3d5a0f05 --- /dev/null +++ b/sysdeps/stub/dirstream.h @@ -0,0 +1,30 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + + +/* This file should define a typedef `DIR', the data type of directory + stream objects returned by `opendir'. */ + +#error "No system-dependent definition of `DIR'." + + +#endif /* dirstream.h */ diff --git a/sysdeps/stub/drem.c b/sysdeps/stub/drem.c new file mode 100644 index 0000000000..e4c7ceaa73 --- /dev/null +++ b/sysdeps/stub/drem.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the remainder of X/Y. */ +double +DEFUN(__drem, (x, y), + double x AND double y) +{ + errno = ENOSYS; + return 0.0; +} + +stub_warning (drem) +weak_alias (__drem, drem) diff --git a/sysdeps/stub/dup.c b/sysdeps/stub/dup.c new file mode 100644 index 0000000000..f15a1bef3b --- /dev/null +++ b/sysdeps/stub/dup.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +/* Duplicate FD, returning a new file descriptor open on the same file. */ +int +DEFUN(__dup, (fd), int fd) +{ + errno = ENOSYS; + return -1; +} +stub_warning (dup) + +weak_alias (__dup, dup) diff --git a/sysdeps/stub/dup2.c b/sysdeps/stub/dup2.c new file mode 100644 index 0000000000..a0f7aad47d --- /dev/null +++ b/sysdeps/stub/dup2.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + + +/* Duplicate FD to FD2, closing the old FD2 and making FD2 be + open the same file as FD is. Return FD2 or -1. */ +int +DEFUN(__dup2, (fd, fd2), int fd AND int fd2) +{ + if (fd < 0 || fd2 < 0) + { + errno = EBADF; + return -1; + } + + if (fd == fd2) + /* No way to check that they are valid. */ + return fd2; + + errno = ENOSYS; + return -1; +} +stub_warning (dup2) + +weak_alias (__dup2, dup2) diff --git a/sysdeps/stub/errlist.c b/sysdeps/stub/errlist.c new file mode 100644 index 0000000000..adc3129748 --- /dev/null +++ b/sysdeps/stub/errlist.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> + +#ifndef HAVE_GNU_LD +#define _sys_errlist sys_errlist +#define _sys_nerr sys_nerr +#endif + +CONST char *CONST _sys_errlist[] = + { + "Error 0", /* 0 */ + "Argument out of function's domain", /* 1 = EDOM */ + "Result out of range", /* 2 = ERANGE */ + "Operation not implemented", /* 3 = ENOSYS */ + "Invalid argument", /* 4 = EINVAL */ + "Illegal seek", /* 5 = ESPIPE */ + "Bad file descriptor", /* 6 = EBADF */ + "Cannot allocate memory", /* 7 = ENOMEM */ + "Permission denied", /* 8 = EACCES */ + "Too many open files in system", /* 9 = ENFILE */ + "Too many open files", /* 10 = EMFILE */ + }; + +CONST int _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]); diff --git a/sysdeps/stub/errnos.h b/sysdeps/stub/errnos.h new file mode 100644 index 0000000000..11708086bf --- /dev/null +++ b/sysdeps/stub/errnos.h @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This file defines the `errno' constants. */ + +#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath)) +#undef __need_Emath +#define __Emath_defined 1 + +#define EDOM 1 +#define ERANGE 2 +#endif + +#ifdef _ERRNO_H +#define ENOSYS 3 +#define EINVAL 4 +#define ESPIPE 5 +#define EBADF 6 +#define ENOMEM 7 +#define EACCES 8 +#define ENFILE 9 +#define EMFILE 10 +#endif diff --git a/sysdeps/stub/exc2signal.c b/sysdeps/stub/exc2signal.c new file mode 100644 index 0000000000..1c4c9ac5ec --- /dev/null +++ b/sysdeps/stub/exc2signal.c @@ -0,0 +1,68 @@ +/* Translate Mach exception codes into signal numbers. Stub version. +Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> + +/* Translate the Mach exception codes, as received in an `exception_raise' RPC, + into a signal number and signal subcode. */ + +void +_hurd_exception2signal (int exception, int code, int subcode, + int *signo, int *sigcode, int *error) +{ + *error = 0; + + switch (exception) + { + default: + *signo = SIGIOT; + *sigcode = exception; + break; + + case EXC_BAD_ACCESS: + if (code == KERN_PROTECTION_FAILURE) + *signo = SIGSEGV; + else + *signo = SIGBUS; + *sigcode = subcode; + *error = code; + break; + + case EXC_BAD_INSTRUCTION: + *signo = SIGILL; + *sigcode = 0; + break; + + case EXC_ARITHMETIC: + *signo = SIGFPE; + *sigcode = 0; + break; + + case EXC_EMULATION: + case EXC_SOFTWARE: + *signo = SIGEMT; + *sigcode = 0; + break; + + case EXC_BREAKPOINT: + *signo = SIGTRAP; + *sigcode = 0; + break; + } +} diff --git a/sysdeps/stub/execve.c b/sysdeps/stub/execve.c new file mode 100644 index 0000000000..680d23757e --- /dev/null +++ b/sysdeps/stub/execve.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Replace the current process, executing PATH with arguments ARGV and + environment ENVP. ARGV and ENVP are terminated by NULL pointers. */ +int +DEFUN(__execve, (path, argv, envp), + CONST char *path AND + char *CONST argv[] AND char *CONST envp[]) +{ + if (path == NULL || argv == NULL || envp == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (execve) + +weak_alias (__execve, execve) diff --git a/sysdeps/stub/exp.c b/sysdeps/stub/exp.c new file mode 100644 index 0000000000..ba9e578ac5 --- /dev/null +++ b/sysdeps/stub/exp.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return e to the X. */ +double +DEFUN(exp, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(exp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/fchdir.c b/sysdeps/stub/fchdir.c new file mode 100644 index 0000000000..ba36ed626a --- /dev/null +++ b/sysdeps/stub/fchdir.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + +/* Change the current directory to FD. */ +int +DEFUN(fchdir, (fd), int fd) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (fchdir) diff --git a/sysdeps/stub/fchflags.c b/sysdeps/stub/fchflags.c new file mode 100644 index 0000000000..e9640d2375 --- /dev/null +++ b/sysdeps/stub/fchflags.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +/* Change the flags of the file FD refers to to FLAGS. */ +int +DEFUN(fchflags, (fd, flags), int fd AND int flags) +{ + if (fd < 0) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + +stub_warning (fchflags) diff --git a/sysdeps/stub/fchmod.c b/sysdeps/stub/fchmod.c new file mode 100644 index 0000000000..43d4919c9b --- /dev/null +++ b/sysdeps/stub/fchmod.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> + +/* Change the protections of the file FD refers to to MODE. */ +int +DEFUN(__fchmod, (fd, mode), int fd AND mode_t mode) +{ + if (fd < 0) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (fchmod) + +weak_alias (__fchmod, fchmod) diff --git a/sysdeps/stub/fchown.c b/sysdeps/stub/fchown.c new file mode 100644 index 0000000000..4af1d0d429 --- /dev/null +++ b/sysdeps/stub/fchown.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <sys/types.h> + +/* Change the owner and group of the file referred to by FD. */ +int +DEFUN(__fchown, (fd, owner, group), + int fd AND uid_t owner AND gid_t group) +{ + if (fd < 0) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (fchown) + +weak_alias (__fchown, fchown) diff --git a/sysdeps/stub/fcntl.c b/sysdeps/stub/fcntl.c new file mode 100644 index 0000000000..e35021a496 --- /dev/null +++ b/sysdeps/stub/fcntl.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> + +/* Perform file control operations on FD. */ +int +DEFUN(__fcntl, (fd, cmd), int fd AND int cmd DOTS) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (fcntl) + +weak_alias (__fcntl, fcntl) diff --git a/sysdeps/stub/fcntlbits.h b/sysdeps/stub/fcntlbits.h new file mode 100644 index 0000000000..236520195a --- /dev/null +++ b/sysdeps/stub/fcntlbits.h @@ -0,0 +1,88 @@ +/* O_*, F_*, FD_* bit values for stub configuration. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These values should be changed as appropriate for your system. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0200 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0800 /* Fail if file already exists. */ +#define O_TRUNC 0x0400 /* Truncate file to zero length. */ +#define O_NOCTTY 0x0100 /* Don't assign a controlling terminal. */ + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */ + +#ifdef __USE_BSD +#define O_NDELAY O_NONBLOCK +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info. */ +#define F_SETLKW 9 /* Set record locking info, wait. */ + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/stub/fdopen.c b/sysdeps/stub/fdopen.c new file mode 100644 index 0000000000..9865f42b9b --- /dev/null +++ b/sysdeps/stub/fdopen.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +/* Open a new stream on a given system file descriptor. */ +FILE * +DEFUN(fdopen, (fd, mode), int fd AND CONST char *mode) +{ + errno = ENOSYS; + return NULL; +} diff --git a/sysdeps/stub/fexecve.c b/sysdeps/stub/fexecve.c new file mode 100644 index 0000000000..c0990f510c --- /dev/null +++ b/sysdeps/stub/fexecve.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Execute the file FD refers to, overlaying the running program image. + ARGV and ENVP are passed to the new program, as for `execve'. */ +int +DEFUN(fexecve, (fd, argv, envp), + int fd AND + char *CONST argv[] AND char *CONST envp[]) +{ + if (fd < 0 || argv == NULL || envp == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + +stub_warning (fexecve) diff --git a/sysdeps/stub/flock.c b/sysdeps/stub/flock.c new file mode 100644 index 0000000000..6855cd4a3e --- /dev/null +++ b/sysdeps/stub/flock.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/file.h> + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +int +DEFUN(__flock, (fd, operation), + int fd AND int operation) +{ + errno = ENOSYS; + return -1; +} + +weak_alias (__flock, flock) diff --git a/sysdeps/stub/fmod.c b/sysdeps/stub/fmod.c new file mode 100644 index 0000000000..e2cdc19df7 --- /dev/null +++ b/sysdeps/stub/fmod.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the floating-point modulo remainder of X/Y. */ +double +DEFUN(fmod, (x, y), double x AND double y) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(fmod); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/fork.c b/sysdeps/stub/fork.c new file mode 100644 index 0000000000..0b0b63afd0 --- /dev/null +++ b/sysdeps/stub/fork.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Clone the calling process, creating an exact copy. + Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ +int +DEFUN_VOID(__fork) +{ + errno = ENOSYS; + return -1; +} +stub_warning (fork) + +weak_alias (__fork, fork) diff --git a/sysdeps/stub/fpathconf.c b/sysdeps/stub/fpathconf.c new file mode 100644 index 0000000000..fe121ba3c2 --- /dev/null +++ b/sysdeps/stub/fpathconf.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Get file-specific information about descriptor FD. */ +long int +DEFUN(__fpathconf, (fd, name), int fd AND int name) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + switch (name) + { + default: + errno = EINVAL; + return -1; + + case _PC_LINK_MAX: + case _PC_MAX_CANON: + case _PC_MAX_INPUT: + case _PC_NAME_MAX: + case _PC_PATH_MAX: + case _PC_PIPE_BUF: + case _PC_CHOWN_RESTRICTED: + case _PC_NO_TRUNC: + case _PC_VDISABLE: + break; + } + + errno = ENOSYS; + return -1; +} + +weak_alias (__fpathconf, fpathconf) diff --git a/sysdeps/stub/frexp.c b/sysdeps/stub/frexp.c new file mode 100644 index 0000000000..f1c3693b95 --- /dev/null +++ b/sysdeps/stub/frexp.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Break VALUE into a normalized fraction and an integral power of 2. */ +double +DEFUN(frexp, (value, exp), double value AND int *exp) +{ + errno = ENOSYS; + *exp = 0; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(frexp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/fstat.c b/sysdeps/stub/fstat.c new file mode 100644 index 0000000000..49981bbd52 --- /dev/null +++ b/sysdeps/stub/fstat.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +/* Get information about the file descriptor FD in BUF. */ +int +DEFUN(__fstat, (fd, buf), int fd AND struct stat *buf) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + else if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (fstat) + +weak_alias (__fstat, fstat) diff --git a/sysdeps/stub/fsync.c b/sysdeps/stub/fsync.c new file mode 100644 index 0000000000..f8c92bf7ef --- /dev/null +++ b/sysdeps/stub/fsync.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Make all changes done to FD actually appear on disk. */ +int +DEFUN(fsync, (fd), int fd) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(fsync); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/ftruncate.c b/sysdeps/stub/ftruncate.c new file mode 100644 index 0000000000..8b2d4665a9 --- /dev/null +++ b/sysdeps/stub/ftruncate.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +DEFUN(ftruncate, (fd, length), + int fd AND off_t length) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/getcwd.c b/sysdeps/stub/getcwd.c new file mode 100644 index 0000000000..16abaeee21 --- /dev/null +++ b/sysdeps/stub/getcwd.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +char * +DEFUN(getcwd, (buf, size), char *buf AND size_t size) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getcwd); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getdents.c b/sysdeps/stub/getdents.c new file mode 100644 index 0000000000..8cf890a4aa --- /dev/null +++ b/sysdeps/stub/getdents.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> + +int +DEFUN(__getdirentries, (fd, buf, nbytes, basep), + int fd AND char *buf AND size_t nbytes AND off_t *basep) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getdirentries) + +weak_alias (__getdirentries, getdirentries) diff --git a/sysdeps/stub/getdomain.c b/sysdeps/stub/getdomain.c new file mode 100644 index 0000000000..c2159df012 --- /dev/null +++ b/sysdeps/stub/getdomain.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Put the name of the current YP domain in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +int +DEFUN(getdomainname, (name, len), + char *name AND size_t len) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (getdomainname) diff --git a/sysdeps/stub/getdtsz.c b/sysdeps/stub/getdtsz.c new file mode 100644 index 0000000000..e9c9b61ba6 --- /dev/null +++ b/sysdeps/stub/getdtsz.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Return the maximum number of file descriptors + the current process could possibly have. */ +int +DEFUN_VOID(__getdtablesize) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getdtablesize) + +weak_alias (__getdtablesize, getdtablesize) diff --git a/sysdeps/stub/getegid.c b/sysdeps/stub/getegid.c new file mode 100644 index 0000000000..6e4e611e59 --- /dev/null +++ b/sysdeps/stub/getegid.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Get the effective group ID of the calling process. */ +__gid_t +DEFUN_VOID(__getegid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getegid) + +weak_alias (__getegid, getegid) diff --git a/sysdeps/stub/getenv.c b/sysdeps/stub/getenv.c new file mode 100644 index 0000000000..2f5dd99380 --- /dev/null +++ b/sysdeps/stub/getenv.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> + +/* Return the value of the environment variable NAME. */ +char * +DEFUN(getenv, (name), CONST char *name) +{ + errno = ENOSYS; + return(NULL); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getenv); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/geteuid.c b/sysdeps/stub/geteuid.c new file mode 100644 index 0000000000..f5f437576c --- /dev/null +++ b/sysdeps/stub/geteuid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Get the effective user ID of the calling process. */ +__uid_t +DEFUN_VOID(__geteuid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (geteuid) + +weak_alias (__geteuid, geteuid) diff --git a/sysdeps/stub/getgid.c b/sysdeps/stub/getgid.c new file mode 100644 index 0000000000..f2bfa7696a --- /dev/null +++ b/sysdeps/stub/getgid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Get the real group ID of the calling process. */ +gid_t +DEFUN_VOID(__getgid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getgid) + +weak_alias (__getgid, getgid) diff --git a/sysdeps/stub/getgroups.c b/sysdeps/stub/getgroups.c new file mode 100644 index 0000000000..f98d966346 --- /dev/null +++ b/sysdeps/stub/getgroups.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <sys/types.h> +#include <limits.h> + + +/* If SIZE is zero, return the number of supplementary groups + the calling process is in. Otherwise, fill in the group IDs + of its supplementary groups in LIST and return the number written. */ +int +DEFUN(__getgroups, (size, list), int size AND gid_t *list) +{ +#if defined (NGROUPS_MAX) && NGROUPS_MAX == 0 + /* The system has no supplementary groups. */ + return 0; +#endif + + errno = ENOSYS; + return -1; +} + +#if defined (HAVE_GNU_LD) && !(defined (NGROUPS_MAX) && NGROUPS_MAX == 0) +stub_warning (getgroups); +#endif + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/stub/gethostid.c b/sysdeps/stub/gethostid.c new file mode 100644 index 0000000000..74a3d66438 --- /dev/null +++ b/sysdeps/stub/gethostid.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Return the current machine's Internet number. */ +long int +DEFUN_VOID(gethostid) +{ + errno = ENOSYS; + return -1L; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(gethostid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/gethostname.c b/sysdeps/stub/gethostname.c new file mode 100644 index 0000000000..1cf3c7bf26 --- /dev/null +++ b/sysdeps/stub/gethostname.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Put the name of the current host in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +int +DEFUN(__gethostname, (name, len), + char *name AND size_t len) +{ + errno = ENOSYS; + return -1; +} +stub_warning (gethostname) + +weak_alias (__gethostname, gethostname) diff --git a/sysdeps/stub/getitimer.c b/sysdeps/stub/getitimer.c new file mode 100644 index 0000000000..75b5488e0e --- /dev/null +++ b/sysdeps/stub/getitimer.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/time.h> + +/* Set *VALUE to the current setting of timer WHICH. + Return 0 on success, -1 on errors. */ +int +DEFUN(__getitimer, (which, value), + enum __itimer_which which AND struct itimerval *value) +{ + if (value == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (getitimer) + +weak_alias (__getitimer, getitimer) diff --git a/sysdeps/stub/getlogin.c b/sysdeps/stub/getlogin.c new file mode 100644 index 0000000000..bd48eb7206 --- /dev/null +++ b/sysdeps/stub/getlogin.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <unistd.h> + +/* Return the login name of the user, or NULL if it can't be determined. + The returned pointer, if not NULL, is good only until the next call. */ +char * +DEFUN_VOID(getlogin) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getlogin); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getpagesize.c b/sysdeps/stub/getpagesize.c new file mode 100644 index 0000000000..1ee441513d --- /dev/null +++ b/sysdeps/stub/getpagesize.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> + +/* Return the system page size. */ +size_t +DEFUN_VOID(__getpagesize) +{ + errno = ENOSYS; + return 0; +} +stub_warning (getpagesize) + +weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/stub/getpeername.c b/sysdeps/stub/getpeername.c new file mode 100644 index 0000000000..ca9cf3539c --- /dev/null +++ b/sysdeps/stub/getpeername.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Put the address of the peer connected to socket FD into *ADDR + (which is *LEN bytes long), and its actual length into *LEN. */ +int +DEFUN(getpeername, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t *len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getpeername); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getpgid.c b/sysdeps/stub/getpgid.c new file mode 100644 index 0000000000..44efc12c10 --- /dev/null +++ b/sysdeps/stub/getpgid.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Get the process group ID of process PID. */ +int +DEFUN(__getpgid, (pid), pid_t pid) +{ + return pid; +} +weak_alias (__getpgid, getpgid) + +stub_warning (getpgid) diff --git a/sysdeps/stub/getpid.c b/sysdeps/stub/getpid.c new file mode 100644 index 0000000000..270c90947b --- /dev/null +++ b/sysdeps/stub/getpid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Get the process ID of the calling process. */ +int +DEFUN_VOID(__getpid) +{ + errno = ENOSYS; + return(-1); +} +stub_warning (getpid) + +weak_alias (__getpid, getpid) diff --git a/sysdeps/stub/getppid.c b/sysdeps/stub/getppid.c new file mode 100644 index 0000000000..d6547c709b --- /dev/null +++ b/sysdeps/stub/getppid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Get the parent process ID of the calling process. */ +int +DEFUN_VOID(__getppid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getppid) + +weak_alias (__getppid, getppid) diff --git a/sysdeps/stub/getpriority.c b/sysdeps/stub/getpriority.c new file mode 100644 index 0000000000..3c0404478e --- /dev/null +++ b/sysdeps/stub/getpriority.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/resource.h> + +/* Return the highest priority of any process specified by WHICH and WHO + (see <sys/resource.h>); if WHO is zero, the current process, process group, + or user (as specified by WHO) is used. A lower priority number means higher + priority. Priorities range from PRIO_MIN to PRIO_MAX. */ +int +DEFUN(getpriority, (which, who), + enum __priority_which which AND int who) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getpriority); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getrlimit.c b/sysdeps/stub/getrlimit.c new file mode 100644 index 0000000000..ed6f04f47a --- /dev/null +++ b/sysdeps/stub/getrlimit.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> + +/* Put the soft and hard limits for RESOURCE in *RLIMITS. + Returns 0 if successful, -1 if not (and sets errno). */ +int +DEFUN(getrlimit, (resource, rlimits), + enum __rlimit_resource resource AND struct rlimit *rlimits) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getrlimit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getrusage.c b/sysdeps/stub/getrusage.c new file mode 100644 index 0000000000..6417c8d9d1 --- /dev/null +++ b/sysdeps/stub/getrusage.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> + +/* Return resource usage information on process indicated by WHO + and put it in *USAGE. Returns 0 for success, -1 for failure. */ +int +DEFUN(__getrusage, (who, usage), + enum __rusage_who who AND struct rusage *usage) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getrusage) + +weak_alias (__getrusage, getrusage) diff --git a/sysdeps/stub/getsockname.c b/sysdeps/stub/getsockname.c new file mode 100644 index 0000000000..93a5f8e008 --- /dev/null +++ b/sysdeps/stub/getsockname.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Put the local address of FD into *ADDR and its length in *LEN. */ +int +DEFUN(getsockname, (fd, addr, len), + int fd AND struct sockaddr *addr AND size_t *len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getsockname); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/getsockopt.c b/sysdeps/stub/getsockopt.c new file mode 100644 index 0000000000..aa71e72193 --- /dev/null +++ b/sysdeps/stub/getsockopt.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL + into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's + actual length. Returns 0 on success, -1 for errors. */ +int +DEFUN(getsockopt, (fd, level, optname, optval, optlen), + int fd AND int level AND int optname AND + PTR optval AND size_t *optlen) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(getsockopt); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/gettimeofday.c b/sysdeps/stub/gettimeofday.c new file mode 100644 index 0000000000..74e4619df9 --- /dev/null +++ b/sysdeps/stub/gettimeofday.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. */ +int +DEFUN(__gettimeofday, (tv, tz), + struct timeval *tv AND struct timezone *tz) +{ + errno = ENOSYS; + return -1; +} +stub_warning (gettimeofday) + +weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/stub/getuid.c b/sysdeps/stub/getuid.c new file mode 100644 index 0000000000..ebdd2688bc --- /dev/null +++ b/sysdeps/stub/getuid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Get the real user ID of the calling process. */ +uid_t +DEFUN_VOID(__getuid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (getuid) + +weak_alias (__getuid, getuid) diff --git a/sysdeps/stub/gtty.c b/sysdeps/stub/gtty.c new file mode 100644 index 0000000000..5695d69a2d --- /dev/null +++ b/sysdeps/stub/gtty.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sgtty.h> +#include <stddef.h> + +/* Fill in *PARAMS with terminal parameters associated with FD. */ +int +DEFUN(gtty, (fd, params), + int fd AND struct sgttyb *params) +{ + if (params == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/huge_val.h b/sysdeps/stub/huge_val.h new file mode 100644 index 0000000000..5c5d379dff --- /dev/null +++ b/sysdeps/stub/huge_val.h @@ -0,0 +1,27 @@ +/* Stub `HUGE_VAL' constant. + Used by <stdlib.h> and <math.h> functions for overflow. + +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HUGE_VAL_H +#define _HUGE_VAL_H 1 + +#define HUGE_VAL 1e37 + +#endif /* huge_val.h */ diff --git a/sysdeps/stub/init-fault.c b/sysdeps/stub/init-fault.c new file mode 100644 index 0000000000..1ba468078f --- /dev/null +++ b/sysdeps/stub/init-fault.c @@ -0,0 +1,38 @@ +/* Set up a thread_state for proc_handle_exceptions. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <mach/thread_status.h> + +static char fault_stack[32]; +static volatile void +faulted (void) +{ + __longjmp (_hurd_sigthread_fault_env, 1); +} + +void +_hurd_initialize_fault_recovery_state (void *state) +{ + struct hurd_thread_state *ts = state; + memset (ts, 0, sizeof (*ts)); + /* Point the SP in TS at the fault stack, + and set the PC to run `faulted' (above). */ + #error "Need to write sysdeps/mach/hurd/MACHINE/init_fault.c" +} diff --git a/sysdeps/stub/init-posix.c b/sysdeps/stub/init-posix.c new file mode 100644 index 0000000000..4673c14cab --- /dev/null +++ b/sysdeps/stub/init-posix.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#ifndef HAVE_GNU_LD + +void +DEFUN_VOID(__init_posix) +{ + return; +} + +#endif + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__init_posix); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/ioctl.c b/sysdeps/stub/ioctl.c new file mode 100644 index 0000000000..579ddab9b7 --- /dev/null +++ b/sysdeps/stub/ioctl.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/ioctl.h> + +/* Perform the I/O control operation specified by REQUEST on FD. + The actual type and use of ARG and the return value depend on REQUEST. */ +int +DEFUN(__ioctl, (fd, request), + int fd AND unsigned long int request DOTS) +{ + errno = ENOSYS; + return -1; +} +stub_warning (ioctl) + +weak_alias (__ioctl, ioctl) diff --git a/sysdeps/stub/ioctls.h b/sysdeps/stub/ioctls.h new file mode 100644 index 0000000000..3b6178bfae --- /dev/null +++ b/sysdeps/stub/ioctls.h @@ -0,0 +1 @@ +/* This space intentionally left blank. */ diff --git a/sysdeps/stub/isatty.c b/sysdeps/stub/isatty.c new file mode 100644 index 0000000000..05477f8cc8 --- /dev/null +++ b/sysdeps/stub/isatty.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Return 1 if FD is a terminal, 0 if not. */ +int +DEFUN(__isatty, (fd), int fd) +{ + errno = ENOSYS; + return -1; +} + +weak_alias (__isatty, isatty) diff --git a/sysdeps/stub/isinf.c b/sysdeps/stub/isinf.c new file mode 100644 index 0000000000..aa02eb19e3 --- /dev/null +++ b/sysdeps/stub/isinf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +int +DEFUN(__isinf, (value), double value) +{ + return 0; +} +weak_alias (__isinf, isinf) + +stub_warning (__isinf) diff --git a/sysdeps/stub/isinfl.c b/sysdeps/stub/isinfl.c new file mode 100644 index 0000000000..71065c77fa --- /dev/null +++ b/sysdeps/stub/isinfl.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <math.h> + +#undef __isinfl +#undef isinfl + + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +int +__isinfl (long double value) +{ + return 0; +} + +weak_alias (__isinfl, isinfl); diff --git a/sysdeps/stub/isnanl.c b/sysdeps/stub/isnanl.c new file mode 100644 index 0000000000..c785b351b8 --- /dev/null +++ b/sysdeps/stub/isnanl.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <math.h> + +#undef __isnanl +#undef isnanl + + +/* Return nonzero if VALUE is not a number. */ + +int +__isnanl (long double value) +{ + return 0; +} + +weak_alias (__isnanl, isnanl); diff --git a/sysdeps/stub/jmp_buf.h b/sysdeps/stub/jmp_buf.h new file mode 100644 index 0000000000..6620e5ab15 --- /dev/null +++ b/sysdeps/stub/jmp_buf.h @@ -0,0 +1,3 @@ +/* Define the machine-dependent type `jmp_buf'. Stub version. */ + +typedef int __jmp_buf[1]; diff --git a/sysdeps/stub/kill.c b/sysdeps/stub/kill.c new file mode 100644 index 0000000000..b9a8b0e3c2 --- /dev/null +++ b/sysdeps/stub/kill.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* Send signal SIG to process number PID. If PID is zero, + send SIG to all processes in the current process's process group. + If PID is < -1, send SIG to all processes in process group - PID. */ +int +DEFUN(__kill, (pid, sig), int pid AND int sig) +{ + errno = ENOSYS; + return -1; +} +stub_warning (kill) + +weak_alias (__kill, kill) diff --git a/sysdeps/stub/killpg.c b/sysdeps/stub/killpg.c new file mode 100644 index 0000000000..eb05bca9b8 --- /dev/null +++ b/sysdeps/stub/killpg.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* Send SIG to all processes in process group PGRP. + If PGRP is zero, send SIG to all processes in + the current process's process group. */ +int +DEFUN(killpg, (pgrp, sig), __pid_t pgrp AND int sig) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/ldbl2mpn.c b/sysdeps/stub/ldbl2mpn.c new file mode 100644 index 0000000000..b8e920d331 --- /dev/null +++ b/sysdeps/stub/ldbl2mpn.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" + +/* Convert a `long double' to a multi-precision integer representing the + significand scaled up by the highest possible number of significant bits + of fraction (LDBL_MANT_DIG), and an integral power of two (MPN frexpl). */ + +mp_size_t +__mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, + int *expt, int *is_neg, + double value) +{ +#error "not implemented for this floating point format" +} diff --git a/sysdeps/stub/libc_fatal.c b/sysdeps/stub/libc_fatal.c new file mode 100644 index 0000000000..5a5d2fb79f --- /dev/null +++ b/sysdeps/stub/libc_fatal.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +/* Abort with an error message. */ +__NORETURN +void +DEFUN(__libc_fatal, (message), CONST char *message) +{ + /* This function should write MESSAGE out in the most reliable way. + It is called in situations like internal stdio lossage. */ + + abort (); +} diff --git a/sysdeps/stub/link.c b/sysdeps/stub/link.c new file mode 100644 index 0000000000..c5ea71374a --- /dev/null +++ b/sysdeps/stub/link.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Make a link to FROM called TO. */ +int +DEFUN(__link, (from, to), CONST char *from AND CONST char *to) +{ + if (from == NULL || to == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (link) + +weak_alias (__link, link) diff --git a/sysdeps/stub/listen.c b/sysdeps/stub/listen.c new file mode 100644 index 0000000000..40bd998ee4 --- /dev/null +++ b/sysdeps/stub/listen.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Prepare to accept connections on socket FD. + N connection requests will be queued before further requests are refused. + Returns 0 on success, -1 for errors. */ +int +DEFUN(listen, (fd, n), + int fd AND unsigned int n) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(listen); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/local_lim.h b/sysdeps/stub/local_lim.h new file mode 100644 index 0000000000..771d1b0c16 --- /dev/null +++ b/sysdeps/stub/local_lim.h @@ -0,0 +1,3 @@ +/* This file should define the implementaton-specific limits described + in posix[12]_lim.h. If there are no useful values to give a limit, + don't define it. */ diff --git a/sysdeps/stub/log.c b/sysdeps/stub/log.c new file mode 100644 index 0000000000..49ed8029fa --- /dev/null +++ b/sysdeps/stub/log.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the natural logarithm of X. */ +double +DEFUN(log, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(log); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/log10.c b/sysdeps/stub/log10.c new file mode 100644 index 0000000000..26fb85477c --- /dev/null +++ b/sysdeps/stub/log10.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the base-ten logarithm of X. */ +double +DEFUN(log10, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(log10); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/logb.c b/sysdeps/stub/logb.c new file mode 100644 index 0000000000..f5af6bfa05 --- /dev/null +++ b/sysdeps/stub/logb.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <math.h> +#include <errno.h> + +/* Return the base 2 signed integral exponent of X. */ +double +DEFUN(__logb, (x), double x) +{ + errno = ENOSYS; + return 0.0; +} +stub_warning (logb) +weak_alias (__logb, logb) diff --git a/sysdeps/stub/longjmp-ctx.c b/sysdeps/stub/longjmp-ctx.c new file mode 100644 index 0000000000..11ed609f3b --- /dev/null +++ b/sysdeps/stub/longjmp-ctx.c @@ -0,0 +1,32 @@ +/* Perform a `longjmp' on a `struct sigcontext'. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <signal.h> +#include <string.h> + +void +_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval) +{ + memset (scp, 0, sizeof (*scp)); + /* Set all the registers in *SCP to the values described by ENV and RETVAL. + After this, calling `__sigreturn (SCP)' in that thread should be just + like calling `longjmp (ENV, RETVAL)'. */ + #error "Need to write sysdeps/mach/hurd/MACHINE/longjmp-ctx.c" +} diff --git a/sysdeps/stub/longjmp-ts.c b/sysdeps/stub/longjmp-ts.c new file mode 100644 index 0000000000..1c50292d3b --- /dev/null +++ b/sysdeps/stub/longjmp-ts.c @@ -0,0 +1,32 @@ +/* Perform a `longjmp' on a Mach thread_state. Stub version. +Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> +#include <mach/thread_status.h> + +/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ + +void +_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) +{ + /* Set all the registers in *STATE to the values described by ENV and + RETVAL. After this, setting that thread's state to STATE should be + just like calling `longjmp (ENV, RETVAL)'. */ + #error "Need to write sysdeps/mach/hurd/MACHINE/longjmp-ctx.c" +} diff --git a/sysdeps/stub/lseek.c b/sysdeps/stub/lseek.c new file mode 100644 index 0000000000..6d9c3660fb --- /dev/null +++ b/sysdeps/stub/lseek.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Seek to OFFSET on FD, starting from WHENCE. */ +off_t +DEFUN(__lseek, (fd, offset, whence), int fd AND off_t offset AND int whence) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + switch (whence) + { + case SEEK_SET: + case SEEK_CUR: + case SEEK_END: + break; + default: + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (lseek) + +weak_alias (__lseek, lseek) diff --git a/sysdeps/stub/lstat.c b/sysdeps/stub/lstat.c new file mode 100644 index 0000000000..0e69a086e3 --- /dev/null +++ b/sysdeps/stub/lstat.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> + +/* Get file information about FILE in BUF. + If FILE is a symbolic link, do not follow it. */ +int +DEFUN(__lstat, (file, buf), CONST char *file AND struct stat *buf) +{ + if (file == NULL || buf == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (lstat) + +weak_alias (__lstat, lstat) diff --git a/sysdeps/stub/machine-lock.h b/sysdeps/stub/machine-lock.h new file mode 100644 index 0000000000..35831c2c64 --- /dev/null +++ b/sysdeps/stub/machine-lock.h @@ -0,0 +1,64 @@ +/* Machine-specific definition for spin locks. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef volatile int __spin_lock_t; + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER 0 + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + *__lock = 0; +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (__spin_lock_t *__lock) +{ + if (*__lock) + return 0; + *__lock = 1; + return 1; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + return *__lock != 0; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/stub/machine-sp.h b/sysdeps/stub/machine-sp.h new file mode 100644 index 0000000000..3bcfd95f04 --- /dev/null +++ b/sysdeps/stub/machine-sp.h @@ -0,0 +1,37 @@ +/* Machine-specific function to return the stack pointer. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +_EXTERN_INLINE void * +__thread_stack_pointer (void) +{ + register void *__sp__ ("{STACK-POINTER}"); + return __sp__; +} + +#endif /* machine-sp.h */ + diff --git a/sysdeps/stub/madvise.c b/sysdeps/stub/madvise.c new file mode 100644 index 0000000000..631a151f36 --- /dev/null +++ b/sysdeps/stub/madvise.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ + +int +madvise (caddr_t addr, size_t len, int advice) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/mkdir.c b/sysdeps/stub/mkdir.c new file mode 100644 index 0000000000..9822b5f8b8 --- /dev/null +++ b/sysdeps/stub/mkdir.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> + + +/* Create a directory named PATH with protections MODE. */ +int +DEFUN(__mkdir, (path, mode), CONST char *path AND mode_t mode) +{ + if (path == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (mkdir) + +weak_alias (__mkdir, mkdir) diff --git a/sysdeps/stub/mkfifo.c b/sysdeps/stub/mkfifo.c new file mode 100644 index 0000000000..2b5c29c061 --- /dev/null +++ b/sysdeps/stub/mkfifo.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> + + +/* Create a named pipe (FIFO) named PATH with protections MODE. */ +int +DEFUN(mkfifo, (path, mode), CONST char *path AND mode_t mode) +{ + if (path == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(mkfifo); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/mknod.c b/sysdeps/stub/mknod.c new file mode 100644 index 0000000000..66f88aa36f --- /dev/null +++ b/sysdeps/stub/mknod.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +/* Create a device file named PATH, with permission and special bits MODE + and device number DEV (which can be constructed from major and minor + device numbers with the `makedev' macro above). */ +int +DEFUN(__mknod, (path, mode, dev), + CONST char *path AND mode_t mode AND dev_t dev) +{ + errno = ENOSYS; + return -1; +} +stub_warning (mknod) + +weak_alias (__mknod, mknod) diff --git a/sysdeps/stub/mkstemp.c b/sysdeps/stub/mkstemp.c new file mode 100644 index 0000000000..0adc52ed62 --- /dev/null +++ b/sysdeps/stub/mkstemp.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <errno.h> + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. + Returns a file descriptor open on the file for reading and writing. */ +int +DEFUN(mkstemp, (template), char *template) +{ + if (strcmp(&template[strlen(template) - 6], "XXXXXX")) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/mktemp.c b/sysdeps/stub/mktemp.c new file mode 100644 index 0000000000..33a1295942 --- /dev/null +++ b/sysdeps/stub/mktemp.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> +#include <errno.h> + +/* Generate a unique temporary file name from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. */ +char * +DEFUN(mktemp, (template), char *template) +{ + if (strcmp(&template[strlen(template) - 6], "XXXXXX")) + { + errno = EINVAL; + return template; + } + + errno = ENOSYS; + return NULL; +} diff --git a/sysdeps/stub/mmap.c b/sysdeps/stub/mmap.c new file mode 100644 index 0000000000..5ee4fa7797 --- /dev/null +++ b/sysdeps/stub/mmap.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +caddr_t +mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + errno = ENOSYS; + return (caddr_t) -1; +} + diff --git a/sysdeps/stub/morecore.c b/sysdeps/stub/morecore.c new file mode 100644 index 0000000000..4f11e9ccef --- /dev/null +++ b/sysdeps/stub/morecore.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> + +#define _MALLOC_INTERNAL +#include <malloc.h> + +/* Allocate INCREMENT more bytes of data space, + and return the start of data space, or NULL on errors. + If INCREMENT is negative, shrink data space. */ +__ptr_t +DEFUN(__default_morecore, (increment), ptrdiff_t increment) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__default_morecore); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/mpn2dbl.c b/sysdeps/stub/mpn2dbl.c new file mode 100644 index 0000000000..7599147165 --- /dev/null +++ b/sysdeps/stub/mpn2dbl.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits and an + integral power of two to a `double'. */ + +double +__mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative) +{ +#error "__mpn_construct_double not implemented for this floating point format" +} + diff --git a/sysdeps/stub/mpn2flt.c b/sysdeps/stub/mpn2flt.c new file mode 100644 index 0000000000..ca28c9831f --- /dev/null +++ b/sysdeps/stub/mpn2flt.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits and an + integral power of two to a `float'. */ + +float +__mpn_construct_float (mp_srcptr frac_ptr, int expt, int negative) +{ +#error "__mpn_construct_float not implemented for this floating point format" +} + diff --git a/sysdeps/stub/mpn2ldbl.c b/sysdeps/stub/mpn2ldbl.c new file mode 100644 index 0000000000..57060dd807 --- /dev/null +++ b/sysdeps/stub/mpn2ldbl.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "gmp.h" +#include "gmp-impl.h" +#include <float.h> + +/* Convert a multi-precision integer of the needed number of bits and an + integral power of two to a `long double'. */ + +long double +__mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int negative) +{ +#error "__mpn_construct_long_double not implemented for floating point format" +} + diff --git a/sysdeps/stub/mprotect.c b/sysdeps/stub/mprotect.c new file mode 100644 index 0000000000..169e6c3ec8 --- /dev/null +++ b/sysdeps/stub/mprotect.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ + +int +mprotect (caddr_t addr, size_t len, int prot) +{ + errno = ENOSYS; + return -1; +} + diff --git a/sysdeps/stub/msync.c b/sysdeps/stub/msync.c new file mode 100644 index 0000000000..ed55915409 --- /dev/null +++ b/sysdeps/stub/msync.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ + +int +msync (caddr_t addr, size_t len) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/munmap.c b/sysdeps/stub/munmap.c new file mode 100644 index 0000000000..c12889a1e5 --- /dev/null +++ b/sysdeps/stub/munmap.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ + +int +munmap (caddr_t addr, size_t len) +{ + errno = ENOSYS; + return -1; +} + diff --git a/sysdeps/stub/nan.h b/sysdeps/stub/nan.h new file mode 100644 index 0000000000..9dd53415c8 --- /dev/null +++ b/sysdeps/stub/nan.h @@ -0,0 +1,6 @@ +#ifndef _NAN_H +#define _NAN_H 1 + +/* This file should define `NAN' on machines that have such things. */ + +#endif /* nan.h */ diff --git a/sysdeps/stub/nice.c b/sysdeps/stub/nice.c new file mode 100644 index 0000000000..c2ca0892f0 --- /dev/null +++ b/sysdeps/stub/nice.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Increment the scheduling priority of the calling process by INCR. + The superuser may use a negative INCR to decrement the priority. */ +int +DEFUN(nice, (incr), int incr) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning (nice); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/nlist.c b/sysdeps/stub/nlist.c new file mode 100644 index 0000000000..d0e0e59fee --- /dev/null +++ b/sysdeps/stub/nlist.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <nlist.h> +#include <stddef.h> + +/* Search the executable FILE for symbols matching those in NL, + which is terminated by an element with a NULL `n_un.n_name' member, + and fill in the elements of NL. */ +int +DEFUN(nlist, (file, nl), + CONST char *file AND struct nlist *nl) +{ + if (nl == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(nlist); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/open.c b/sysdeps/stub/open.c new file mode 100644 index 0000000000..af0d2723f8 --- /dev/null +++ b/sysdeps/stub/open.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stddef.h> + +/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, + a third argument is the file protection. */ +int +DEFUN(__open, (file, oflag), CONST char *file AND int oflag DOTS) +{ + int mode; + + if (file == NULL) + { + errno = EINVAL; + return -1; + } + + if (oflag & O_CREAT) + { + va_list arg; + va_start(arg, oflag); + mode = va_arg(arg, int); + va_end(arg); + } + + errno = ENOSYS; + return -1; +} +stub_warning (open) + +weak_alias (__open, open) diff --git a/sysdeps/stub/opendir.c b/sysdeps/stub/opendir.c new file mode 100644 index 0000000000..e3697d710c --- /dev/null +++ b/sysdeps/stub/opendir.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Open a directory stream on NAME. */ +DIR * +DEFUN(opendir, (name), CONST char *name) +{ + errno = ENOSYS; + return(NULL); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(opendir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/pathconf.c b/sysdeps/stub/pathconf.c new file mode 100644 index 0000000000..f14d10f7d1 --- /dev/null +++ b/sysdeps/stub/pathconf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Get file-specific information about PATH. */ +long int +DEFUN(__pathconf, (path, name), CONST char *path AND int name) +{ + if (path == NULL) + { + errno = EINVAL; + return -1; + } + return __fpathconf (0, name); +} + +weak_alias (__pathconf, pathconf) diff --git a/sysdeps/stub/pause.c b/sysdeps/stub/pause.c new file mode 100644 index 0000000000..6d268643aa --- /dev/null +++ b/sysdeps/stub/pause.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Suspend the process until a signal arrives. + This is supposed to always return -1 and set errno to EINTR, + but rules were meant to be broken. */ +int +DEFUN_VOID(pause) +{ + errno = ENOSYS; + return(-1); +} + + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(pause); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/pipe.c b/sysdeps/stub/pipe.c new file mode 100644 index 0000000000..acef99b112 --- /dev/null +++ b/sysdeps/stub/pipe.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +/* Create a one-way communication channel (__pipe). + If successul, two file descriptors are stored in PIPEDES; + bytes written on PIPEDES[1] can be read from PIPEDES[0]. + Returns 0 if successful, -1 if not. */ +int +DEFUN(__pipe, (__pipedes), int __pipedes[2]) +{ + if (__pipedes == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (pipe) + +weak_alias (__pipe, pipe) diff --git a/sysdeps/stub/pipestream.c b/sysdeps/stub/pipestream.c new file mode 100644 index 0000000000..143cf71940 --- /dev/null +++ b/sysdeps/stub/pipestream.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <signal.h> +#include <stdio.h> +#include <errno.h> + + +/* Open a new stream that is a one-way pipe to a + child process running the given shell command. */ +FILE * +DEFUN(popen, (command, mode), CONST char *command AND CONST char *mode) +{ + if (command == NULL || mode == NULL || (*mode != 'r' && *mode != 'w')) + { + errno = EINVAL; + return NULL; + } + + errno = ENOSYS; + return NULL; +} + +/* Close a stream opened by popen and return its status. + Returns -1 if the stream was not opened by popen. */ +int +DEFUN(pclose, (stream), register FILE *stream) +{ + if (!__validfp (stream) || !stream->__ispipe) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(popen); +stub_warning(pclose); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/poll.c b/sysdeps/stub/poll.c new file mode 100644 index 0000000000..3436eaa33d --- /dev/null +++ b/sysdeps/stub/poll.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/poll.h> +#include <errno.h> + +/* Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors. */ + +int +poll (fds, nfds, timeout) + struct pollfd *fds; + unsigned long int nfds; + int timeout; +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/posix_opt.h b/sysdeps/stub/posix_opt.h new file mode 100644 index 0000000000..54f5a79aa2 --- /dev/null +++ b/sysdeps/stub/posix_opt.h @@ -0,0 +1,2 @@ +/* This file should define the POSIX options described in <unistd.h>, + or leave them undefined, as appropriate. */ diff --git a/sysdeps/stub/ptrace.c b/sysdeps/stub/ptrace.c new file mode 100644 index 0000000000..6bd5917f39 --- /dev/null +++ b/sysdeps/stub/ptrace.c @@ -0,0 +1,108 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/ptrace.h> +#include <sys/types.h> +#include <stdarg.h> + +/* Perform process tracing functions. REQUEST is one of the values + in <sys/ptrace.h>, and determines the action to be taken. + For all requests except PTRACE_TRACEME, PID specifies the process to be + traced. + + PID and the other arguments described above for the various requests should + appear (those that are used for the particular request) as: + pid_t PID, void *ADDR, int DATA, void *ADDR2 + after PID. */ +int +DEFUN(ptrace, (request), enum __ptrace_request request DOTS) +{ + pid_t pid; + PTR addr; + PTR addr2; + int data; + va_list ap; + + switch (request) + { + case PTRACE_TRACEME: + case PTRACE_CONT: + case PTRACE_KILL: + case PTRACE_SINGLESTEP: + case PTRACE_ATTACH: + case PTRACE_DETACH: + break; + + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + case PTRACE_PEEKUSER: + case PTRACE_GETREGS: + case PTRACE_SETREGS: +#ifdef PTRACE_GETFPREGS + case PTRACE_GETFPGEGS: +#endif + case PTRACE_SETFPREGS: + case PTRACE_GETFPAREGS: + case PTRACE_SETFPAREGS: + va_start(ap, request); + pid = va_arg(ap, pid_t); + addr = va_arg(ap, PTR); + va_end(ap); + break; + + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + case PTRACE_POKEUSER: + va_start(ap, request); + pid = va_arg(ap, pid_t); + addr = va_arg(ap, PTR); + data = va_arg(ap, int); + va_end(ap); + break; + + case PTRACE_READDATA: + case PTRACE_WRITEDATA: + case PTRACE_READTEXT: + case PTRACE_WRITETEXT: + va_start(ap, request); + pid = va_arg(ap, pid_t); + addr = va_arg(ap, PTR); + data = va_arg(ap, int); + addr2 = va_arg(ap, PTR); + va_end(ap); + break; + + default: + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(ptrace); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/putenv.c b/sysdeps/stub/putenv.c new file mode 100644 index 0000000000..964655f3e0 --- /dev/null +++ b/sysdeps/stub/putenv.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> + +/* Put STRING, which is of the form "NAME=VALUE", in the environment. + If there is no `=', remove NAME from the environment. */ +int +DEFUN(putenv, (string), CONST char *string) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(putenv); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/raise.c b/sysdeps/stub/raise.c new file mode 100644 index 0000000000..b3af76b5b4 --- /dev/null +++ b/sysdeps/stub/raise.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <errno.h> + +/* Raise the signal SIG. */ +int +DEFUN(raise, (sig), int sig) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/read.c b/sysdeps/stub/read.c new file mode 100644 index 0000000000..014313216b --- /dev/null +++ b/sysdeps/stub/read.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +/* Read NBYTES into BUF from FD. Return the number read or -1. */ +ssize_t +DEFUN(__read, (fd, buf, nbytes), + int fd AND PTR buf AND size_t nbytes) +{ + if (nbytes == 0) + return 0; + if (fd < 0) + { + errno = EBADF; + return -1; + } + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (read) + +weak_alias (__read, read) diff --git a/sysdeps/stub/readdir.c b/sysdeps/stub/readdir.c new file mode 100644 index 0000000000..bce3df271b --- /dev/null +++ b/sysdeps/stub/readdir.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Read a directory entry from DIRP. */ +struct dirent * +DEFUN(readdir, (dirp), DIR *dirp) +{ + errno = ENOSYS; + return(NULL); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(readdir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/readlink.c b/sysdeps/stub/readlink.c new file mode 100644 index 0000000000..b640a8db0f --- /dev/null +++ b/sysdeps/stub/readlink.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Read the contents of the symbolic link PATH into no more than + LEN bytes of BUF. The contents are not null-terminated. + Returns the number of characters read, or -1 for errors. */ +int +DEFUN(__readlink, (path, buf, len), + CONST char *path AND char *buf AND size_t len) +{ + errno = ENOSYS; + return -1; +} +stub_warning (readlink) + +weak_alias (__readlink, readlink) diff --git a/sysdeps/stub/readv.c b/sysdeps/stub/readv.c new file mode 100644 index 0000000000..beebd950c1 --- /dev/null +++ b/sysdeps/stub/readv.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Read data from file descriptor FD, and put the result in the + buffers described by VECTOR, which is a vector of COUNT `struct iovec's. + The buffers are filled in the order specified. + Operates just like `read' (see <unistd.h>) except that data are + put in VECTOR instead of a contiguous buffer. */ +int +DEFUN(readv, (fd, vector, count), + int fd AND CONST struct iovec *vector AND size_t count) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/reboot.c b/sysdeps/stub/reboot.c new file mode 100644 index 0000000000..6801499e59 --- /dev/null +++ b/sysdeps/stub/reboot.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Reboot the system. */ +int +DEFUN(reboot, (howto), int howto) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(reboot); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/recv.c b/sysdeps/stub/recv.c new file mode 100644 index 0000000000..e7355af49c --- /dev/null +++ b/sysdeps/stub/recv.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Read N bytes into BUF from socket FD. + Returns the number read or -1 for errors. */ +int +DEFUN(recv, (fd, buf, n, flags), + int fd AND PTR buf AND size_t n AND int flags) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(recv); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/recvfrom.c b/sysdeps/stub/recvfrom.c new file mode 100644 index 0000000000..6d33bb6282 --- /dev/null +++ b/sysdeps/stub/recvfrom.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Read N bytes into BUF through socket FD from peer + at address ADDR (which is ADDR_LEN bytes long). + Returns the number read or -1 for errors. */ +int +DEFUN(recvfrom, (fd, buf, n, flags, addr, addr_len), + int fd AND PTR buf AND size_t n AND int flags AND + struct sockaddr *addr AND size_t *addr_len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(recvfrom); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/recvmsg.c b/sysdeps/stub/recvmsg.c new file mode 100644 index 0000000000..eecff02084 --- /dev/null +++ b/sysdeps/stub/recvmsg.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Receive a message as described by MESSAGE from socket FD. + Returns the number of bytes read or -1 for errors. */ +int +DEFUN(recvmsg, (fd, message, flags), + int fd AND struct msghdr *message AND int flags) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (recvmsg) diff --git a/sysdeps/stub/remove.c b/sysdeps/stub/remove.c new file mode 100644 index 0000000000..c044e0aac0 --- /dev/null +++ b/sysdeps/stub/remove.c @@ -0,0 +1,31 @@ +/* ANSI C `remove' function to delete a file or directory. Stub version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <stdio.h> + +int +remove (file) + const char *file; +{ + errno = ENOSYS; + return -1; +} + +stub_warning (remove) diff --git a/sysdeps/stub/rename.c b/sysdeps/stub/rename.c new file mode 100644 index 0000000000..c69df72050 --- /dev/null +++ b/sysdeps/stub/rename.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <errno.h> + + +/* Rename the file OLD to NEW. */ +int +DEFUN(rename, (old, new), CONST char *old AND CONST char *new) +{ + if (old == NULL || new == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(rename); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/rewinddir.c b/sysdeps/stub/rewinddir.c new file mode 100644 index 0000000000..1eb5a0bf5c --- /dev/null +++ b/sysdeps/stub/rewinddir.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + + +/* Rewind DIRP to the beginning of the directory. */ +void +DEFUN(rewinddir, (dirp), DIR *dirp) +{ + errno = ENOSYS; + /* No way to indicate failure. */ +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(rewinddir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/rmdir.c b/sysdeps/stub/rmdir.c new file mode 100644 index 0000000000..828a261a13 --- /dev/null +++ b/sysdeps/stub/rmdir.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Remove the directory PATH. */ +int +DEFUN(__rmdir, (path), CONST char *path) +{ + if (path == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (rmdir) + +weak_alias (__rmdir, rmdir) diff --git a/sysdeps/stub/sbrk.c b/sysdeps/stub/sbrk.c new file mode 100644 index 0000000000..46d9ecde60 --- /dev/null +++ b/sysdeps/stub/sbrk.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> + +/* Extend the process's data space by INCREMENT. + If INCREMENT is negative, shrink data space by - INCREMENT. + Return the address of the start of data space, or -1 for errors. */ +PTR +DEFUN(__sbrk, (increment), int increment) +{ + errno = ENOSYS; + return (PTR) -1; +} +stub_warning (sbrk) + +weak_alias (__sbrk, sbrk) diff --git a/sysdeps/stub/seekdir.c b/sysdeps/stub/seekdir.c new file mode 100644 index 0000000000..61d270b8b8 --- /dev/null +++ b/sysdeps/stub/seekdir.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> + +/* Seek to position POS in DIRP. */ +void +DEFUN(seekdir, (dirp, pos), DIR *dirp AND off_t pos) +{ + if (dirp == NULL) + { + errno = EINVAL; + return; + } + + errno = ENOSYS; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(seekdir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/select.c b/sysdeps/stub/select.c new file mode 100644 index 0000000000..837f0adab4 --- /dev/null +++ b/sysdeps/stub/select.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <errno.h> + +/* Check the first NFDS descriptors each in READFDS (if not NULL) for read + readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS + (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out + after waiting the interval specified therein. Returns the number of ready + descriptors, or -1 for errors. */ +int +DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), + int nfds AND fd_set *readfds AND fd_set *writefds AND + fd_set *exceptfds AND struct timeval *timeout) +{ + errno = ENOSYS; + return -1; +} +stub_warning (select) + +weak_alias (__select, select) diff --git a/sysdeps/stub/send.c b/sysdeps/stub/send.c new file mode 100644 index 0000000000..d1fbc69481 --- /dev/null +++ b/sysdeps/stub/send.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ +int +DEFUN(send, (fd, buf, n, flags), + int fd AND PTR buf AND size_t n AND int flags) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(send); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sendmsg.c b/sysdeps/stub/sendmsg.c new file mode 100644 index 0000000000..2066e52168 --- /dev/null +++ b/sysdeps/stub/sendmsg.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Send a message described MESSAGE on socket FD. + Returns the number of bytes sent, or -1 for errors. */ +int +DEFUN(sendmsg, (fd, message, flags), + int fd AND CONST struct msghdr *message AND int flags) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (sendmsg) diff --git a/sysdeps/stub/sendto.c b/sysdeps/stub/sendto.c new file mode 100644 index 0000000000..21d76ba12f --- /dev/null +++ b/sysdeps/stub/sendto.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Send N bytes of BUF on socket FD to peer at address ADDR (which is + ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ +int +DEFUN(sendto, (fd, buf, n, flags, addr, addr_len), + int fd AND PTR buf AND size_t n AND int flags AND + struct sockaddr *addr AND size_t addr_len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sendto); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setdomain.c b/sysdeps/stub/setdomain.c new file mode 100644 index 0000000000..74da5398b5 --- /dev/null +++ b/sysdeps/stub/setdomain.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the name of the current YP domain to NAME, which is LEN bytes long. + This call is restricted to the super-user. */ +int +DEFUN(setdomainname, (name, len), + char *name AND size_t len) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (setdomainname) diff --git a/sysdeps/stub/setegid.c b/sysdeps/stub/setegid.c new file mode 100644 index 0000000000..58a3fe93c8 --- /dev/null +++ b/sysdeps/stub/setegid.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the effective group ID of the calling process to GID. */ +int +DEFUN(setegid, (gid), __gid_t gid) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(setegid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setenv.c b/sysdeps/stub/setenv.c new file mode 100644 index 0000000000..992a15df02 --- /dev/null +++ b/sysdeps/stub/setenv.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <errno.h> + +int +DEFUN(setenv, (name, value, replace), + CONST char *name AND CONST char *value AND int replace) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/seteuid.c b/sysdeps/stub/seteuid.c new file mode 100644 index 0000000000..73180ccf67 --- /dev/null +++ b/sysdeps/stub/seteuid.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the effective user ID of the calling process to UID. */ +int +DEFUN(seteuid, (uid), __uid_t uid) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(seteuid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setgid.c b/sysdeps/stub/setgid.c new file mode 100644 index 0000000000..df1adbbac7 --- /dev/null +++ b/sysdeps/stub/setgid.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the group ID of the calling process to GID. + If the calling process is the super-user, the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID. */ +int +DEFUN(__setgid, (gid), gid_t gid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setgid) + +weak_alias (__setgid, setgid) diff --git a/sysdeps/stub/setgroups.c b/sysdeps/stub/setgroups.c new file mode 100644 index 0000000000..71d08d2732 --- /dev/null +++ b/sysdeps/stub/setgroups.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <grp.h> + +/* Set the group set for the current user to GROUPS (N of them). */ +int +DEFUN(setgroups, (n, groups), size_t n AND CONST gid_t *groups) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(setgroups); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sethostid.c b/sysdeps/stub/sethostid.c new file mode 100644 index 0000000000..500e1003cf --- /dev/null +++ b/sysdeps/stub/sethostid.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the current machine's Internet number to ID. + This call is restricted to the super-user. */ +int +DEFUN(sethostid, (id), long int id) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sethostid); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sethostname.c b/sysdeps/stub/sethostname.c new file mode 100644 index 0000000000..db44239b8f --- /dev/null +++ b/sysdeps/stub/sethostname.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the name of the current host to NAME, which is LEN bytes long. + This call is restricted to the super-user. */ +int +DEFUN(sethostname, (name, len), + CONST char *name AND size_t len) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sethostname); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setitimer.c b/sysdeps/stub/setitimer.c new file mode 100644 index 0000000000..6ba7031184 --- /dev/null +++ b/sysdeps/stub/setitimer.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/time.h> + +/* Set the timer WHICH to *NEW. If OLD is not NULL, + set *OLD to the old value of timer WHICH. + Returns 0 on success, -1 on errors. */ +int +DEFUN(__setitimer, (which, new, old), + enum __itimer_which which AND + struct itimerval *new AND struct itimerval *old) +{ + if (new == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (setitimer) + +weak_alias (__setitimer, setitimer) diff --git a/sysdeps/stub/setjmp.c b/sysdeps/stub/setjmp.c new file mode 100644 index 0000000000..47a471df02 --- /dev/null +++ b/sysdeps/stub/setjmp.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <setjmp.h> + + +/* Save the current program position in ENV and return 0. */ +int +__sigsetjmp (jmp_buf env, int savemask) +{ + /* Save the signal mask if requested. */ + __sigjmp_save (env, savemask); + + errno = ENOSYS; + /* No way to signal failure. */ + return 0; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__sigsetjmp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setlogin.c b/sysdeps/stub/setlogin.c new file mode 100644 index 0000000000..393fd5864a --- /dev/null +++ b/sysdeps/stub/setlogin.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the login name returned by `getlogin'. */ +int +DEFUN(setlogin, (name), CONST char *name) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/setpgid.c b/sysdeps/stub/setpgid.c new file mode 100644 index 0000000000..7e1d1a9b9a --- /dev/null +++ b/sysdeps/stub/setpgid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the process group ID of the process matching PID to PGID. + If PID is zero, the current process's process group ID is set. + If PGID is zero, the process ID of the process is used. */ +int +DEFUN(__setpgid, (pid, pgid), int pid AND int pgid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setpgid) + +weak_alias (__setpgid, setpgid) +weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/stub/setpriority.c b/sysdeps/stub/setpriority.c new file mode 100644 index 0000000000..b826927f73 --- /dev/null +++ b/sysdeps/stub/setpriority.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/resource.h> + +/* Set the priority of all processes specified by WHICH and WHO + to PRIO. Returns 0 on success, -1 on errors. */ +int +DEFUN(setpriority, (which, who, prio), + enum __priority_which which AND int who AND int prio) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(setpriority); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setregid.c b/sysdeps/stub/setregid.c new file mode 100644 index 0000000000..017dd08692 --- /dev/null +++ b/sysdeps/stub/setregid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the real group ID of the calling process to RGID, + and the effective group ID of the calling process to EGID. */ +int +DEFUN(__setregid, (effective_gid, real_gid), + gid_t effective_gid AND gid_t real_gid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setregid) + +weak_alias (__setregid, setregid) diff --git a/sysdeps/stub/setreuid.c b/sysdeps/stub/setreuid.c new file mode 100644 index 0000000000..7640d2f674 --- /dev/null +++ b/sysdeps/stub/setreuid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the real user ID of the calling process to RUID, + and the effective user ID of the calling process to EUID. */ +int +DEFUN(__setreuid, (effective_uid, real_uid), + uid_t effective_uid AND uid_t real_uid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setreuid) + +weak_alias (__setreuid, setreuid) diff --git a/sysdeps/stub/setrlimit.c b/sysdeps/stub/setrlimit.c new file mode 100644 index 0000000000..4e8083f8a8 --- /dev/null +++ b/sysdeps/stub/setrlimit.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> + +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int +DEFUN(setrlimit, (resource, rlimits), + enum __rlimit_resource resource AND struct rlimit *rlimits) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(setrlimit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/setsid.c b/sysdeps/stub/setsid.c new file mode 100644 index 0000000000..9baf1ee4ef --- /dev/null +++ b/sysdeps/stub/setsid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +int +DEFUN_VOID(__setsid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setsid) + +weak_alias (__setsid, setsid) diff --git a/sysdeps/stub/setsockopt.c b/sysdeps/stub/setsockopt.c new file mode 100644 index 0000000000..bd1500a903 --- /dev/null +++ b/sysdeps/stub/setsockopt.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Set socket FD's option OPTNAME at protocol level LEVEL + to *OPTVAL (which is OPTLEN bytes long). + Returns 0 on success, -1 for errors. */ +int +DEFUN(setsockopt, (fd, level, optname, optval, optlen), + int fd AND int level AND int optname AND + PTR optval AND size_t optlen) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(setsockopt); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/settimeofday.c b/sysdeps/stub/settimeofday.c new file mode 100644 index 0000000000..7d654cde57 --- /dev/null +++ b/sysdeps/stub/settimeofday.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +int +DEFUN(__settimeofday, (tv, tz), + CONST struct timeval *tv AND CONST struct timezone *tz) +{ + errno = ENOSYS; + return -1; +} +stub_warning (settimeofday) + +weak_alias (__settimeofday, settimeofday) diff --git a/sysdeps/stub/setuid.c b/sysdeps/stub/setuid.c new file mode 100644 index 0000000000..3415925967 --- /dev/null +++ b/sysdeps/stub/setuid.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the user ID of the calling process to UID. + If the calling process is the super-user, the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID. */ +int +DEFUN(__setuid, (uid), uid_t uid) +{ + errno = ENOSYS; + return -1; +} +stub_warning (setuid) + +weak_alias (__setuid, setuid) diff --git a/sysdeps/stub/shutdown.c b/sysdeps/stub/shutdown.c new file mode 100644 index 0000000000..65d418fa95 --- /dev/null +++ b/sysdeps/stub/shutdown.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Shut down all or part of the connection open on socket FD. + HOW determines what to shut down: + 0 = No more receptions; + 1 = No more transmissions; + 2 = No more receptions or transmissions. + Returns 0 on success, -1 for errors. */ +int +DEFUN(shutdown, (fd, how), + int fd AND int how) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(shutdown); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sigaction.c b/sysdeps/stub/sigaction.c new file mode 100644 index 0000000000..7321140acd --- /dev/null +++ b/sysdeps/stub/sigaction.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +DEFUN(__sigaction, (sig, act, oact), + int sig AND CONST struct sigaction *act AND struct sigaction *OACT) +{ + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} +stub_warning (sigaction) + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/stub/sigaltstack.c b/sysdeps/stub/sigaltstack.c new file mode 100644 index 0000000000..ae5a7ae413 --- /dev/null +++ b/sysdeps/stub/sigaltstack.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Run signals handlers on the stack specified by SS (if not NULL). + If OSS is not NULL, it is filled in with the old signal stack status. */ +int +DEFUN(sigaltstack, (ss, oss), + CONST struct sigaltstack *ss AND struct sigaltstack *oss) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/sigblock.c b/sysdeps/stub/sigblock.c new file mode 100644 index 0000000000..7c7469eee7 --- /dev/null +++ b/sysdeps/stub/sigblock.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Block signals in MASK, returning the old mask. */ +int +DEFUN(__sigblock, (mask), int mask) +{ + errno = ENOSYS; + return -1; +} +stub_warning (sigblock) + +weak_alias (__sigblock, sigblock) diff --git a/sysdeps/stub/sigcontext.h b/sysdeps/stub/sigcontext.h new file mode 100644 index 0000000000..18d599fa8a --- /dev/null +++ b/sysdeps/stub/sigcontext.h @@ -0,0 +1,29 @@ +/* Structure describing state saved while handling a signal. Stub version. +Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* State of this thread when the signal was taken. */ +struct sigcontext + { + int sc_onstack; + __sigset_t sc_mask; + + /* Registers and such. */ + }; + +/* Signal subcodes should be defined here. */ diff --git a/sysdeps/stub/sigintr.c b/sysdeps/stub/sigintr.c new file mode 100644 index 0000000000..5ec83e0506 --- /dev/null +++ b/sysdeps/stub/sigintr.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* If INTERRUPT is nonzero, make signal SIG interrupt system calls + (causing them to fail with EINTR); if INTERRUPT is zero, make system + calls be restarted after signal SIG. */ +int +DEFUN(siginterrupt, (sig, interrupt), + int sig AND int interrupt) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/siglist.c b/sysdeps/stub/siglist.c new file mode 100644 index 0000000000..f32127c9d0 --- /dev/null +++ b/sysdeps/stub/siglist.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> + +CONST char *CONST _sys_siglist[] = + { + "Signal 0", + "Aborted", + "Erroneous arithmetic operation", + "Illegal instruction", + "Interrupt", + "Invalid access to storage", + "Terminated", + "Hangup", + "Quit", + "Broken pipe", + "Killed", + "Alarm clock", + "Stopped (signal)", + "Stopped", + "Continued", + "Child exited", + "Stopped (tty input)", + "Stopped (tty output)", + NULL + }; diff --git a/sysdeps/stub/signal.c b/sysdeps/stub/signal.c new file mode 100644 index 0000000000..88dc14a402 --- /dev/null +++ b/sysdeps/stub/signal.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* Set the handler for the signal SIG to HANDLER, + returning the old handler, or SIG_ERR on error. */ +__sighandler_t +DEFUN(signal, (sig, handler), int sig AND __sighandler_t handler) +{ + errno = ENOSYS; + return SIG_ERR; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(signal); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/signum.h b/sysdeps/stub/signum.h new file mode 100644 index 0000000000..fbcc1fe5e1 --- /dev/null +++ b/sysdeps/stub/signum.h @@ -0,0 +1,53 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* Fake signal functions. */ +extern void _sig_ign __P ((int sig)); +extern void _sig_dfl __P ((int sig)); + +#define SIG_ERR ((__sighandler_t) 0) /* Error return. */ +#define SIG_DFL _sig_dfl /* Default action. */ +#define SIG_IGN _sig_ign /* Ignore signal. */ + + +/* ANSI signals. */ +#define SIGABRT 1 /* Abnormal termination. */ +#define SIGFPE 2 /* Erroneous arithmetic operation. */ +#define SIGILL 3 /* Illegal instruction. */ +#define SIGINT 3 /* Interactive attention signal. */ +#define SIGSEGV 4 /* Invalid access to storage. */ +#define SIGTERM 5 /* Termination request. */ + +/* POSIX signals. */ +#define SIGHUP 6 /* Hangup. */ +#define SIGQUIT 7 /* Quit. */ +#define SIGPIPE 8 /* Broken pipe. */ +#define SIGKILL 9 /* Kill (cannot be blocked, caught, or ignored). */ +#define SIGALRM 10 /* Alarm clock. */ +#define SIGSTOP 11 /* Stop (cannot be blocked, caught, or ignored). */ +#define SIGTSTP 12 /* Keyboard stop. */ +#define SIGCONT 13 /* Continue. */ +#define SIGCHLD 14 /* Child terminated or stopped. */ +#define SIGTTIN 15 /* Background read from control terminal. */ +#define SIGTTOU 16 /* Background write to control terminal. */ + +#endif /* <signal.h> included. */ + +#define _NSIG 17 diff --git a/sysdeps/stub/sigpause.c b/sysdeps/stub/sigpause.c new file mode 100644 index 0000000000..a307422d06 --- /dev/null +++ b/sysdeps/stub/sigpause.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +int +DEFUN(__sigpause, (mask), int mask) +{ + errno = ENOSYS; + return -1; +} +stub_warning (sigpause) + +weak_alias (__sigpause, sigpause) diff --git a/sysdeps/stub/sigpending.c b/sysdeps/stub/sigpending.c new file mode 100644 index 0000000000..def44ed1a1 --- /dev/null +++ b/sysdeps/stub/sigpending.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> + + +/* Store in SET all signals that are blocked and pending. */ +int +DEFUN(sigpending, (set), sigset_t *set) +{ + if (set == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return -1; +} + +stub_warning (sigpending) diff --git a/sysdeps/stub/sigprocmask.c b/sysdeps/stub/sigprocmask.c new file mode 100644 index 0000000000..a89f683d54 --- /dev/null +++ b/sysdeps/stub/sigprocmask.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* If SET is not NULL, modify the current set of blocked signals + according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK. + If OSET is not NULL, store the old set of blocked signals in *OSET. */ +int +DEFUN(__sigprocmask, (how, set, oset), + int how AND CONST sigset_t *set AND sigset_t *oset) +{ + switch (how) + { + case SIG_BLOCK: + case SIG_UNBLOCK: + case SIG_SETMASK: + break; + default: + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + +/* No stub warning because abort calls __sigprocmask, + and we don't want warnings for every use of abort on + a system without safe signals. */ + +weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/stub/sigreturn.c b/sysdeps/stub/sigreturn.c new file mode 100644 index 0000000000..d4370e4b34 --- /dev/null +++ b/sysdeps/stub/sigreturn.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <errno.h> + +int +DEFUN(__sigreturn, (context), struct sigcontext *context) +{ + errno = ENOSYS; + return -1; +} +stub_warning (sigreturn) + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/stub/sigsetmask.c b/sysdeps/stub/sigsetmask.c new file mode 100644 index 0000000000..ab4ae811ac --- /dev/null +++ b/sysdeps/stub/sigsetmask.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +int +DEFUN(__sigsetmask, (mask), int mask) +{ + errno = ENOSYS; + return -1; +} +stub_warning (sigsetmask) + +weak_alias (__sigsetmask, sigsetmask) diff --git a/sysdeps/stub/sigstack.c b/sysdeps/stub/sigstack.c new file mode 100644 index 0000000000..001acfd996 --- /dev/null +++ b/sysdeps/stub/sigstack.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + +/* Run signals handlers on the stack specified by SS (if not NULL). + If OSS is not NULL, it is filled in with the old signal stack status. */ +int +DEFUN(sigstack, (ss, oss), + CONST struct sigstack *ss AND struct sigstack *oss) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/sigsuspend.c b/sysdeps/stub/sigsuspend.c new file mode 100644 index 0000000000..9c2067b2bf --- /dev/null +++ b/sysdeps/stub/sigsuspend.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> + + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +int +DEFUN(sigsuspend, (set), CONST sigset_t *set) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sigsuspend); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sigvec.c b/sysdeps/stub/sigvec.c new file mode 100644 index 0000000000..af8e24dc64 --- /dev/null +++ b/sysdeps/stub/sigvec.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <errno.h> + +/* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member + of VEC. The signals in `sv_mask' will be blocked while the handler runs. + If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be + reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL, + it is filled in with the old information for SIG. */ +int +DEFUN(__sigvec, (sig, vec, ovec), + int sig AND CONST struct sigvec *vec AND struct sigvec *ovec) +{ + errno = ENOSYS; + return -1; +} +stub_warning (sigvec) + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/stub/sin.c b/sysdeps/stub/sin.c new file mode 100644 index 0000000000..9286811cfe --- /dev/null +++ b/sysdeps/stub/sin.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the sine of X. */ +double +DEFUN(sin, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sin); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sinh.c b/sysdeps/stub/sinh.c new file mode 100644 index 0000000000..80c1b8833f --- /dev/null +++ b/sysdeps/stub/sinh.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the hyperbolic sine of X. */ +double +DEFUN(sinh, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sinh); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sleep.c b/sysdeps/stub/sleep.c new file mode 100644 index 0000000000..5cbeaaff49 --- /dev/null +++ b/sysdeps/stub/sleep.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> + +/* Make the process sleep for SECONDS seconds, or until a signal arrives + and is not ignored. The function returns the number of seconds less + than SECONDS which it actually slept (zero if it slept the full time). + If a signal handler does a `longjmp' or modifies the handling of the + SIGALRM signal while inside `sleep' call, the handling of the SIGALRM + signal afterwards is undefined. There is no return value to indicate + error, but if `sleep' returns SECONDS, it probably didn't work. */ +unsigned int +DEFUN(sleep, (seconds), unsigned int seconds) +{ + errno = ENOSYS; + return seconds; +} diff --git a/sysdeps/stub/socket.c b/sysdeps/stub/socket.c new file mode 100644 index 0000000000..a1e3d97e78 --- /dev/null +++ b/sysdeps/stub/socket.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Create a new socket of type TYPE in domain DOMAIN, using + protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. + Returns a file descriptor for the new socket, or -1 for errors. */ +int +DEFUN(socket, (domain, type, protocol), + int domain AND enum __socket_type type AND int protocol) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(socket); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/socketpair.c b/sysdeps/stub/socketpair.c new file mode 100644 index 0000000000..f79cc28823 --- /dev/null +++ b/sysdeps/stub/socketpair.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/socket.h> + +/* Create two new sockets, of type TYPE in domain DOMAIN and using + protocol PROTOCOL, which are connected to each other, and put file + descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, + one will be chosen automatically. Returns 0 on success, -1 for errors. */ +int +DEFUN(socketpair, (domain, type, protocol, fds), + int domain AND enum __socket_type type AND int protocol AND int fds[2]) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(socketpair); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sqrt.c b/sysdeps/stub/sqrt.c new file mode 100644 index 0000000000..bdba5e5944 --- /dev/null +++ b/sysdeps/stub/sqrt.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the square root of X. */ +double +DEFUN(sqrt, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sqrt); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sstk.c b/sysdeps/stub/sstk.c new file mode 100644 index 0000000000..0426d394af --- /dev/null +++ b/sysdeps/stub/sstk.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> + +/* Increase the size of the stack by INCREMENT, + and return the address of the bottom of the stack. */ +PTR +DEFUN(sstk, (increment), int increment) +{ + errno = ENOSYS; + return (PTR) -1; +} diff --git a/sysdeps/stub/start.c b/sysdeps/stub/start.c new file mode 100644 index 0000000000..b8bb04bbb4 --- /dev/null +++ b/sysdeps/stub/start.c @@ -0,0 +1,16 @@ +/* This file should define the low-level program entry point, + which should set up `__environ', and then do: + __libc_init(argc, argv, __environ); + exit(main(argc, argv, __environ)); + + This file should be prepared to be the first thing in the text section (on + Unix systems), or otherwise appropriately special. */ + +volatile int errno; + +#ifndef HAVE_GNU_LD +#undef environ +#define __environ environ +#endif + +char **__environ; diff --git a/sysdeps/stub/stat.c b/sysdeps/stub/stat.c new file mode 100644 index 0000000000..f24ce64e0c --- /dev/null +++ b/sysdeps/stub/stat.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/stat.h> +#include <stddef.h> + +/* Get file information about FILE in BUF. */ +int +DEFUN(__stat, (file, buf), CONST char *file AND struct stat *buf) +{ + if (file == NULL || buf == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (stat) + +weak_alias (__stat, stat) diff --git a/sysdeps/stub/statbuf.h b/sysdeps/stub/statbuf.h new file mode 100644 index 0000000000..e3fbce1667 --- /dev/null +++ b/sysdeps/stub/statbuf.h @@ -0,0 +1,71 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This structure needs to be defined in accordance with the + implementation of __stat, __fstat, and __lstat. */ + +#ifndef _STATBUF_H + +#define _STATBUF_H 1 + +#include <gnu/types.h> + +/* Structure describing file characteristics. */ +struct stat + { + /* These are the members that POSIX.1 requires. */ + + __mode_t st_mode; /* File mode. */ + __ino_t st_ino; /* File serial number. */ + __dev_t st_dev; /* Device containing the file. */ + __nlink_t st_nlink; /* Link count. */ + + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group. */ + __off_t st_size; /* Size of file, in bytes. */ + + __time_t st_atime; /* Time of last access. */ + __time_t st_mtime; /* Time of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + + /* This should be defined if there is a `st_blksize' member. */ +#undef _STATBUF_ST_BLKSIZE + }; + +/* Encoding of the file mode. These are the standard Unix values, + but POSIX.1 does not specify what values should be used. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + + +#endif /* statbuf.h */ diff --git a/sysdeps/stub/stdio_init.c b/sysdeps/stub/stdio_init.c new file mode 100644 index 0000000000..153b1a9491 --- /dev/null +++ b/sysdeps/stub/stdio_init.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +/* Initialize STREAM as necessary. + This may change I/O functions, give a buffer, etc. + If no buffer is allocated, but the bufsize is set, + the bufsize will be used to allocate the buffer. */ +void +DEFUN(__stdio_init_stream, (stream), FILE *stream) +{ + stream->__bufsize = BUFSIZ; +} diff --git a/sysdeps/stub/stdio_lim.h b/sysdeps/stub/stdio_lim.h new file mode 100644 index 0000000000..1a9125b55a --- /dev/null +++ b/sysdeps/stub/stdio_lim.h @@ -0,0 +1,6 @@ +#define L_tmpnam 1 +#define TMPMAX 0 +#define L_ctermid 1 +#define L_cuserid 1 +#define FOPEN_MAX 16 +#define FILENAME_MAX 14 diff --git a/sysdeps/stub/stime.c b/sysdeps/stub/stime.c new file mode 100644 index 0000000000..df6fdba12c --- /dev/null +++ b/sysdeps/stub/stime.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <time.h> +#include <stddef.h> + +/* Set the system clock to *WHEN. */ + +int +DEFUN(stime, (when), CONST time_t *when) +{ + if (when == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/strtsupp.c b/sysdeps/stub/strtsupp.c new file mode 100644 index 0000000000..9c5d041d99 --- /dev/null +++ b/sysdeps/stub/strtsupp.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil), + On-Line Applications Research Corporation. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <standalone.h> + +/* This file is only required when a "bare" board is configured. */ + +/* Start Support Routines + +The start code for some CPUs (e.g. i386) require target dependent +support. For more info, consult the start file for your CPU. */ + diff --git a/sysdeps/stub/stty.c b/sysdeps/stub/stty.c new file mode 100644 index 0000000000..24a865b2ea --- /dev/null +++ b/sysdeps/stub/stty.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sgtty.h> +#include <stddef.h> + +/* Set the terminal parameters associated with FD to *PARAMS. */ +int +DEFUN(stty, (fd, params), + int fd AND CONST struct sgttyb *params) +{ + if (params == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/swapon.c b/sysdeps/stub/swapon.c new file mode 100644 index 0000000000..825f353a88 --- /dev/null +++ b/sysdeps/stub/swapon.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Make the block special device PATH available to the system for swapping. + This call is restricted to the super-user. */ +int +DEFUN(swapon, (path), CONST char *path) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (swapon) diff --git a/sysdeps/stub/symlink.c b/sysdeps/stub/symlink.c new file mode 100644 index 0000000000..c8e6f1242a --- /dev/null +++ b/sysdeps/stub/symlink.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Make a link to FROM called TO. */ +int +DEFUN(__symlink, (from, to), CONST char *from AND CONST char *to) +{ + if (from == NULL || to == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (symlink) + +weak_alias (__symlink, symlink) diff --git a/sysdeps/stub/sync.c b/sysdeps/stub/sync.c new file mode 100644 index 0000000000..6a8e5e6976 --- /dev/null +++ b/sysdeps/stub/sync.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Make all changes done to all files actually appear on disk. */ +int +DEFUN_VOID(sync) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(sync); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sys/param.h b/sysdeps/stub/sys/param.h new file mode 100644 index 0000000000..8a3e73b406 --- /dev/null +++ b/sysdeps/stub/sys/param.h @@ -0,0 +1,8 @@ +/* This file should contain various parameter macros appropriate for the + machine and operating system. There is no standard set of macros; this + file is just for compatibility with programs written for Unix that + expect it to define things. On Unix systems that do not have their own + sysdep version of this file, it is generated at build time by examining + the installed headers on the system. */ + +#include <limits.h> diff --git a/sysdeps/stub/sys/reboot.h b/sysdeps/stub/sys/reboot.h new file mode 100644 index 0000000000..bada28dd6c --- /dev/null +++ b/sysdeps/stub/sys/reboot.h @@ -0,0 +1,9 @@ +/* This file should define RB_* macros to be used as flag + bits in the argument to the `reboot' system call. */ + +#ifndef _SYS_REBOOT_H +#define _SYS_REBOOT_H + +#define RB_AUTOBOOT 0 + +#endif /* <sys/reboot.h> */ diff --git a/sysdeps/stub/syscall.c b/sysdeps/stub/syscall.c new file mode 100644 index 0000000000..e8deffd0ad --- /dev/null +++ b/sysdeps/stub/syscall.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> + +/* Do system call CALLNO, passing it the remaining arguments. + This only makes sense in certain operating systems. */ + +int +DEFUN(syscall, (callno), int callno DOTS) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/syscall.h b/sysdeps/stub/syscall.h new file mode 100644 index 0000000000..719bd08904 --- /dev/null +++ b/sysdeps/stub/syscall.h @@ -0,0 +1,2 @@ +/* For Unix-like systems, this file should contain definitions + of macros SYS_call for each system call, giving the call numbers. */ diff --git a/sysdeps/stub/sysconf.c b/sysdeps/stub/sysconf.c new file mode 100644 index 0000000000..1d5d483793 --- /dev/null +++ b/sysdeps/stub/sysconf.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> +#include <limits.h> + + +/* Get the value of the system variable NAME. */ +long int +DEFUN(__sysconf, (name), int name) +{ + switch (name) + { + default: + errno = EINVAL; + return -1; + + case _SC_TZNAME_MAX: + return __tzname_max (); + + case _SC_ARG_MAX: + case _SC_CHILD_MAX: + case _SC_CLK_TCK: + case _SC_NGROUPS_MAX: + case _SC_OPEN_MAX: + case _SC_JOB_CONTROL: + case _SC_SAVED_IDS: + case _SC_VERSION: + + case _SC_BC_BASE_MAX: + case _SC_BC_DIM_MAX: + case _SC_BC_SCALE_MAX: + case _SC_BC_STRING_MAX: + case _SC_EQUIV_CLASS_MAX: + case _SC_EXPR_NEST_MAX: + case _SC_LINE_MAX: + case _SC_RE_DUP_MAX: + case _SC_2_VERSION: + case _SC_2_C_BIND: + case _SC_2_C_DEV: + case _SC_2_FORT_DEV: + case _SC_2_SW_DEV: + + break; + } + + errno = ENOSYS; + return -1; +} + +weak_alias (__sysconf, sysconf) diff --git a/sysdeps/stub/sysd-stdio.c b/sysdeps/stub/sysd-stdio.c new file mode 100644 index 0000000000..51d2ddb519 --- /dev/null +++ b/sysdeps/stub/sysd-stdio.c @@ -0,0 +1,111 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + + +/* Read up to N chars into BUF from COOKIE. + Return how many chars were read, 0 for EOF or -1 for error. */ +int +DEFUN(__stdio_read, (cookie, buf, n), + PTR cookie AND register char *buf AND register size_t n) +{ + errno = ENOSYS; + return -1; +} + +/* Write up to N chars from BUF to COOKIE. + Return how many chars were written or -1 for error. */ +int +DEFUN(__stdio_write, (cookie, buf, n), + PTR cookie AND register CONST char *buf AND register size_t n) +{ + errno = ENOSYS; + return -1; +} + +/* Move COOKIE's file position *POS bytes, according to WHENCE. + The new file position is stored in *POS. + Returns zero if successful, nonzero if not. */ +int +DEFUN(__stdio_seek, (cookie, pos, whence), + PTR cookie AND fpos_t *pos AND int whence) +{ + errno = ENOSYS; + return -1; +} + +/* Close the file associated with COOKIE. + Return 0 for success or -1 for failure. */ +int +DEFUN(__stdio_close, (cookie), PTR cookie) +{ + errno = ENOSYS; + return -1; +} + +/* Return the POSIX.1 file descriptor associated with COOKIE, + or -1 for errors. If COOKIE does not relate to any POSIX.1 file + descriptor, this should return -1 with errno set to EOPNOTSUPP. */ +int +DEFUN(__stdio_fileno, (cookie), PTR cookie) +{ + errno = ENOSYS; + return -1; +} + + +/* Open FILENAME with the mode in M. + Store the magic cookie associated with the opened file in *COOKIEPTR. + Return zero on success and nonzero on failure. */ +int +DEFUN(__stdio_open, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND PTR *cookieptr) +{ + errno = ENOSYS; + return -1; +} + + +/* Open FILENAME with the mode in M. Use the same magic cookie + already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */ +int +DEFUN(__stdio_reopen, (filename, m, cookieptr), + CONST char *filename AND __io_mode m AND + PTR *cookieptr AND __io_close_fn closefn) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__stdio_read); +stub_warning(__stdio_write); +stub_warning(__stdio_seek); +stub_warning(__stdio_close); +stub_warning(__stdio_fileno); +stub_warning(__stdio_open); +stub_warning(__stdio_reopen); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/sysdep.c b/sysdeps/stub/sysdep.c new file mode 100644 index 0000000000..5442eee00d --- /dev/null +++ b/sysdeps/stub/sysdep.c @@ -0,0 +1,2 @@ +/* This file should contain any system-dependent functions + that will be used by many parts of the library. */ diff --git a/sysdeps/stub/sysdep.h b/sysdeps/stub/sysdep.h new file mode 100644 index 0000000000..8c3184bf03 --- /dev/null +++ b/sysdeps/stub/sysdep.h @@ -0,0 +1,3 @@ +/* This file should contain any system-dependent types and macros + that will be used by many parts of the library. It should also + contain declarations for any functions defined in sysdep.c. */ diff --git a/sysdeps/stub/system.c b/sysdeps/stub/system.c new file mode 100644 index 0000000000..c2b35fbbcd --- /dev/null +++ b/sysdeps/stub/system.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> + + +/* Execute LINE as a shell command. */ +int +DEFUN(system, (line), CONST char *line) +{ + if (line == NULL) + return 0; /* This indicates no command processor. */ + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(system); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tan.c b/sysdeps/stub/tan.c new file mode 100644 index 0000000000..de7b56130e --- /dev/null +++ b/sysdeps/stub/tan.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the tangent of X. */ +double +DEFUN(tan, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tan); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tanh.c b/sysdeps/stub/tanh.c new file mode 100644 index 0000000000..3d748c015e --- /dev/null +++ b/sysdeps/stub/tanh.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Return the hyperbolic tangent of X. */ +double +DEFUN(tanh, (x), double x) +{ + errno = ENOSYS; + return(0.0); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tanh); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcdrain.c b/sysdeps/stub/tcdrain.c new file mode 100644 index 0000000000..9fc96b8e1e --- /dev/null +++ b/sysdeps/stub/tcdrain.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> + +/* Wait for pending output to be written on FD. */ +int +DEFUN(tcdrain, (fd), int fd) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcdrain); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcflow.c b/sysdeps/stub/tcflow.c new file mode 100644 index 0000000000..968b9a48de --- /dev/null +++ b/sysdeps/stub/tcflow.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> + +/* Suspend or restart transmission on FD. */ +int +DEFUN(tcflow, (fd, action), int fd AND int action) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + switch (action) + { + case TCOOFF: + case TCOON: + case TCIOFF: + case TCION: + break; + + default: + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcflow); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcflush.c b/sysdeps/stub/tcflush.c new file mode 100644 index 0000000000..3e9f7efa3a --- /dev/null +++ b/sysdeps/stub/tcflush.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> + +/* Flush pending data on FD. */ +int +DEFUN(tcflush, (fd, queue_selector), int fd AND int queue_selector) +{ + switch (queue_selector) + { + case TCIFLUSH: + case TCOFLUSH: + case TCIOFLUSH: + break; + + default: + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcflush); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcgetattr.c b/sysdeps/stub/tcgetattr.c new file mode 100644 index 0000000000..70208491ed --- /dev/null +++ b/sysdeps/stub/tcgetattr.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +/* Put the state of FD into *TERMIOS_P. */ +int +DEFUN(__tcgetattr, (fd, termios_p), + int fd AND struct termios *termios_p) +{ + if (fd < 0) + { + errno = EBADF; + return(-1); + } + if (termios_p == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} +stub_warning (tcgetattr) + +weak_alias (__tcgetattr, tcgetattr) diff --git a/sysdeps/stub/tcgetpgrp.c b/sysdeps/stub/tcgetpgrp.c new file mode 100644 index 0000000000..6a667d0a35 --- /dev/null +++ b/sysdeps/stub/tcgetpgrp.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Return the foreground process group ID of FD. */ +pid_t +DEFUN(tcgetpgrp, (fd), int fd) +{ + if (fd < 0) + { + errno = EBADF; + return (pid_t) -1; + } + + errno = ENOSYS; + return (pid_t) -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcgetpgrp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcsendbrk.c b/sysdeps/stub/tcsendbrk.c new file mode 100644 index 0000000000..4c90426186 --- /dev/null +++ b/sysdeps/stub/tcsendbrk.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> + +/* Send zero bits on FD. */ +int +DEFUN(tcsendbreak, (fd, duration), int fd AND int duration) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcsendbreak); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcsetattr.c b/sysdeps/stub/tcsetattr.c new file mode 100644 index 0000000000..21de21e3cb --- /dev/null +++ b/sysdeps/stub/tcsetattr.c @@ -0,0 +1,100 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +static int EXFUN(bad_speed, (speed_t speed)); + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + switch (optional_actions) + { + case TCSANOW: + case TCSADRAIN: + case TCSAFLUSH: + break; + default: + errno = EINVAL; + return -1; + } + + if (bad_speed(termios_p->__ospeed) || + bad_speed(termios_p->__ispeed == 0 ? + termios_p->__ospeed : termios_p->__ispeed)) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +/* Stricknine checking. */ +static int +DEFUN(bad_speed, (speed), speed_t speed) +{ + switch (speed) + { + case B0: + case B50: + case B75: + case B110: + case B134: + case B150: + case B200: + case B300: + case B600: + case B1200: + case B1800: + case B2400: + case B4800: + case B9600: + case B19200: + case B38400: + return 0; + default: + return 1; + } +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcsetattr); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tcsetpgrp.c b/sysdeps/stub/tcsetpgrp.c new file mode 100644 index 0000000000..06b8feda00 --- /dev/null +++ b/sysdeps/stub/tcsetpgrp.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the foreground process group ID of FD set PGRP_ID. */ +int +DEFUN(tcsetpgrp, (fd, pgrp_id), + int fd AND pid_t pgrp_id) +{ + if (fd < 0) + { + errno = EBADF; + return -1; + } + + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(tcsetpgrp); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/telldir.c b/sysdeps/stub/telldir.c new file mode 100644 index 0000000000..3d2a40e38c --- /dev/null +++ b/sysdeps/stub/telldir.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/types.h> +#include <stddef.h> +#include <dirent.h> + +/* Return the current position of DIRP. */ +off_t +DEFUN(telldir, (dirp), DIR *dirp) +{ + if (dirp == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return((off_t) -1); +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(telldir); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/tempname.c b/sysdeps/stub/tempname.c new file mode 100644 index 0000000000..6292f8acec --- /dev/null +++ b/sysdeps/stub/tempname.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdio.h> + +/* Generate a (hopefully) unique temporary filename + in DIR (if applicable), using prefix PFX. + If DIR_SEARCH is nonzero, perform directory searching + malarky as per the SVID for tempnam. + Return the generated filename or NULL if one could not + be generated, putting the length of the string in *LENPTR. */ +char * +DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr), + CONST char *dir AND CONST char *pfx AND + int dir_search AND size_t *lenptr AND + FILE **streamptr) +{ + *lenptr = 0; + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__stdio_gen_tempname); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/thread_state.h b/sysdeps/stub/thread_state.h new file mode 100644 index 0000000000..f2ec4ca56e --- /dev/null +++ b/sysdeps/stub/thread_state.h @@ -0,0 +1,47 @@ +/* Mach thread state definitions for machine-independent code. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Everything else is called `thread_state', but CMU's header file is + called `thread_status'. Oh boy. */ +#include <mach/thread_state.h> + +/* Replace <machine> with "i386" or "mips" or whatever. */ + +#define MACHINE_THREAD_STATE_FLAVOR <machine>_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT <machine>_THREAD_STATE_COUNT + +#define machine_thread_state <machine>_thread_state + +/* Define these to the member names in `struct <machine>_thread_state' + for the PC and stack pointer. */ +#define PC ? +#define SP ? + +/* This structure should contain all of the different flavors of thread + state structures which are meaningful for this machine. Every machine's + definition of this structure should have a member `int set' which is a + bit mask (1 << FLAVOR) of the flavors of thread state in the structure + which are filled in; and a member `struct machine_thread_state basic'. + On some machines those are the only members (e.g. i386); on others, + there are several relevant flavors of thread state (e.g. mips). */ +struct machine_thread_all_state + { + int set; /* Mask of bits (1 << FLAVOR). */ + struct <machine>_thread_state basic; + }; diff --git a/sysdeps/stub/time.c b/sysdeps/stub/time.c new file mode 100644 index 0000000000..bc1d3fccfe --- /dev/null +++ b/sysdeps/stub/time.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <time.h> + + +/* Return the time now, and store it in *TIMER if not NULL. */ +time_t +DEFUN(time, (timer), time_t *timer) +{ + errno = ENOSYS; + + if (timer != NULL) + *timer = (time_t) -1; + return (time_t) -1; +} + + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(time); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/times.c b/sysdeps/stub/times.c new file mode 100644 index 0000000000..2b47ec2f1d --- /dev/null +++ b/sysdeps/stub/times.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/times.h> +#include <stddef.h> + +/* Store the CPU time used by this process and all its + dead children (and their dead children) in BUFFER. + Return the elapsed real time, or (clock_t) -1 for errors. + All times are in CLK_TCKths of a second. */ +clock_t +DEFUN(__times, (buffer), struct tms *buffer) +{ + if (buffer == NULL) + { + errno = EINVAL; + return (clock_t) -1; + } + + errno = ENOSYS; + return (clock_t) -1; +} +stub_warning (times) + +weak_alias (__times, times) diff --git a/sysdeps/stub/trampoline.c b/sysdeps/stub/trampoline.c new file mode 100644 index 0000000000..8129d3be2c --- /dev/null +++ b/sysdeps/stub/trampoline.c @@ -0,0 +1,37 @@ +/* Set thread_state for sighandler, and sigcontext to recover. Stub version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <mach/thread_status.h> + +/* Set up STATE to run a signal handler in the thread it describes. + This should save the original state in a `struct sigcontext' on the + thread's stack (or possibly a signal stack described by SIGALTSTACK, + if the SA_ONSTACK bit is set in FLAGS), and return the address of + that structure. */ + +struct sigcontext * +_hurd_setup_sighandler (int flags, + __sighandler_t handler, + struct sigaltstack *sigaltstack, + int signo, int sigcode, + void *state) +{ +#error "Need to write sysdeps/mach/hurd/MACHINE/trampoline.c" +} diff --git a/sysdeps/stub/truncate.c b/sysdeps/stub/truncate.c new file mode 100644 index 0000000000..32d32d81f7 --- /dev/null +++ b/sysdeps/stub/truncate.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <errno.h> + +/* Truncate PATH to LENGTH bytes. */ +int +DEFUN(truncate, (path, length), + CONST char *path AND off_t length) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/ttyname.c b/sysdeps/stub/ttyname.c new file mode 100644 index 0000000000..1a7c559ee4 --- /dev/null +++ b/sysdeps/stub/ttyname.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +char *__ttyname = NULL; + +/* Return the pathname of the terminal FD is open on, or NULL on errors. + The returned storage is good only until the next call to this function. */ +char * +DEFUN(ttyname, (fd), int fd) +{ + errno = ENOSYS; + return NULL; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(ttyname); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/ualarm.c b/sysdeps/stub/ualarm.c new file mode 100644 index 0000000000..4a596d77e8 --- /dev/null +++ b/sysdeps/stub/ualarm.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> + +/* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds. + If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go + off every INTERVAL microseconds thereafter. + + Returns the number of microseconds remaining before the alarm. */ +unsigned int +DEFUN(ualarm, (value, interval), + unsigned int value AND unsigned int interval) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/udiv_qrnnd.c b/sysdeps/stub/udiv_qrnnd.c new file mode 100644 index 0000000000..d32796c04d --- /dev/null +++ b/sysdeps/stub/udiv_qrnnd.c @@ -0,0 +1,10 @@ +/* For some machines GNU MP needs to define an auxiliary function: + + udiv_qrnnd (quotient, remainder, high_numerator, low_numerator, denominator) + + Divides a two-word unsigned integer, composed by the integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. */ diff --git a/sysdeps/stub/ulimit.c b/sysdeps/stub/ulimit.c new file mode 100644 index 0000000000..aa9e515983 --- /dev/null +++ b/sysdeps/stub/ulimit.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> + +/* Function depends on CMD: + 1 = Return the limit on the size of a file, in units of 512 bytes. + 2 = Set the limit on the size of a file to NEWLIMIT. Only the + super-user can increase the limit. + 3 = Return the maximum possible address of the data segment. + 4 = Return the maximum number of files that the calling process + can open. + Returns -1 on errors. */ +long int +DEFUN(__ulimit, (cmd, newlimit), int cmd AND long int newlimit) +{ + errno = ENOSYS; + return -1; +} + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(__ulimit); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/umask.c b/sysdeps/stub/umask.c new file mode 100644 index 0000000000..18c85b74b7 --- /dev/null +++ b/sysdeps/stub/umask.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/stat.h> +#include <errno.h> +#include <sys/types.h> + +/* Set the file creation mask to MASK, returning the old mask. */ +mode_t +DEFUN(__umask, (mask), mode_t mask) +{ + errno = ENOSYS; + return -1; +} +stub_warning (umask) + +weak_alias (__umask, umask) diff --git a/sysdeps/stub/unlink.c b/sysdeps/stub/unlink.c new file mode 100644 index 0000000000..7f8e249f27 --- /dev/null +++ b/sysdeps/stub/unlink.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> + + +/* Remove the link named NAME. */ +int +DEFUN(__unlink, (name), CONST char *name) +{ + if (name == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} +stub_warning (unlink) + +weak_alias (__unlink, unlink) diff --git a/sysdeps/stub/usleep.c b/sysdeps/stub/usleep.c new file mode 100644 index 0000000000..f0c65d0710 --- /dev/null +++ b/sysdeps/stub/usleep.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> + +/* Sleep USECONDS microseconds, or until a previously set timer goes off. */ +unsigned int +DEFUN(usleep, (useconds), unsigned int useconds) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/stub/utime.c b/sysdeps/stub/utime.c new file mode 100644 index 0000000000..eee736fabd --- /dev/null +++ b/sysdeps/stub/utime.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <utime.h> + + +/* Set the access and modification times of FILE to those given in TIMES. + If TIMES is NULL, set them to the current time. */ +int +DEFUN(utime, (file, times), CONST char *file AND CONST struct utimbuf *times) +{ + if (file == NULL) + { + errno = EINVAL; + return(-1); + } + + errno = ENOSYS; + return(-1); +} + + + +#ifdef HAVE_GNU_LD + +#include <gnu-stabs.h> + +stub_warning(utime); + +#endif /* GNU stabs. */ diff --git a/sysdeps/stub/utimes.c b/sysdeps/stub/utimes.c new file mode 100644 index 0000000000..5172b0714a --- /dev/null +++ b/sysdeps/stub/utimes.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/time.h> +#include <errno.h> +#include <stddef.h> + +/* Change the access time of FILE to TVP[0] and + the modification time of FILE to TVP[1]. */ +int +DEFUN(__utimes, (file, tvp), + CONST char *file AND struct timeval tvp[2]) +{ + if (file == NULL || tvp == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} + +weak_alias (__utimes, utimes) diff --git a/sysdeps/stub/vhangup.c b/sysdeps/stub/vhangup.c new file mode 100644 index 0000000000..6a7a994365 --- /dev/null +++ b/sysdeps/stub/vhangup.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +/* Revoke access permissions to all processes currently communicating + with the control terminal, and then send a SIGHUP signal to the process + group of the control terminal. */ +int +DEFUN_VOID(vhangup) +{ + errno = ENOSYS; + return -1; +} + +stub_warning (vhangup) diff --git a/sysdeps/stub/wait.c b/sysdeps/stub/wait.c new file mode 100644 index 0000000000..97b78417b6 --- /dev/null +++ b/sysdeps/stub/wait.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/wait.h> +#include <errno.h> + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +__pid_t +DEFUN(__wait, (stat_loc), __WAIT_STATUS_DEFN stat_loc) +{ + errno = ENOSYS; + return -1; +} +stub_warning (wait) + +weak_alias (__wait, wait) diff --git a/sysdeps/stub/wait3.c b/sysdeps/stub/wait3.c new file mode 100644 index 0000000000..c1640dde8a --- /dev/null +++ b/sysdeps/stub/wait3.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not nil, + store information about the child's resource usage (as a `struct rusage') + there. If the WUNTRACED bit is set in OPTIONS, return status for stopped + children; otherwise don't. */ +pid_t +DEFUN(__wait3, (stat_loc, options, usage), + __WAIT_STATUS_DEFN stat_loc AND int options AND struct rusage *usage) +{ + if ((options & ~(WNOHANG|WUNTRACED)) != 0) + { + errno = EINVAL; + return (pid_t) -1; + } + + errno = ENOSYS; + return (pid_t) -1; +} +stub_warning (wait3) + +weak_alias (__wait3, wait3) diff --git a/sysdeps/stub/wait4.c b/sysdeps/stub/wait4.c new file mode 100644 index 0000000000..2062d4b2cc --- /dev/null +++ b/sysdeps/stub/wait4.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> + +pid_t +DEFUN(__wait4, (pid, stat_loc, options, usage), + pid_t pid AND __WAIT_STATUS_DEFN stat_loc AND int options AND + struct rusage *usage) +{ + errno = ENOSYS; + return (pid_t) -1; +} +stub_warning (wait4) + +weak_alias (__wait4, wait4) diff --git a/sysdeps/stub/waitflags.h b/sysdeps/stub/waitflags.h new file mode 100644 index 0000000000..52e4f80619 --- /dev/null +++ b/sysdeps/stub/waitflags.h @@ -0,0 +1,28 @@ +/* Definitions of flag bits for `waitpid' et al. +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _WAITFLAGS_H + +#define _WAITFLAGS_H 1 + +/* Bits in the third argument to `waitpid'. */ +#define WNOHANG 1 /* Don't block waiting. */ +#define WUNTRACED 2 /* Report status of stopped children. */ + +#endif /* waitflags.h */ diff --git a/sysdeps/stub/waitpid.c b/sysdeps/stub/waitpid.c new file mode 100644 index 0000000000..22eb019eb5 --- /dev/null +++ b/sysdeps/stub/waitpid.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> + + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS, + return status for stopped children; otherwise don't. */ +pid_t +DEFUN(__waitpid, (pid, stat_loc, options), + pid_t pid AND int *stat_loc AND int options) +{ + if ((options & ~(WNOHANG|WUNTRACED)) != 0) + { + errno = EINVAL; + return (pid_t) -1; + } + + errno = ENOSYS; + return (pid_t) -1; +} +stub_warning (waitpid) + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/stub/write.c b/sysdeps/stub/write.c new file mode 100644 index 0000000000..deb4851e06 --- /dev/null +++ b/sysdeps/stub/write.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <unistd.h> +#include <stddef.h> + +/* Write NBYTES of BUF to FD. Return the number written, or -1. */ +ssize_t +DEFUN(__write, (fd, buf, nbytes), + int fd AND CONST PTR buf AND size_t nbytes) +{ + if (nbytes == 0) + return 0; + if (fd < 0) + { + errno = EBADF; + return -1; + } + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + errno = ENOSYS; + return -1; +} +stub_warning (write) + +weak_alias (__write, write) diff --git a/sysdeps/stub/writev.c b/sysdeps/stub/writev.c new file mode 100644 index 0000000000..de354e8cd7 --- /dev/null +++ b/sysdeps/stub/writev.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/uio.h> + +/* Write data pointed by the buffers described by VECTOR, which + is a vector of COUNT `struct iovec's, to file descriptor FD. + The data is written in the order specified. + Operates just like `write' (see <unistd.h>) except that the data + are taken from VECTOR instead of a contiguous buffer. */ +int +DEFUN(writev, (fd, vector, count), + int fd AND CONST struct iovec *vector AND size_t count) +{ + errno = ENOSYS; + return -1; +} diff --git a/sysdeps/tahoe/Implies b/sysdeps/tahoe/Implies new file mode 100644 index 0000000000..5a3163701f --- /dev/null +++ b/sysdeps/tahoe/Implies @@ -0,0 +1,2 @@ +# A Tahoe is mostly just like a Vax. +vax diff --git a/sysdeps/tahoe/log10.c b/sysdeps/tahoe/log10.c new file mode 100644 index 0000000000..2cf2cee58b --- /dev/null +++ b/sysdeps/tahoe/log10.c @@ -0,0 +1,22 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define FPCONST(hi0, lo0, hi1, lo1) { (hi0), (lo0), (hi1), (lo1) } + +#include <../sysdeps/vax/log10.c> + diff --git a/sysdeps/unix/Dist b/sysdeps/unix/Dist new file mode 100644 index 0000000000..1816f6bdae --- /dev/null +++ b/sysdeps/unix/Dist @@ -0,0 +1,4 @@ +errnos-tmpl.c errnos.awk +ioctls-tmpl.c ioctls.awk snarf-ioctls +make_errlist.c +mk-local_lim.c diff --git a/sysdeps/unix/Implies b/sysdeps/unix/Implies new file mode 100644 index 0000000000..b3188f7428 --- /dev/null +++ b/sysdeps/unix/Implies @@ -0,0 +1 @@ +posix diff --git a/sysdeps/unix/Makefile b/sysdeps/unix/Makefile new file mode 100644 index 0000000000..6bc0f5a1d0 --- /dev/null +++ b/sysdeps/unix/Makefile @@ -0,0 +1,267 @@ +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# The unix-specific configure fragment writes `unix-generated' in config.make. +config-generated := $(config-generated) $(unix-generated) + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/local_lim.h)))))) + +ifneq (,$(wildcard $(sysincludedir)/sys/param.h)) +local_lim-CFLAGS := $(local_lim-CFLAGS) -DHAVE_SYS_PARAM_H +endif +ifneq (,$(wildcard $(sysincludedir)/sys/limits.h)) +local_lim-CFLAGS := $(local_lim-CFLAGS) -DHAVE_SYS_LIMITS_H +endif +ifneq (,$(wildcard $(sysincludedir)/limits.h)) +local_lim-CFLAGS := $(local_lim-CFLAGS) -DHAVE_LIMITS_H +endif + +$(common-objpfx)local_lim.h: $(common-objpfx)mk-local_lim + if $(dir $<)$(notdir $<) > $@-t; then mv $@-t $@; else XXX; fi +$(common-objpfx)mk-local_lim: $(sysdep_dir)/unix/mk-local_lim.c + cwd=`pwd`; cd $(@D); \ + $(BUILD_CC) $(BUILD_CFLAGS) $(local_lim-CFLAGS) $$cwd/$< -o $(@F) + +before-compile := $(before-compile) $(common-objpfx)local_lim.h +common-generated := $(common-generated) local_lim.h mk-local_lim + +endif + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(patsubst %/sys/param.h,%/,\ + $(firstword $(wildcard $(+sysdep_dirs:%=%/sys/param.h)))))) + +before-compile := $(before-compile) $(common-objpfx)sys/param.h + +$(common-objpfx)sys/param.h: $(sysincludedir)/sys/param.h + -mkdir $(@D:%/=%) + (echo '#ifndef _GNU_SYS_PARAM_H'; \ + echo '#define _GNU_SYS_PARAM_H 1'; \ + echo '#include <endian.h>'; \ + awk < $< \ + '/^#define[ ]*NULL/ { print "#ifndef NULL"; \ + print $$0; \ + print "#endif"; \ + was_null = 1 } \ + { if (!was_null) print $$0; \ + was_null = 0 }'; \ + echo '#ifndef MAXHOSTNAMELEN'; \ + echo '#define MAXHOSTNAMELEN 64 /* XXX */'; \ + echo '#endif /* No MAXHOSTNAMELEN. */'; \ + echo '#endif /* sys/param.h */') > $@-tmp + mv $@-tmp $@ + +$(common-objpfx)param.h.c: $(sysincludedir)/sys/param.h + rm -f $@ + cp $< $@ +$(common-objpfx)param.h.dep: $(common-objpfx)param.h.c \ + $(sysdep_dir)/unix/Makefile + $(+mkdep) -I$(sysincludedir) $< \ + | sed > $@ \ + -e 's@^.*:@@' \ + -e 's@$<@@g' \ + -e 's@$(sysincludedir)/*@@g' \ + -e 's@\\$$@@' \ + -e 's@^@sys/param.h-includes := $$(sys/param.h-includes) @' + +# Get the generated definition of sys/param.h-includes. +ifndef no_deps +include $(common-objpfx)param.h.dep +endif + +# Don't preempt our own headers. +sys/param.h-includes := \ + $(filter-out $(patsubst $(..)%,%,\ + $(wildcard $(addprefix $(..),\ + $(sys/param.h-includes)))),\ + $(sys/param.h-includes)) + + +.PHONY: sys/param.h-includes +sys/param.h-includes: $(addprefix $(common-objpfx),$(sys/param.h-includes)) + +ifdef sys/param.h-includes +# Copy the system files to $(common-objdir). +$(addprefix $(common-objpfx),$(sys/param.h-includes)): $(common-objpfx)%: \ + $(sysincludedir)/% + -mkdir $(@D:%/=%) +# Some of these files sometimes contain conflicting declarations for htons, +# ntohs, etc. They also often contain definitions of *_ENDIAN and +# BYTE_ORDER, which we define ourselves in <endian.h>. + sed -e '/[ ]*[hn]to[nh][sl][ (]*/d' \ + -e '/^#define[ ]*[A-Z]*_ENDIAN/d' \ + -e '/^#define[ ]*BYTE_ORDER/d' \ + $< > $@-t + mv $@-t $@ +endif + +common-generated := $(common-generated) \ + sys/param.h $(sys/param.h-includes) param.h.c param.h.dep + + +ifeq ($(subdir),misc) + +# Install system headers the system sys/param.h uses. + +sysdep_headers := $(sysdep_headers) $(sys/param.h-includes) + +endif # misc + +endif # No sysdep sys/param.h. + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/errnos.h)))))) + +# These need to exist before any compiling is done, +# so cpp doesn't instead find the stub versions. +before-compile := $(before-compile) $(common-objpfx)errnos.h + +$(common-objpfx)errnos.h: $(common-objpfx)make-errnos + $(dir $<)$(notdir $<) > $@-tmp + mv $@-tmp $@ + +$(common-objpfx)make-errnos: $(common-objpfx)make-errnos.c + $(common-objdir-compile) + +$(common-objpfx)make-errnos.c: $(sysdep_dir)/unix/errnos-tmpl.c \ + $(sysdep_dir)/unix/errnos.awk $(common-objpfx)errnos + awk -f $(word 2,$^) errnos="`tr '\012' ' ' < $(word 3,$^)`" $< > $@T + mv $@T $@ + +$(common-objpfx)errnos: $(wildcard $(sysincludedir)/errno.h \ + $(sysincludedir)/sys/errno.h) + cat $^ | sed -n 's/^#define[ ]*\(E[A-Z0-9][A-Z0-9]*\)[ ].*$$/\1/p' > $@-tmp + mv $@-tmp $@ + +common-generated := $(common-generated) \ + errnos.h errnos make-errnos make-errnos.c +endif + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/ioctls.h)))))) + +before-compile := $(before-compile) $(common-objpfx)ioctls.h + +$(common-objpfx)ioctls.h: $(common-objpfx)make-ioctls + $(dir $<)$(notdir $<) > $@-tmp + mv $@-tmp $@ + +ioctl-includes := sys/termios.h net/nit.h +ioctl-includes := $(wildcard $(addprefix $(sysincludedir)/,$(ioctl-includes))) +make-ioctls-CFLAGS := $(subst /,_,$(subst .,_,\ + $(patsubst $(sysincludedir)/%,-DHAVE_%,\ + $(ioctl-includes)))) + +$(common-objpfx)make-ioctls: $(common-objpfx)make-ioctls.c + cd $(@D); $(BUILD_CC) $(BUILD_CFLAGS) $(make-ioctls-CFLAGS) \ + $(<:$(common-objpfx)%=%) -o $(@F) + +$(common-objpfx)make-ioctls.c: $(sysdep_dir)/unix/ioctls-tmpl.c \ + $(sysdep_dir)/unix/ioctls.awk \ + $(common-objpfx)ioctls + awk -f $(word 2,$^) requests="`cat $(word 3,$^)`" $< > $@T + mv $@T $@ + + +termbits.h := $(firstword $(wildcard $(+sysdep_dirs:%=%/termbits.h))) +ifeq ($(termbits.h),$(sysdep_dir)/generic/termbits.h) +termbits.h := # Ignore the generic version. +endif + +# If there is a system-specific <termbits.h> file, we want to omit all the +# symbols it defines from ioctls. Otherwise, both ioctls.h and termbits.h +# would define them. The system-specific <termbits.h> file presumably +# defines them with the same values as we find from the system's headers. +# We also want to omit from ioctls the symbols defined in our own +# <sys/ttydefaults.h>, to avoid multiple definition conflicts. We use +# snarf-ioctls on these files to find what symbols we want to omit. fgrep +# -xv gives all lines which do not match in their entirety; without -x, +# CSTOP's presence elided TIOCSTOP. + +$(common-objpfx)ioctls: $(sysdep_dir)/unix/snarf-ioctls \ + $(sysincludedir)/sys/ioctl.h $(ioctl-includes) + $(dir $<)$(notdir $<) $(filter-out $<,$^) \ + | fgrep -xv "`$(dir $<)$(notdir $<) $(termbits.h) \ + $(..)termios/sys/ttydefaults.h \ + | sort | uniq`" \ + | sort | uniq | tr '\012' ' ' > $@-tmp + mv $@-tmp $@ + +common-generated := $(common-generated) \ + ioctls.h ioctls make-ioctls make-ioctls.c +endif + +ifeq ($(subdir),stdio) +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/errlist.c)))))) + +before-compile: $(objpfx)errlist.c +$(objpfx)errlist.c: $(objpfx)make_errlist + @rm -f $@ + $(dir $<)$(notdir $<) > $@-tmp + mv $@-tmp $@ + +$(objpfx)make_errlist: $(sysdep_dir)/unix/make_errlist.c + $(native-compile) + +generated := $(generated) make_errlist errlist.c + +endif +endif # stdio + +ifeq (,$(filter-out $(sysdep_dir)/stub/ $(common-objpfx),\ + $(dir $(firstword $(wildcard $(+sysdep_dirs:%=%/syscall.h)))))) + +# The syscall code assumes a file <syscall.h> that defines macros +# `SYS_call' for syscall `call'. Variations on this I have seen include: +# it's in <sys/syscall.h>; +# it's in <sys.s>; +# it defines `CALL' instead of `SYS_call'. +# Irix has a <syscall.h> which is not what we want, so check for <sys.s> first. + +# Find a file that might have these. NOTE: This list of possibilities is +# repeated in sysdeps/unix/configure and the two should be kept in sync. +syscall.h := $(firstword $(wildcard $(addprefix $(sysincludedir)/, \ + sys.s sys/sys.s \ + sys.S sys/sys.S \ + syscall.h sys/syscall.h \ + ))) +ifdef syscall.h + +# Transmogrify any of several formats of the file into the one we want. +$(common-objpfx)syscall.h: $(syscall.h) + tr '[A-Z]' '[a-z]' < $< | \ + sed -e 's/[ ]sys_/ /' \ + -e 's/^#define[ ]*\([a-z0-9_]*\)[ ]*/#define SYS_\1 /' \ + -e 's/[ ]sys_/ SYS_/' \ + -e 's/SYS_syscall_basenum/syscall_basenum/g' \ + -e 's/SYS_kerncall_basenum/kerncall_basenum/g' \ + -e 's/SYS_sysvoffset/sysvoffset/g' \ + -e '/^#/!d' \ + -e '/^#ident/d' \ + -e 's-\(/\*[^*]*\)$$-\1\*/-' \ + > $@-tmp + mv $@-tmp $@ + +before-compile := $(before-compile) $(common-objpfx)syscall.h +common-generated := $(common-generated) syscall.h + +endif + +endif diff --git a/sysdeps/unix/_exit.S b/sysdeps/unix/_exit.S new file mode 100644 index 0000000000..a171689473 --- /dev/null +++ b/sysdeps/unix/_exit.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (_exit, exit, 1) + /* Shouldn't get here. */ diff --git a/sysdeps/unix/acct.S b/sysdeps/unix/acct.S new file mode 100644 index 0000000000..f9363d253d --- /dev/null +++ b/sysdeps/unix/acct.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (acct, 1) + ret diff --git a/sysdeps/unix/bsd/Attic/osf1/=dirstream.h b/sysdeps/unix/bsd/Attic/osf1/=dirstream.h new file mode 100644 index 0000000000..c37610e258 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/=dirstream.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + +#define __need_size_t +#include <stddef.h> + +/* Directory stream type. */ + +typedef struct + { + int __fd; /* File descriptor. */ + + size_t __offset; /* Current offset into the block. */ + size_t __size; /* Total valid data in the block. */ + char *__data; /* Directory block. */ + + int __allocation; /* Space allocated for the block. */ + + int __data_len; /* Size of __data. */ + long __dd_seek; /* OSF/1 magic cookie returned by getdents. */ + void *dd_lock; /* Used by OSF/1 for inter-thread locking. */ + + } DIR; + +#endif /* dirstream.h */ diff --git a/sysdeps/unix/bsd/Attic/osf1/Implies b/sysdeps/unix/bsd/Attic/osf1/Implies new file mode 100644 index 0000000000..82719f5a5d --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/Implies @@ -0,0 +1,2 @@ +# OSF/1 has the canonical set of <sys/mman.h> system calls. +unix/mman diff --git a/sysdeps/unix/bsd/Attic/osf1/Makefile b/sysdeps/unix/bsd/Attic/osf1/Makefile new file mode 100644 index 0000000000..743788a41a --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/Makefile @@ -0,0 +1,3 @@ +# Without -non_shared (via the compiler's -static flag), we'll end up +# with some unresolved symbols wrt exceptions. +LDFLAGS := $(LDFLAGS) -static diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/brk.S b/sysdeps/unix/bsd/Attic/osf1/alpha/brk.S new file mode 100644 index 0000000000..111f3397af --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/brk.S @@ -0,0 +1,53 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef HAVE_GNU_LD +#define __end end +#endif + +.data + .extern __end,8 + .globl __curbrk +__curbrk: + .quad __end + +.text +ENTRY(__brk) + ! FIXME We do not check for asking for less than a page yet. + ldiq v0, SYS_brk + call_pal PAL_callsys + bne a3, error + + /* Update __curbrk and exit cleanly. */ +! ldgp gp, 0(t12) + stl a0, __curbrk + + mov zero, v0 + ret + /* What a horrible way to die. */ +error: ldgp gp,0(gp) + jmp zero,syscall_error + .end __brk + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/fork.S b/sysdeps/unix/bsd/Attic/osf1/alpha/fork.S new file mode 100644 index 0000000000..7c8d671893 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/fork.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fork, 0) + cmovne a4, 0, v0 + ret + +weak_alias (__fork, fork) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/getdents.S b/sysdeps/unix/bsd/Attic/osf1/alpha/getdents.S new file mode 100644 index 0000000000..16ccbc2ce2 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/getdents.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getdirentries, 4) + ret + +weak_alias (__getdirentries, getdirentries) + diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/killpg.S b/sysdeps/unix/bsd/Attic/osf1/alpha/killpg.S new file mode 100644 index 0000000000..f0b82b3d1a --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/killpg.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_killpg SYS_ult_killpg + +SYSCALL (killpg, 2) + ret diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/pipe.S b/sysdeps/unix/bsd/Attic/osf1/alpha/pipe.S new file mode 100644 index 0000000000..6b074eda1a --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/pipe.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pipe, 1) + /* Plop in the two descriptors. */ + stl r0, 0(a0) + stl r1, 4(a0) + + /* Go out with a clean status. */ + mov zero, r0 + ret + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/recv.S b/sysdeps/unix/bsd/Attic/osf1/alpha/recv.S new file mode 100644 index 0000000000..4ac00eb44e --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/recv.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_recv SYS_ult_recv + +SYSCALL (recv, 4) + ret diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/send.S b/sysdeps/unix/bsd/Attic/osf1/alpha/send.S new file mode 100644 index 0000000000..ca46894a25 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/send.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_send SYS_ult_send + +SYSCALL (send, 4) + ret diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sigblock.S b/sysdeps/unix/bsd/Attic/osf1/alpha/sigblock.S new file mode 100644 index 0000000000..c3556a915f --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sigblock.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_sigblock SYS_ult_sigblock + +SYSCALL__ (sigblock, 1) + ret + +weak_alias (__sigblock, sigblock) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sigpause.S b/sysdeps/unix/bsd/Attic/osf1/alpha/sigpause.S new file mode 100644 index 0000000000..04b6d45db7 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sigpause.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_sigpause SYS_ult_sigpause + +SYSCALL__ (sigpause, 1) + ret + +weak_alias (__sigpause, sigpause) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sigsetmask.S b/sysdeps/unix/bsd/Attic/osf1/alpha/sigsetmask.S new file mode 100644 index 0000000000..fb3a1d19f7 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sigsetmask.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_sigsetmask SYS_ult_sigsetmask + +SYSCALL__ (sigsetmask, 1) + ret + +weak_alias (__sigsetmask, sigsetmask) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sigvec.S b/sysdeps/unix/bsd/Attic/osf1/alpha/sigvec.S new file mode 100644 index 0000000000..b04ec6e12e --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sigvec.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_sigvec SYS_ult_sigvec + +SYSCALL__ (sigvec, 3) + ret + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/start.S b/sysdeps/unix/bsd/Attic/osf1/alpha/start.S new file mode 100644 index 0000000000..8b7109a512 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/start.S @@ -0,0 +1,72 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef HAVE_WEAK_SYMBOLS +#define __environ environ +#else +weak_alias (__environ, environ) +#endif + +.comm __environ, 8 +.comm errno, 4 + +!.sdata +!.globl STARTFRM +!STARTFRM = 0 + +.text +ENTRY(__start) + lda sp, -16(sp) + stq zero, 8(sp) + + ! This branch puts the address of the current insn in t0. + br t0, 10f +10: + ! We set the GP register by using the address of the ldgp + ! (what we just put into t0). + ldgp gp, 0(t0) + + ! get argc + ldl a0, 16(sp) + + ! get argv + lda a1, 24(sp) + + ! move ahead to envp + s8addq a0, a1, a2 + addq a2, 0x8, a2 + + ! Store in environ. + stq a2, environ + + ! Clear out errno. +! ldgp gp, 0(t12) + stl zero, errno + + ! Call main. + jsr ra, main + ldgp gp, 0(ra) + + mov v0, a0 + + jsr ra, exit + ldgp gp, 0(ra) + + .end __start diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/statbuf.h b/sysdeps/unix/bsd/Attic/osf1/alpha/statbuf.h new file mode 100644 index 0000000000..9cadfaefd3 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/statbuf.h @@ -0,0 +1,75 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H +#define _STATBUF_H + +#include <gnu/types.h> + +/* Structure describing file characteristics. */ +struct stat + { + int st_dev; /* Device. */ + unsigned int st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned short st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group.*/ + int st_rdev; /* Device number, if device. */ + + long st_size; /* Size of file, in bytes. */ + + int st_atime; /* Time of last access. */ + int st_atime_usec; + int st_mtime; /* Time of last modification. */ + int st_mtime_usec; + int st_ctime; /* Time of last status change. */ + int st_ctime_usec; + + unsigned int st_blksize; /* Optimal block size for I/O. */ +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + + int st_blocks; /* Number of 512-byte blocks allocated. */ + unsigned int st_flags; + unsigned int st_gen; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#endif /* statbuf.h */ diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.S b/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.S new file mode 100644 index 0000000000..bc4865cef2 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.S @@ -0,0 +1,40 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +ENTRY(syscall_error) +#ifdef EWOULDBLOCK_sys + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + subq v0, EWOULDBLOCK_sys, t0 + cmoveq t0, EAGAIN, v0 +#endif + + /* Store it in errno... */ +! ldgp gp, 0(t12) + stl v0, errno + + /* And just kick back a -1. */ + ldil v0, -1 + ret + + .end syscall_error diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.h b/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.h new file mode 100644 index 0000000000..3669a69b9b --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/sysdep.h @@ -0,0 +1,73 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#include <machine/pal.h> /* get PAL_callsys */ +#include <regdef.h> + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl name; \ + .ent name,0; \ + name##:; \ + .frame sp,0,ra +#else +#define ENTRY(name) \ + .globl name; \ + .ent name,0; \ + name/**/:; \ + .frame sp,0,ra +#endif + +#ifdef __STDC__ +#define PSEUDO(name, syscall_name, args) \ + ENTRY(name); \ + ldiq v0, SYS_##syscall_name; \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + beq a3, 10f; \ + br gp, 20f; \ +20:; \ + ldgp gp, 0(gp); \ + jmp zero, syscall_error; \ +10: +#else +#define PSEUDO(name, syscall_name, args) \ + ENTRY(name); \ + ldiq v0, SYS_/**/syscall_name; \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + beq a3, 10f; \ + br gp, 20f; \ +20:; \ + ldgp gp, 0(gp); \ + jmp zero, syscall_error; \ +10: +#endif + +#define ret ret zero,(ra),1 +#define r0 v0 +#define r1 a4 +#define MOVE(x,y) mov x, y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/vhangup.S b/sysdeps/unix/bsd/Attic/osf1/alpha/vhangup.S new file mode 100644 index 0000000000..d4d2b1c485 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/vhangup.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#include <sys/ult_syscall.h> +#define SYS_vhangup SYS_ult_vhangup + +SYSCALL (vhangup, 1) + ret diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/wait4.S b/sysdeps/unix/bsd/Attic/osf1/alpha/wait4.S new file mode 100644 index 0000000000..e4c322341d --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/wait4.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait4.S> diff --git a/sysdeps/unix/bsd/Attic/osf1/alpha/waitpid.c b/sysdeps/unix/bsd/Attic/osf1/alpha/waitpid.c new file mode 100644 index 0000000000..8378982ac7 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/alpha/waitpid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/waitpid.c> diff --git a/sysdeps/unix/bsd/Attic/osf1/msync.S b/sysdeps/unix/bsd/Attic/osf1/msync.S new file mode 100644 index 0000000000..75b9f1531d --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/msync.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/sunos4/msync.S> diff --git a/sysdeps/unix/bsd/Attic/osf1/sigaction.h b/sysdeps/unix/bsd/Attic/osf1/sigaction.h new file mode 100644 index 0000000000..8a4e2c5b84 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/sigaction.h @@ -0,0 +1,45 @@ +/* Structure and constand definitions for sigaction et al. OSF/1 version. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Structure describing the action to be taken when a signal arrives. */ +struct sigaction + { + /* Signal handler. */ + __sighandler_t sa_handler; + + /* Additional set of signals to be blocked. */ + __sigset_t sa_mask; + + /* Special flags. */ + int sa_flags; + }; + +/* Bits in `sa_flags'. */ +#ifdef __USE_BSD +#define SA_ONSTACK 0x1 /* Take signal on signal stack. */ +#define SA_RESTART 0x2 /* Don't restart syscall on signal return. */ +#define SA_DISABLE 0x4 /* Disable alternate signal stack. */ +#endif +#define SA_NOCLDSTOP 0x4 /* Don't send SIGCHLD when children stop. */ + + +/* Values for the HOW argument to `sigprocmask'. */ +#define SIG_BLOCK 1 /* Block signals. */ +#define SIG_UNBLOCK 2 /* Unblock signals. */ +#define SIG_SETMASK 3 /* Set the set of blocked signals. */ diff --git a/sysdeps/unix/bsd/Attic/osf1/sys/mman.h b/sysdeps/unix/bsd/Attic/osf1/sys/mman.h new file mode 100644 index 0000000000..6ac25f459f --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/sys/mman.h @@ -0,0 +1,114 @@ +/* Definitions for BSD-style memory management. OSF/1 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These are the bits used by 4.4 BSD and its derivatives. On systems + (such as GNU) where these facilities are not system services but can be + emulated in the C library, these are the definitions we emulate. */ + +#ifndef _SYS_MMAN_H + +#define _SYS_MMAN_H 1 +#include <features.h> + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x01 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x04 /* Pages can be executed. */ + + +/* Flags contain mapping type, sharing type and options. */ + +/* Mapping type (must choose one and only one of these). */ +#define MAP_FILE 0x00 /* Mapped from a file or device. */ +#define MAP_ANON 0x10 /* Allocated from anonymous virtual memory. */ +#define MAP_ANONYMOUS MAP_ANON +#define MAP_TYPE 0xf0 /* Mask for type field. */ + +/* Sharing types (must choose one and only one of these). */ +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes private; copy pages on write. */ + +/* Other flags. */ +#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */ +#define MAP_VARIABLE 0 /* Absence of MAP_FIXED. */ +#define MAP_HASSEMPHORE 0x0200 /* Region may contain semaphores. */ +#define MAP_INHERIT 0x0400 /* Region is retained after exec. */ +#define MAP_UNALIGNED 0x0800 /* File offset need not be page-aligned. */ + +/* Advice to `madvise'. */ +#define MADV_NORMAL 0 /* No further special treatment. */ +#define MADV_RANDOM 1 /* Expect random page references. */ +#define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define MADV_WILLNEED 3 /* Will need these pages. */ +#define MADV_DONTNEED 4 /* Don't need these pages. */ +#define MADV_SPACEAVAIL 5 /* Ensure that resources are available. */ + +/* Flags to `msync'. */ +#define MS_ASYNC 1 /* Asynchronous cache flush. */ +#define MS_SYNC 3 /* Synchronous cache flush. */ +#define MS_INVALIDATE 4 /* Invalidate cached pages. */ + + +#include <sys/cdefs.h> + +__BEGIN_DECLS +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__caddr_t mmap __P ((__caddr_t __addr, size_t __len, + int __prot, int __flags, int __fd, off_t __offset)); + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ +int munmap __P ((__caddr_t __addr, size_t __len)); + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ +int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ +int msync __P ((__caddr_t __addr, size_t __len, int __flags)); + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ +int madvise __P ((__caddr_t __addr, size_t __len, int __advice)); + +__END_DECLS + + +#endif /* sys/mman.h */ diff --git a/sysdeps/unix/bsd/Attic/osf1/system.c b/sysdeps/unix/bsd/Attic/osf1/system.c new file mode 100644 index 0000000000..ef42ea2155 --- /dev/null +++ b/sysdeps/unix/bsd/Attic/osf1/system.c @@ -0,0 +1,2 @@ +/* OSF/1 does have `waitpid'. Avoid unix/system.c, which says we don't. */ +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/bsd/Dist b/sysdeps/unix/bsd/Dist new file mode 100644 index 0000000000..9e0e553aa7 --- /dev/null +++ b/sysdeps/unix/bsd/Dist @@ -0,0 +1 @@ +bsdtty.h diff --git a/sysdeps/unix/bsd/Implies b/sysdeps/unix/bsd/Implies new file mode 100644 index 0000000000..cfc44915d8 --- /dev/null +++ b/sysdeps/unix/bsd/Implies @@ -0,0 +1,5 @@ +# The directory unix/common contains things which are common to both BSD +# and SVR4. +unix/common +# The directory unix/inet implements sockets and networking in the usual way. +unix/inet diff --git a/sysdeps/unix/bsd/alarm.c b/sysdeps/unix/bsd/alarm.c new file mode 100644 index 0000000000..7743256a09 --- /dev/null +++ b/sysdeps/unix/bsd/alarm.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/time.h> + +/* Schedule an alarm. In SECONDS seconds, the process will get a SIGALRM. + If SECONDS is zero, any currently scheduled alarm will be cancelled. + The function returns the number of seconds remaining until the last + alarm scheduled would have signaled, or zero if there wasn't one. + There is no return value to indicate an error, but you can set `errno' + to 0 and check its value after calling `alarm', and this might tell you. + The signal may come late due to processor scheduling. */ +unsigned int +DEFUN(alarm, (seconds), unsigned int seconds) +{ + struct itimerval old, new; + + new.it_interval.tv_usec = 0; + new.it_interval.tv_sec = 0; + new.it_value.tv_usec = 0; + new.it_value.tv_sec = (long int) seconds; + if (__setitimer(ITIMER_REAL, &new, &old) < 0) + return 0; + + return (old.it_value.tv_sec + (old.it_value.tv_usec + 999999) / 1000000); +} diff --git a/sysdeps/unix/bsd/bsd4.4/Implies b/sysdeps/unix/bsd/bsd4.4/Implies new file mode 100644 index 0000000000..3bdab54448 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/Implies @@ -0,0 +1,2 @@ +# 4.4 BSD has the canonical set of <sys/mman.h> system calls. +unix/mman diff --git a/sysdeps/unix/bsd/bsd4.4/chflags.S b/sysdeps/unix/bsd/bsd4.4/chflags.S new file mode 100644 index 0000000000..629ff5c399 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/chflags.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (chflags, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/direct.h b/sysdeps/unix/bsd/bsd4.4/direct.h new file mode 100644 index 0000000000..06641fc955 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/direct.h @@ -0,0 +1,16 @@ +#ifndef MAXNAMLEN +#define MAXNAMLEN 255 +#endif + +struct direct + { + unsigned long int d_fileno; + unsigned short int d_reclen; + unsigned char d_type; /* File type, possibly unknown. */ + unsigned char d_namlen; /* Length of the file name. */ + char d_name[MAXNAMLEN + 1]; + }; + +#define D_NAMLEN(d) ((d)->d_namlen) + +#define HAVE_D_TYPE diff --git a/sysdeps/unix/bsd/bsd4.4/errnos.h b/sysdeps/unix/bsd/bsd4.4/errnos.h new file mode 100644 index 0000000000..dcfdd9c47f --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/errnos.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1982, 1986, 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)errno.h 8.5 (Berkeley) 1/21/94 + */ + +#ifdef _ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ + /* 11 was EAGAIN */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#ifdef __USE_BSD +#define ENOTBLK 15 /* Block device required */ +#endif +#define EBUSY 16 /* Device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#ifdef __USE_BSD +#define ETXTBSY 26 /* Text file busy */ +#endif +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ + +#endif /* <errno.h> included. */ + +/* math software */ + +#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath)) +#define EDOM 33 /* Numerical argument out of domain */ +#endif /* Emath not defined and <errno.h> included or need Emath. */ +#if !defined(__Emath_defined) && (defined(_ERRNO_H) || defined(__need_Emath)) +#define ERANGE 34 /* Result too large */ +#endif /* Emath not defined and <errno.h> included or need Emath. */ + +#ifdef _ERRNO_H + +/* non-blocking and interrupt i/o */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#ifdef __USE_BSD +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ + +/* ipc/network software -- argument errors */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ + +/* ipc/network software -- operational errors */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Operation timed out */ +#define ECONNREFUSED 61 /* Connection refused */ + +#define ELOOP 62 /* Too many levels of symbolic links */ +#endif /* __USE_BSD */ +#define ENAMETOOLONG 63 /* File name too long */ + +/* should be rearranged */ +#ifdef __USE_BSD +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#endif /* __USE_BSD */ +#define ENOTEMPTY 66 /* Directory not empty */ + +/* quotas & mush */ +#ifdef __USE_BSD +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ + +/* Network File System */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ +#define EBADRPC 72 /* RPC struct is bad */ +#define ERPCMISMATCH 73 /* RPC version wrong */ +#define EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define EPROGMISMATCH 75 /* Program version wrong */ +#define EPROCUNAVAIL 76 /* Bad procedure for program */ +#endif /* __USE_BSD */ + +#define ENOLCK 77 /* No locks available */ +#define ENOSYS 78 /* Function not implemented */ + +#define EFTYPE 79 /* Inappropriate file type or format */ + +#ifdef __USE_BSD +#define EAUTH 80 /* Authentication error */ +#define ENEEDAUTH 81 /* Need authenticator */ +#define ELAST 81 /* Must be equal largest errno */ +#endif /* __USE_BSD */ + + +#endif /* <errno.h> included. */ diff --git a/sysdeps/unix/bsd/bsd4.4/fchdir.S b/sysdeps/unix/bsd/bsd4.4/fchdir.S new file mode 100644 index 0000000000..e749adee2b --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/fchdir.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (fchdir, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/fchflags.S b/sysdeps/unix/bsd/bsd4.4/fchflags.S new file mode 100644 index 0000000000..9e4d1435f8 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/fchflags.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (fchflags, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/fcntlbits.h b/sysdeps/unix/bsd/bsd4.4/fcntlbits.h new file mode 100644 index 0000000000..bb61392569 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/fcntlbits.h @@ -0,0 +1,116 @@ +/* O_*, F_*, FD_* bit values for 4.4 BSD. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0200 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0800 /* Fail if file already exists. */ +#define O_TRUNC 0x0400 /* Truncate file to zero length. */ +/* Apparently not assigning a controlling terminal is the default + behavior in BSD, so no bit is required to request that behavior. */ +#define O_NOCTTY 0 /* Don't assign a controlling terminal. */ +#ifdef __USE_MISC +#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x0080 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#define O_SHLOCK 0x0010 /* Open with shared file lock. */ +#define O_EXLOCK 0x0020 /* Open with shared exclusive lock. */ +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */ + +#ifdef __USE_BSD +#define O_NDELAY O_NONBLOCK +#endif + +#ifdef __USE_BSD +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +#define FREAD 1 +#define FWRITE 2 + +/* Traditional BSD names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNDELAY O_NDELAY +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/bsd/bsd4.4/getdents.S b/sysdeps/unix/bsd/bsd4.4/getdents.S new file mode 100644 index 0000000000..be449b2bcb --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/getdents.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/getdents.S> diff --git a/sysdeps/unix/bsd/bsd4.4/getdomain.S b/sysdeps/unix/bsd/bsd4.4/getdomain.S new file mode 100644 index 0000000000..b1ba2fd896 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/getdomain.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getdomainname, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/ioctls.h b/sysdeps/unix/bsd/bsd4.4/ioctls.h new file mode 100644 index 0000000000..6c351f46a6 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/ioctls.h @@ -0,0 +1,292 @@ +/*- + * Copyright (c) 1982, 1986, 1990 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. + * + * @(#)ioctl.h 7.19 (Berkeley) 6/26/91 + */ + +#ifndef _IOCTLS_H_ +#define _IOCTLS_H_ + +#define TIOCGSIZE TIOCGWINSZ +#define TIOCSSIZE TIOCSWINSZ + +/* + * Ioctl's have the command encoded in the lower word, and the size of + * any in or out parameters in the upper word. The high 3 bits of the + * upper word are used to encode the in/out status of the parameter. + */ +#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ +#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) +#define IOCBASECMD(x) ((x) & ~IOCPARM_MASK) +#define IOCGROUP(x) (((x) >> 8) & 0xff) + +#define IOCPARM_MAX NBPG /* max size of ioctl, mult. of NBPG */ +#define IOC_VOID 0x20000000 /* no parameters */ +#define IOC_OUT 0x40000000 /* copy out parameters */ +#define IOC_IN 0x80000000 /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) +#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */ + +#define _IOC(inout,group,num,len) \ + (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) +#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) +#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) +#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) +/* this should be _IORW, but stdio got there first */ +#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) + +#define TIOCMODG _IOR('t', 3, int) /* get modem control state */ +#define TIOCMODS _IOW('t', 4, int) /* set modem control state */ +#define TIOCM_LE 0001 /* line enable */ +#define TIOCM_DTR 0002 /* data terminal ready */ +#define TIOCM_RTS 0004 /* request to send */ +#define TIOCM_ST 0010 /* secondary transmit */ +#define TIOCM_SR 0020 /* secondary receive */ +#define TIOCM_CTS 0040 /* clear to send */ +#define TIOCM_CAR 0100 /* carrier detect */ +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RNG 0200 /* ring */ +#define TIOCM_RI TIOCM_RNG +#define TIOCM_DSR 0400 /* data set ready */ + /* 8-10 compat */ +#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */ +#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */ + /* 15 unused */ +#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */ + /* 17-18 compat */ +#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */ +#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */ +#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */ +#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */ +#define TIOCGETD _IOR('t', 26, int) /* get line discipline */ +#define TIOCSETD _IOW('t', 27, int) /* set line discipline */ + /* 127-124 compat */ +#define TIOCSBRK _IO('t', 123) /* set break bit */ +#define TIOCCBRK _IO('t', 122) /* clear break bit */ +#define TIOCSDTR _IO('t', 121) /* set data terminal ready */ +#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */ +#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */ +#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */ + /* 117-116 compat */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ +#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */ +#define TIOCNOTTY _IO('t', 113) /* void tty association */ +#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */ +#define TIOCPKT_DATA 0x00 /* data packet */ +#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define TIOCPKT_STOP 0x04 /* stop output */ +#define TIOCPKT_START 0x08 /* start output */ +#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ +#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */ +#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */ +#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ +#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */ +#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ +#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ +#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */ +#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */ +#define TIOCCONS _IOW('t', 98, int) /* become virtual console */ +#define TIOCSCTTY _IO('t', 97) /* become controlling tty */ +#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */ +#define TIOCSIG _IO('t', 95) /* pty: generate signal */ +#define TIOCDRAIN _IO('t', 94) /* wait till output drained */ + +#define TTYDISC 0 /* termios tty line discipline */ +#define TABLDISC 3 /* tablet discipline */ +#define SLIPDISC 4 /* serial IP discipline */ + + +#define FIOCLEX _IO('f', 1) /* set close on exec on fd */ +#define FIONCLEX _IO('f', 2) /* remove close on exec */ +#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */ +#define FIOSETOWN _IOW('f', 124, int) /* set owner */ +#define FIOGETOWN _IOR('f', 123, int) /* get owner */ + +/* socket i/o controls */ +#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */ +#define SIOCSPGRP _IOW('s', 8, int) /* set process group */ +#define SIOCGPGRP _IOR('s', 9, int) /* get process group */ + +#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */ +#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */ + +#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */ +#define OSIOCGIFADDR _IOWR('i',13, struct ifreq) /* get ifnet address */ +#define SIOCGIFADDR _IOWR('i',33, struct ifreq) /* get ifnet address */ +#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */ +#define OSIOCGIFDSTADDR _IOWR('i',15, struct ifreq) /* get p-p address */ +#define SIOCGIFDSTADDR _IOWR('i',34, struct ifreq) /* get p-p address */ +#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */ +#define SIOCGIFFLAGS _IOWR('i',17, struct ifreq) /* get ifnet flags */ +#define OSIOCGIFBRDADDR _IOWR('i',18, struct ifreq) /* get broadcast addr */ +#define SIOCGIFBRDADDR _IOWR('i',35, struct ifreq) /* get broadcast addr */ +#define SIOCSIFBRDADDR _IOW('i',19, struct ifreq) /* set broadcast addr */ +#define OSIOCGIFCONF _IOWR('i',20, struct ifconf) /* get ifnet list */ +#define SIOCGIFCONF _IOWR('i',36, struct ifconf) /* get ifnet list */ +#define OSIOCGIFNETMASK _IOWR('i',21, struct ifreq) /* get net addr mask */ +#define SIOCGIFNETMASK _IOWR('i',37, struct ifreq) /* get net addr mask */ +#define SIOCSIFNETMASK _IOW('i',22, struct ifreq) /* set net addr mask */ +#define SIOCGIFMETRIC _IOWR('i',23, struct ifreq) /* get IF metric */ +#define SIOCSIFMETRIC _IOW('i',24, struct ifreq) /* set IF metric */ +#define SIOCDIFADDR _IOW('i',25, struct ifreq) /* delete IF addr */ +#define SIOCAIFADDR _IOW('i',26, struct ifaliasreq) /* add/chg IF alias */ + +#define SIOCSARP _IOW('i', 30, struct arpreq) /* set arp entry */ +#define OSIOCGARP _IOWR('i',31, struct arpreq) /* get arp entry */ +#define SIOCGARP _IOWR('i',38, struct arpreq) /* get arp entry */ +#define SIOCDARP _IOW('i', 32, struct arpreq) /* delete arp entry */ + + +/* Compatibility with 4.3 BSD terminal driver. + From 4.4 <sys/ioctl_compat.h>. */ + +#ifdef USE_OLD_TTY +# undef TIOCGETD +# define TIOCGETD _IOR('t', 0, int) /* get line discipline */ +# undef TIOCSETD +# define TIOCSETD _IOW('t', 1, int) /* set line discipline */ +#else +# define OTIOCGETD _IOR('t', 0, int) /* get line discipline */ +# define OTIOCSETD _IOW('t', 1, int) /* set line discipline */ +#endif +#define TIOCHPCL _IO('t', 2) /* hang up on last close */ +#define TIOCGETP _IOR('t', 8,struct sgttyb)/* get parameters -- gtty */ +#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */ +#define TIOCSETN _IOW('t',10,struct sgttyb)/* as above, but no flushtty*/ +#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */ +#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */ +#define TANDEM 0x00000001 /* send stopc on out q full */ +#define CBREAK 0x00000002 /* half-cooked mode */ +#define LCASE 0x00000004 /* simulate lower case */ +#define ECHO 0x00000008 /* echo input */ +#define CRMOD 0x00000010 /* map \r to \r\n on output */ +#define RAW 0x00000020 /* no i/o processing */ +#define ODDP 0x00000040 /* get/send odd parity */ +#define EVENP 0x00000080 /* get/send even parity */ +#define ANYP 0x000000c0 /* get any parity/send none */ +#define NLDELAY 0x00000300 /* \n delay */ +#define NL0 0x00000000 +#define NL1 0x00000100 /* tty 37 */ +#define NL2 0x00000200 /* vt05 */ +#define NL3 0x00000300 +#define TBDELAY 0x00000c00 /* horizontal tab delay */ +#define TAB0 0x00000000 +#define TAB1 0x00000400 /* tty 37 */ +#define TAB2 0x00000800 +#define XTABS 0x00000c00 /* expand tabs on output */ +#define CRDELAY 0x00003000 /* \r delay */ +#define CR0 0x00000000 +#define CR1 0x00001000 /* tn 300 */ +#define CR2 0x00002000 /* tty 37 */ +#define CR3 0x00003000 /* concept 100 */ +#define VTDELAY 0x00004000 /* vertical tab delay */ +#define FF0 0x00000000 +#define FF1 0x00004000 /* tty 37 */ +#define BSDELAY 0x00008000 /* \b delay */ +#define BS0 0x00000000 +#define BS1 0x00008000 +#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY) +#define CRTBS 0x00010000 /* do backspacing for crt */ +#define PRTERA 0x00020000 /* \ ... / erase */ +#define CRTERA 0x00040000 /* " \b " to wipe out char */ +#define TILDE 0x00080000 /* hazeltine tilde kludge */ +#define MDMBUF 0x00100000 /*start/stop output on carrier*/ +#define LITOUT 0x00200000 /* literal output */ +#define TOSTOP 0x00400000 /*SIGSTOP on background output*/ +#define FLUSHO 0x00800000 /* flush output to terminal */ +#define NOHANG 0x01000000 /* (no-op) was no SIGHUP on carrier drop */ +#define L001000 0x02000000 +#define CRTKIL 0x04000000 /* kill line with " \b " */ +#define PASS8 0x08000000 +#define CTLECH 0x10000000 /* echo control chars as ^X */ +#define PENDIN 0x20000000 /* tp->t_rawq needs reread */ +#define DECCTQ 0x40000000 /* only ^Q starts after ^S */ +#define NOFLSH 0x80000000 /* no output flush on signal */ +#define TIOCLBIS _IOW('t', 127, int) /* bis local mode bits */ +#define TIOCLBIC _IOW('t', 126, int) /* bic local mode bits */ +#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */ +#define TIOCLGET _IOR('t', 124, int) /* get local modes */ +#define LCRTBS (CRTBS>>16) +#define LPRTERA (PRTERA>>16) +#define LCRTERA (CRTERA>>16) +#define LTILDE (TILDE>>16) +#define LMDMBUF (MDMBUF>>16) +#define LLITOUT (LITOUT>>16) +#define LTOSTOP (TOSTOP>>16) +#define LFLUSHO (FLUSHO>>16) +#define LNOHANG (NOHANG>>16) +#define LCRTKIL (CRTKIL>>16) +#define LPASS8 (PASS8>>16) +#define LCTLECH (CTLECH>>16) +#define LPENDIN (PENDIN>>16) +#define LDECCTQ (DECCTQ>>16) +#define LNOFLSH (NOFLSH>>16) +#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars*/ +#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars*/ +#define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */ +#define OTTYDISC 0 +#define NETLDISC 1 +#define NTTYDISC 2 + +/* From 4.4 <sys/ttydev.h>. */ +#ifdef USE_OLD_TTY +#define B0 0 +#define B50 1 +#define B75 2 +#define B110 3 +#define B134 4 +#define B150 5 +#define B200 6 +#define B300 7 +#define B600 8 +#define B1200 9 +#define B1800 10 +#define B2400 11 +#define B4800 12 +#define B9600 13 +#define EXTA 14 +#define EXTB 15 +#endif /* USE_OLD_TTY */ + +#endif /* !_IOCTLS_H_ */ diff --git a/sysdeps/unix/bsd/bsd4.4/setdomain.S b/sysdeps/unix/bsd/bsd4.4/setdomain.S new file mode 100644 index 0000000000..fbaa7a81a2 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/setdomain.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setdomainname, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/setegid.S b/sysdeps/unix/bsd/bsd4.4/setegid.S new file mode 100644 index 0000000000..b47187244c --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/setegid.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setegid, 1) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/seteuid.S b/sysdeps/unix/bsd/bsd4.4/seteuid.S new file mode 100644 index 0000000000..a4f55d3e89 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/seteuid.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (seteuid, 1) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/setlogin.S b/sysdeps/unix/bsd/bsd4.4/setlogin.S new file mode 100644 index 0000000000..ba364b9aae --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/setlogin.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setlogin, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/setsid.S b/sysdeps/unix/bsd/bsd4.4/setsid.S new file mode 100644 index 0000000000..6e776e1f7b --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/setsid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setsid, 0) + ret + +weak_alias (__setsid, setsid) diff --git a/sysdeps/unix/bsd/bsd4.4/sigaltstack.S b/sysdeps/unix/bsd/bsd4.4/sigaltstack.S new file mode 100644 index 0000000000..86d7706a5e --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sigaltstack.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sigaltstack, 2) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/sigblock.c b/sysdeps/unix/bsd/bsd4.4/sigblock.c new file mode 100644 index 0000000000..2647327db0 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sigblock.c @@ -0,0 +1 @@ +#include <sysdeps/posix/sigblock.c> diff --git a/sysdeps/unix/bsd/bsd4.4/sigsetmask.c b/sysdeps/unix/bsd/bsd4.4/sigsetmask.c new file mode 100644 index 0000000000..47f1e36a7f --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sigsetmask.c @@ -0,0 +1 @@ +#include <sysdeps/posix/sigsetmask.c> diff --git a/sysdeps/unix/bsd/bsd4.4/sigvec.c b/sysdeps/unix/bsd/bsd4.4/sigvec.c new file mode 100644 index 0000000000..d03d9bb3df --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sigvec.c @@ -0,0 +1 @@ +#include <sysdeps/posix/sigvec.c> diff --git a/sysdeps/unix/bsd/bsd4.4/sockaddrcom.h b/sysdeps/unix/bsd/bsd4.4/sockaddrcom.h new file mode 100644 index 0000000000..4d81f1e3f5 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sockaddrcom.h @@ -0,0 +1,35 @@ +/* Definition of `struct sockaddr_*' common members. 4.4 BSD version. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SOCKADDRCOM_H +#define _SOCKADDRCOM_H 1 + + +/* This macro is used to declare the initial common members + of the data types used for socket addresses, `struct sockaddr', + `struct sockaddr_in', `struct sockaddr_un', etc. */ + +#define __SOCKADDR_COMMON(sa_prefix) \ + unsigned char sa_prefix##len; \ + unsigned char sa_prefix##family + +#define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char)) + + +#endif /* sockaddrcom.h */ diff --git a/sysdeps/unix/bsd/bsd4.4/sstk.S b/sysdeps/unix/bsd/bsd4.4/sstk.S new file mode 100644 index 0000000000..c73840f47e --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/sstk.S @@ -0,0 +1,23 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* XXX: not 0 args */ +SYSCALL (sstk, 0) + ret diff --git a/sysdeps/unix/bsd/bsd4.4/system.c b/sysdeps/unix/bsd/bsd4.4/system.c new file mode 100644 index 0000000000..9283f74558 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/system.c @@ -0,0 +1,2 @@ +/* BSD 4.4 does have `waitpid'. Avoid unix/system.c, which says we don't. */ +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/bsd/bsd4.4/tcdrain.c b/sysdeps/unix/bsd/bsd4.4/tcdrain.c new file mode 100644 index 0000000000..ac7c9cd2a1 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/tcdrain.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <sys/ioctl.h> + +/* Wait for pending output to be written on FD. */ +int +DEFUN(tcdrain, (fd), int fd) +{ + return __ioctl (fd, TIOCDRAIN); +} diff --git a/sysdeps/unix/bsd/bsd4.4/tcgetattr.c b/sysdeps/unix/bsd/bsd4.4/tcgetattr.c new file mode 100644 index 0000000000..0173dc5c3e --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/tcgetattr.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <termios.h> + +/* These are defined both in termbits.h and in ioctls.h. + They should have the same values, but perhaps not written the same way. */ +#undef ECHO +#undef MDMBUF +#undef TOSTOP +#undef FLUSHO +#undef PENDIN +#undef NOFLSH +#include <sys/ioctl.h> + +/* Put the state of FD into *TERMIOS_P. */ +int +DEFUN(__tcgetattr, (fd, termios_p), + int fd AND struct termios *termios_p) +{ + return __ioctl (fd, TIOCGETA, termios_p); +} + +weak_alias (__tcgetattr, tcgetattr) diff --git a/sysdeps/unix/bsd/bsd4.4/tcsetattr.c b/sysdeps/unix/bsd/bsd4.4/tcsetattr.c new file mode 100644 index 0000000000..8852ad5da0 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/tcsetattr.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +/* These are defined both in termbits.h and in ioctls.h. + They should have the same values, but perhaps not written the same way. */ +#undef ECHO +#undef MDMBUF +#undef TOSTOP +#undef FLUSHO +#undef PENDIN +#undef NOFLSH +#include <sys/ioctl.h> + + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + struct termios myt; + + if (optional_actions & TCSASOFT) + { + myt = *termios_p; + myt.c_cflag |= CIGNORE; + termios_p = &myt; + optional_actions &= ~TCSASOFT; + } + + switch (optional_actions) + { + case TCSANOW: + return __ioctl (fd, TIOCSETA, termios_p); + + case TCSADRAIN: + return __ioctl (fd, TIOCSETAW, termios_p); + + default: + return __ioctl (fd, TIOCSETAF, termios_p); + } +} diff --git a/sysdeps/unix/bsd/bsd4.4/wait.c b/sysdeps/unix/bsd/bsd4.4/wait.c new file mode 100644 index 0000000000..a29a99f9b9 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/wait.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/wait.h> +#include <errno.h> +#include <sys/resource.h> +#include <stddef.h> + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +__pid_t +DEFUN(__wait, (stat_loc), __WAIT_STATUS_DEFN stat_loc) +{ + return __wait4 (WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); +} + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/bsd/bsd4.4/wait3.c b/sysdeps/unix/bsd/bsd4.4/wait3.c new file mode 100644 index 0000000000..2f18c2cd6b --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/wait3.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not nil, + store information about the child's resource usage (as a `struct rusage') + there. If the WUNTRACED bit is set in OPTIONS, return status for stopped + children; otherwise don't. */ +pid_t +DEFUN(__wait3, (stat_loc, options, usage), + __WAIT_STATUS_DEFN stat_loc AND int options AND struct rusage *usage) +{ + return __wait4 (WAIT_ANY, stat_loc, options, usage); +} + +weak_alias (__wait3, wait3) diff --git a/sysdeps/unix/bsd/bsd4.4/wait4.S b/sysdeps/unix/bsd/bsd4.4/wait4.S new file mode 100644 index 0000000000..43b866f164 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/wait4.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (wait4, 4) + ret + +weak_alias (__wait4, wait4) diff --git a/sysdeps/unix/bsd/bsd4.4/waitpid.c b/sysdeps/unix/bsd/bsd4.4/waitpid.c new file mode 100644 index 0000000000..b5a34c32d0 --- /dev/null +++ b/sysdeps/unix/bsd/bsd4.4/waitpid.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <stddef.h> + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS, + return status for stopped children; otherwise don't. */ +pid_t +DEFUN(__waitpid, (pid, stat_loc, options), + pid_t pid AND int *stat_loc AND int options) +{ + return __wait4 (pid, (union wait *) stat_loc, options, NULL); +} + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/unix/bsd/bsdstat.h b/sysdeps/unix/bsd/bsdstat.h new file mode 100644 index 0000000000..45b68b98c6 --- /dev/null +++ b/sysdeps/unix/bsd/bsdstat.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "ansidecl.h" +#include <errno.h> +#include <stddef.h> +#include <sys/types.h> + +/* This will make it not define major, minor, makedev, and S_IF*. */ +#undef __USE_BSD +#undef __USE_MISC +#include <sys/stat.h> + +#undef stat +#undef fstat + +#undef S_IRWXU +#undef S_IRUSR +#undef S_IWUSR +#undef S_IXUSR +#undef S_IRWXG +#undef S_IRGRP +#undef S_IWGRP +#undef S_IXGRP +#undef S_IRWXO +#undef S_IROTH +#undef S_IWOTH +#undef S_IXOTH +#undef S_ISBLK +#undef S_ISCHR +#undef S_ISDIR +#undef S_ISFIFO +#undef S_ISREG +#undef S_ISUID +#undef S_ISGID +#define stat system_stat +#define fstat system_fstat +#define KERNEL /* Try to avoid misc decls. */ +#include "/usr/include/sys/stat.h" +#undef KERNEL +#undef stat +#undef fstat + +#define member_same(statbufp, sysbufp, member) \ + (offsetof(struct __stat, member) == offsetof(struct system_stat, member) && \ + sizeof((statbufp)->member) == sizeof((sysbufp)->member)) +#define need_stat_mapping(statbufp, sysbufp) \ + (!(member_same(statbufp, sysbufp, st_dev) && \ + member_same(statbufp, sysbufp, st_ino) && \ + member_same(statbufp, sysbufp, st_mode) && \ + member_same(statbufp, sysbufp, st_nlink) && \ + member_same(statbufp, sysbufp, st_uid) && \ + member_same(statbufp, sysbufp, st_gid) && \ + member_same(statbufp, sysbufp, st_rdev) && \ + member_same(statbufp, sysbufp, st_size) && \ + member_same(statbufp, sysbufp, st_atime) && \ + member_same(statbufp, sysbufp, st_mtime) && \ + member_same(statbufp, sysbufp, st_ctime) && \ + member_same(statbufp, sysbufp, st_blksize) && \ + member_same(statbufp, sysbufp, st_blocks))) + +/* Map a system `struct stat' to our `struct stat'. */ +#ifdef __GNUC__ +inline +#endif +static int +DEFUN(mapstat, (sysbuf, statbuf), + CONST struct system_stat *sysbuf AND struct __stat *buf) +{ + if (buf == NULL) + { + errno = EINVAL; + return -1; + } + + if (!need_stat_mapping(buf, sysbuf)) + /* Hopefully this will be optimized out. */ + *buf = *(struct __stat *) sysbuf; + else + { + buf->st_dev = (dev_t) sysbuf->st_dev; + buf->st_ino = (ino_t) sysbuf->st_ino; + buf->st_mode = (mode_t) sysbuf->st_mode; + buf->st_nlink = (nlink_t) sysbuf->st_nlink; + buf->st_uid = (uid_t) sysbuf->st_uid; + buf->st_gid = (gid_t) sysbuf->st_gid; + buf->st_rdev = (dev_t) sysbuf->st_rdev; + buf->st_size = (size_t) sysbuf->st_size; + buf->st_atime = (time_t) sysbuf->st_atime; + buf->st_mtime = (time_t) sysbuf->st_mtime; + buf->st_ctime = (time_t) sysbuf->st_ctime; + buf->st_blksize = (size_t) sysbuf->st_blksize; + buf->st_blocks = (size_t) sysbuf->st_blocks; + } + + return 0; +} diff --git a/sysdeps/unix/bsd/bsdtty.h b/sysdeps/unix/bsd/bsdtty.h new file mode 100644 index 0000000000..a1da8d5cc3 --- /dev/null +++ b/sysdeps/unix/bsd/bsdtty.h @@ -0,0 +1,218 @@ +#undef B0 +#undef B50 +#undef B75 +#undef B110 +#undef B134 +#undef B150 +#undef B200 +#undef B300 +#undef B600 +#undef B1200 +#undef B1800 +#undef B2400 +#undef B4800 +#undef B9600 +#undef B19200 +#undef B38400 +#undef EXTA +#undef EXTB +#undef ECHO +#undef TOSTOP +#undef NOFLSH +#undef MDMBUF +#undef FLUSHO +#undef PENDIN +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS +#undef CERASE +#undef CKILL +#undef CINTR +#undef CQUIT +#undef CSTART +#undef CSTOP +#undef CEOF +#undef CEOT +#undef CBRK +#undef CSUSP +#undef CDSUSP +#undef CRPRNT +#undef CFLUSH +#undef CWERASE +#undef CLNEXT +#undef CSTATUS + +#include <sys/ioctl.h> diff --git a/sysdeps/unix/bsd/clock.c b/sysdeps/unix/bsd/clock.c new file mode 100644 index 0000000000..2c3e028444 --- /dev/null +++ b/sysdeps/unix/bsd/clock.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <time.h> +#include <sys/time.h> + +#ifdef __GNUC__ +__inline +#endif +static clock_t +DEFUN(timeval_to_clock_t, (tv), CONST struct timeval *tv) +{ + return (clock_t) ((tv->tv_sec * CLK_TCK) + + (tv->tv_usec * CLK_TCK / 1000)); +} + +/* Return the time used by the program so far (user time + system time). */ +clock_t +DEFUN_VOID(clock) +{ + struct rusage usage; + + if (__getrusage(RUSAGE_SELF, &usage) < 0) + return (clock_t) -1; + + return (timeval_to_clock_t(&usage.ru_stime) + + timeval_to_clock_t(&usage.ru_utime)) * CLOCKS_PER_SEC; +} diff --git a/sysdeps/unix/bsd/confstr.h b/sysdeps/unix/bsd/confstr.h new file mode 100644 index 0000000000..befefb6520 --- /dev/null +++ b/sysdeps/unix/bsd/confstr.h @@ -0,0 +1 @@ +#define CS_PATH "/usr/ucb:/bin:/usr/bin" diff --git a/sysdeps/unix/bsd/direct.h b/sysdeps/unix/bsd/direct.h new file mode 100644 index 0000000000..d663bbb116 --- /dev/null +++ b/sysdeps/unix/bsd/direct.h @@ -0,0 +1,13 @@ +#ifndef MAXNAMLEN +#define MAXNAMLEN 255 +#endif + +struct direct + { + unsigned int d_fileno; /* 32 bits. */ + unsigned short int d_reclen; /* 16 bits. */ + unsigned short int d_namlen; /* 16 bits. */ + char d_name[MAXNAMLEN + 1]; + }; + +#define D_NAMLEN(d) ((d)->d_namlen) diff --git a/sysdeps/unix/bsd/dirstream.h b/sysdeps/unix/bsd/dirstream.h new file mode 100644 index 0000000000..f3bf9ca894 --- /dev/null +++ b/sysdeps/unix/bsd/dirstream.h @@ -0,0 +1,48 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + +#define __need_size_t +#include <stddef.h> +#include <gnu/types.h> /* For __off_t. */ + +/* Directory stream type. + + The BSD directory format is the same as `struct dirent', so `readdir' + returns a pointer into the buffer we read directory data into. */ + +typedef struct + { + int __fd; /* File descriptor. */ + + char *__data; /* Directory block. */ + size_t __allocation; /* Space allocated for the block. */ + size_t __offset; /* Current offset into the block. */ + size_t __size; /* Total valid data in the block. */ + __off_t __pos; /* Position in directory of this block. */ + } DIR; + +#ifdef __USE_BSD +/* Macro to return the file descriptor used for an open directory. */ +#define dirfd(DIR) ((DIR)->__fd) +#endif + +#endif /* dirstream.h */ diff --git a/sysdeps/unix/bsd/fcntlbits.h b/sysdeps/unix/bsd/fcntlbits.h new file mode 100644 index 0000000000..dd8b2a9efa --- /dev/null +++ b/sysdeps/unix/bsd/fcntlbits.h @@ -0,0 +1,117 @@ +/* O_*, F_*, FD_* bit values for 4.3 BSD. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0200 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0800 /* Fail if file already exists. */ +#define O_TRUNC 0x0400 /* Truncate file to zero length. */ +/* Apparently not assigning a controlling terminal is the default + behavior in BSD, so no bit is required to request that behavior. */ +#define O_NOCTTY 0 /* Don't assign a controlling terminal. */ +#if defined (__USE_BSD) || defined (__USE_SVID) +#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x2000 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */ + +#ifdef __USE_BSD +/* BSD before 4.4 doesn't support POSIX.1 O_NONBLOCK, + but O_NDELAY is close. */ +#define O_NDELAY O_NONBLOCK +#endif + +#ifdef __USE_BSD +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +#define FREAD 1 +#define FWRITE 2 + +/* Traditional BSD names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNDELAY O_NDELAY +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_pid; /* Process holding the lock. */ + short int l_xxx; /* Reserved for future use. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/bsd/flock.S b/sysdeps/unix/bsd/flock.S new file mode 100644 index 0000000000..6d72f62c9d --- /dev/null +++ b/sysdeps/unix/bsd/flock.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (flock, 2) + ret + +weak_alias (__flock, flock) diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c new file mode 100644 index 0000000000..66c9ac2b8b --- /dev/null +++ b/sysdeps/unix/bsd/ftime.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/timeb.h> +#include <sys/time.h> + +int +ftime (timebuf) + struct timeb *timebuf; +{ + struct timeval tv; + struct timezone tz; + + if (__gettimeofday (&tv, &tz) < 0) + return -1; + + timebuf->time = tv.tv_sec; + timebuf->millitm = (tv.tv_usec + 999) / 1000; + timebuf->timezone = tz.tz_minuteswest; + timebuf->dstflag = tz.tz_dsttime; + return 0; +} diff --git a/sysdeps/unix/bsd/getdtsz.S b/sysdeps/unix/bsd/getdtsz.S new file mode 100644 index 0000000000..fbba806285 --- /dev/null +++ b/sysdeps/unix/bsd/getdtsz.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getdtablesize, 0) + ret + +weak_alias (__getdtablesize, getdtablesize) diff --git a/sysdeps/unix/bsd/getpagesize.S b/sysdeps/unix/bsd/getpagesize.S new file mode 100644 index 0000000000..16232f0b36 --- /dev/null +++ b/sysdeps/unix/bsd/getpagesize.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getpagesize, 0) + ret + +weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/unix/bsd/gtty.c b/sysdeps/unix/bsd/gtty.c new file mode 100644 index 0000000000..a5bdb10c69 --- /dev/null +++ b/sysdeps/unix/bsd/gtty.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sgtty.h> + +/* Fill in *PARAMS with terminal parameters associated with FD. */ +int +DEFUN(gtty, (fd, params), + int fd AND struct sgttyb *params) +{ + return ioctl(fd, TIOCGETP, (PTR) params); +} diff --git a/sysdeps/unix/bsd/hp/m68k/brk.S b/sysdeps/unix/bsd/hp/m68k/brk.S new file mode 100644 index 0000000000..cf46b4d902 --- /dev/null +++ b/sysdeps/unix/bsd/hp/m68k/brk.S @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef HAVE_GNU_LD +#define __end _end +#endif + +.data +.globl ___curbrk +___curbrk: + .long __end + +.text +ENTRY (__brk) + movel #__end, d0 + cmpl sp@(4), d0 + ble 0f + movel d0, sp@(4) +0: DO_CALL (#SYS_brk, 1) + movel sp@(4), ___curbrk + clrl d0 + rts +error: jmp syscall_error + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/bsd/hp/m68k/getdents.S b/sysdeps/unix/bsd/hp/m68k/getdents.S new file mode 100644 index 0000000000..be449b2bcb --- /dev/null +++ b/sysdeps/unix/bsd/hp/m68k/getdents.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/getdents.S> diff --git a/sysdeps/unix/bsd/hp/m68k/start.c b/sysdeps/unix/bsd/hp/m68k/start.c new file mode 100644 index 0000000000..e04ca0632d --- /dev/null +++ b/sysdeps/unix/bsd/hp/m68k/start.c @@ -0,0 +1,10 @@ +/* hp300 4.3 BSD starts at 4, rather than 0, when the start address is 0. + Go figure. */ +asm(".globl __start"); +asm("__start: .long 0"); + +#define _start __start0 + +#define DUMMIES dummy0 + +#include <sysdeps/unix/start.c> diff --git a/sysdeps/unix/bsd/hp/m68k/sysdep.h b/sysdeps/unix/bsd/hp/m68k/sysdep.h new file mode 100644 index 0000000000..3487ab2027 --- /dev/null +++ b/sysdeps/unix/bsd/hp/m68k/sysdep.h @@ -0,0 +1,56 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This code wants to be run through m4. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#define POUND # + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl _##name; \ + .even; \ + _##name##: +#else +#define ENTRY(name) \ + .globl _/**/name; \ + .even; \ + _/**/name/**/: +#endif + +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error; \ + error: jmp syscall_error; \ + ENTRY (name) \ + DO_CALL (POUND SYS_ify (syscall_name), args) + +#define DO_CALL(syscall, args) \ + movel syscall, d0; \ + trap POUND 0; \ + bcs error + +#define ret rts +#define r0 d0 +#define r1 d1 +#define MOVE(x,y) movel x , y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/hp/m68k/wait3.S b/sysdeps/unix/bsd/hp/m68k/wait3.S new file mode 100644 index 0000000000..d0e758595a --- /dev/null +++ b/sysdeps/unix/bsd/hp/m68k/wait3.S @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY(__wait3) + movel sp@(8), d1 + moveal sp@(12), a0 + movel #SYS_wait, d0 + /* Set all condition codes to tell the kernel this is wait3. */ + movew #31, ccr + trap #0 + bcs error + + tstl sp@(4) + beq 1f + moveal sp@(4), a0 + movel d1, a0@ +1: rts + +.globl syscall_error +error: jmp syscall_error + +weak_alias (__wait3, wait3) diff --git a/sysdeps/unix/bsd/i386/wait3.S b/sysdeps/unix/bsd/i386/wait3.S new file mode 100644 index 0000000000..c54417bf74 --- /dev/null +++ b/sysdeps/unix/bsd/i386/wait3.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* <sysdeps/unix/bsd/sequent/i386/sysdep.h> defines this to put the first + two arguments into registers. Since the arguments to wait3 are + transferred magically through the same registers, we want to disable this. + This allows us to avoid rewriting this file for that system. */ + +#undef ARGS_2 +#define ARGS_2 /* Special-case no-op. */ + +.text +.globl syscall_error +.align 4 +ENTRY (__wait3) + mov 8(%esp), %ecx /* Flags. */ + mov 12(%esp), %edx /* rusage pointer. */ + pushl $0xdf; popf /* Set all the condition codes. */ + DO_CALL (wait, 2) /* Do the system call. */ + je syscall_error /* Check for error. */ + mov 4(%esp), scratch /* Status pointer. */ + orl scratch, scratch /* Is it nil? */ + je done /* Yup; return. */ + mov r1, 0(scratch) /* Non-nil; store the status in it. */ +done: ret + +weak_alias (__wait3, wait3) diff --git a/sysdeps/unix/bsd/init-posix.c b/sysdeps/unix/bsd/init-posix.c new file mode 100644 index 0000000000..a3b2ee1ecc --- /dev/null +++ b/sysdeps/unix/bsd/init-posix.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <time.h> + +/* This must be initialized data or its presence will not be sufficient to + merit linkage of this file, which is necessary for the real + initialization function below to be called. */ +time_t _posix_start_time = -1; + +void +DEFUN_VOID(__init_posix) +{ + _posix_start_time = time((time_t *) NULL); +} + +#ifdef HAVE_GNU_LD +text_set_element(__libc_subinit, __init_posix); +#endif diff --git a/sysdeps/unix/bsd/isatty.c b/sysdeps/unix/bsd/isatty.c new file mode 100644 index 0000000000..c3e80eb1c3 --- /dev/null +++ b/sysdeps/unix/bsd/isatty.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> + +/* Return 1 if FD is a terminal, 0 if not. */ +int +DEFUN(__isatty, (fd), int fd) +{ + int save; + int is_tty; + struct sgttyb term; + + save = errno; + is_tty = __ioctl (fd, TIOCGETP, &term) == 0; + errno = save; + + return is_tty; +} + +weak_alias (__isatty, isatty) diff --git a/sysdeps/unix/bsd/killpg.S b/sysdeps/unix/bsd/killpg.S new file mode 100644 index 0000000000..7ce0f49972 --- /dev/null +++ b/sysdeps/unix/bsd/killpg.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (killpg, 2) + ret diff --git a/sysdeps/unix/bsd/m68k/pipe.S b/sysdeps/unix/bsd/m68k/pipe.S new file mode 100644 index 0000000000..633d18fe2c --- /dev/null +++ b/sysdeps/unix/bsd/m68k/pipe.S @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pipe, 1) +#ifdef __motorola__ + move.l 4(sp), a0 + movem.l d0-d1, (a0) +#else + movel sp@(4), a0 + moveml d0-d1, a0@ +#endif + clrl d0 + rts + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/bsd/m68k/start.c b/sysdeps/unix/bsd/m68k/start.c new file mode 100644 index 0000000000..1067853d61 --- /dev/null +++ b/sysdeps/unix/bsd/m68k/start.c @@ -0,0 +1,3 @@ +#define DUMMIES ignore0 + +#include <sysdeps/unix/start.c> diff --git a/sysdeps/unix/bsd/m68k/syscall.S b/sysdeps/unix/bsd/m68k/syscall.S new file mode 100644 index 0000000000..18ef815559 --- /dev/null +++ b/sysdeps/unix/bsd/m68k/syscall.S @@ -0,0 +1,26 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (syscall) + movel sp@+, a0 /* Pop return address into A0. */ + DO_CALL (sp@, 0) /* Do system call. */ + jmp a0@ /* Return to A0. */ +error: movel a0, sp@- /* Error; push return address */ + jmp syscall_error /* and jump to error handler. */ diff --git a/sysdeps/unix/bsd/m68k/sysdep.S b/sysdeps/unix/bsd/m68k/sysdep.S new file mode 100644 index 0000000000..cef8990eea --- /dev/null +++ b/sysdeps/unix/bsd/m68k/sysdep.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define _ERRNO_H +#include <errnos.h> + +.globl syscall_error +syscall_error: + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ +#ifdef __motorola__ +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + cmp.l #EWOULDBLOCK_sys, d0 + bne store + moveq.l #EAGAIN, d0 +#endif +store: move.l d0, _errno + moveq.l #-1, d0 +#else +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + cmpl #EWOULDBLOCK_sys, d0 + bne store + moveq #EAGAIN, d0 +#endif +store: movel d0, _errno + moveq #-1, d0 +#endif + rts diff --git a/sysdeps/unix/bsd/m68k/wait.S b/sysdeps/unix/bsd/m68k/wait.S new file mode 100644 index 0000000000..c7685b72aa --- /dev/null +++ b/sysdeps/unix/bsd/m68k/wait.S @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (wait, 1) +#ifdef __motorola__ + tst.l 4(sp) + beq 1f + movea.l 4(sp), a0 + move.l d1, (a0) +#else + tstl sp@(4) + beq 1f + moveal sp@(4), a0 + movel d1, a0@ +#endif +1: rts + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/bsd/nice.c b/sysdeps/unix/bsd/nice.c new file mode 100644 index 0000000000..01f1412adf --- /dev/null +++ b/sysdeps/unix/bsd/nice.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/resource.h> + +/* Increment the scheduling priority of the calling process by INCR. + The superuser may use a negative INCR to decrement the priority. */ +int +DEFUN(nice, (incr), int incr) +{ + int save; + int prio; + + /* -1 is a valid priority, so we use errno to check for an error. */ + save = errno; + errno = 0; + prio = getpriority (PRIO_PROCESS, 0); + if (prio == -1) + { + if (errno != 0) + return -1; + else + errno = save; + } + + return setpriority (PRIO_PROCESS, 0, prio + incr); +} diff --git a/sysdeps/unix/bsd/pause.c b/sysdeps/unix/bsd/pause.c new file mode 100644 index 0000000000..b2fafb958e --- /dev/null +++ b/sysdeps/unix/bsd/pause.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <signal.h> +#include <unistd.h> + + +/* Suspend the process until a signal arrives. + This always returns -1 and sets errno to EINTR. */ + +int +DEFUN_VOID(pause) +{ + return __sigpause(__sigblock(0)); +} diff --git a/sysdeps/unix/bsd/poll.c b/sysdeps/unix/bsd/poll.c new file mode 100644 index 0000000000..4797ee04a1 --- /dev/null +++ b/sysdeps/unix/bsd/poll.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/poll.h> +#include <sys/types.h> +#include <errno.h> +#include <string.h> +#include <sys/time.h> + +/* Poll the file descriptors described by the NFDS structures starting at + FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + an event to occur; if TIMEOUT is -1, block until an event occurs. + Returns the number of file descriptors with events, zero if timed out, + or -1 for errors. */ + +int +poll (fds, nfds, timeout) + struct pollfd *fds; + unsigned long int nfds; + int timeout; +{ + struct timeval tv; + fd_set rset, wset, xset; + struct pollfd *f; + int ready; + int maxfd = 0; + + FD_ZERO (&rset); + FD_ZERO (&wset); + FD_ZERO (&xset); + + for (f = fds; f < &fds[nfds]; ++f) + if (f->fd >= 0) + { + if (f->events & POLLIN) + FD_SET (f->fd, &rset); + if (f->events & POLLOUT) + FD_SET (f->fd, &wset); + if (f->events & POLLPRI) + FD_SET (f->fd, &xset); + if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) + maxfd = f->fd; + } + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout + 999) / 1000; + + ready = __select (maxfd + 1, &rset, &wset, &xset, + timeout == -1 ? NULL : &tv); + if (ready > 0) + for (f = fds; f < &fds[nfds]; ++f) + { + f->revents = 0; + if (f->fd >= 0) + { + if (FD_ISSET (f->fd, &rset)) + f->revents |= POLLIN; + if (FD_ISSET (f->fd, &wset)) + f->revents |= POLLOUT; + if (FD_ISSET (f->fd, &xset)) + f->revents |= POLLPRI; + } + } + + return ready; +} diff --git a/sysdeps/unix/bsd/posix_opt.h b/sysdeps/unix/bsd/posix_opt.h new file mode 100644 index 0000000000..7d5e5782eb --- /dev/null +++ b/sysdeps/unix/bsd/posix_opt.h @@ -0,0 +1,5 @@ +#define _POSIX_JOB_CONTROL 1 +#undef _POSIX_SAVED_IDS +#define _POSIX_CHOWN_RESTRICTED 1 +#define _POSIX_NO_TRUNC -1 +#define _POSIX_VDISABLE ((unsigned char) -1) diff --git a/sysdeps/unix/bsd/readdir.c b/sysdeps/unix/bsd/readdir.c new file mode 100644 index 0000000000..e86a94dd52 --- /dev/null +++ b/sysdeps/unix/bsd/readdir.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include "direct.h" + + +/* Read a directory entry from DIRP. */ +struct dirent * +DEFUN(readdir, (dirp), DIR *dirp) +{ + struct dirent *dp; + + if (dirp == NULL || dirp->__data == NULL) + { + errno = EINVAL; + return NULL; + } + + do + { + if (dirp->__offset >= dirp->__size) + { + /* We've emptied out our buffer. Refill it. */ + + ssize_t bytes = __getdirentries (dirp->__fd, dirp->__data, + dirp->__allocation, &dirp->__pos); + if (bytes <= 0) + return NULL; + dirp->__size = (size_t) bytes; + + /* Reset the offset into the buffer. */ + dirp->__offset = 0; + } + + dp = (struct dirent *) &dirp->__data[dirp->__offset]; + dirp->__offset += dp->d_reclen; + +#ifndef HAVE_D_TYPE + dp->d_namlen = ((struct direct *) dp)->d_namlen; + dp->d_type = DT_UNKNOWN; +#endif + + /* Loop to ignore deleted files. */ + } while (dp->d_fileno == 0); + + return dp; +} diff --git a/sysdeps/unix/bsd/seekdir.c b/sysdeps/unix/bsd/seekdir.c new file mode 100644 index 0000000000..4d244f53bd --- /dev/null +++ b/sysdeps/unix/bsd/seekdir.c @@ -0,0 +1 @@ +/* Because they share a private data structure, seekdir is in telldir.c. */ diff --git a/sysdeps/unix/bsd/sequent/i386/getgroups.S b/sysdeps/unix/bsd/sequent/i386/getgroups.S new file mode 100644 index 0000000000..b68bcbdbaa --- /dev/null +++ b/sysdeps/unix/bsd/sequent/i386/getgroups.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#include <limits.h> + +/* Dynix erroneously reports `getgroups (0, 0)' as an error. + We fix up for that case. */ + +#define syscall_error myerror +SYSCALL__ (getgroups, 2) +#undef syscall_error + ret +myerror: + tstl 4(%esp) /* Was the first arg 0? */ + jnz syscall_error /* If not, go to the normal error case. */ + /* When called with (0, 0), we want to return the number of groups + without storing anything. The Dynix system call gives an error + for this case, so we fix up by calling it with a local array we + never use, and just use the return value. */ + subl %esp, $(NGROUPS_MAX * 4) /* Allocate a local array. */ + movl $NGROUPS_MAX, %ecx /* Pass NGROUPS_MAX for first arg. */ + movl %esp, %edx /* Pass local array for second arg. */ + DO_CALL (getgroups, 2) /* Do the system call. */ + addl %esp, $(NGROUPS_MAX * 4) /* Pop the local array. */ + jb syscall_error /* Check for error from the system call. */ + ret /* Return its value. */ + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/unix/bsd/sequent/i386/sigvec.S b/sysdeps/unix/bsd/sequent/i386/sigvec.S new file mode 100644 index 0000000000..1bb57c2074 --- /dev/null +++ b/sysdeps/unix/bsd/sequent/i386/sigvec.S @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* The Dynix `sigvec' system call takes an extra argument, + which is the address of the trampoline function. */ + +.text +.align 4 +trampoline: + cld /* Clear direction flag. */ + call %eax /* Call the handler, address in %eax. */ + addl $8, %esp /* Pop signum & code off the stack. */ + /* __sigreturn will restore the context, and never return here. */ + call C_SYMBOL_NAME (__sigreturn) + +.globl syscall_error +ENTRY (__sigvec) + pushl $trampoline /* Push fourth arg: trampoline address. */ + pushl 16(%esp) /* Push third arg: our third arg. */ + pushl 16(%esp) /* Push second arg: our second arg. */ + pushl 16(%esp) /* Push first arg: our first arg. */ + mov %esp, %ecx /* Point the syscall at the arguments. */ + addl $16, %esp /* Pop those four args. */ + DO_CALL (sigvec, 4) /* Do the system call. */ + jb syscall_error /* Check for error. */ + ret + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/unix/bsd/sequent/i386/syscall.S b/sysdeps/unix/bsd/sequent/i386/syscall.S new file mode 100644 index 0000000000..bebab8ee51 --- /dev/null +++ b/sysdeps/unix/bsd/sequent/i386/syscall.S @@ -0,0 +1,31 @@ +/* `syscall' function for Sequent Symmetry running Dynix version 3. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.text +.globl syscall_error +.align 4 +ENTRY (syscall) + leal 8(%esp), %ecx /* Load address of second argument. */ + movl $SYS_HANDLER, %eax /* Use BSD system calls. */ + movw 4(%esp), %ax /* Load system call number into low word. */ + int $T_SVC6 /* Pretend it takes six args. */ + jb syscall_error + ret diff --git a/sysdeps/unix/bsd/sequent/i386/sysdep.h b/sysdeps/unix/bsd/sequent/i386/sysdep.h new file mode 100644 index 0000000000..f1365e764e --- /dev/null +++ b/sysdeps/unix/bsd/sequent/i386/sysdep.h @@ -0,0 +1,82 @@ +/* System call interface code for Sequent Symmetry running Dynix version 3. +Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/i386/sysdep.h> + +#ifdef ASSEMBLER + +/* Get the symbols for system call interrupts. */ +#include <machine/trap.h> + +/* Use the BSD versions of system calls, by setting the high 16 bits + of the syscall number (see /usr/include/syscall.h). */ +#define SYS_HANDLER (SYS_bsd << 16) + +/* Dynix uses an interrupt interface to system calls. + "int $T_SVCn" are syscall interfaces for 0-6 arg functions. + (see /usr/include/machine/trap.h). */ + +#undef DO_CALL + +#ifdef __STDC__ +#define DO_CALL(syscall_name, args) \ + movl $(SYS_HANDLER | SYS_##syscall_name), %eax; \ + int $T_SVC##args; +#else +#define DO_CALL(syscall_name, args) \ + movl $(SYS_HANDLER | SYS_/**/syscall_name), %eax; \ + int $T_SVC/**/args; +#endif + +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ + .text; \ + .globl syscall_error; \ + .align 4; \ + ENTRY (name) \ + ARGS (args) \ + DO_CALL (syscall_name, args) \ + jb syscall_error + +/* For one and two-argument calls, Dynix takes the arguments in %ecx and + %edx. For 3-6 argument calls, Dynix takes the address of the first + argument in %ecx. */ + +#ifdef __STDC__ +#define ARGS(n) ARGS_##n +#else +#define ARGS(n) ARGS_/**/n +#endif + +#define ARGS_0 +#define ARGS_1 movl 4(%esp), %ecx; +#define ARGS_2 movl 4(%esp), %ecx; movl 8(%esp), %edx; +#define ARGS_3 leal 4(%esp), %ecx; +#define ARGS_4 ARGS_3 +#define ARGS_5 ARGS_3 +#define ARGS_6 ARGS_3 + +/* Dynix reverses %ecx and %edx relative to most i386 Unices. */ + +#undef r1 +#define r1 %ecx /* Secondary return-value register. */ +#undef scratch +#define scratch %edx /* Call-clobbered register for random use. */ + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/setegid.c b/sysdeps/unix/bsd/setegid.c new file mode 100644 index 0000000000..85ebea2c96 --- /dev/null +++ b/sysdeps/unix/bsd/setegid.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/types.h> + +int +DEFUN(setegid, (gid), gid_t gid) +{ + return __setregid (-1, gid); +} diff --git a/sysdeps/unix/bsd/seteuid.c b/sysdeps/unix/bsd/seteuid.c new file mode 100644 index 0000000000..a4be2d98a3 --- /dev/null +++ b/sysdeps/unix/bsd/seteuid.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/types.h> + +int +DEFUN(seteuid, (uid), uid_t uid) +{ + return __setreuid (-1, uid); +} diff --git a/sysdeps/unix/bsd/setgid.c b/sysdeps/unix/bsd/setgid.c new file mode 100644 index 0000000000..aa6c4de97b --- /dev/null +++ b/sysdeps/unix/bsd/setgid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the group ID of the calling process to GID. + If the calling process is the super-user, the real + and effective group IDs, and the saved set-group-ID to GID; + if not, the effective group ID is set to GID. */ +int +DEFUN(__setgid, (gid), gid_t gid) +{ + return __setregid (gid, gid); +} + +weak_alias (__setgid, setgid) diff --git a/sysdeps/unix/bsd/setrgid.c b/sysdeps/unix/bsd/setrgid.c new file mode 100644 index 0000000000..8a421b731f --- /dev/null +++ b/sysdeps/unix/bsd/setrgid.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/types.h> + +int +DEFUN(setrgid, (gid), gid_t gid) +{ + return __setregid (gid, -1); +} diff --git a/sysdeps/unix/bsd/setruid.c b/sysdeps/unix/bsd/setruid.c new file mode 100644 index 0000000000..320b9274bd --- /dev/null +++ b/sysdeps/unix/bsd/setruid.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/types.h> + +int +DEFUN(setruid, (uid), uid_t uid) +{ + return __setreuid (uid, -1); +} diff --git a/sysdeps/unix/bsd/setsid.c b/sysdeps/unix/bsd/setsid.c new file mode 100644 index 0000000000..59594101cf --- /dev/null +++ b/sysdeps/unix/bsd/setsid.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <fcntl.h> + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +int +DEFUN_VOID(__setsid) +{ + pid_t pid = getpid (); + int tty; + int save = errno; + + if (__getpgrp (pid) == pid) + { + /* Already the leader. */ + errno = EPERM; + return -1; + } + + if (setpgid (pid, pid) < 0) + return -1; + + tty = open ("/dev/tty", 0); + if (tty < 0) + { + errno = save; + return 0; + } + (void) __ioctl (tty, TIOCNOTTY, 0); + (void) __close (tty); + + errno = save; + return 0; +} + +weak_alias (__setsid, setsid) diff --git a/sysdeps/unix/bsd/settimeofday.S b/sysdeps/unix/bsd/settimeofday.S new file mode 100644 index 0000000000..2dcf18d7ce --- /dev/null +++ b/sysdeps/unix/bsd/settimeofday.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (settimeofday, 2) + ret + +weak_alias (__settimeofday, settimeofday) diff --git a/sysdeps/unix/bsd/setuid.c b/sysdeps/unix/bsd/setuid.c new file mode 100644 index 0000000000..ed68cd0a55 --- /dev/null +++ b/sysdeps/unix/bsd/setuid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Set the user ID of the calling process to UID. + If the calling process is the super-user, the real + and effective user IDs, and the saved set-user-ID to UID; + if not, the effective user ID is set to UID. */ +int +DEFUN(__setuid, (uid), uid_t uid) +{ + return __setreuid (uid, uid); +} + +weak_alias (__setuid, setuid) diff --git a/sysdeps/unix/bsd/sigaction.c b/sysdeps/unix/bsd/sigaction.c new file mode 100644 index 0000000000..aa1c53f6cd --- /dev/null +++ b/sysdeps/unix/bsd/sigaction.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> + + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +DEFUN(__sigaction, (sig, act, oact), + int sig AND CONST struct sigaction *act AND struct sigaction *oact) +{ + struct sigvec vec, ovec; + + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return -1; + } + + if (act != NULL) + { + vec.sv_mask = act->sa_mask; + vec.sv_handler = act->sa_handler; + vec.sv_flags = (((act->sa_flags & SA_ONSTACK) ? SV_ONSTACK : 0) | + (!(act->sa_flags & SA_RESTART) ? SV_INTERRUPT : 0)); + } + + if (__sigvec(sig, act != NULL ? &vec : (struct sigvec *) NULL, &ovec) < 0) + return -1; + + if (oact != NULL) + { + oact->sa_handler = (void EXFUN((*), (int))) ovec.sv_handler; + oact->sa_mask = ovec.sv_mask; + oact->sa_flags = (((ovec.sv_flags & SV_ONSTACK) ? SA_ONSTACK : 0) | + (!(ovec.sv_flags & SV_INTERRUPT) ? SA_RESTART : 0)); + } + + return 0; +} + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/unix/bsd/sigblock.S b/sysdeps/unix/bsd/sigblock.S new file mode 100644 index 0000000000..26fc674cc2 --- /dev/null +++ b/sysdeps/unix/bsd/sigblock.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigblock, 1) + ret + +weak_alias (__sigblock, sigblock) diff --git a/sysdeps/unix/bsd/signum.h b/sysdeps/unix/bsd/signum.h new file mode 100644 index 0000000000..ebbae18379 --- /dev/null +++ b/sysdeps/unix/bsd/signum.h @@ -0,0 +1,70 @@ +/* Signal number definitions. BSD version. +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* This file defines the fake signal functions and signal + number constants for 4.2 or 4.3 BSD-derived Unix system. */ + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGEMT 7 /* EMT trap (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call (4.2 BSD). */ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGURG 16 /* Urgent condition on socket (4.2 BSD). */ +#define SIGSTOP 17 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 18 /* Keyboard stop (POSIX). */ +#define SIGCONT 19 /* Continue (POSIX). */ +#define SIGCHLD 20 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGTTIN 21 /* Background read from tty (POSIX). */ +#define SIGTTOU 22 /* Background write to tty (POSIX). */ +#define SIGIO 23 /* I/O now possible (4.2 BSD). */ +#define SIGPOLL SIGIO /* Same as SIGIO? (SVID). */ +#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ +#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ +#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ +#define SIGINFO 29 /* Information request (4.4 BSD). */ +#define SIGUSR1 30 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 31 /* User-defined signal 2 (POSIX). */ +#define SIGLOST 32 /* Resource lost (Sun); server died (GNU). */ + +#endif /* <signal.h> included. */ + +#define _NSIG 33 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/bsd/sigpause.S b/sysdeps/unix/bsd/sigpause.S new file mode 100644 index 0000000000..de89e99164 --- /dev/null +++ b/sysdeps/unix/bsd/sigpause.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigpause, 1) + ret + +weak_alias (__sigpause, sigpause) diff --git a/sysdeps/unix/bsd/sigprocmask.c b/sysdeps/unix/bsd/sigprocmask.c new file mode 100644 index 0000000000..31ebb743a8 --- /dev/null +++ b/sysdeps/unix/bsd/sigprocmask.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> + + +/* If SET is not NULL, modify the current set of blocked signals + according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK. + If OSET is not NULL, store the old set of blocked signals in *OSET. */ +int +DEFUN(__sigprocmask, (how, set, oset), + int how AND CONST sigset_t *set AND sigset_t *oset) +{ + int mask; + + if (set != NULL) + { + mask = *set; + switch (how) + { + case SIG_BLOCK: + mask = __sigblock(mask); + break; + + case SIG_UNBLOCK: + mask = __sigblock (0) & ~mask; + /* Fall through. */ + + case SIG_SETMASK: + mask = __sigsetmask(mask); + break; + + default: + errno = EINVAL; + return -1; + } + } + else + mask = __sigblock(0); + + if (oset != NULL) + *oset = mask; + + return 0; +} + +weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/unix/bsd/sigsetmask.S b/sysdeps/unix/bsd/sigsetmask.S new file mode 100644 index 0000000000..39fa9e7e00 --- /dev/null +++ b/sysdeps/unix/bsd/sigsetmask.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigsetmask, 1) + ret + +weak_alias (__sigsetmask, sigsetmask) diff --git a/sysdeps/unix/bsd/sigstack.S b/sysdeps/unix/bsd/sigstack.S new file mode 100644 index 0000000000..be92d9312d --- /dev/null +++ b/sysdeps/unix/bsd/sigstack.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sigstack, 2) + ret diff --git a/sysdeps/unix/bsd/sigsuspend.c b/sysdeps/unix/bsd/sigsuspend.c new file mode 100644 index 0000000000..fff56a950f --- /dev/null +++ b/sysdeps/unix/bsd/sigsuspend.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <unistd.h> + + +/* Change the set of blocked signals to SET, + wait until a signal arrives, and restore the set of blocked signals. */ +int +DEFUN(sigsuspend, (set), CONST sigset_t *set) +{ + int mask; + int sig; + + if (set == NULL) + { + errno = EINVAL; + return -1; + } + + mask = 0; + for (sig = 1; sig <= NSIG; ++sig) + if (__sigismember(set, sig)) + mask |= sigmask(sig); + + return __sigpause(mask); +} diff --git a/sysdeps/unix/bsd/sigvec.S b/sysdeps/unix/bsd/sigvec.S new file mode 100644 index 0000000000..2922a224ce --- /dev/null +++ b/sysdeps/unix/bsd/sigvec.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigvec, 3) + ret + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/unix/bsd/sony/newsos/m68k/Implies b/sysdeps/unix/bsd/sony/newsos/m68k/Implies new file mode 100644 index 0000000000..7b5f3cfc96 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos/m68k/Implies @@ -0,0 +1,2 @@ +# A news800 is almost exactly like an hp300 +unix/bsd/hp/m68k diff --git a/sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h b/sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h new file mode 100644 index 0000000000..a62c17edbc --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h @@ -0,0 +1,56 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#define POUND # + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl _##name; \ + .even; \ + _##name##: +#else +#define ENTRY(name) \ + .globl _/**/name; \ + .even; \ + _/**/name/**/: +#endif + +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error; \ + error: jmp syscall_error; \ + ENTRY (name) \ + DO_CALL (POUND SYS_ify (syscall_name), args) + +#define DO_CALL(syscall, args) \ + movel syscall, d0; \ + linkw a6, POUND(0); \ + trap POUND(0); \ + unlk a6; \ + bcs error + +#define ret rts +#define r0 d0 +#define r1 d1 +#define MOVE(x,y) movel x , y + +#endif diff --git a/sysdeps/unix/bsd/sony/newsos4/Dist b/sysdeps/unix/bsd/sony/newsos4/Dist new file mode 100644 index 0000000000..d7500fde41 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/Dist @@ -0,0 +1 @@ +sys_wait4.S diff --git a/sysdeps/unix/bsd/sony/newsos4/Makefile b/sysdeps/unix/bsd/sony/newsos4/Makefile new file mode 100644 index 0000000000..7cfecf2e18 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir), posix) +sysdep_routines := $(sysdep_routines) sys_wait4 +endif diff --git a/sysdeps/unix/bsd/sony/newsos4/fchdir.S b/sysdeps/unix/bsd/sony/newsos4/fchdir.S new file mode 100644 index 0000000000..6db7282ac9 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/fchdir.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/fchdir.S> diff --git a/sysdeps/unix/bsd/sony/newsos4/sys_wait4.S b/sysdeps/unix/bsd/sony/newsos4/sys_wait4.S new file mode 100644 index 0000000000..6a79710b07 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/sys_wait4.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/sunos4/sys_wait4.S> diff --git a/sysdeps/unix/bsd/sony/newsos4/wait.c b/sysdeps/unix/bsd/sony/newsos4/wait.c new file mode 100644 index 0000000000..79d54580fd --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/wait.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait.c> diff --git a/sysdeps/unix/bsd/sony/newsos4/wait3.c b/sysdeps/unix/bsd/sony/newsos4/wait3.c new file mode 100644 index 0000000000..0b3bdee771 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/wait3.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait3.c> diff --git a/sysdeps/unix/bsd/sony/newsos4/wait4.c b/sysdeps/unix/bsd/sony/newsos4/wait4.c new file mode 100644 index 0000000000..856c99fd61 --- /dev/null +++ b/sysdeps/unix/bsd/sony/newsos4/wait4.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/sunos4/wait4.c> diff --git a/sysdeps/unix/bsd/statbuf.h b/sysdeps/unix/bsd/statbuf.h new file mode 100644 index 0000000000..166d68bbf7 --- /dev/null +++ b/sysdeps/unix/bsd/statbuf.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GNU_STAT_H + +#define _GNU_STAT_H 1 + +#include <gnu/types.h> + +/* Structure describing file characteristics. */ +struct stat + { + /* This is a short instead of dev_t for compatibility with 4.3. */ + short int st_dev; /* Device containing the file. */ + __ino_t st_ino; /* File serial number. */ + + /* This is a short instead of mode_t for compatibility with 4.3. */ + unsigned short int st_mode; /* File mode. */ + + __nlink_t st_nlink; /* Link count. */ + + /* These are shorts instead of uid_t/gid_t for compatibility with 4.3. */ + unsigned short int st_uid; /* User ID of the file's owner. */ + unsigned short int st_gid; /* Group ID of the file's group.*/ + + /* This is a short instead of dev_t for compatibility with 4.3. */ + short int st_rdev; /* Device number, if device. */ + + __off_t st_size; /* Size of file, in bytes. */ + + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atime_usec; + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtime_usec; + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctime_usec; + + unsigned long int st_blksize; /* Optimal block size for I/O. */ +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + + unsigned long int st_blocks; /* Number of 512-byte blocks allocated. */ + + long int st_spare[2]; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + + +#endif /* gnu/stat.h */ diff --git a/sysdeps/unix/bsd/stime.c b/sysdeps/unix/bsd/stime.c new file mode 100644 index 0000000000..be928e8f39 --- /dev/null +++ b/sysdeps/unix/bsd/stime.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> + +/* Set the system clock to *WHEN. */ + +int +DEFUN(stime, (when), CONST time_t *when) +{ + struct timeval tv; + + if (when == NULL) + { + errno = EINVAL; + return -1; + } + + tv.tv_sec = *when; + tv.tv_usec = 0; + return __settimeofday (&tv, (struct timezone *) 0); +} diff --git a/sysdeps/unix/bsd/stty.c b/sysdeps/unix/bsd/stty.c new file mode 100644 index 0000000000..c6322ba833 --- /dev/null +++ b/sysdeps/unix/bsd/stty.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sgtty.h> + +/* Set the terminal parameters associated with FD to *PARAMS. */ +int +DEFUN(stty, (fd, params), + int fd AND CONST struct sgttyb *params) +{ + return ioctl(fd, TIOCSETP, (PTR) params); +} diff --git a/sysdeps/unix/bsd/sun/getdents.S b/sysdeps/unix/bsd/sun/getdents.S new file mode 100644 index 0000000000..f283a5cc71 --- /dev/null +++ b/sysdeps/unix/bsd/sun/getdents.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getdirentries, 4) + ret + +weak_alias (__getdirentries, getdirentries) diff --git a/sysdeps/unix/bsd/sun/m68k/Dist b/sysdeps/unix/bsd/sun/m68k/Dist new file mode 100644 index 0000000000..cd893ff463 --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/Dist @@ -0,0 +1 @@ +sigtramp.c diff --git a/sysdeps/unix/bsd/sun/m68k/Makefile b/sysdeps/unix/bsd/sun/m68k/Makefile new file mode 100644 index 0000000000..ac4121dc2c --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),signal) +sysdep_routines := $(sysdep_routines) sigtramp +endif diff --git a/sysdeps/unix/bsd/sun/m68k/brk.S b/sysdeps/unix/bsd/sun/m68k/brk.S new file mode 100644 index 0000000000..114fa73c85 --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/brk.S @@ -0,0 +1,49 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef HAVE_GNU_LD +#define __end _end +#endif + +.data +.globl ___curbrk +___curbrk: + .long __end + +.text +ENTRY (__brk) + movel __end, d0 + cmpl sp@(4), d0 + ble 0f + movel d0, sp@(4) +0: pea SYS_brk + trap #0 + bcs 1f + movel sp@(4), ___curbrk + clrl d0 + rts +1: + jmp syscall_error + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/bsd/sun/m68k/sethostid.S b/sysdeps/unix/bsd/sun/m68k/sethostid.S new file mode 100644 index 0000000000..8b30f3fe65 --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/sethostid.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifdef SYS_sethostid + +SYSCALL (sethostid, 1) + ret + +#else + +#include <errnos.h> + +.globl _sethostid +.even +_sethostid: + movel #ENOSYS, _errno + moveq #-1, d0 + rts + +#ifdef HAVE_GNU_LD + +.stabs "warning: sethostid is not implemented and will always fail",30,0,0,0 +.stabs "_sethostid",1,0,0,0 + +#endif + +#endif diff --git a/sysdeps/unix/bsd/sun/m68k/sigcontext.h b/sysdeps/unix/bsd/sun/m68k/sigcontext.h new file mode 100644 index 0000000000..471b516bdc --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/sigcontext.h @@ -0,0 +1,26 @@ +/* Structure describing state saved while handling a signal. Sun 3 version. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +struct sigcontext + { + int sc_onstack; + __sigset_t sc_mask; + + int sc_sp, sc_pc, sc_ps; + }; diff --git a/sysdeps/unix/bsd/sun/m68k/sigtramp.c b/sysdeps/unix/bsd/sun/m68k/sigtramp.c new file mode 100644 index 0000000000..32a2c2047e --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/sigtramp.c @@ -0,0 +1,142 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* Get the definition of `struct sigcontext'. */ +#define KERNEL +#define sigvec sun_sigvec +#define sigstack sun_sigstack +#define sigcontext sun_sigcontext +#include "/usr/include/sys/signal.h" +#undef sigvec +#undef sigstack +#undef sigcontext +#undef NSIG +#undef SIGABRT +#undef SIGCLD +#undef SV_ONSTACK +#undef SV_RESETHAND +#undef SV_INTERRUPT +#undef SA_ONSTACK +#undef SA_NOCLDSTOP +#undef SIG_ERR +#undef SIG_DFL +#undef SIG_IGN +#undef sigmask +#undef SIG_BLOCK +#undef SIG_UNBLOCK +#undef SIG_SETMASK + +#include <signal.h> +#include <stddef.h> +#include <errno.h> + +/* Defined in __sigvec.S. */ +extern int EXFUN(__raw_sigvec, (int sig, CONST struct sigvec *vec, + struct sigvec *ovec)); + +/* User-specified signal handlers. */ +#define mytramp 1 +#ifdef mytramp +static __sighandler_t handlers[NSIG]; +#else +#define handlers _sigfunc +extern __sighandler_t _sigfunc[]; +#endif + +#if mytramp + +/* Handler for all signals that are handled by a user-specified function. + Saves and restores the general regs %g2-%g7, the %y register, and + all the FPU regs (including %fsr), around calling the user's handler. */ +static void +DEFUN(trampoline, (sig, code, context, addr), + int sig AND int code AND struct sigcontext *context AND PTR addr) +{ + int save[4]; + + /* Save the call-clobbered registers. */ + asm volatile ("movem%.l d0-d1/a0-a1, %0" : : "m" (save[0])); + + /* XXX should save/restore FP regs */ + + /* Call the user's handler. */ + (*((void EXFUN((*), (int sig, int code, struct sigcontext *context, + PTR addr))) handlers[sig])) + (sig, code, context, addr); + + /* Restore the call-clobbered registers. */ + asm volatile ("movem%.l %0, d0-d1/a0-a1" : : "g" (save[0]) : + "d0", "d1", "a0", "a1"); + + __sigreturn (context); +} + +#endif + +int +DEFUN(__sigvec, (sig, vec, ovec), + int sig AND CONST struct sigvec *vec AND struct sigvec *ovec) +{ +#ifndef mytramp + extern void _sigtramp (int); +#define trampoline _sigtramp +#endif + struct sigvec myvec; + int mask; + __sighandler_t ohandler; + + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return -1; + } + + mask = __sigblock(sigmask(sig)); + + ohandler = handlers[sig]; + + if (vec != NULL && + vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL) + { + handlers[sig] = vec->sv_handler; + myvec = *vec; + myvec.sv_handler = trampoline; + vec = &myvec; + } + + if (__raw_sigvec(sig, vec, ovec) < 0) + { + int save = errno; + (void) __sigsetmask(mask); + errno = save; + return -1; + } + + if (ovec != NULL && ovec->sv_handler == trampoline) + ovec->sv_handler = ohandler; + + (void) __sigsetmask(mask); + + return 0; +} diff --git a/sysdeps/unix/bsd/sun/m68k/syscall.S b/sysdeps/unix/bsd/sun/m68k/syscall.S new file mode 100644 index 0000000000..0a98da7c67 --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/syscall.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (syscall) + movel sp@, d0 /* Save return address in D0. */ + movel sp@(4), sp@ /* Put syscall number at top of stack. */ + movel d0, sp@(4) /* Put return address under it. */ + trap #0 /* Do syscall; pops number from stack. */ + jcs error + ret +error: jmp syscall_error diff --git a/sysdeps/unix/bsd/sun/m68k/sysdep.h b/sysdeps/unix/bsd/sun/m68k/sysdep.h new file mode 100644 index 0000000000..80f6aba7b0 --- /dev/null +++ b/sysdeps/unix/bsd/sun/m68k/sysdep.h @@ -0,0 +1,62 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#define POUND # + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl _##name; \ + .even; \ + _##name##: +#else +#define ENTRY(name) \ + .globl _/**/name; \ + .even; \ + _/**/name/**/: +#endif + +#ifdef __STDC__ +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error; \ + error: jmp syscall_error; \ + ENTRY (name) \ + pea SYS_##syscall_name; \ + trap POUND 0; \ + bcs error +#else +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error; \ + error: jmp syscall_error; \ + ENTRY (name) \ + pea SYS_/**/syscall_name; \ + trap POUND 0; \ + bcs error +#endif + +#define ret rts +#define r0 d0 +#define r1 d1 +#define MOVE(x,y) movel x , y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/sun/sethostid.c b/sysdeps/unix/bsd/sun/sethostid.c new file mode 100644 index 0000000000..a8951fa7d5 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sethostid.c @@ -0,0 +1 @@ +#include <sysdeps/stub/sethostid.c> diff --git a/sysdeps/unix/bsd/sun/signum.h b/sysdeps/unix/bsd/sun/signum.h new file mode 100644 index 0000000000..ea83d710f6 --- /dev/null +++ b/sysdeps/unix/bsd/sun/signum.h @@ -0,0 +1,69 @@ +/* Signal number definitions. SunOS version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* This file defines the fake signal functions and signal + number constants for SunOS 3 and 4 Unix systems. */ + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGEMT 7 /* EMT trap (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call (4.2 BSD). */ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGURG 16 /* Urgent condition on socket (4.2 BSD). */ +#define SIGSTOP 17 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 18 /* Keyboard stop (POSIX). */ +#define SIGCONT 19 /* Continue (POSIX). */ +#define SIGCHLD 20 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGTTIN 21 /* Background read from tty (POSIX). */ +#define SIGTTOU 22 /* Background write to tty (POSIX). */ +#define SIGIO 23 /* I/O now possible (4.2 BSD). */ +#define SIGPOLL SIGIO /* Same as SIGIO? (SVID). */ +#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ +#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ +#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ +#define SIGLOST 29 /* Resource lost (Sun). */ +#define SIGUSR1 30 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 31 /* User-defined signal 2 (POSIX). */ + +#endif /* <signal.h> included. */ + +#define _NSIG 32 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/bsd/sun/sigreturn.S b/sysdeps/unix/bsd/sun/sigreturn.S new file mode 100644 index 0000000000..d0a3f3a56b --- /dev/null +++ b/sysdeps/unix/bsd/sun/sigreturn.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_sigreturn +#define SYS_sigreturn 139 +#endif + +SYSCALL__ (sigreturn, 1) + /* Does not return. */ + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/bsd/sun/sigvec.S b/sysdeps/unix/bsd/sun/sigvec.S new file mode 100644 index 0000000000..c09397486f --- /dev/null +++ b/sysdeps/unix/bsd/sun/sigvec.S @@ -0,0 +1,26 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* __sigvec is defined by sigtramp.c. */ + +PSEUDO (__raw_sigvec, sigvec, 3) + ret + +weak_alias (__sigvec, sigvec) diff --git a/sysdeps/unix/bsd/sun/sparc/Dist b/sysdeps/unix/bsd/sun/sparc/Dist new file mode 100644 index 0000000000..cd893ff463 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sparc/Dist @@ -0,0 +1 @@ +sigtramp.c diff --git a/sysdeps/unix/bsd/sun/sparc/Makefile b/sysdeps/unix/bsd/sun/sparc/Makefile new file mode 100644 index 0000000000..59d10dbdbf --- /dev/null +++ b/sysdeps/unix/bsd/sun/sparc/Makefile @@ -0,0 +1,7 @@ +# Basically `-e start' is magical to the Sun linker. You would think that +# having start.o first would be enough, but you would be wrong. +LDFLAGS := $(LDFLAGS) -Xlinker -e -Xlinker start + +ifeq ($(subdir),signal) +sysdep_routines := $(sysdep_routines) sigtramp +endif diff --git a/sysdeps/unix/bsd/sun/sparc/sethostid.S b/sysdeps/unix/bsd/sun/sparc/sethostid.S new file mode 100644 index 0000000000..fbafba5277 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sparc/sethostid.S @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifdef SYS_sethostid + +SYSCALL (sethostid, 1) + ret + +#else + +/* <errnos.h> only defines E* #ifdef _ERRNO_H. */ +#define _ERRNO_H +#include <errnos.h> + +ENTRY (sethostid) + mov ENOSYS, %o0 + sethi %hi(_errno), %g1 + st %o0, [%g1 + %lo(_errno)] + retl + sub %g0, 1, %o0 + +#ifdef HAVE_GNU_LD + +.stabs "warning: sethostid is not implemented and will always fail",30,0,0,0 +.stabs "_sethostid",1,0,0,0 + +#endif + +#endif diff --git a/sysdeps/unix/bsd/sun/sparc/sigcontext.h b/sysdeps/unix/bsd/sun/sparc/sigcontext.h new file mode 100644 index 0000000000..290bf817af --- /dev/null +++ b/sysdeps/unix/bsd/sun/sparc/sigcontext.h @@ -0,0 +1,31 @@ +/* Structure describing state saved while handling a signal. Sparc version. +Copyright (C) 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +struct sigcontext + { + int sc_onstack; + __sigset_t sc_mask; + +#define SPARC_MAXREGWINDOW 31 /* Maximum usable register windows. */ + int sc_sp, sc_pc, sc_npc, sc_psr, sc_g1, sc_o0; + int sc_wbcnt; /* Number of outstanding windows. */ + __ptr_t sc_spbuf[SPARC_MAXREGWINDOW]; /* SP's for each window. */ + int sc_wbuf[SPARC_MAXREGWINDOW][16]; /* Saved register windows. */ + }; + diff --git a/sysdeps/unix/bsd/sun/sparc/sigtramp.c b/sysdeps/unix/bsd/sun/sparc/sigtramp.c new file mode 100644 index 0000000000..54f62933a8 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sparc/sigtramp.c @@ -0,0 +1,246 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* Get the definition of `struct sigcontext'. */ +#define KERNEL +#define sigvec sun_sigvec +#define sigstack sun_sigstack +#define sigcontext sun_sigcontext +#include "/usr/include/sys/signal.h" +#undef sigvec +#undef sigstack +#undef sigcontext +#undef NSIG +#undef SIGABRT +#undef SIGCLD +#undef SV_ONSTACK +#undef SV_RESETHAND +#undef SV_INTERRUPT +#undef SA_ONSTACK +#undef SA_NOCLDSTOP +#undef SIG_ERR +#undef SIG_DFL +#undef SIG_IGN +#undef sigmask +#undef SIG_BLOCK +#undef SIG_UNBLOCK +#undef SIG_SETMASK + +#include <signal.h> +#include <stddef.h> +#include <errno.h> + +/* Defined in __sigvec.S. */ +extern int EXFUN(__raw_sigvec, (int sig, CONST struct sigvec *vec, + struct sigvec *ovec)); + +/* User-specified signal handlers. */ +#define mytramp 1 +#ifdef mytramp +static __sighandler_t handlers[NSIG]; +#else +#define handlers _sigfunc +extern __sighandler_t _sigfunc[]; +#endif + +#if mytramp + +/* Handler for all signals that are handled by a user-specified function. + Saves and restores the general regs %g2-%g7, the %y register, and + all the FPU regs (including %fsr), around calling the user's handler. */ +static void +DEFUN(trampoline, (sig), int sig) +{ + /* We use `double' and `long long int' so `std' (store doubleword) insns, + which might be faster than single-word stores, will be generated. */ + register double f0 asm("%f0"); + register double f2 asm("%f2"); + register double f4 asm("%f4"); + register double f6 asm("%f6"); + register double f8 asm("%f8"); + register double f10 asm("%f10"); + register double f12 asm("%f12"); + register double f14 asm("%f14"); + register double f16 asm("%f16"); + register double f18 asm("%f18"); + register double f20 asm("%f20"); + register double f22 asm("%f22"); + register double f24 asm("%f24"); + register double f26 asm("%f26"); + register double f28 asm("%f28"); + register double f30 asm("%f30"); + register long long int g2 asm("%g2"); + register long long int g4 asm("%g4"); + register long long int g6 asm("%g6"); + register int *fp asm("%fp"); + + int code; + register struct sigcontext *context asm("%i0"); /* See end of fn. */ + PTR addr; + int y; + double fpsave[16]; + int fsr; + int savefpu; + long long int glsave[3]; + + /* SIG isn't really passed as an arg. + The args to the signal handler are at fp[16..19]. */ + sig = fp[16]; + code = fp[17]; + context = (struct sigcontext *) fp[18]; + addr = (PTR) fp[19]; + + /* Save the Y register. */ + asm("rd %%y, %0" : "=r" (y)); + + /* Save the FPU regs if the FPU enable bit is set in the PSR, + and the signal isn't an FP exception. */ + savefpu = (context->sc_psr & 0x1000) && sig != SIGFPE; + if (savefpu) + { + fpsave[0] = f0; + fpsave[1] = f2; + fpsave[2] = f4; + fpsave[3] = f6; + fpsave[4] = f8; + fpsave[5] = f10; + fpsave[6] = f12; + fpsave[7] = f14; + fpsave[8] = f16; + fpsave[9] = f18; + fpsave[10] = f20; + fpsave[11] = f22; + fpsave[12] = f24; + fpsave[13] = f26; + fpsave[14] = f28; + fpsave[15] = f30; + + /* Force it into a stack slot so the asm won't barf. Sigh. */ + (void) &fsr; + asm("st %%fsr, %0" : "=m" (fsr)); + } + + /* Save the global registers (except for %g1, which is a scratch reg). */ + glsave[0] = g2; + glsave[1] = g4; + glsave[2] = g6; + + /* Call the user's handler. */ + (*((void EXFUN((*), (int sig, int code, struct sigcontext *context, + PTR addr))) handlers[sig])) + (sig, code, context, addr); + + /* Restore the Y register. */ + asm("mov %0, %%y" : : "r" (y)); + + if (savefpu) + { + /* Restore the FPU regs. */ + f0 = fpsave[0]; + f2 = fpsave[1]; + f4 = fpsave[2]; + f6 = fpsave[3]; + f8 = fpsave[4]; + f10 = fpsave[5]; + f12 = fpsave[6]; + f14 = fpsave[7]; + f16 = fpsave[8]; + f18 = fpsave[9]; + f20 = fpsave[10]; + f22 = fpsave[11]; + f24 = fpsave[12]; + f26 = fpsave[13]; + f28 = fpsave[14]; + f30 = fpsave[15]; + + asm("ld %0, %%fsr" : : "m" (fsr)); + } + + /* Restore the globals. */ + g2 = glsave[0]; + g4 = glsave[1]; + g6 = glsave[2]; + + /* Unwind a frame, and do a "sigcleanup" system call. + The system call apparently does a return. + I don't know what it's for. Ask Sun. */ + asm("restore %%g0, 139, %%g1\n" + "ta 0\n" + "! this should be i0: %0" /* Useless insn that will never be executed, */ + /* here to make the compiler happy. */ + : /* No outputs. */ : + /* CONTEXT is bound to %i0. We reference it as an input here to make + sure the compiler considers it live at this point, and preserves + the value in that register. The restore makes %i0 become %o0, the + argument to the system call. */ + "r" (context)); +} +#endif + +int +DEFUN(__sigvec, (sig, vec, ovec), + int sig AND CONST struct sigvec *vec AND struct sigvec *ovec) +{ +#ifndef mytramp + extern void _sigtramp (int); +#define trampoline _sigtramp +#endif + struct sigvec myvec; + int mask; + __sighandler_t ohandler; + + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return -1; + } + + mask = __sigblock(sigmask(sig)); + + ohandler = handlers[sig]; + + if (vec != NULL && + vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL) + { + handlers[sig] = vec->sv_handler; + myvec = *vec; + myvec.sv_handler = trampoline; + vec = &myvec; + } + + if (__raw_sigvec(sig, vec, ovec) < 0) + { + int save = errno; + (void) __sigsetmask(mask); + errno = save; + return -1; + } + + if (ovec != NULL && ovec->sv_handler == trampoline) + ovec->sv_handler = ohandler; + + (void) __sigsetmask(mask); + + return 0; +} diff --git a/sysdeps/unix/bsd/sun/sunos3/m68k/wait.S b/sysdeps/unix/bsd/sun/sunos3/m68k/wait.S new file mode 100644 index 0000000000..f69c4b4431 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos3/m68k/wait.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/hp/m68k/wait.S> diff --git a/sysdeps/unix/bsd/sun/sunos4/.cvsignore b/sysdeps/unix/bsd/sun/sunos4/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/sysdeps/unix/bsd/sun/sunos4/Dist b/sysdeps/unix/bsd/sun/sunos4/Dist new file mode 100644 index 0000000000..f1c9046516 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/Dist @@ -0,0 +1,2 @@ +sys_wait4.S +sys_mmap.S diff --git a/sysdeps/unix/bsd/sun/sunos4/Implies b/sysdeps/unix/bsd/sun/sunos4/Implies new file mode 100644 index 0000000000..c99e256ac1 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/Implies @@ -0,0 +1,2 @@ +# SunOS 4 has the canonical set of <sys/mman.h> system calls. +unix/mman diff --git a/sysdeps/unix/bsd/sun/sunos4/Makefile b/sysdeps/unix/bsd/sun/sunos4/Makefile new file mode 100644 index 0000000000..96b88e1b72 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/Makefile @@ -0,0 +1,7 @@ +ifeq ($(subdir), posix) +sysdep_routines := $(sysdep_routines) sys_wait4 +endif + +ifeq ($(subdir), misc) +sysdep_routines := $(sysdep_routines) sys_mmap +endif diff --git a/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h b/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h new file mode 100644 index 0000000000..210072222c --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/fcntlbits.h @@ -0,0 +1,145 @@ +/* O_*, F_*, FD_* bit values for SunOS 4. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0200 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0800 /* Fail if file already exists. */ +#define O_TRUNC 0x0400 /* Truncate file to zero length. */ +#define O_NOCTTY 0x8000 /* Don't assign a controlling terminal. */ +#if defined (__USE_BSD) || defined (__USE_SVID) +#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x2000 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x4000 /* Non-blocking I/O. */ + +/* Sun defines O_NDELAY one way for BSD behavior and another for System V + behavior. In the GNU C library, you get the BSD behavior unless you + define _USG_SOURCE without also defining _BSD_SOURCE or _GNU_SOURCE. */ +#ifdef __USE_BSD +#define O_NDELAY 0x0004 +#endif +#if !defined (O_NDELAY) && defined (__USE_SVID) +#define O_NDELAY 0x1000 +#endif + +#ifdef __USE_BSD +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +#define FREAD 1 +#define FWRITE 2 + +/* Traditional Unix names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNONBIO O_NONBLOCK +#define FNDELAY 0x0004 /* BSD O_NDELAY. */ +#define FNBIO 0x1000 /* System V O_NDELAY. */ +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ +#ifdef __USE_BSD +#define F_RGETLK 10 /* Get remote record locking info. */ +#define F_RSETLK 11 /* Set remote locking info (non-blocking). */ +#define F_CNVT 12 /* Convert a fhandle to an open fd. */ +#define F_RSETLKW 13 /* Set remote locking info (blocking). */ +#endif + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_pid; /* Process holding the lock. */ + short int l_xxx; /* Reserved for future use. */ + }; + +#ifdef __USE_BSD +/* The structure describing a remote advisory lock. This is the type of the + third arg to `fcntl' for the F_RGETLK, F_RSETLK, and F_RSETLKW requests. */ +struct eflock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_pid; /* Process holding the lock. */ + short int l_xxx; /* Reserved for future use. */ + long int l_rpid; /* Remote process ID wanting this lock. */ + long int l_rsys; /* Remote system ID wanting this lock. */ + }; + +#endif + + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/bsd/sun/sunos4/mmap.c b/sysdeps/unix/bsd/sun/sunos4/mmap.c new file mode 100644 index 0000000000..4dfc1ca2da --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/mmap.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +extern caddr_t __mmap_syscall (caddr_t addr, size_t len, + int prot, int flags, int fd, off_t offset); + + +caddr_t +mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + return __mmap_syscall (addr, len, prot, flags | _MAP_NEW, fd, offset); +} + diff --git a/sysdeps/unix/bsd/sun/sunos4/msync.S b/sysdeps/unix/bsd/sun/sunos4/msync.S new file mode 100644 index 0000000000..9fb8955dc2 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/msync.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (msync, 3) + ret diff --git a/sysdeps/unix/bsd/sun/sunos4/poll.S b/sysdeps/unix/bsd/sun/sunos4/poll.S new file mode 100644 index 0000000000..95c4fd2f82 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/poll.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/poll.S> diff --git a/sysdeps/unix/bsd/sun/sunos4/resourcebits.h b/sysdeps/unix/bsd/sun/sunos4/resourcebits.h new file mode 100644 index 0000000000..b5d3704e6c --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/resourcebits.h @@ -0,0 +1,48 @@ +/* Bit values for resource limits. SunOS 4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These are the values for 4.4 BSD and GNU. Earlier BSD systems have a + subset of these kinds of resource limit. In systems where `getrlimit' + and `setrlimit' are not system calls, these are the values used by the C + library to emulate them. */ + +/* Kinds of resource limit. */ +enum __rlimit_resource + { + /* Per-process CPU limit, in seconds. */ + RLIMIT_CPU, + /* Largest file that can be created, in bytes. */ + RLIMIT_FSIZE, + /* Maximum size of data segment, in bytes. */ + RLIMIT_DATA, + /* Maximum size of stack segment, in bytes. */ + RLIMIT_STACK, + /* Largest core file that can be created, in bytes. */ + RLIMIT_CORE, + /* Largest resident set size, in bytes. + This affects swapping; processes that are exceeding their + resident set size will be more likely to have physical memory + taken from them. */ + RLIMIT_RSS, + /* Number of open files. */ + RLIMIT_NOFILE, + RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */ + + RLIM_NLIMITS + }; diff --git a/sysdeps/unix/bsd/sun/sunos4/setsid.S b/sysdeps/unix/bsd/sun/sunos4/setsid.S new file mode 100644 index 0000000000..4930c56dcf --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/setsid.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/setsid.S> diff --git a/sysdeps/unix/bsd/sun/sunos4/speed.c b/sysdeps/unix/bsd/sun/sunos4/speed.c new file mode 100644 index 0000000000..1c09d55dab --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/speed.c @@ -0,0 +1,113 @@ +/* `struct termios' speed frobnication functions. SunOS 4 version. +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <termios.h> + +static CONST speed_t speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + }; + + +/* Return the output baud rate stored in *TERMIOS_P. */ +speed_t +DEFUN(cfgetospeed, (termios_p), CONST struct termios *termios_p) +{ + return termios_p->c_cflag & CBAUD; +} + +/* Return the input baud rate stored in *TERMIOS_P. */ +speed_t +DEFUN(cfgetispeed, (termios_p), CONST struct termios *termios_p) +{ + return (termios_p->c_cflag & CIBAUD) >> IBSHIFT; +} + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +int +DEFUN(cfsetospeed, (termios_p, speed), + struct termios *termios_p AND speed_t speed) +{ + register unsigned int i; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + /* This allows either B1200 or 1200 to work. XXX + Do we really want to try to support this, given that + fetching the speed must return one or the other? */ + + for (i = 0; i < sizeof (speeds) / sizeof (speeds[0]); ++i) + if (i == speed || speeds[i] == speed) + { + termios_p->c_cflag &= ~CBAUD; + termios_p->c_cflag |= i; + return 0; + } + + errno = EINVAL; + return -1; +} + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. */ +int +DEFUN(cfsetispeed, (termios_p, speed), + struct termios *termios_p AND speed_t speed) +{ + register unsigned int i; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + /* See comment in cfsetospeed (above). */ + for (i = 0; i < sizeof (speeds) / sizeof (speeds[0]); ++i) + if (i == speed || speeds[i] == speed) + { + termios_p->c_cflag &= ~CIBAUD; + termios_p->c_cflag |= i << IBSHIFT; + return 0; + } + + errno = EINVAL; + return -1; +} diff --git a/sysdeps/unix/bsd/sun/sunos4/sys/mman.h b/sysdeps/unix/bsd/sun/sunos4/sys/mman.h new file mode 100644 index 0000000000..727e665fb6 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/sys/mman.h @@ -0,0 +1,107 @@ +/* Definitions for BSD-style memory management. SunOS 4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_MMAN_H + +#define _SYS_MMAN_H 1 +#include <features.h> + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x01 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x04 /* Pages can be executed. */ + + +/* Sharing types (must choose one and only one of these). */ +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes private; copy pages on write. */ +#define MAP_TYPE 0x0f /* Mask for sharing type. */ + +/* Other flags. */ +#define MAP_FIXED 0x10 /* Map address must be exactly as requested. */ +/* The following three flags are not actually implemented in SunOS 4.1. */ +#define MAP_RENAME 0x20 /* Rename private pages to file. */ +#define MAP_NORESERVE 0x40 /* Don't reserve needed swap area. */ +#define MAP_INHERIT 0x80 /* Region is retained after exec. */ + +/* This is an internal flag that is always set in `mmap' system calls. In + older versions of SunOS 4 `mmap' did not return the actual mapping + address, but always returned zero. This flag says to return the + address; the `mmap' C library function always sets it. */ +#define _MAP_NEW 0x80000000 + +/* Advice to `madvise'. */ +#define MADV_NORMAL 0 /* No further special treatment. */ +#define MADV_RANDOM 1 /* Expect random page references. */ +#define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define MADV_WILLNEED 3 /* Will need these pages. */ +#define MADV_DONTNEED 4 /* Don't need these pages. */ + +/* Flags to `msync'. */ +#define MS_ASYNC 0x1 /* Return immediately, don't fsync. */ +#define MS_INVALIDATE 0x2 /* Invalidate caches. */ + + +#include <sys/cdefs.h> + +__BEGIN_DECLS +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__caddr_t mmap __P ((__caddr_t __addr, size_t __len, + int __prot, int __flags, int __fd, __off_t __offset)); + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ +int munmap __P ((__caddr_t __addr, size_t __len)); + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ +int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ +int msync __P ((__caddr_t __addr, size_t __len, int __flags)); + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ +int madvise __P ((__caddr_t __addr, size_t __len, int __advice)); + +__END_DECLS + + +#endif /* sys/mman.h */ diff --git a/sysdeps/unix/bsd/sun/sunos4/sys_mmap.S b/sysdeps/unix/bsd/sun/sunos4/sys_mmap.S new file mode 100644 index 0000000000..61fe877342 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/sys_mmap.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__mmap_syscall, mmap, 5) + ret diff --git a/sysdeps/unix/bsd/sun/sunos4/sys_wait4.S b/sysdeps/unix/bsd/sun/sunos4/sys_wait4.S new file mode 100644 index 0000000000..6b796b7ea6 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/sys_wait4.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__wait4_syscall, wait4, 4) + ret diff --git a/sysdeps/unix/bsd/sun/sunos4/system.c b/sysdeps/unix/bsd/sun/sunos4/system.c new file mode 100644 index 0000000000..2c8e634bc8 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/system.c @@ -0,0 +1,2 @@ +/* SunOS 4 does have `waitpid'. Avoid unix/system.c, which says we don't. */ +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/bsd/sun/sunos4/tcflow.c b/sysdeps/unix/bsd/sun/sunos4/tcflow.c new file mode 100644 index 0000000000..bb9a7fc7a0 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/tcflow.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* Suspend or restart transmission on FD. */ +int +DEFUN(tcflow, (fd, action), int fd AND int action) +{ + return __ioctl (fd, TCXONC, action); +} diff --git a/sysdeps/unix/bsd/sun/sunos4/tcflush.c b/sysdeps/unix/bsd/sun/sunos4/tcflush.c new file mode 100644 index 0000000000..d76fc07cf0 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/tcflush.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* Flush pending data on FD. */ +int +DEFUN(tcflush, (fd, queue_selector), int fd AND int queue_selector) +{ + return __ioctl (fd, TCFLSH, queue_selector); +} diff --git a/sysdeps/unix/bsd/sun/sunos4/tcgetattr.c b/sysdeps/unix/bsd/sun/sunos4/tcgetattr.c new file mode 100644 index 0000000000..5e45037bb2 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/tcgetattr.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* Put the state of FD into *TERMIOS_P. */ +int +DEFUN(__tcgetattr, (fd, termios_p), + int fd AND struct termios *termios_p) +{ + return __ioctl (fd, TCGETS, termios_p); +} + +weak_alias (__tcgetattr, tcgetattr) diff --git a/sysdeps/unix/bsd/sun/sunos4/tcsendbrk.c b/sysdeps/unix/bsd/sun/sunos4/tcsendbrk.c new file mode 100644 index 0000000000..7a6d5cc05f --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/tcsendbrk.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <sys/termio.h> /* Sun header file. */ + +/* Send zero bits on FD. */ +int +DEFUN(tcsendbreak, (fd, duration), int fd AND int duration) +{ + /* According to SunOS 4.1's termios(4), you can't specify a duration. */ + return __ioctl (fd, TCSBRK, 0); +} diff --git a/sysdeps/unix/bsd/sun/sunos4/tcsetattr.c b/sysdeps/unix/bsd/sun/sunos4/tcsetattr.c new file mode 100644 index 0000000000..4ae139a1f8 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/tcsetattr.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + int cmd; + + switch (optional_actions) + { + case TCSANOW: + cmd = TCSETS; + break; + case TCSADRAIN: + cmd = TCSETSW; + break; + case TCSAFLUSH: + cmd = TCSETSF; + break; + default: + errno = EINVAL; + return -1; + } + + return __ioctl (fd, cmd, termios_p); +} diff --git a/sysdeps/unix/bsd/sun/sunos4/termbits.h b/sysdeps/unix/bsd/sun/sunos4/termbits.h new file mode 100644 index 0000000000..b768deab6f --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/termbits.h @@ -0,0 +1,208 @@ +/* termios type and macro definitions. SunOS 4 version. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Type of terminal control flag masks. */ +typedef unsigned long int tcflag_t; + +/* Type of control characters. */ +typedef unsigned char cc_t; + +/* Type of baud rate specifiers. */ +typedef unsigned int speed_t; + +/* Terminal control structure. */ +struct termios +{ + /* Input modes. */ + tcflag_t c_iflag; +#define IGNBRK 0x0001 /* Ignore break condition. */ +#define BRKINT 0x0002 /* Signal interrupt on break. */ +#define IGNPAR 0x0004 /* Ignore characters with parity errors. */ +#define PARMRK 0x0008 /* Mark parity and framing errors. */ +#define INPCK 0x0010 /* Enable input parity check. */ +#define ISTRIP 0x0020 /* Strip 8th bit off characters. */ +#define INLCR 0x0040 /* Map NL to CR on input. */ +#define IGNCR 0x0080 /* Ignore CR. */ +#define ICRNL 0x0100 /* Map CR to NL on input. */ +#ifdef __USE_BSD +#define IUCLC 0x0200 /* Map upper case to lower case on input. */ +#endif +#define IXON 0x0400 /* Enable start/stop output control. */ +#define IXOFF 0x1000 /* Enable start/stop input control. */ +#ifdef __USE_BSD +#define IXANY 0x0800 /* Any character will restart after stop. */ +#define IMAXBEL 0x2000 /* Ring bell when input queue is full. */ +#endif + + /* Output modes. */ + tcflag_t c_oflag; +#define OPOST 0x0001 /* Perform output processing. */ +#ifdef __USE_BSD +#define OLCUC 0x00000002 /* Map lower case to upper case on output. */ +#define ONLCR 0x00000004 /* Map NL to CR-NL on output. */ +#define OCRNL 0x00000008 +#define ONOCR 0x00000010 +#define ONLRET 0x00000020 +#define OFILL 0x00000040 +#define OFDEL 0x00000080 +#define NLDLY 0x00000100 +#define NL0 0 +#define NL1 0x00000100 +#define CRDLY 0x00000600 +#define CR0 0 +#define CR1 0x00000200 +#define CR2 0x00000400 +#define CR3 0x00000600 +#define TABDLY 0x00001800 +#define TAB0 0 +#define TAB1 0x00000800 +#define TAB2 0x00001000 +#define XTABS 0x00001800 +#define TAB3 XTABS +#define BSDLY 0x00002000 +#define BS0 0 +#define BS1 0x00002000 +#define VTDLY 0x00004000 +#define VT0 0 +#define VT1 0x00004000 +#define FFDLY 0x00008000 +#define FF0 0 +#define FF1 0x00008000 +#define PAGEOUT 0x00010000 +#define WRAP 0x00020000 +#endif + + /* Control modes. */ + tcflag_t c_cflag; +#define CSIZE (CS5|CS6|CS7|CS8) /* Number of bits per byte (mask). */ +#define CS5 0 /* 5 bits per byte. */ +#define CS6 0x00000010 /* 6 bits per byte. */ +#define CS7 0x00000020 /* 7 bits per byte. */ +#define CS8 0x00000030 /* 8 bits per byte. */ +#define CSTOPB 0x00000040 /* Two stop bits instead of one. */ +#define CREAD 0x00000080 /* Enable receiver. */ +#define PARENB 0x00000100 /* Parity enable. */ +#define PARODD 0x00000200 /* Odd parity instead of even. */ +#define HUPCL 0x00000400 /* Hang up on last close. */ +#define CLOCAL 0x00000800 /* Ignore modem status lines. */ +#ifdef __USE_BSD +#define LOBLK 0x00001000 +#define CRTSCTS 0x80000000 +#define CIBAUD 0x000f0000 /* Mask for input speed from c_cflag. */ +#define CBAUD 0x0000000f /* Mask for output speed from c_cflag. */ +#define IBSHIFT 16 /* Bits to shift for input speed. */ +#endif + + /* Input and output baud rates. These are encoded in c_cflag. */ +#define B0 0 +#define B50 1 +#define B75 2 +#define B110 3 +#define B134 4 +#define B150 5 +#define B200 6 +#define B300 7 +#define B600 8 +#define B1200 9 +#define B1800 10 +#define B2400 11 +#define B4800 12 +#define B9600 13 +#define B19200 14 +#define B38400 15 +#ifdef __USE_BSD +#define EXTA 14 +#define EXTB 15 +#endif + + /* Local modes. */ + tcflag_t c_lflag; +#ifdef __USE_BSD +#define ECHOKE 0x00000800 /* Visual erase for KILL. */ +#endif +#define ECHOE 0x00000010 /* Visual erase for ERASE. */ +#define ECHOK 0x00000020 /* Echo NL after KILL. */ +#define ECHO 0x00000008 /* Enable echo. */ +#define ECHONL 0x00000040 /* Echo NL even if ECHO is off. */ +#ifdef __USE_BSD +#define ECHOPRT 0x00000400 /* Hardcopy visual erase. */ +#define ECHOCTL 0x00000200 /* Echo control characters as ^X. */ +#endif +#define ISIG 0x00000001 /* Enable signals. */ +#define ICANON 0x00000002 /* Do erase and kill processing. */ +#define IEXTEN 0x00008000 /* Enable DISCARD and LNEXT. */ +#define TOSTOP 0x00000100 /* Send SIGTTOU for background output. */ +#ifdef __USE_BSD +#define PENDIN 0x00004000 /* Retype pending input (state). */ +#endif +#define NOFLSH 0x00000080 /* Disable flush after interrupt. */ + + char c_line; /* Line discipline (?) */ + + /* Control characters. */ +#define VEOF 4 /* End-of-file character [ICANON]. */ +#define VEOL 5 /* End-of-line character [ICANON]. */ +#ifdef __USE_BSD +#define VEOL2 6 /* Second EOL character [ICANON]. */ +#define VSWTCH 7 /* ??? */ +#endif +#define VERASE 2 /* Erase character [ICANON]. */ +#ifdef __USE_BSD +#define VWERASE 14 /* Word-erase character [ICANON]. */ +#endif +#define VKILL 3 /* Kill-line character [ICANON]. */ +#ifdef __USE_BSD +#define VREPRINT 12 /* Reprint-line character [ICANON]. */ +#endif +#define VINTR 0 /* Interrupt character [ISIG]. */ +#define VQUIT 1 /* Quit character [ISIG]. */ +#define VSUSP 10 /* Suspend character [ISIG]. */ +#ifdef __USE_BSD +#define VDSUSP 11 /* Delayed suspend character [ISIG]. */ +#endif +#define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */ +#define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */ +#ifdef __USE_BSD +#define VLNEXT 15 /* Literal-next character [IEXTEN]. */ +#define VDISCARD 13 /* Discard character [IEXTEN]. */ +#endif +#define VMIN VEOF /* Minimum number of bytes read at once [!ICANON]. */ +#define VTIME VEOL /* Time-out value (tenths of a second) [!ICANON]. */ +#define NCCS 17 + cc_t c_cc[NCCS]; +}; + +#define _IOT_termios /* Hurd ioctl type field. */ \ + _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2) + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 /* Change immediately. */ +#define TCSADRAIN 1 /* Change when pending output is written. */ +#define TCSAFLUSH 2 /* Flush pending input before changing. */ + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 /* Discard data received but not yet read. */ +#define TCOFLUSH 1 /* Discard data written but not yet sent. */ +#define TCIOFLUSH 2 /* Discard all pending data. */ + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 /* Suspend output. */ +#define TCOON 1 /* Restart suspended output. */ +#define TCIOFF 2 /* Send a STOP character. */ +#define TCION 3 /* Send a START character. */ diff --git a/sysdeps/unix/bsd/sun/sunos4/uname.S b/sysdeps/unix/bsd/sun/sunos4/uname.S new file mode 100644 index 0000000000..488eeb1d97 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/uname.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/uname.S> diff --git a/sysdeps/unix/bsd/sun/sunos4/utsnamelen.h b/sysdeps/unix/bsd/sun/sunos4/utsnamelen.h new file mode 100644 index 0000000000..e9111b6504 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/utsnamelen.h @@ -0,0 +1,2 @@ +#define _UTSNAME_LENGTH 9 +#define _UTSNAME_NODENAME_LENGTH 65 diff --git a/sysdeps/unix/bsd/sun/sunos4/wait.c b/sysdeps/unix/bsd/sun/sunos4/wait.c new file mode 100644 index 0000000000..79d54580fd --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/wait.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait.c> diff --git a/sysdeps/unix/bsd/sun/sunos4/wait3.c b/sysdeps/unix/bsd/sun/sunos4/wait3.c new file mode 100644 index 0000000000..0b3bdee771 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/wait3.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait3.c> diff --git a/sysdeps/unix/bsd/sun/sunos4/wait4.c b/sysdeps/unix/bsd/sun/sunos4/wait4.c new file mode 100644 index 0000000000..919cd7c42c --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/wait4.c @@ -0,0 +1,50 @@ +/* This implements wait4 with the 4.4 BSD semantics (also those documented in + SunOS 4.1) on top of SunOS's wait4 system call, which has semantics + different from those documented. Go Sun! + +Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +extern pid_t __wait4_syscall __P ((pid_t pid, __WAIT_STATUS_DEFN stat_loc, + int options, struct rusage *usage)); + +pid_t +DEFUN(__wait4, (pid, stat_loc, options, usage), + pid_t pid AND __WAIT_STATUS_DEFN stat_loc AND + int options AND struct rusage *usage) +{ + switch (pid) + { + case WAIT_ANY: + pid = 0; + break; + + case WAIT_MYPGRP: + pid = - getpgrp (); + break; + } + + return __wait4_syscall (pid, stat_loc, options, usage); +} + +weak_alias (__wait4, wait4) diff --git a/sysdeps/unix/bsd/sun/sunos4/waitpid.c b/sysdeps/unix/bsd/sun/sunos4/waitpid.c new file mode 100644 index 0000000000..8378982ac7 --- /dev/null +++ b/sysdeps/unix/bsd/sun/sunos4/waitpid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/waitpid.c> diff --git a/sysdeps/unix/bsd/sys/reboot.h b/sysdeps/unix/bsd/sys/reboot.h new file mode 100644 index 0000000000..c3c957e17e --- /dev/null +++ b/sysdeps/unix/bsd/sys/reboot.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1982, 1986, 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. + * + * @(#)reboot.h 8.1 (Berkeley) 6/2/93 + */ + +/* + * Arguments to reboot system call. + * These are passed to boot program in r11, + * and on to init. + */ +#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#define RB_ASKNAME 0x01 /* ask for file name to reboot from */ +#define RB_SINGLE 0x02 /* reboot to single user only */ +#define RB_NOSYNC 0x04 /* dont sync before reboot */ +#define RB_HALT 0x08 /* don't reboot, just halt */ +#define RB_INITNAME 0x10 /* name given for /etc/init (unused) */ +#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */ +#define RB_KDB 0x40 /* give control to kernel debugger */ +#define RB_RDONLY 0x80 /* mount root fs read-only */ +#define RB_DUMP 0x100 /* dump kernel memory before reboot */ +#define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */ + +/* + * Constants for converting boot-style device number to type, + * adaptor (uba, mba, etc), unit number and partition number. + * Type (== major device number) is in the low byte + * for backward compatibility. Except for that of the "magic + * number", each mask applies to the shifted value. + * Format: + * (4) (4) (4) (4) (8) (8) + * -------------------------------- + * |MA | AD| CT| UN| PART | TYPE | + * -------------------------------- + */ +#define B_ADAPTORSHIFT 24 +#define B_ADAPTORMASK 0x0f +#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK) +#define B_CONTROLLERSHIFT 20 +#define B_CONTROLLERMASK 0xf +#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK) +#define B_UNITSHIFT 16 +#define B_UNITMASK 0xf +#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK) +#define B_PARTITIONSHIFT 8 +#define B_PARTITIONMASK 0xff +#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK) +#define B_TYPESHIFT 0 +#define B_TYPEMASK 0xff +#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK) + +#define B_MAGICMASK ((u_long)0xf0000000) +#define B_DEVMAGIC ((u_long)0xa0000000) + +#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \ + (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \ + ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \ + ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC) diff --git a/sysdeps/unix/bsd/tahoe/Implies b/sysdeps/unix/bsd/tahoe/Implies new file mode 100644 index 0000000000..a7ecf58273 --- /dev/null +++ b/sysdeps/unix/bsd/tahoe/Implies @@ -0,0 +1 @@ +unix/bsd/vax diff --git a/sysdeps/unix/bsd/tahoe/sysdep.h b/sysdeps/unix/bsd/tahoe/sysdep.h new file mode 100644 index 0000000000..b875906320 --- /dev/null +++ b/sysdeps/unix/bsd/tahoe/sysdep.h @@ -0,0 +1,5 @@ +/* The Tahoe is just like the Vax, except the + `chmk' instruction is called `kcall'. */ + +#define chmk kcall +#include <sysdeps/unix/bsd/vax/sysdep.h> diff --git a/sysdeps/unix/bsd/tcdrain.c b/sysdeps/unix/bsd/tcdrain.c new file mode 100644 index 0000000000..c9ed18d4f8 --- /dev/null +++ b/sysdeps/unix/bsd/tcdrain.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> + +#include "bsdtty.h" + +/* Wait for pending output to be written on FD. */ +int +DEFUN(tcdrain, (fd), int fd) +{ + /* The TIOCSETP control waits for pending output to be written before + affecting its changes, so we use that without changing anything. */ + struct sgttyb b; + if (__ioctl(fd, TIOCGETP, (PTR) &b) < 0 || + __ioctl(fd, TIOCSETP, (PTR) &b) < 0) + return -1; + return 0; +} diff --git a/sysdeps/unix/bsd/tcflow.c b/sysdeps/unix/bsd/tcflow.c new file mode 100644 index 0000000000..06de144a45 --- /dev/null +++ b/sysdeps/unix/bsd/tcflow.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> + +#include "bsdtty.h" + +/* Suspend or restart transmission on FD. */ +int +DEFUN(tcflow, (fd, action), int fd AND int action) +{ + switch (action) + { + case TCOOFF: + return __ioctl(fd, TIOCSTOP, (PTR) NULL); + case TCOON: + return __ioctl(fd, TIOCSTART, (PTR) NULL); + + case TCIOFF: + case TCION: + { + /* This just writes the START or STOP character with + `write'. Is there another way to do this? */ + struct termios attr; + unsigned char c; + if (tcgetattr(fd, &attr) < 0) + return -1; + c = attr.c_cc[action == TCIOFF ? VSTOP : VSTART]; + if (c != _POSIX_VDISABLE && write (fd, &c, 1) < 1) + return -1; + return 0; + } + + default: + errno = EINVAL; + return -1; + } +} diff --git a/sysdeps/unix/bsd/tcflush.c b/sysdeps/unix/bsd/tcflush.c new file mode 100644 index 0000000000..46454b8229 --- /dev/null +++ b/sysdeps/unix/bsd/tcflush.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> +#include "bsdtty.h" +#include <sys/file.h> + +/* Flush pending data on FD. */ +int +DEFUN(tcflush, (fd, queue_selector), int fd AND int queue_selector) +{ + int arg; + + switch (queue_selector) + { + case TCIFLUSH: + arg = FREAD; + break; + case TCOFLUSH: + arg = FWRITE; + break; + case TCIOFLUSH: + arg = FREAD | FWRITE; + break; + default: + errno = EINVAL; + return -1; + } + + return __ioctl (fd, TIOCFLUSH, (PTR) &arg); +} diff --git a/sysdeps/unix/bsd/tcgetattr.c b/sysdeps/unix/bsd/tcgetattr.c new file mode 100644 index 0000000000..0e6e3785dd --- /dev/null +++ b/sysdeps/unix/bsd/tcgetattr.c @@ -0,0 +1,130 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +#include "bsdtty.h" + +extern CONST speed_t __bsd_speeds[]; /* Defined in tcsetattr.c. */ + +/* Put the state of FD into *TERMIOS_P. */ +int +DEFUN(__tcgetattr, (fd, termios_p), + int fd AND struct termios *termios_p) +{ + struct sgttyb buf; + struct tchars tchars; + struct ltchars ltchars; + int local; +#ifdef TIOCGETX + int extra; +#endif + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + if (__ioctl(fd, TIOCGETP, &buf) < 0 || + __ioctl(fd, TIOCGETC, &tchars) < 0 || + __ioctl(fd, TIOCGLTC, <chars) < 0 || +#ifdef TIOCGETX + __ioctl(fd, TIOCGETX, &extra) < 0 || +#endif + __ioctl(fd, TIOCLGET, &local) < 0) + return -1; + + termios_p->__ispeed = __bsd_speeds[(unsigned char) buf.sg_ispeed]; + termios_p->__ospeed = __bsd_speeds[(unsigned char) buf.sg_ospeed]; + + termios_p->c_iflag = 0; + termios_p->c_oflag = 0; + termios_p->c_cflag = 0; + termios_p->c_lflag = 0; + termios_p->c_oflag |= CREAD | HUPCL; +#ifdef LPASS8 + if (local & LPASS8) + termios_p->c_oflag |= CS8; + else +#endif + termios_p->c_oflag |= CS7; + if (!(buf.sg_flags & RAW)) + { + termios_p->c_iflag |= IXON; + termios_p->c_cflag |= OPOST; +#ifndef NOISIG + termios_p->c_lflag |= ISIG; +#endif + } + if ((buf.sg_flags & (CBREAK|RAW)) == 0) + termios_p->c_lflag |= ICANON; + if (!(buf.sg_flags & RAW) && !(local & LLITOUT)) + termios_p->c_oflag |= OPOST; + if (buf.sg_flags & CRMOD) + termios_p->c_iflag |= ICRNL; + if (buf.sg_flags & TANDEM) + termios_p->c_iflag |= IXOFF; +#ifdef TIOCGETX + if (!(extra & NOISIG)) + termios_p->c_lflag |= ISIG; + if (extra & STOPB) + termios_p->c_cflag |= CSTOPB; +#endif + + switch (buf.sg_flags & (EVENP|ODDP)) + { + case EVENP|ODDP: + break; + case ODDP: + termios_p->c_cflag |= PARODD; + default: + termios_p->c_cflag |= PARENB; + termios_p->c_iflag |= IGNPAR | INPCK; + break; + } + if (buf.sg_flags & ECHO) + termios_p->c_lflag |= _ECHO; + if (local & LCRTERA) + termios_p->c_lflag |= ECHOE; + if (local & LCRTKIL) + termios_p->c_lflag |= ECHOK; + if (local & LTOSTOP) + termios_p->c_lflag |= _TOSTOP; + if (local & LNOFLSH) + termios_p->c_lflag |= _NOFLSH; + + termios_p->c_cc[VEOF] = tchars.t_eofc; + termios_p->c_cc[VEOL] = '\n'; + termios_p->c_cc[VERASE] = buf.sg_erase; + termios_p->c_cc[VKILL] = buf.sg_kill; + termios_p->c_cc[VINTR] = tchars.t_intrc; + termios_p->c_cc[VQUIT] = tchars.t_quitc; + termios_p->c_cc[VSTART] = tchars.t_startc; + termios_p->c_cc[VSTOP] = tchars.t_stopc; + termios_p->c_cc[VSUSP] = ltchars.t_suspc; + termios_p->c_cc[VMIN] = -1; + termios_p->c_cc[VTIME] = -1; + + return 0; +} + +weak_alias (__tcgetattr, tcgetattr) diff --git a/sysdeps/unix/bsd/tcgetpgrp.c b/sysdeps/unix/bsd/tcgetpgrp.c new file mode 100644 index 0000000000..b41f005375 --- /dev/null +++ b/sysdeps/unix/bsd/tcgetpgrp.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +/* Return the foreground process group ID of FD. */ +pid_t +DEFUN(tcgetpgrp, (fd), int fd) +{ + int pgrp; + if (__ioctl(fd, TIOCGPGRP, &pgrp) < 0) + return (pid_t) -1; + return (pid_t) pgrp; +} diff --git a/sysdeps/unix/bsd/tcsendbrk.c b/sysdeps/unix/bsd/tcsendbrk.c new file mode 100644 index 0000000000..574f442b7b --- /dev/null +++ b/sysdeps/unix/bsd/tcsendbrk.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> +#include <termios.h> +#include <unistd.h> +#include "bsdtty.h" +#include <sys/file.h> +#include <sys/time.h> +#include <sys/types.h> + +/* Send zero bits on FD. */ +int +DEFUN(tcsendbreak, (fd, duration), int fd AND int duration) +{ + struct timeval delay; + + /* The break lasts 0.25 to 0.5 seconds if DURATION is zero, + and an implementation-defined period if DURATION is nonzero. + We define a positive DURATION to be number of microseconds to break. */ + if (duration <= 0) + duration = 400000; + + delay.tv_sec = 0; + delay.tv_usec = duration; + + /* Starting sending break. */ + if (__ioctl (fd, TIOCSBRK, (PTR) NULL) < 0) + return -1; + + /* Wait DURATION microseconds. */ + (void) __select (0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL, + &delay); + + /* Turn off the break. */ + return __ioctl (fd, TIOCCBRK, (PTR) NULL); +} diff --git a/sysdeps/unix/bsd/tcsetattr.c b/sysdeps/unix/bsd/tcsetattr.c new file mode 100644 index 0000000000..e731d830f6 --- /dev/null +++ b/sysdeps/unix/bsd/tcsetattr.c @@ -0,0 +1,186 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> + +#include "bsdtty.h" + + +CONST speed_t __bsd_speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + }; + + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + struct sgttyb buf; + struct tchars tchars; + struct ltchars ltchars; + int local; +#ifdef TIOCGETX + int extra; +#endif + size_t i; + + if (__ioctl(fd, TIOCGETP, &buf) < 0 || + __ioctl(fd, TIOCGETC, &tchars) < 0 || + __ioctl(fd, TIOCGLTC, <chars) < 0 || +#ifdef TIOCGETX + __ioctl(fd, TIOCGETX, &extra) < 0 || +#endif + __ioctl(fd, TIOCLGET, &local) < 0) + return -1; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + switch (optional_actions) + { + case TCSANOW: + break; + case TCSADRAIN: + if (tcdrain(fd) < 0) + return -1; + break; + case TCSAFLUSH: + if (tcflush(fd, TCIFLUSH) < 0) + return -1; + break; + default: + errno = EINVAL; + return -1; + } + + buf.sg_ispeed = buf.sg_ospeed = -1; + for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i) + { + if (__bsd_speeds[i] == termios_p->__ispeed) + buf.sg_ispeed = i; + if (__bsd_speeds[i] == termios_p->__ospeed) + buf.sg_ospeed = i; + } + if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1) + { + errno = EINVAL; + return -1; + } + + buf.sg_flags &= ~(CBREAK|RAW); + if (!(termios_p->c_lflag & ICANON)) + buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW; +#ifdef LPASS8 + if (termios_p->c_oflag & CS8) + local |= LPASS8; + else + local &= ~LPASS8; +#endif + if (termios_p->c_lflag & _NOFLSH) + local |= LNOFLSH; + else + local &= ~LNOFLSH; + if (termios_p->c_oflag & OPOST) + local &= ~LLITOUT; + else + local |= LLITOUT; +#ifdef TIOCGETX + if (termios_p->c_lflag & ISIG) + extra &= ~NOISIG; + else + extra |= NOISIG; + if (termios_p->c_cflag & CSTOPB) + extra |= STOPB; + else + extra &= ~STOPB; +#endif + if (termios_p->c_iflag & ICRNL) + buf.sg_flags |= CRMOD; + else + buf.sg_flags &= ~CRMOD; + if (termios_p->c_iflag & IXOFF) + buf.sg_flags |= TANDEM; + else + buf.sg_flags &= ~TANDEM; + + buf.sg_flags &= ~(ODDP|EVENP); + if (!(termios_p->c_cflag & PARENB)) + buf.sg_flags |= ODDP | EVENP; + else if (termios_p->c_cflag & PARODD) + buf.sg_flags |= ODDP; + else + buf.sg_flags |= EVENP; + + if (termios_p->c_lflag & _ECHO) + buf.sg_flags |= ECHO; + else + buf.sg_flags &= ~ECHO; + if (termios_p->c_lflag & ECHOE) + local |= LCRTERA; + else + local &= ~LCRTERA; + if (termios_p->c_lflag & ECHOK) + local |= LCRTKIL; + else + local &= ~LCRTKIL; + if (termios_p->c_lflag & _TOSTOP) + local |= LTOSTOP; + else + local &= ~LTOSTOP; + + buf.sg_erase = termios_p->c_cc[VERASE]; + buf.sg_kill = termios_p->c_cc[VKILL]; + tchars.t_eofc = termios_p->c_cc[VEOF]; + tchars.t_intrc = termios_p->c_cc[VINTR]; + tchars.t_quitc = termios_p->c_cc[VQUIT]; + ltchars.t_suspc = termios_p->c_cc[VSUSP]; + tchars.t_startc = termios_p->c_cc[VSTART]; + tchars.t_stopc = termios_p->c_cc[VSTOP]; + + if (__ioctl(fd, TIOCSETP, &buf) < 0 || + __ioctl(fd, TIOCSETC, &tchars) < 0 || + __ioctl(fd, TIOCSLTC, <chars) < 0 || +#ifdef TIOCGETX + __ioctl(fd, TIOCSETX, &extra) < 0 || +#endif + __ioctl(fd, TIOCLSET, &local) < 0) + return -1; + return 0; +} diff --git a/sysdeps/unix/bsd/tcsetpgrp.c b/sysdeps/unix/bsd/tcsetpgrp.c new file mode 100644 index 0000000000..e5da8b3f8c --- /dev/null +++ b/sysdeps/unix/bsd/tcsetpgrp.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> + +/* Set the foreground process group ID of FD set PGRP_ID. */ +int +DEFUN(tcsetpgrp, (fd, pgrp_id), int fd AND pid_t pgrp_id) +{ + return __ioctl(fd, TIOCSPGRP, &pgrp_id); +} diff --git a/sysdeps/unix/bsd/telldir.c b/sysdeps/unix/bsd/telldir.c new file mode 100644 index 0000000000..0321f954b8 --- /dev/null +++ b/sysdeps/unix/bsd/telldir.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <stdlib.h> + +/* Internal data structure for telldir and seekdir. */ +struct record + { + struct record *next; /* Link in chain. */ + off_t cookie; /* Value returned by `telldir'. */ + off_t pos; + size_t offset; + }; +#define NBUCKETS 32 +static struct record *records[32]; +static off_t lastpos; + + +/* Return the current position of DIRP. */ +off_t +DEFUN(telldir, (dirp), DIR *dirp) +{ + struct record *new; + + new = malloc (sizeof *new); + if (new == NULL) + return (off_t) -1; + + new->pos = dirp->__pos; + new->offset = dirp->__offset; + new->cookie = ++lastpos; + new->next = records[new->cookie % NBUCKETS]; + records[new->cookie % NBUCKETS] = new; + + return new->cookie; +} + + + +/* Seek to position POS in DIRP. */ +void +DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos) +{ + struct record *r, **prevr; + + for (prevr = &records[pos % NBUCKETS], r = *prevr; + r != NULL; + prevr = &r->next, r = r->next) + if (r->cookie == pos) + { + if (dirp->__pos != r->pos || dirp->__offset != r->offset) + { + dirp->__size = 0; /* Must read a fresh buffer. */ + /* Move to the saved position. */ + __lseek (dirp->__fd, r->pos, SEEK_SET); + dirp->__pos = r->pos; + dirp->__offset = 0; + /* Read entries until we reach the saved offset. */ + while (dirp->__offset < r->offset) + if (readdir (dirp) == NULL) + break; + } + + /* To prevent leaking memory, cookies returned from telldir + can only be used once. So free this one's record now. */ + *prevr = r->next; + free (r); + return; + } + + /* We lost, but have no way to indicate it. Oh well. */ +} diff --git a/sysdeps/unix/bsd/time.c b/sysdeps/unix/bsd/time.c new file mode 100644 index 0000000000..8f8a46f830 --- /dev/null +++ b/sysdeps/unix/bsd/time.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <time.h> +#include <sys/time.h> + + +/* Return the current time as a `time_t' and also put it in *T if T is + not NULL. Time is represented as seconds from Jan 1 00:00:00 1970. */ +time_t +DEFUN(time, (t), time_t *t) +{ + struct timeval tv; + time_t result; + + if (__gettimeofday (&tv, (struct timezone *) NULL)) + result = (time_t) -1; + else + result = (time_t) tv.tv_sec; + + if (t != NULL) + *t = result; + return result; +} diff --git a/sysdeps/unix/bsd/times.c b/sysdeps/unix/bsd/times.c new file mode 100644 index 0000000000..edf3e90972 --- /dev/null +++ b/sysdeps/unix/bsd/times.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/times.h> +#include <sys/time.h> +#include <sys/resource.h> + + +/* Time the program started. */ +extern time_t _posix_start_time; + +#ifdef __GNUC__ +__inline +#endif +static clock_t +DEFUN(timeval_to_clock_t, (tv), CONST struct timeval *tv) +{ + return (clock_t) ((tv->tv_sec * CLK_TCK) + + (tv->tv_usec * CLK_TCK / 1000000L)); +} + +/* Store the CPU time used by this process and all its + dead children (and their dead children) in BUFFER. + Return the elapsed real time, or (clock_t) -1 for errors. + All times are in CLK_TCKths of a second. */ +clock_t +DEFUN(__times, (buffer), struct tms *buffer) +{ + struct rusage usage; + + if (buffer == NULL) + { + errno = EINVAL; + return (clock_t) -1; + } + + if (__getrusage(RUSAGE_SELF, &usage) < 0) + return (clock_t) -1; + buffer->tms_utime = (clock_t) timeval_to_clock_t(&usage.ru_utime); + buffer->tms_stime = (clock_t) timeval_to_clock_t(&usage.ru_stime); + + if (__getrusage(RUSAGE_CHILDREN, &usage) < 0) + return (clock_t) -1; + buffer->tms_cutime = (clock_t) timeval_to_clock_t(&usage.ru_utime); + buffer->tms_cstime = (clock_t) timeval_to_clock_t(&usage.ru_stime); + + return (time((time_t *) NULL) - _posix_start_time) * CLK_TCK; +} + +weak_alias (__times, times) diff --git a/sysdeps/unix/bsd/ualarm.c b/sysdeps/unix/bsd/ualarm.c new file mode 100644 index 0000000000..8d8e01d475 --- /dev/null +++ b/sysdeps/unix/bsd/ualarm.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/time.h> + +/* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds. + If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go + off every INTERVAL microseconds thereafter. + + Returns the number of microseconds remaining before the alarm. */ +unsigned int +DEFUN(ualarm, (value, interval), + unsigned int value AND unsigned int interval) +{ + struct itimerval timer, otimer; + + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = value; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = interval; + + if (setitimer(ITIMER_REAL, &timer, &otimer) < 0) + return -1; + + return (otimer.it_value.tv_sec * 1000) + otimer.it_value.tv_usec; +} diff --git a/sysdeps/unix/bsd/ulimit.c b/sysdeps/unix/bsd/ulimit.c new file mode 100644 index 0000000000..912faf42e2 --- /dev/null +++ b/sysdeps/unix/bsd/ulimit.c @@ -0,0 +1,86 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <sys/resource.h> +#include <unistd.h> +#include <errno.h> + +#ifndef HAVE_GNU_LD +#define _etext etext +#endif + +extern int _etext; + +/* Function depends on CMD: + 1 = Return the limit on the size of a file, in units of 512 bytes. + 2 = Set the limit on the size of a file to NEWLIMIT. Only the + super-user can increase the limit. + 3 = Return the maximum possible address of the data segment. + 4 = Return the maximum number of files that the calling process + can open. + Returns -1 on errors. */ +long int +DEFUN(ulimit, (cmd, newlimit), + int cmd AND long int newlimit) +{ + int status; + + switch (cmd) + { + case 1: + { + /* Get limit on file size. */ + struct rlimit fsize; + + status = getrlimit(RLIMIT_FSIZE, &fsize); + if (status < 0) + return -1; + + /* Convert from bytes to 512 byte units. */ + return fsize.rlim_cur / 512; + } + case 2: + /* Set limit on file size. */ + { + struct rlimit fsize; + fsize.rlim_cur = newlimit * 512; + fsize.rlim_max = newlimit * 512; + + return setrlimit(RLIMIT_FSIZE, &fsize); + } + case 3: + /* Get maximum address for `brk'. */ + { + struct rlimit dsize; + + status = getrlimit(RLIMIT_DATA, &dsize); + if (status < 0) + return -1; + + return ((long int) &_etext) + dsize.rlim_cur; + } + case 4: + return sysconf(_SC_OPEN_MAX); + + default: + errno = EINVAL; + return -1; + } +} diff --git a/sysdeps/unix/bsd/ultrix4/Dist b/sysdeps/unix/bsd/ultrix4/Dist new file mode 100644 index 0000000000..6745cd4b04 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/Dist @@ -0,0 +1 @@ +getsysinfo.S diff --git a/sysdeps/unix/bsd/ultrix4/Implies b/sysdeps/unix/bsd/ultrix4/Implies new file mode 100644 index 0000000000..b0e08ef1db --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/Implies @@ -0,0 +1,2 @@ +# Ultrix 4 has the canonical set of <sys/mman.h> system calls. +unix/mman diff --git a/sysdeps/unix/bsd/ultrix4/Makefile b/sysdeps/unix/bsd/ultrix4/Makefile new file mode 100644 index 0000000000..26b90346ee --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),posix) +sysdep_routines := $(sysdep_routines) getsysinfo +endif diff --git a/sysdeps/unix/bsd/ultrix4/fcntlbits.h b/sysdeps/unix/bsd/ultrix4/fcntlbits.h new file mode 100644 index 0000000000..bf8e7b2a35 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/fcntlbits.h @@ -0,0 +1,125 @@ +/* O_*, F_*, FD_* bit values for Ultrix 4. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0200 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0800 /* Fail if file already exists. */ +#define O_TRUNC 0x0400 /* Truncate file to zero length. */ +#ifdef __USE_MISC +#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x8000 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#define O_BLKINUSE 0x1000 /* Block if "in use". */ +#define O_BLKANDSET 0x3000 /* Block, test and set "in use" flag. */ +#define O_TERMIO 0x40000 /* "termio style program". */ +#endif +#define O_NOCTTY 0x80000 /* Don't assign a controlling terminal. */ + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x20000 /* Non-blocking I/O. */ + +#ifdef __USE_BSD +#define O_NDELAY 0x0004 +#endif + +#ifdef __USE_BSD +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +#define FREAD 1 +#define FWRITE 2 + +/* Traditional BSD names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNDELAY O_NDELAY +#define FNBLOCK O_NONBLOCK +#define FTERMIO O_TERMIO +#define FNOCTTY O_NOCTTY +#define FSYNCRON O_FSYNC +#define FBLKINUSE O_BLKINUSE +#define FBLKANDSET O_BLKANDSET +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 7 /* Get record locking info. */ +#define F_SETLK 8 /* Set record locking info (non-blocking). */ +#define F_SETLKW 9 /* Set record locking info (blocking). */ +#ifdef __USE_MISC +#define F_SETSYN 10 /* Set synchronous writing. */ +#define F_CLRSYN 10 /* Clear synchronous writing. */ +#endif + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/bsd/ultrix4/getdents.S b/sysdeps/unix/bsd/ultrix4/getdents.S new file mode 100644 index 0000000000..be449b2bcb --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/getdents.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/getdents.S> diff --git a/sysdeps/unix/bsd/ultrix4/getsysinfo.S b/sysdeps/unix/bsd/ultrix4/getsysinfo.S new file mode 100644 index 0000000000..1f5b2cf487 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/getsysinfo.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. + Contributed by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Get various sorts of information about the system. + This is an Ultrix only call. */ + +#include <sysdep.h> + +SYSCALL__ (getsysinfo, 5) + ret diff --git a/sysdeps/unix/bsd/ultrix4/mips/Dist b/sysdeps/unix/bsd/ultrix4/mips/Dist new file mode 100644 index 0000000000..c2e8abb84d --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/Dist @@ -0,0 +1 @@ +sigtramp.c __handler.S diff --git a/sysdeps/unix/bsd/ultrix4/mips/Makefile b/sysdeps/unix/bsd/ultrix4/mips/Makefile new file mode 100644 index 0000000000..0b71fd9e18 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),signal) +sysdep_routines := $(sysdep_routines) sigtramp __handler +endif diff --git a/sysdeps/unix/bsd/ultrix4/mips/__handler.S b/sysdeps/unix/bsd/ultrix4/mips/__handler.S new file mode 100644 index 0000000000..3ea697c5a0 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/__handler.S @@ -0,0 +1,113 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + Also hacked by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* This function saves all the registers, calls the + user function, and then executes a sigreturn system call. The + sigreturn call wants the address of a sigcontext structure. This + is all hideously system dependent and, for all intents and + purposes, undocumented. + + When we enter here, a3 holds the user's signal handler. We are + supposed to fill in the context given in a2, and then pass it and + the first two arguments to the user's function. If the user's + function returns, we execute a sigreturn system call. + + The sc_onstack, sc_mask and sc_pc elements of the context are + already set by the kernel. For some reason we don't have to save + the floating point state or the coprocessor state; the kernel may + have saved them for us, or it doesn't use them. */ + +.set noat +ENTRY (__handler) + /* Store zero and the asm temp reg. */ + sw $0, 12(a2) + sw AT, 16(a2) + + /* Put v1 in sc_regs[3]. */ + sw v1, 24(a2) + + /* Save the caller saved registers in sc_regs[8..15]. */ + sw t0, 44(a2) + sw t1, 48(a2) + sw t2, 52(a2) + sw t3, 56(a2) + sw t4, 60(a2) + sw t5, 64(a2) + sw t6, 68(a2) + sw t7, 72(a2) + + /* Save the callee saved registers in sc_regs[16..23]. */ + sw s0, 76(a2) + sw s1, 80(a2) + sw s2, 84(a2) + sw s3, 88(a2) + sw s4, 92(a2) + sw s5, 96(a2) + sw s6, 100(a2) + sw s7, 104(a2) + + /* Save the code generator registers in sc_regs[24] & sc_regs[25]. */ + sw t8, 108(a2) + sw t9, 112(a2) + + /* Save the kernel temp regs in sc_regs[26] & sc_regs[27]. */ + sw k0, 116(a2) + sw k1, 120(a2) + + /* Save the global pointer in sc_regs[28]. */ + sw gp, 124(a2) + + /* ... and also the return address in sc_regs[31]. */ + sw ra, 136(a2) + + /* Note: we don't save the stack pointer in sc_regs[29]; + instead, we use the one that was already there. */ +#if 0 + sw sp, 128(a2) +#endif + + /* Save the floating pointer in sc_regs[30]. */ + sw $fp, 132(a2) + + /* Save the mul/div stuff in sc_mdlo and sc_mdhi. */ + mflo t0 + sw t0, 140(a2) + mfhi t0 + sw t0, 144(a2) + + /* Move the stack up four. This will save the context. */ + addu sp, sp, -32 + sw a2, 16(sp) + + /* Call their handler with the signal, code, and context; note + this will clobber the context. */ + .set noreorder + jal ra, a3 + nop + .set reorder + + /* When we come back, restore the context and pass it right + on into sigreturn(). */ + lw a0, 16(sp) + + /* Do a sigreturn syscall; this doesn't return. */ + la v0, __sigreturn + jal ra, v0 diff --git a/sysdeps/unix/bsd/ultrix4/mips/sigcontext.h b/sysdeps/unix/bsd/ultrix4/mips/sigcontext.h new file mode 100644 index 0000000000..4bddcf2f4b --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/sigcontext.h @@ -0,0 +1,60 @@ +/* Copyright (C) 1992, 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Note that ANY change to this instantly implies a change to __handler.S. */ + +struct sigcontext + { + /* Nonzero if running on signal stack. */ + int sc_onstack; + + /* Signal mask to restore. */ + __sigset_t sc_mask; + + /* Program counter when the signal hit. */ + __ptr_t sc_pc; + + /* Registers 0 through 31. */ + int sc_regs[32]; + + /* mul/div low and hi; these aren't part of a jmp_buf, but are part of the + sigcontext and are referenced from the signal trampoline code. */ + int sc_mdlo; + int sc_mdhi; + + /* Flag to see if the FP's been used. */ + int sc_ownedfp; + + /* Floating point registers 0 to 31. */ + int sc_fpregs[32]; + /* Control & status register for FP. */ + int sc_fpc_csr; + + /* Exception instruction register for FP. */ + int sc_fpc_eir; + + /* The coprocessor's cause register. */ + int sc_cause; + + /* CPU bad virtual address. */ + __ptr_t sc_badvaddr; + + /* CPU board bad physical address. */ + __ptr_t sc_badpaddr; + }; + diff --git a/sysdeps/unix/bsd/ultrix4/mips/sigtramp.c b/sysdeps/unix/bsd/ultrix4/mips/sigtramp.c new file mode 100644 index 0000000000..1bb208dd8b --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/sigtramp.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* The sigvec system call on MIPS Ultrix takes an additional + parameter, which is the address that is actually called when the + signal occurs. + + When a signal occurs, we arrange for the kernel to call __handler. + That will save the frame and stack pointers into the context, and + then jump to this routine. See __handler.S. + + This code is based on sysdeps/unix/bsd/sun4/sigtramp.c, but it's + different because since we get passed the user signal handler we + don't actually need a trampoline. */ + +#include <ansidecl.h> +#include <signal.h> +#include <stddef.h> +#include <errno.h> + +/* The user's signal handler is called with three arguments. */ +typedef void (*handler_type) (int sig, int code, struct sigcontext *); + +/* Defined in __raw_sigvec.S. */ +extern int EXFUN(__raw_sigvec, (int sig, CONST struct sigvec *vec, + struct sigvec *ovec, + void (*)(int sig, int code, + struct sigcontext *, + handler_type))); + +extern void EXFUN(__handler, (int sig, int code, + struct sigcontext *, + handler_type)); + +int +DEFUN(__sigvec, (sig, vec, ovec), + int sig AND CONST struct sigvec *vec AND struct sigvec *ovec) +{ + return __raw_sigvec (sig, vec, ovec, __handler); +} diff --git a/sysdeps/unix/bsd/ultrix4/mips/sigvec.S b/sysdeps/unix/bsd/ultrix4/mips/sigvec.S new file mode 100644 index 0000000000..20a5dd1c49 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/sigvec.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* __sigvec is defined by sigtramp.c. */ + +PSEUDO (__raw_sigvec, sigvec, 3) + ret diff --git a/sysdeps/unix/bsd/ultrix4/mips/start.S b/sysdeps/unix/bsd/ultrix4/mips/start.S new file mode 100644 index 0000000000..ec0f9d833d --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/start.S @@ -0,0 +1,77 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef HAVE_WEAK_SYMBOLS +#define __environ environ +#else +weak_alias (__environ, environ) +#endif + +.comm __environ, 4 +.comm errno, 4 + +ENTRY(__start) + .set noreorder + + /* The first thing on the stack is argc. */ + lw s0, 0(sp) + nop + + /* Set up the global pointer. */ + la gp, _gp + + /* Then set up argv. */ + addiu s1, sp, 4 + + /* To compute where envp is, first we have to jump ahead four + bytes from what argv was. This will bring us ahead, so we don't + need to compute the NULL at the end of argv later. */ + addiu v1, s1, 4 + + /* Now, compute the space to skip given the number of arguments + we've got. We do this by multiplying argc by 4. */ + sll v0, s0, 2 + + /* Now, add (argv+4) with the space to skip...that's envp. */ + addu s2, v1, v0 + + /* __environ = envp; */ + sw s2, __environ + + addiu sp, sp, -24 + + /* __libc_init (argc, argv, envp); */ + move a0, s0 + move a1, s1 + jal __libc_init + move a2, s2 + + /* errno = 0; */ + sw zero, errno + + /* exit (main (argc, argv, envp)); */ + move a0, s0 + move a1, s1 + jal main + move a2, s2 + + /* Make the value returned by main be the argument to exit. */ + jal exit + move a0, v0 diff --git a/sysdeps/unix/bsd/ultrix4/mips/vfork.S b/sysdeps/unix/bsd/ultrix4/mips/vfork.S new file mode 100644 index 0000000000..37f6d8016d --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/mips/vfork.S @@ -0,0 +1,33 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_vfork +#define SYS_vfork 66 +#endif + +SYSCALL__ (vfork, 0) + beq v1, zero, parent /* Branch if parent. */ + nop + move v0, zero +parent: + ret + nop + +weak_alias (__vfork, vfork) diff --git a/sysdeps/unix/bsd/ultrix4/posix_opt.h b/sysdeps/unix/bsd/ultrix4/posix_opt.h new file mode 100644 index 0000000000..ecd04d1f0e --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/posix_opt.h @@ -0,0 +1,23 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. + Contributed by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define _POSIX_JOB_CONTROL 1 +#define _POSIX_SAVED_IDS 1 +#define _POSIX_CHOWN_RESTRICTED 1 +#define _POSIX_NO_TRUNC 1 +#define _POSIX_VDISABLE ((unsigned char) -1) diff --git a/sysdeps/unix/bsd/ultrix4/setsid.S b/sysdeps/unix/bsd/ultrix4/setsid.S new file mode 100644 index 0000000000..4930c56dcf --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/setsid.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/setsid.S> diff --git a/sysdeps/unix/bsd/ultrix4/sys/mman.h b/sysdeps/unix/bsd/ultrix4/sys/mman.h new file mode 100644 index 0000000000..c850b4f7c8 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/sys/mman.h @@ -0,0 +1,99 @@ +/* Definitions for BSD-style memory management. Ultrix 4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* These are the bits used by 4.4 BSD and its derivatives. On systems + (such as GNU) where these facilities are not system services but can be + emulated in the C library, these are the definitions we emulate. */ + +#ifndef _SYS_MMAN_H + +#define _SYS_MMAN_H 1 +#include <features.h> + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x01 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x04 /* Pages can be executed. */ + + +/* Sharing types (must choose one and only one of these). */ +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes private; copy pages on write. */ +#define MAP_TYPE 0x0f /* Mask for sharing type. */ + +/* Other flags. */ +#define MAP_FIXED 0x10 /* Map address must be exactly as requested. */ + +/* Advice to `madvise'. */ +#define MADV_NORMAL 0 /* No further special treatment. */ +#define MADV_RANDOM 1 /* Expect random page references. */ +#define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define MADV_WILLNEED 3 /* Will need these pages. */ +#define MADV_DONTNEED 4 /* Don't need these pages. */ + + +#include <sys/cdefs.h> + +__BEGIN_DECLS +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__caddr_t mmap __P ((__caddr_t __addr, size_t __len, + int __prot, int __flags, int __fd, off_t __offset)); + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ +int munmap __P ((__caddr_t __addr, size_t __len)); + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ +int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); + +/* Ultrix 4 does not implement `msync' or `madvise'. */ + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ +int msync __P ((caddr_t __addr, size_t __len)); + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ +int madvise __P ((__caddr_t __addr, size_t __len, int __advice)); + +__END_DECLS + + +#endif /* sys/mman.h */ diff --git a/sysdeps/unix/bsd/ultrix4/sysconf.c b/sysdeps/unix/bsd/ultrix4/sysconf.c new file mode 100644 index 0000000000..a9f3c5bbbe --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/sysconf.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* On Ultrix we can use the getsysinfo call to get the right return + value for _SC_CHILD_MAX. Everything else is from <sys/param.h>, + which the default sysconf already knows how to handle. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <errno.h> + +/* This is an Ultrix header file. */ +#include <sys/sysinfo.h> + +extern int EXFUN(__getsysinfo, (unsigned int op, void *buffer, + size_t nbytes, int *start, + void *arg)); +extern long int EXFUN(__default_sysconf, (int name)); + +long int +DEFUN(__sysconf, (name), int name) +{ + if (name == _SC_CHILD_MAX) + { + int save = errno; + int start = 0; + int ret; + + /* getsysinfo returns the number of values it put into the + buffer, or 0 if not available, or -1 on error. */ + if (__getsysinfo (GSI_MAX_UPROCS, &ret, sizeof (ret), &start, + (void *) 0) > 0) + { + errno = save; + return ret; + } + + errno = save; + } + + return __default_sysconf (name); +} + +#define __sysconf __default_sysconf + +#include <sysdeps/posix/sysconf.c> diff --git a/sysdeps/unix/bsd/ultrix4/system.c b/sysdeps/unix/bsd/ultrix4/system.c new file mode 100644 index 0000000000..b133fe77c0 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/system.c @@ -0,0 +1,2 @@ +/* Ultrix 4 does have `waitpid'. Avoid unix/system.c, which says we don't. */ +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/bsd/ultrix4/uname.S b/sysdeps/unix/bsd/ultrix4/uname.S new file mode 100644 index 0000000000..488eeb1d97 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/uname.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/uname.S> diff --git a/sysdeps/unix/bsd/ultrix4/utsnamelen.h b/sysdeps/unix/bsd/ultrix4/utsnamelen.h new file mode 100644 index 0000000000..ad4389ab02 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/utsnamelen.h @@ -0,0 +1 @@ +#define _UTSNAME_LENGTH 32 diff --git a/sysdeps/unix/bsd/ultrix4/wait3.S b/sysdeps/unix/bsd/ultrix4/wait3.S new file mode 100644 index 0000000000..83910a5d7b --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/wait3.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (wait3, 3) + ret + +weak_alias (__wait3, wait3) diff --git a/sysdeps/unix/bsd/ultrix4/waitpid.S b/sysdeps/unix/bsd/ultrix4/waitpid.S new file mode 100644 index 0000000000..b64e528b69 --- /dev/null +++ b/sysdeps/unix/bsd/ultrix4/waitpid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (waitpid, 3) + ret + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/unix/bsd/usleep.c b/sysdeps/unix/bsd/usleep.c new file mode 100644 index 0000000000..850233aaad --- /dev/null +++ b/sysdeps/unix/bsd/usleep.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/time.h> + +/* Sleep USECONDS microseconds, or until a previously set timer goes off. */ +unsigned int +DEFUN(usleep, (useconds), unsigned int useconds) +{ + struct timeval delay; + + delay.tv_sec = 0; + delay.tv_usec = useconds; + + (void) __select (0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL, + &delay); + + return 0; +} diff --git a/sysdeps/unix/bsd/utime.c b/sysdeps/unix/bsd/utime.c new file mode 100644 index 0000000000..c7ed20ffe3 --- /dev/null +++ b/sysdeps/unix/bsd/utime.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <utime.h> +#include <time.h> +#include <sys/types.h> +#include <sys/time.h> + + +/* Set the access and modification times of FILE to those given in TIMES. + If TIMES is NULL, set them to the current time. */ +int +DEFUN(utime, (file, times), CONST char *file AND CONST struct utimbuf *times) +{ + struct timeval timevals[2]; + + if (times != NULL) + { + timevals[0].tv_sec = (long int) times->actime; + timevals[0].tv_usec = 0L; + timevals[1].tv_sec = (long int) times->modtime; + timevals[1].tv_usec = 0L; + } + else + { + if (__gettimeofday (&timevals[0], NULL) < 0) + return -1; + timevals[1] = timevals[0]; + } + + return __utimes (file, timevals); +} diff --git a/sysdeps/unix/bsd/utimes.S b/sysdeps/unix/bsd/utimes.S new file mode 100644 index 0000000000..2f700b0e1e --- /dev/null +++ b/sysdeps/unix/bsd/utimes.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (utimes, 2) + ret + +weak_alias (__utimes, utimes) diff --git a/sysdeps/unix/bsd/vax/brk.S b/sysdeps/unix/bsd/vax/brk.S new file mode 100644 index 0000000000..b3e8e10307 --- /dev/null +++ b/sysdeps/unix/bsd/vax/brk.S @@ -0,0 +1,47 @@ +/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef HAVE_GNU_LD +#define __end _end +#endif + +.data +.globl ___curbrk +___curbrk: + .long __end + +.text +ENTRY (__brk) + cmpl 4(ap), __end + bgeq 0f + movl __env, 4(ap) +0: chmk $SYS_brk + bcs 1f + movl 4(ap), ___curbrk + clrl r0 + ret +1: + jmp syscall_error + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/bsd/vax/pipe.S b/sysdeps/unix/bsd/vax/pipe.S new file mode 100644 index 0000000000..10c681aac6 --- /dev/null +++ b/sysdeps/unix/bsd/vax/pipe.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pipe, 1) + movl 4(ap), r2 + movl r0, (r2)+ + movl r1, (r2) + clrl r0 + ret + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/bsd/vax/sysdep.S b/sysdeps/unix/bsd/vax/sysdep.S new file mode 100644 index 0000000000..618d889742 --- /dev/null +++ b/sysdeps/unix/bsd/vax/sysdep.S @@ -0,0 +1,35 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define _ERRNO_H +#include <errnos.h> + +.globl _errno +.globl syscall_error +syscall_error: +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmpl r0, $EWOULDBLOCK_sys + bne 0f + movl $EAGAIN, r0 +#endif +0: movl r0, _errno + mnegl $1, r0 + ret diff --git a/sysdeps/unix/bsd/vax/sysdep.h b/sysdeps/unix/bsd/vax/sysdep.h new file mode 100644 index 0000000000..aeddad99ae --- /dev/null +++ b/sysdeps/unix/bsd/vax/sysdep.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl _##name; \ + .even; \ + _##name##: +#else +#define ENTRY(name) \ + .globl _/**/name; \ + .even; \ + _/**/name/**/: +#endif + +#ifdef __STDC__ +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error \ + error: jmp syscall_error; \ + ENTRY (name) \ + chmk $SYS_##syscall_name \ + bcs error +#else +#define PSEUDO(name, syscall_name, args) \ + .even; \ + .globl syscall_error \ + error: jmp syscall_error; \ + ENTRY (name) \ + chmk $SYS_/**/syscall_name \ + bcs error +#endif + +#define MOVE(x,y) movl x , y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/vax/wait.S b/sysdeps/unix/bsd/vax/wait.S new file mode 100644 index 0000000000..77311b49bf --- /dev/null +++ b/sysdeps/unix/bsd/vax/wait.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (wait, 1) + movl 4(ap), r2 + beq 1f + movl r1, (r2) +1: ret + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/bsd/vax/wait3.S b/sysdeps/unix/bsd/vax/wait3.S new file mode 100644 index 0000000000..2d8dba8297 --- /dev/null +++ b/sysdeps/unix/bsd/vax/wait3.S @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY(___wait3) + movel 8(ap), r1 + movel 12(ap), r0 + /* Set all condition codes to tell the kernel this is wait3. */ + bispsw $15 + chmk $SYS_wait + bcs error + + movl 4(ap), r2 + beq 1f + movl r1, (r2) +1: ret + +.globl syscall_error +error: jmp syscall_error + +weak_alias (__wait3, wait3) diff --git a/sysdeps/unix/bsd/waitflags.h b/sysdeps/unix/bsd/waitflags.h new file mode 100644 index 0000000000..52e4f80619 --- /dev/null +++ b/sysdeps/unix/bsd/waitflags.h @@ -0,0 +1,28 @@ +/* Definitions of flag bits for `waitpid' et al. +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _WAITFLAGS_H + +#define _WAITFLAGS_H 1 + +/* Bits in the third argument to `waitpid'. */ +#define WNOHANG 1 /* Don't block waiting. */ +#define WUNTRACED 2 /* Report status of stopped children. */ + +#endif /* waitflags.h */ diff --git a/sysdeps/unix/chdir.S b/sysdeps/unix/chdir.S new file mode 100644 index 0000000000..38d6b88510 --- /dev/null +++ b/sysdeps/unix/chdir.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (chdir, 1) + ret + +weak_alias (__chdir, chdir) diff --git a/sysdeps/unix/chmod.S b/sysdeps/unix/chmod.S new file mode 100644 index 0000000000..b8654eb41c --- /dev/null +++ b/sysdeps/unix/chmod.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (chmod, 2) + ret + +weak_alias (__chmod, chmod) diff --git a/sysdeps/unix/chown.S b/sysdeps/unix/chown.S new file mode 100644 index 0000000000..83442b4be1 --- /dev/null +++ b/sysdeps/unix/chown.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (chown, 3) + ret + +weak_alias (__chown, chown) diff --git a/sysdeps/unix/chroot.S b/sysdeps/unix/chroot.S new file mode 100644 index 0000000000..37802cc37b --- /dev/null +++ b/sysdeps/unix/chroot.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (chroot, 1) + ret diff --git a/sysdeps/unix/close.S b/sysdeps/unix/close.S new file mode 100644 index 0000000000..5b0a698ca4 --- /dev/null +++ b/sysdeps/unix/close.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (close, 1) + ret + +weak_alias (__close, close) diff --git a/sysdeps/unix/closedir.c b/sysdeps/unix/closedir.c new file mode 100644 index 0000000000..e01dccb54c --- /dev/null +++ b/sysdeps/unix/closedir.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <dirent.h> +#include <unistd.h> + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +int +DEFUN(closedir, (dirp), DIR *dirp) +{ + int fd; + + if (dirp == NULL) + { + errno = EINVAL; + return -1; + } + + fd = dirp->__fd; + + free ((PTR) dirp->__data); + free ((PTR) dirp); + + return __close (fd); +} + diff --git a/sysdeps/unix/common/.cvsignore b/sysdeps/unix/common/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/sysdeps/unix/common/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/sysdeps/unix/common/Dist b/sysdeps/unix/common/Dist new file mode 100644 index 0000000000..0c47cabcfa --- /dev/null +++ b/sysdeps/unix/common/Dist @@ -0,0 +1 @@ +glue-ctype.c diff --git a/sysdeps/unix/common/Makefile b/sysdeps/unix/common/Makefile new file mode 100644 index 0000000000..5c338a269c --- /dev/null +++ b/sysdeps/unix/common/Makefile @@ -0,0 +1,35 @@ +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifndef inhibit-glue +ifeq ($(subdir),ctype) + +sysdep_routines := $(sysdep_routines) ctype-glue + +generated := $(generated) glue-ctype ctype-glue.c + +$(objpfx)ctype-glue.c: $(objpfx)glue-ctype + @rm -f $@ + $(dir $<)$(notdir $<) > $@-t + mv $@-t $@ + +$(objpfx)glue-ctype: $(sysdep_dir)/unix/common/glue-ctype.c + $(native-compile) + +endif +endif diff --git a/sysdeps/unix/common/access.S b/sysdeps/unix/common/access.S new file mode 100644 index 0000000000..ec0f3c9a3f --- /dev/null +++ b/sysdeps/unix/common/access.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (access, 2) + ret + +weak_alias (__access, access) diff --git a/sysdeps/unix/common/adjtime.S b/sysdeps/unix/common/adjtime.S new file mode 100644 index 0000000000..af080a7d6e --- /dev/null +++ b/sysdeps/unix/common/adjtime.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (adjtime, 2) + ret + +weak_alias (__adjtime, adjtime) diff --git a/sysdeps/unix/common/configure b/sysdeps/unix/common/configure new file mode 100755 index 0000000000..b01c547c60 --- /dev/null +++ b/sysdeps/unix/common/configure @@ -0,0 +1,101 @@ + +if test -z "$inhibit_glue"; then + +# Find out what this system calls `sys_siglist'. +echo $ac_n "checking for sys_siglist""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_check_symbol_sys_siglist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext <<EOF +#line 11 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +extern char *sys_siglist[]; puts(*sys_siglist); +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + ac_cv_check_symbol_sys_siglist=yes +else + rm -rf conftest* + ac_cv_check_symbol_sys_siglist=no +fi +rm -f conftest* + +fi + +if test "$ac_cv_check_symbol_sys_siglist" = yes; then + ac_tr_symbol=`echo sys_siglist | tr '[a-z]' '[A-Z]'` + cat >> confdefs.h <<EOF +#define HAVE_${ac_tr_symbol} 1 +EOF + +fi +echo "$ac_t""$ac_cv_check_symbol_sys_siglist" 1>&4 +echo $ac_n "checking for _sys_siglist""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_check_symbol__sys_siglist'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext <<EOF +#line 43 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +extern char *_sys_siglist[]; puts(*_sys_siglist); +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + ac_cv_check_symbol__sys_siglist=yes +else + rm -rf conftest* + ac_cv_check_symbol__sys_siglist=no +fi +rm -f conftest* + +fi + +if test "$ac_cv_check_symbol__sys_siglist" = yes; then + ac_tr_symbol=`echo _sys_siglist | tr '[a-z]' '[A-Z]'` + cat >> confdefs.h <<EOF +#define HAVE_${ac_tr_symbol} 1 +EOF + +fi +echo "$ac_t""$ac_cv_check_symbol__sys_siglist" 1>&4 + +# Find out the name of the table the system's <ctype.h> uses for character +# classification. This is used by sysdeps/unix/common/glue-ctype.c. +echo $ac_n "checking ctype array name for glue""... $ac_c" 1>&4 +if eval "test \"`echo '${'libc_cv_ctype_glue'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + for ctype in _ctype_ __ctype_ __ctype _ctype__ _ctype _locp; do +cat > conftest.$ac_ext <<EOF +#line 79 "configure" +#include "confdefs.h" +#include <ctype.h> +int main() { return 0; } +int t() { +$ctype[13]; +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + libc_cv_ctype_glue="$ctype"; break +fi +rm -f conftest* + +done +fi + +echo "$ac_t""$libc_cv_ctype_glue" 1>&4 +cat >> confdefs.h <<EOF +#define HAVE_`echo $libc_cv_ctype_glue | tr 'a-z' 'A-Z'` 1 +EOF + + +fi diff --git a/sysdeps/unix/common/configure.in b/sysdeps/unix/common/configure.in new file mode 100644 index 0000000000..807c44619e --- /dev/null +++ b/sysdeps/unix/common/configure.in @@ -0,0 +1,22 @@ +sinclude(./aclocal.m4)dnl +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +if test -z "$inhibit_glue"; then + +# Find out what this system calls `sys_siglist'. +AC_CHECK_SYMBOL(sys_siglist) +AC_CHECK_SYMBOL(_sys_siglist) + +# Find out the name of the table the system's <ctype.h> uses for character +# classification. This is used by sysdeps/unix/common/glue-ctype.c. +AC_MSG_CHECKING(ctype array name for glue) +AC_CACHE_VAL(libc_cv_ctype_glue, [dnl +for ctype in _ctype_ __ctype_ __ctype _ctype__ _ctype _locp; do +AC_TRY_LINK([#include <ctype.h>], + [$ctype[13];], + [libc_cv_ctype_glue="$ctype"; break]) +done]) +AC_MSG_RESULT($libc_cv_ctype_glue) +AC_DEFINE_UNQUOTED(HAVE_`echo $libc_cv_ctype_glue | tr '[a-z]' '[A-Z]'`) + +fi diff --git a/sysdeps/unix/common/direct.h b/sysdeps/unix/common/direct.h new file mode 100644 index 0000000000..ef88147d81 --- /dev/null +++ b/sysdeps/unix/common/direct.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _BSDDIR_H +#define _BSDDIR_H 1 + +#include <limits.h> + +/* This is what system V calls a "struct dirent". */ + +struct direct + { + unsigned long int d_fileno; + long int d_off; + unsigned short int d_reclen; + char d_name[NAME_MAX + 1]; + }; + +#include <stddef.h> + +/* We calculate the length of the name by taking the length of the whole + `struct direct' record, subtracting the size of everything before the + name, and subtracting one for the terminating null. */ + +#define D_NAMLEN(d) \ + ((d)->d_reclen - offsetof (struct direct, d_name) - 1) + +#endif diff --git a/sysdeps/unix/common/dup2.S b/sysdeps/unix/common/dup2.S new file mode 100644 index 0000000000..77bcaaf03a --- /dev/null +++ b/sysdeps/unix/common/dup2.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (dup2, 2) + ret + +weak_alias (__dup2, dup2) diff --git a/sysdeps/unix/common/fchmod.S b/sysdeps/unix/common/fchmod.S new file mode 100644 index 0000000000..93196485a9 --- /dev/null +++ b/sysdeps/unix/common/fchmod.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fchmod, 2) + ret + +weak_alias (__fchmod, fchmod) diff --git a/sysdeps/unix/common/fchown.S b/sysdeps/unix/common/fchown.S new file mode 100644 index 0000000000..bb05e05304 --- /dev/null +++ b/sysdeps/unix/common/fchown.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fchown, 3) + ret + +weak_alias (__fchown, fchown) diff --git a/sysdeps/unix/common/fcntlbits.h b/sysdeps/unix/common/fcntlbits.h new file mode 100644 index 0000000000..0f8443313f --- /dev/null +++ b/sysdeps/unix/common/fcntlbits.h @@ -0,0 +1,122 @@ +/* O_*, F_*, FD_* bit values for SVR4 and Irix 4. +Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 0x0100 /* Create file if it doesn't exist. */ +#define O_EXCL 0x0400 /* Fail if file already exists. */ +#define O_TRUNC 0x0200 /* Truncate file to zero length. */ +#define O_NOCTTY 0x0800 /* Don't assign a controlling terminal. */ +#ifdef __USE_MISC +#define O_ASYNC 0x0040 /* Send SIGIO to owner when data is ready. */ +#define O_FSYNC 0x0010 /* Synchronous writes. */ +#define O_SYNC O_FSYNC +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 0x0008 /* Writes append to the file. */ +#define O_NONBLOCK 0x0080 /* Non-blocking I/O. */ + +#ifdef __USE_MISC +#define O_NDELAY 0x0004 +#endif + +#ifdef __USE_MISC +/* Bits in the file status flags returned by F_GETFL. + These are all the O_* flags, plus FREAD and FWRITE, which are + independent bits set by which of O_RDONLY, O_WRONLY, and O_RDWR, was + given to `open'. */ +#define FREAD 1 +#define FWRITE 2 + +/* Traditional Unix names the O_* bits. */ +#define FASYNC O_ASYNC +#define FCREAT O_CREAT +#define FEXCL O_EXCL +#define FTRUNC O_TRUNC +#define FNOCTTY O_NOCTTY +#define FFSYNC O_FSYNC +#define FSYNC O_SYNC +#define FAPPEND O_APPEND +#define FNONBLOCK O_NONBLOCK +#define FNONBIO O_NONBLOCK +#define FNDELAY O_NDELAY +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#ifdef __USE_BSD +#define F_GETOWN 23 /* Get owner (receiver of SIGIO). */ +#define F_SETOWN 24 /* Set owner (receiver of SIGIO). */ +#endif +#define F_GETLK 14 /* Get record locking info. */ +#define F_SETLK 6 /* Set record locking info (non-blocking). */ +#define F_SETLKW 7 /* Set record locking info (blocking). */ +#ifdef __USE_SVID +#define F_ALLOCSP 10 /* Allocate space in the file. */ +#define F_FREESP 11 /* Free space in the file. */ +#define F_RGETLK 20 /* Get remote record locking info. */ +#define F_RSETLK 21 /* Set remote locking info (non-blocking). */ +#define F_RSETLKW 22 /* Set remote locking info (blocking). */ +#endif + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + long int l_sysid; /* System ID where locking process resides. */ + __pid_t l_pid; /* Process holding the lock. */ + long int pad[4]; /* Reserved for future use. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/common/ftruncate.S b/sysdeps/unix/common/ftruncate.S new file mode 100644 index 0000000000..6081a055b5 --- /dev/null +++ b/sysdeps/unix/common/ftruncate.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (ftruncate, 2) + ret diff --git a/sysdeps/unix/common/getgroups.S b/sysdeps/unix/common/getgroups.S new file mode 100644 index 0000000000..74b657a88a --- /dev/null +++ b/sysdeps/unix/common/getgroups.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getgroups, 2) + ret + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/unix/common/getitimer.S b/sysdeps/unix/common/getitimer.S new file mode 100644 index 0000000000..d8db92123c --- /dev/null +++ b/sysdeps/unix/common/getitimer.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getitimer, 2) + ret + +weak_alias (__getitimer, getitimer) diff --git a/sysdeps/unix/common/getpgid.S b/sysdeps/unix/common/getpgid.S new file mode 100644 index 0000000000..0ddfe9667e --- /dev/null +++ b/sysdeps/unix/common/getpgid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__getpgid, getpgrp, 1) + ret + +weak_alias (__getpgid, getpgid) diff --git a/sysdeps/unix/common/getpriority.S b/sysdeps/unix/common/getpriority.S new file mode 100644 index 0000000000..d71eeac698 --- /dev/null +++ b/sysdeps/unix/common/getpriority.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getpriority, 2) + ret diff --git a/sysdeps/unix/common/getrlimit.S b/sysdeps/unix/common/getrlimit.S new file mode 100644 index 0000000000..193acf3962 --- /dev/null +++ b/sysdeps/unix/common/getrlimit.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getrlimit, 2) + ret diff --git a/sysdeps/unix/common/getrusage.S b/sysdeps/unix/common/getrusage.S new file mode 100644 index 0000000000..227e1ca67c --- /dev/null +++ b/sysdeps/unix/common/getrusage.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getrusage, 2) + ret + +weak_alias (__getrusage, getrusage) diff --git a/sysdeps/unix/common/gettimeofday.S b/sysdeps/unix/common/gettimeofday.S new file mode 100644 index 0000000000..9d7fc3fa30 --- /dev/null +++ b/sysdeps/unix/common/gettimeofday.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (gettimeofday, 2) + ret + +weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/unix/common/glue-ctype.c b/sysdeps/unix/common/glue-ctype.c new file mode 100644 index 0000000000..d2d645b5b0 --- /dev/null +++ b/sysdeps/unix/common/glue-ctype.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Different systems have different names for the array. + This order is important for some systems. */ + +#if !defined(TABLE) && defined(HAVE__LOCP) +/* OSF/1 has the name _ctype defined as a macro, which points down into + the _locp structure. Jesus. We'll hope this works. We need to + check for LOCP first, since there is no symbol actually named _ctype + in their library. */ +#include <sys/types.h> /* for wchar_t used by localdef.h */ +#include <sys/localedef.h> +extern loc_t *_locp; +#define TABLE (_locp->lc_chrtbl)->lc_ctype +#undef _ctype +#define TABLE_NAME _ctype +#endif +#ifdef HAVE__CTYPE__ +#define TABLE _ctype__ +#endif +#if !defined(TABLE) && defined(HAVE__CTYPE) +#define TABLE _ctype +#endif +#if !defined(TABLE) && defined(HAVE__CTYPE_) +#define TABLE _ctype_ +#endif +#if !defined(TABLE) && defined(HAVE___CTYPE_) +#define TABLE __ctype_ +#endif +#if !defined(TABLE) && defined(HAVE___CTYPE) +#define TABLE __ctype +#endif + +#if defined (__STDC__) && __STDC__ +#define STRINGIFY(arg) #arg +#else +#define STRINGIFY(arg) "arg" +#endif + +#define EVALLED_STRINGIFY(x) STRINGIFY (x) + +main () +{ +#ifdef TABLE + + int i; + +#ifndef HAVE__LOCP + /* This won't work for the define to look into _locp. */ + extern unsigned char TABLE[]; +#endif + + puts ("#include <ansidecl.h>"); +#ifdef TABLE_NAME + printf ("CONST unsigned char %s[] =\n {\n", EVALLED_STRINGIFY (TABLE_NAME)); +#else + printf ("CONST unsigned char %s[] =\n {\n", EVALLED_STRINGIFY (TABLE)); +#endif + + for (i = -1; i < 256; ++i) + printf (" %d,\n", (int) ((TABLE+1)[i])); + + puts (" };"); + +#else + + puts ("/* I don't know what the ctype table is called on this system."); + puts (" If there is a table, and you want the ctype glue to work,"); + puts (" edit configure.in and glue-ctype.c in sysdeps/unix/common/"); + puts (" to check for the right name. */"); + +#endif + + exit (0); +} diff --git a/sysdeps/unix/common/lstat.S b/sysdeps/unix/common/lstat.S new file mode 100644 index 0000000000..bc9592232f --- /dev/null +++ b/sysdeps/unix/common/lstat.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (lstat, 2) + ret + +weak_alias (__lstat, lstat) diff --git a/sysdeps/unix/common/mk-local_lim.c b/sysdeps/unix/common/mk-local_lim.c new file mode 100644 index 0000000000..1b014f0d16 --- /dev/null +++ b/sysdeps/unix/common/mk-local_lim.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/types.h> +#include <sys/param.h> + +/* Generate local_limits.h from <sys/param.h> values for BSD. */ + +struct param + { + char *name; + int value; + }; + +static struct param params[] = + { + { "NGROUPS_MAX", NGROUPS }, + + { "ARG_MAX", NCARGS }, + +#ifdef MAXUPRC + { "CHILD_MAX", MAXUPRC }, +#endif + + { "OPEN_MAX", NOFILE }, + + /* Apparently, Ultrix's <sys/param.h> defines LINK_MAX and not MAXLINK. */ +#if defined (LINK_MAX) && !defined (MAXLINK) +#define MAXLINK LINK_MAX +#endif +#ifdef MAXLINK + { "LINK_MAX", MAXLINK }, +#endif + + { "MAX_CANON", CANBSIZ }, + +#ifndef MAXNAMLEN +#define MAXNAMLEN 255 +#endif + { "NAME_MAX", MAXNAMLEN }, + + { "PATH_MAX", MAXPATHLEN }, + + { NULL, 0 } + }; + +int +main() +{ + extern char *ctime(); + extern time_t time(); + time_t now = time((time_t *) NULL); + register struct param *p; + + printf("\ +/* Implementation-specific limits.\n\ + Generated at %.25s. */\n\n", ctime(&now)); + + for (p = params; p->name != NULL; ++p) + printf("#define %s %d\n", p->name, p->value); + + exit(0); +} diff --git a/sysdeps/unix/common/mkdir.S b/sysdeps/unix/common/mkdir.S new file mode 100644 index 0000000000..d8274805cc --- /dev/null +++ b/sysdeps/unix/common/mkdir.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (mkdir, 2) + ret + +weak_alias (__mkdir, mkdir) diff --git a/sysdeps/unix/common/readlink.S b/sysdeps/unix/common/readlink.S new file mode 100644 index 0000000000..cf5f25e6c9 --- /dev/null +++ b/sysdeps/unix/common/readlink.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (readlink, 3) + ret + +weak_alias (__readlink, readlink) diff --git a/sysdeps/unix/common/readv.S b/sysdeps/unix/common/readv.S new file mode 100644 index 0000000000..1d643ac6d3 --- /dev/null +++ b/sysdeps/unix/common/readv.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (readv, 3) + ret diff --git a/sysdeps/unix/common/rename.S b/sysdeps/unix/common/rename.S new file mode 100644 index 0000000000..f5ed73e5bb --- /dev/null +++ b/sysdeps/unix/common/rename.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (rename, 2) + ret diff --git a/sysdeps/unix/common/rmdir.S b/sysdeps/unix/common/rmdir.S new file mode 100644 index 0000000000..90b89bb175 --- /dev/null +++ b/sysdeps/unix/common/rmdir.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (rmdir, 1) + ret + +weak_alias (__rmdir, rmdir) diff --git a/sysdeps/unix/common/select.S b/sysdeps/unix/common/select.S new file mode 100644 index 0000000000..54ffcec70a --- /dev/null +++ b/sysdeps/unix/common/select.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (select, 5) + ret + +weak_alias (__select, select) diff --git a/sysdeps/unix/common/setgroups.S b/sysdeps/unix/common/setgroups.S new file mode 100644 index 0000000000..7f4f1f800e --- /dev/null +++ b/sysdeps/unix/common/setgroups.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setgroups, 2) + ret diff --git a/sysdeps/unix/common/setitimer.S b/sysdeps/unix/common/setitimer.S new file mode 100644 index 0000000000..63e4e03d65 --- /dev/null +++ b/sysdeps/unix/common/setitimer.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setitimer, 3) + ret + +weak_alias (__setitimer, setitimer) diff --git a/sysdeps/unix/common/setpgid.S b/sysdeps/unix/common/setpgid.S new file mode 100644 index 0000000000..5b338255dc --- /dev/null +++ b/sysdeps/unix/common/setpgid.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__setpgid, setpgrp, 2) + ret + +weak_alias (__setpgid, setpgid) +weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/unix/common/setpriority.S b/sysdeps/unix/common/setpriority.S new file mode 100644 index 0000000000..89477c2c8b --- /dev/null +++ b/sysdeps/unix/common/setpriority.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setpriority, 3) + ret diff --git a/sysdeps/unix/common/setregid.S b/sysdeps/unix/common/setregid.S new file mode 100644 index 0000000000..dd80ef44cd --- /dev/null +++ b/sysdeps/unix/common/setregid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setregid, 2) + ret + +weak_alias (__setregid, setregid) diff --git a/sysdeps/unix/common/setreuid.S b/sysdeps/unix/common/setreuid.S new file mode 100644 index 0000000000..245265a2ff --- /dev/null +++ b/sysdeps/unix/common/setreuid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setreuid, 2) + ret + +weak_alias (__setreuid, setreuid) diff --git a/sysdeps/unix/common/setrlimit.S b/sysdeps/unix/common/setrlimit.S new file mode 100644 index 0000000000..3ae577fbd9 --- /dev/null +++ b/sysdeps/unix/common/setrlimit.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setrlimit, 2) + ret diff --git a/sysdeps/unix/common/swapon.S b/sysdeps/unix/common/swapon.S new file mode 100644 index 0000000000..f410372c26 --- /dev/null +++ b/sysdeps/unix/common/swapon.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (swapon, 1) + ret diff --git a/sysdeps/unix/common/symlink.S b/sysdeps/unix/common/symlink.S new file mode 100644 index 0000000000..0a4a084d42 --- /dev/null +++ b/sysdeps/unix/common/symlink.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (symlink, 2) + ret + +weak_alias (__symlink, symlink) diff --git a/sysdeps/unix/common/truncate.S b/sysdeps/unix/common/truncate.S new file mode 100644 index 0000000000..a643e46e8a --- /dev/null +++ b/sysdeps/unix/common/truncate.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (truncate, 2) + ret diff --git a/sysdeps/unix/common/vhangup.S b/sysdeps/unix/common/vhangup.S new file mode 100644 index 0000000000..8b1b833168 --- /dev/null +++ b/sysdeps/unix/common/vhangup.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (vhangup, 1) + ret diff --git a/sysdeps/unix/common/writev.S b/sysdeps/unix/common/writev.S new file mode 100644 index 0000000000..3d1692c8fe --- /dev/null +++ b/sysdeps/unix/common/writev.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (writev, 3) + ret diff --git a/sysdeps/unix/configure b/sysdeps/unix/configure new file mode 100755 index 0000000000..8069c52d6b --- /dev/null +++ b/sysdeps/unix/configure @@ -0,0 +1,127 @@ + # Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + + +sysincludedir=/usr/include # XXX + +# Find the <syscall.h> file we will be using, or something like it. +unix_found= +for unix_dir in $sysnames; do + if test -r $sysdep_dir/$unix_dir/syscall.h; then + unix_found=$unix_dir + break + fi +done +if test $unix_found = stub; then + # XXX This list of possibilities duplicates the list in Makefile. + for try in sys.s sys/sys.s sys.S sys/sys.S syscall.h sys/syscall.h; do + if test -r $sysincludedir/$try; then + unix_syscall_h=$sysincludedir/$try + break + fi + done +else + unix_syscall_h=$sysdep_dir/$unix_dir/syscall.h +fi + +test -n "$unix_syscall_h" && { + +# Where to put the .S files we write. +if test "`pwd`" = "`(cd $srcdir; pwd)`"; then + unix_generated_dirpfx=sysdeps/unix/ +else + # We are running in a separate build directory. + unix_generated_dirpfx= +fi + +# This variable will collect the names of the files we create. +unix_generated= +unix_srcs= +unix_dests= + +# These several functions are system calls on Unix systems which have them. +# The details of these calls are universal enough that if a system's +# <syscall.h> defines the system call number, we know that the simple +# system call implementations in unix/common will be sufficient. + +for unix_function in \ + dup2 lstat mkdir rmdir readlink symlink rename swapon \ + access select getgroups setgroups \ + getitimer setitimer \ + getdomainname/getdomain=bsd/bsd4.4 \ + setdomainname/setdomain=bsd/bsd4.4 +do + + # $unix_function => $unix_syscall $unix_srcname + # CALL CALL CALL + # CALL/NAME CALL NAME + unix_srcname= + unix_srcdir=common + eval "unix_syscall=`echo $unix_function | \ + sed -e 's@=\(.*\)$@ unix_srcdir=\1@' \ + -e 's@/\(.*\)$@ unix_srcname=\1@'`" + test -z "$unix_srcname" && unix_srcname=$unix_function + + unix_implementor=none + for unix_dir in $sysnames; do + if test -r $sysdep_dir/$unix_dir/${unix_srcname}.c || + test -r $sysdep_dir/$unix_dir/${unix_srcname}.S || + test -r $sysdep_dir/$unix_dir/${unix_srcname}.s; then + unix_implementor=$unix_dir + break + fi + done + + # mkdir and rmdir have implementations in unix/sysv, but + # the simple syscall versions are preferable if available. + test $unix_syscall = mkdir -o $unix_syscall = rmdir && \ + test $unix_implementor = unix/sysv && \ + unix_implementor=generic + + case $unix_implementor in + none|stub|generic|posix) + # The chosen implementation of ${unix_syscall} is a boring one. + # We want to use the unix/common implementation instead iff + # ${unix_syscall} appears in <syscall.h>. + echo $ac_n "checking for ${unix_syscall} system call""... $ac_c" 1>&4 + if grep -i "[ _]${unix_syscall}[ ]" $unix_syscall_h >/dev/null + then + # It does seem to be present in <syscall.h>. + echo "$ac_t""yes" 1>&4 + unix_dests="$unix_dests ${unix_generated_dirpfx}${unix_srcname}.S" + unix_srcs="$unix_srcs sysdeps/unix/${unix_srcdir}/${unix_srcname}.S" + unix_generated="$unix_generated $unix_generated_dirpfx${unix_srcname}.S" + else + echo "$ac_t""no" 1>&4 + fi + ;; + *) ;; + esac + +done + +# Autoconf magic in the top-level configure.in causes config.status to +# actually make the links. +libc_link_dests="$libc_link_dests $unix_dests" +libc_link_sources="$libc_link_sources $unix_srcs" + +# Store the list of files we created in config.make; Makefile uses it. +test -n "$unix_generated" && config_vars="$config_vars +unix-generated := \$(addprefix \$(objpfx),${unix_generated})" + +} diff --git a/sysdeps/unix/configure.in b/sysdeps/unix/configure.in new file mode 100644 index 0000000000..85bc3d1c2c --- /dev/null +++ b/sysdeps/unix/configure.in @@ -0,0 +1,136 @@ +sinclude(./aclocal.m4)dnl Autoconf lossage. +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +dnl configure fragment for Unix-based systems. This is processed by Autoconf, +dnl but we just use the AC_MSG_* macros. This file is sourced by the +dnl top-level configure script. Note that we use the prefix `unix_' on all +dnl shell variables here, to avoid conflicting with any variables the +dnl top-level script might be using. + +sysincludedir=/usr/include # XXX + +# Find the <syscall.h> file we will be using, or something like it. +unix_found= +for unix_dir in $sysnames; do + if test -r $sysdep_dir/$unix_dir/syscall.h; then + unix_found=$unix_dir + break + fi +done +if test $unix_found = stub; then + # XXX This list of possibilities duplicates the list in Makefile. + for try in sys.s sys/sys.s sys.S sys/sys.S syscall.h sys/syscall.h; do + if test -r $sysincludedir/$try; then + unix_syscall_h=$sysincludedir/$try + break + fi + done +else + unix_syscall_h=$sysdep_dir/$unix_dir/syscall.h +fi + +test -n "$unix_syscall_h" && { + +# Where to put the .S files we write. +if test "`pwd`" = "`(cd $srcdir; pwd)`"; then + unix_generated_dirpfx=sysdeps/unix/ +else + # We are running in a separate build directory. + unix_generated_dirpfx= +fi + +# This variable will collect the names of the files we create. +unix_generated= +unix_srcs= +unix_dests= + +# These several functions are system calls on Unix systems which have them. +# The details of these calls are universal enough that if a system's +# <syscall.h> defines the system call number, we know that the simple +# system call implementations in unix/common will be sufficient. + +for unix_function in \ + dup2 lstat mkdir rmdir readlink symlink rename swapon \ + access select getgroups setgroups \ + getitimer setitimer \ + getdomainname/getdomain=bsd/bsd4.4 \ + setdomainname/setdomain=bsd/bsd4.4 +do + + # $unix_function => $unix_syscall $unix_srcname + # CALL CALL CALL + # CALL/NAME CALL NAME + unix_srcname= + unix_srcdir=common + eval "unix_syscall=`echo $unix_function | \ + sed -e 's@=\(.*\)$@ unix_srcdir=\1@' \ + -e 's@/\(.*\)$@ unix_srcname=\1@'`" + test -z "$unix_srcname" && unix_srcname=$unix_function + + unix_implementor=none + for unix_dir in $sysnames; do + if test -r $sysdep_dir/$unix_dir/${unix_srcname}.c || + test -r $sysdep_dir/$unix_dir/${unix_srcname}.S || + test -r $sysdep_dir/$unix_dir/${unix_srcname}.s; then + unix_implementor=$unix_dir + break + fi + done + + # mkdir and rmdir have implementations in unix/sysv, but + # the simple syscall versions are preferable if available. + test $unix_syscall = mkdir -o $unix_syscall = rmdir && \ + test $unix_implementor = unix/sysv && \ + unix_implementor=generic + + case $unix_implementor in + none|stub|generic|posix) + # The chosen implementation of ${unix_syscall} is a boring one. + # We want to use the unix/common implementation instead iff + # ${unix_syscall} appears in <syscall.h>. + AC_MSG_CHECKING(for ${unix_syscall} system call) +changequote(,)dnl We need to use [ and ] for real now. + if grep -i "[ _]${unix_syscall}[ ]" $unix_syscall_h >/dev/null +changequote([,])dnl Back to Autoconf land. + then + # It does seem to be present in <syscall.h>. + AC_MSG_RESULT(yes) + unix_dests="$unix_dests ${unix_generated_dirpfx}${unix_srcname}.S" + unix_srcs="$unix_srcs sysdeps/unix/${unix_srcdir}/${unix_srcname}.S" + unix_generated="$unix_generated $unix_generated_dirpfx${unix_srcname}.S" + else + AC_MSG_RESULT(no) + fi + ;; + *) ;; + esac + +done + +# Autoconf magic in the top-level configure.in causes config.status to +# actually make the links. +libc_link_dests="$libc_link_dests $unix_dests" +libc_link_sources="$libc_link_sources $unix_srcs" + +# Store the list of files we created in config.make; Makefile uses it. +test -n "$unix_generated" && config_vars="$config_vars +unix-generated := \$(addprefix \$(objpfx),${unix_generated})" + +} diff --git a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h new file mode 100644 index 0000000000..15859c3b27 --- /dev/null +++ b/sysdeps/unix/confstr.h @@ -0,0 +1 @@ +#define CS_PATH "/bin:/usr/bin" diff --git a/sysdeps/unix/dirstream.h b/sysdeps/unix/dirstream.h new file mode 100644 index 0000000000..20c4922fb9 --- /dev/null +++ b/sysdeps/unix/dirstream.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _DIRSTREAM_H + +#define _DIRSTREAM_H 1 + +#define __need_size_t +#include <stddef.h> + +/* Directory stream type. + + The miscellaneous Unix `readdir' implementations read directory data + into a buffer and fill in a `struct dirent' copy in the `DIR' object. */ + +typedef struct + { + int __fd; /* File descriptor. */ + + char *__data; /* Directory block. */ + size_t __allocation; /* Space allocated for the block. */ + size_t __offset; /* Current offset into the block. */ + size_t __size; /* Total valid data in the block. */ + + struct dirent __entry; /* Returned by `readdir'. */ + } DIR; + +#endif /* dirstream.h */ diff --git a/sysdeps/unix/dup.S b/sysdeps/unix/dup.S new file mode 100644 index 0000000000..3da637d830 --- /dev/null +++ b/sysdeps/unix/dup.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (dup, 2) + ret + +weak_alias (__dup, dup) diff --git a/sysdeps/unix/errnos-tmpl.c b/sysdeps/unix/errnos-tmpl.c new file mode 100644 index 0000000000..67611fd7b6 --- /dev/null +++ b/sysdeps/unix/errnos-tmpl.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <errno.h> + +static char iferrno[] = "#ifdef _ERRNO_H"; +static char endiferrno[] = "#endif /* <errno.h> included. */"; +static char ifEmath[] = "#if !defined(__Emath_defined) && \ + (defined(_ERRNO_H) || defined(__need_Emath))"; +static char endifEmath[] = "#endif /* Emath not defined and <errno.h> \ +included or need Emath. */"; + +static int biggest_value = 0; +static int done_ENOSYS = 0; +static int done_ERANGE = 0, done_EDOM = 0; + +static void +DO(name, value) + char *name; + int value; +{ + int is_ERANGE = !done_ERANGE && !strcmp(name, "ERANGE"); + int is_EDOM = !done_EDOM && !strcmp(name, "EDOM"); + int is_Emath = is_ERANGE || is_EDOM; + + if (is_Emath) + { + puts(endiferrno); + puts(ifEmath); + } + + if (!strcmp (name, "EWOULDBLOCK")) + { + puts ("#define EWOULDBLOCK EAGAIN /* Translated in glibc. */"); + name = "EWOULDBLOCK_sys /* Value actually returned by kernel. */"; + } + + printf ("#define %s %d\n", name, value); + + if (is_Emath) + { + puts(endifEmath); + puts(iferrno); + } + + if (value > biggest_value) + biggest_value = value; + + if (is_ERANGE) + done_ERANGE = 1; + else if (is_EDOM) + done_EDOM = 1; + else if (!done_ENOSYS && !strcmp(name, "ENOSYS")) + done_ENOSYS = 1; +} + +int +main() +{ + puts(iferrno); + + ERRNOS; + + if (!done_EDOM || !done_ERANGE) + { + puts(endiferrno); + puts(ifEmath); + if (!done_EDOM) + printf("#define EDOM %d\n", ++biggest_value); + if (!done_ERANGE) + printf("#define ERANGE %d\n", ++biggest_value); + puts(endifEmath); + } + + if (!done_ENOSYS) + printf("#define ENOSYS %d\n", ++biggest_value); + + puts(endiferrno); + + puts("#undef __need_Emath"); + puts("#ifndef __Emath_defined\n#define __Emath_defined 1\n#endif"); + + exit(0); +} diff --git a/sysdeps/unix/errnos.awk b/sysdeps/unix/errnos.awk new file mode 100644 index 0000000000..8648f41fb2 --- /dev/null +++ b/sysdeps/unix/errnos.awk @@ -0,0 +1,12 @@ +BEGIN { special = 0 } + +/ERRNOS/ { nerrnos = split(errnos, errs) + for (i = 1; i <= nerrnos; ++i) + # Some systems define errno codes inside undefined #ifdefs, + # and then never actually use them. + printf "#ifdef %s\n DO(\"%s\", %s);\n#endif\n", \ + errs[i], errs[i], errs[i] + special = 1 } + + +{ if (special == 0) print $0; special = 0 } diff --git a/sysdeps/unix/execve.S b/sysdeps/unix/execve.S new file mode 100644 index 0000000000..7a4fc139ec --- /dev/null +++ b/sysdeps/unix/execve.S @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* Some systems misname the system call number macro for this. */ +#if !defined (SYS_execve) && defined (SYS_exece) +#define SYS_execve SYS_exece +#endif +#if !defined (SYS_execve) && defined (SYS_exec) +#define SYS_execve SYS_exec +#endif + +SYSCALL__ (execve, 3) + ret + +weak_alias (__execve, execve) diff --git a/sysdeps/unix/fcntl.S b/sysdeps/unix/fcntl.S new file mode 100644 index 0000000000..7ac4f28fe4 --- /dev/null +++ b/sysdeps/unix/fcntl.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fcntl, 3) + ret + +weak_alias (__fcntl, fcntl) diff --git a/sysdeps/unix/fork.S b/sysdeps/unix/fork.S new file mode 100644 index 0000000000..1c360c6ed2 --- /dev/null +++ b/sysdeps/unix/fork.S @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* This code works for at least m68k. */ + +SYSCALL__ (fork, 0) + /* R1 is now 0 for the parent and 1 for the child. Decrement it to + make it -1 (all bits set) for the parent, and 0 (no bits set) + for the child. Then AND it with R0, so the parent gets + R0&-1==R0, and the child gets R0&0==0. */ + subl #1, r1 + andl r1, r0 + ret + +weak_alias (__fork, fork) diff --git a/sysdeps/unix/fstat.S b/sysdeps/unix/fstat.S new file mode 100644 index 0000000000..cf501efe3e --- /dev/null +++ b/sysdeps/unix/fstat.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fstat, 2) + ret + +weak_alias (__fstat, fstat) diff --git a/sysdeps/unix/fsync.S b/sysdeps/unix/fsync.S new file mode 100644 index 0000000000..109994bf27 --- /dev/null +++ b/sysdeps/unix/fsync.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (fsync, 1) + ret diff --git a/sysdeps/unix/getdents.c b/sysdeps/unix/getdents.c new file mode 100644 index 0000000000..485faa13c2 --- /dev/null +++ b/sysdeps/unix/getdents.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> + +int +DEFUN(__getdirentries, (fd, buf, nbytes, basep), + int fd AND char *buf AND size_t nbytes AND off_t *basep) +{ + if (basep) + *basep = __lseek (fd, (off_t) 0, SEEK_CUR); + + return __read (fd, buf, nbytes); +} + +weak_alias (__getdirentries, getdirentries) + diff --git a/sysdeps/unix/getegid.S b/sysdeps/unix/getegid.S new file mode 100644 index 0000000000..1bd447b623 --- /dev/null +++ b/sysdeps/unix/getegid.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifdef SYS_getegid +SYSCALL__ (getegid, 0) +#else +PSEUDO (__getegid, getgid, 0) + MOVE(r1, r0) +#endif + ret + +weak_alias (__getegid, getegid) diff --git a/sysdeps/unix/geteuid.S b/sysdeps/unix/geteuid.S new file mode 100644 index 0000000000..339eb536f5 --- /dev/null +++ b/sysdeps/unix/geteuid.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifdef SYS_geteuid +SYSCALL__ (geteuid, 0) +#else +PSEUDO (__geteuid, getuid, 0) + MOVE(r1, r0) +#endif + ret + +weak_alias (__geteuid, geteuid) diff --git a/sysdeps/unix/getgid.S b/sysdeps/unix/getgid.S new file mode 100644 index 0000000000..5788654db7 --- /dev/null +++ b/sysdeps/unix/getgid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getgid, 0) + ret + +weak_alias (__getgid, getgid) diff --git a/sysdeps/unix/getlogin.c b/sysdeps/unix/getlogin.c new file mode 100644 index 0000000000..504a7aa4c0 --- /dev/null +++ b/sysdeps/unix/getlogin.c @@ -0,0 +1,90 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <limits.h> +#include <fcntl.h> + +#include <utmp.h> + +/* Defined in ttyname.c. */ +extern char *__ttyname; + +/* Return the login name of the user, or NULL if it can't be determined. + The returned pointer, if not NULL, is good only until the next call. */ + +char * +DEFUN_VOID(getlogin) +{ + char save_tty_pathname[2 + 2 * NAME_MAX]; + char *save_ttyname; + char *real_tty_path; + char *result = NULL; + FILE *f; + static struct utmp ut; + + if (__ttyname == NULL) + save_ttyname = NULL; + else + save_ttyname = strcpy (save_tty_pathname, __ttyname); + + { + int err; + int d = __open ("/dev/tty", 0); + if (d < 0) + return NULL; + + real_tty_path = ttyname (d); + err = errno; + (void) close (d); + + if (real_tty_path == NULL) + { + errno = err; + return NULL; + } + } + + real_tty_path += 5; /* Remove "/dev/". */ + + f = fopen ("/etc/utmp", "r"); + if (f != NULL) + { + while (fread ((PTR) &ut, sizeof(ut), 1, f) == 1) + if (!strncmp (ut.ut_line, real_tty_path, sizeof (ut.ut_line))) + { + result = ut.ut_name; + /* The name is not null-terminated if + it is as long as sizeof (ut.ut_name). */ + result[sizeof (ut.ut_name)] = '\0'; + break; + } + (void) fclose (f); + } + + if (save_ttyname != NULL) + strcpy (__ttyname, save_ttyname); + if (result == NULL) + errno = ENOENT; + return result; +} diff --git a/sysdeps/unix/getpagesize.c b/sysdeps/unix/getpagesize.c new file mode 100644 index 0000000000..399126e5a1 --- /dev/null +++ b/sysdeps/unix/getpagesize.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <sys/param.h> + +/* Return the system page size. */ +size_t +DEFUN_VOID(__getpagesize) +{ +#ifdef EXEC_PAGESIZE + return EXEC_PAGESIZE; +#else /* No EXEC_PAGESIZE. */ +#ifdef NBPG +#ifndef CLSIZE +#define CLSIZE 1 +#endif /* No CLSIZE. */ + return NBPG * CLSIZE; +#else /* No NBPG. */ + return NBPC; +#endif /* NBPG. */ +#endif /* EXEC_PAGESIZE. */ +} + +weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/unix/getpid.S b/sysdeps/unix/getpid.S new file mode 100644 index 0000000000..9689c1d31d --- /dev/null +++ b/sysdeps/unix/getpid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getpid, 1) + ret + +weak_alias (__getpid, getpid) diff --git a/sysdeps/unix/getppid.S b/sysdeps/unix/getppid.S new file mode 100644 index 0000000000..132c3740a0 --- /dev/null +++ b/sysdeps/unix/getppid.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifdef SYS_getppid +SYSCALL__ (getppid, 0) +#else +PSEUDO (__getppid, getpid, 0) + MOVE(r1, r0) +#endif + ret + +weak_alias (__getppid, getppid) diff --git a/sysdeps/unix/getuid.S b/sysdeps/unix/getuid.S new file mode 100644 index 0000000000..df076f0a0a --- /dev/null +++ b/sysdeps/unix/getuid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getuid, 0) + ret + +weak_alias (__getuid, getuid) diff --git a/sysdeps/unix/i386/brk.S b/sysdeps/unix/i386/brk.S new file mode 100644 index 0000000000..f55ac7c775 --- /dev/null +++ b/sysdeps/unix/i386/brk.S @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +.data +.globl C_SYMBOL_NAME(__curbrk) +C_LABEL(__curbrk) +#ifdef HAVE_GNU_LD + .long C_SYMBOL_NAME(_end) +#else + .long C_SYMBOL_NAME(end) +#endif + +.text +SYSCALL__ (brk, 1) + movl 4(%esp), %eax + movl %eax, C_SYMBOL_NAME(__curbrk) + xorl %eax, %eax + ret + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/i386/fork.S b/sysdeps/unix/i386/fork.S new file mode 100644 index 0000000000..4388b04fd4 --- /dev/null +++ b/sysdeps/unix/i386/fork.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fork, 0) + /* R1 is now 0 for the parent and 1 for the child. Decrement it to + make it -1 (all bits set) for the parent, and 0 (no bits set) + for the child. Then AND it with R0, so the parent gets + R0&-1==R0, and the child gets R0&0==0. */ + decl r1 + andl r1, r0 + ret + +weak_alias (__fork, fork) diff --git a/sysdeps/unix/i386/pipe.S b/sysdeps/unix/i386/pipe.S new file mode 100644 index 0000000000..7c7c51aa53 --- /dev/null +++ b/sysdeps/unix/i386/pipe.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pipe, 1) + movl 4(%esp), scratch + movl %eax, (scratch) + movl r1, 4(scratch) + xorl %eax, %eax + ret + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/i386/sigreturn.S b/sysdeps/unix/i386/sigreturn.S new file mode 100644 index 0000000000..3cf79a5415 --- /dev/null +++ b/sysdeps/unix/i386/sigreturn.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.text +ENTRY (__sigreturn) + addl $4, %esp /* Pop the return PC. */ + DO_CALL (sigreturn, 0) /* Do the system call; it never returns. */ + /* NOTREACHED */ + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/i386/start.c b/sysdeps/unix/i386/start.c new file mode 100644 index 0000000000..e6c89ee3f3 --- /dev/null +++ b/sysdeps/unix/i386/start.c @@ -0,0 +1,2 @@ +#define DUMMIES dummy0 +#include <sysdeps/unix/start.c> diff --git a/sysdeps/unix/i386/syscall.S b/sysdeps/unix/i386/syscall.S new file mode 100644 index 0000000000..5241ee4ac1 --- /dev/null +++ b/sysdeps/unix/i386/syscall.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.globl syscall_error +ENTRY (syscall) + popl %ecx /* Pop return address into %ecx. */ + popl %eax /* Pop syscall number into %eax. */ + pushl %ecx /* Push back return address. */ + .byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- gas bug */ + jb syscall_error + ret diff --git a/sysdeps/unix/i386/sysdep.S b/sysdeps/unix/i386/sysdep.S new file mode 100644 index 0000000000..dae7153796 --- /dev/null +++ b/sysdeps/unix/i386/sysdep.S @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +.globl C_SYMBOL_NAME(errno) +.globl syscall_error + +#undef syscall_error +#ifdef NO_UNDERSCORES +__syscall_error: +#else +syscall_error: +#endif +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmpl $EWOULDBLOCK_sys, %eax /* Is it the old EWOULDBLOCK? */ + jne notb /* Branch if not. */ + movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */ +#endif +notb: movl %eax, C_SYMBOL_NAME(errno) + movl $-1, %eax + ret diff --git a/sysdeps/unix/i386/sysdep.h b/sysdeps/unix/i386/sysdep.h new file mode 100644 index 0000000000..38dd2378b5 --- /dev/null +++ b/sysdeps/unix/i386/sysdep.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#define ENTRY(name) \ + .globl C_SYMBOL_NAME(name); \ + .align 4; \ + C_LABEL(name) + +#ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#endif + +#define PSEUDO(name, syscall_name, args) \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jb syscall_error + +/* This is defined as a separate macro so that other sysdep.h files + can include this one and then redefine DO_CALL. */ + +#define DO_CALL(syscall_name, args) \ + lea SYS_ify (syscall_name), %eax; \ + /* lcall $7, $0; */ \ + /* Above loses; GAS bug. */ \ + .byte 0x9a, 0, 0, 0, 0, 7, 0 + +#define r0 %eax /* Normal return-value register. */ +#define r1 %edx /* Secondary return-value register. */ +#define scratch %ecx /* Call-clobbered register for random use. */ +#define MOVE(x,y) movl x, y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/i386/wait.S b/sysdeps/unix/i386/wait.S new file mode 100644 index 0000000000..4b2e62ca3b --- /dev/null +++ b/sysdeps/unix/i386/wait.S @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (wait, 1) + movl 4(%esp), scratch /* Put status pointer in scratch register. */ + testl scratch, scratch /* Is it non-nil? */ + je null + movl r1, (scratch) /* Yes; store the status there. */ +null: ret + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/inet/Subdirs b/sysdeps/unix/inet/Subdirs new file mode 100644 index 0000000000..4a40811754 --- /dev/null +++ b/sysdeps/unix/inet/Subdirs @@ -0,0 +1,3 @@ +inet +resolv +sunrpc diff --git a/sysdeps/unix/inet/accept.S b/sysdeps/unix/inet/accept.S new file mode 100644 index 0000000000..25d4d05f8c --- /dev/null +++ b/sysdeps/unix/inet/accept.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (accept, 3) + ret diff --git a/sysdeps/unix/inet/bind.S b/sysdeps/unix/inet/bind.S new file mode 100644 index 0000000000..fc8c818362 --- /dev/null +++ b/sysdeps/unix/inet/bind.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (bind, 3) + ret diff --git a/sysdeps/unix/inet/connect.S b/sysdeps/unix/inet/connect.S new file mode 100644 index 0000000000..714d743874 --- /dev/null +++ b/sysdeps/unix/inet/connect.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (connect, 3) + ret diff --git a/sysdeps/unix/inet/gethostid.S b/sysdeps/unix/inet/gethostid.S new file mode 100644 index 0000000000..e3296f45fa --- /dev/null +++ b/sysdeps/unix/inet/gethostid.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (gethostid, 0) + ret diff --git a/sysdeps/unix/inet/gethostname.S b/sysdeps/unix/inet/gethostname.S new file mode 100644 index 0000000000..d9a1e906e3 --- /dev/null +++ b/sysdeps/unix/inet/gethostname.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (gethostname, 2) + ret + +weak_alias (__gethostname, gethostname) diff --git a/sysdeps/unix/inet/getpeername.S b/sysdeps/unix/inet/getpeername.S new file mode 100644 index 0000000000..115c93b9f4 --- /dev/null +++ b/sysdeps/unix/inet/getpeername.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getpeername, 3) + ret diff --git a/sysdeps/unix/inet/getsockname.S b/sysdeps/unix/inet/getsockname.S new file mode 100644 index 0000000000..94d5c9cb37 --- /dev/null +++ b/sysdeps/unix/inet/getsockname.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getsockname, 3) + ret diff --git a/sysdeps/unix/inet/getsockopt.S b/sysdeps/unix/inet/getsockopt.S new file mode 100644 index 0000000000..d7b468173d --- /dev/null +++ b/sysdeps/unix/inet/getsockopt.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getsockopt, 5) + ret diff --git a/sysdeps/unix/inet/listen.S b/sysdeps/unix/inet/listen.S new file mode 100644 index 0000000000..38d42ae612 --- /dev/null +++ b/sysdeps/unix/inet/listen.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (listen, 2) + ret diff --git a/sysdeps/unix/inet/recv.S b/sysdeps/unix/inet/recv.S new file mode 100644 index 0000000000..576863e874 --- /dev/null +++ b/sysdeps/unix/inet/recv.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (recv, 4) + ret diff --git a/sysdeps/unix/inet/recvfrom.S b/sysdeps/unix/inet/recvfrom.S new file mode 100644 index 0000000000..bd75e6dd34 --- /dev/null +++ b/sysdeps/unix/inet/recvfrom.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (recvfrom, 6) + ret diff --git a/sysdeps/unix/inet/recvmsg.S b/sysdeps/unix/inet/recvmsg.S new file mode 100644 index 0000000000..dd0a268eba --- /dev/null +++ b/sysdeps/unix/inet/recvmsg.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (recvmsg, 3) + ret diff --git a/sysdeps/unix/inet/send.S b/sysdeps/unix/inet/send.S new file mode 100644 index 0000000000..85ac36bc23 --- /dev/null +++ b/sysdeps/unix/inet/send.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (send, 4) + ret diff --git a/sysdeps/unix/inet/sendmsg.S b/sysdeps/unix/inet/sendmsg.S new file mode 100644 index 0000000000..1dadaf3a12 --- /dev/null +++ b/sysdeps/unix/inet/sendmsg.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sendmsg, 3) + ret diff --git a/sysdeps/unix/inet/sendto.S b/sysdeps/unix/inet/sendto.S new file mode 100644 index 0000000000..18d6f6a079 --- /dev/null +++ b/sysdeps/unix/inet/sendto.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sendto, 6) + ret diff --git a/sysdeps/unix/inet/sethostid.S b/sysdeps/unix/inet/sethostid.S new file mode 100644 index 0000000000..141db2039c --- /dev/null +++ b/sysdeps/unix/inet/sethostid.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sethostid, 1) + ret diff --git a/sysdeps/unix/inet/sethostname.S b/sysdeps/unix/inet/sethostname.S new file mode 100644 index 0000000000..e7d9f93168 --- /dev/null +++ b/sysdeps/unix/inet/sethostname.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sethostname, 2) + ret diff --git a/sysdeps/unix/inet/setsockopt.S b/sysdeps/unix/inet/setsockopt.S new file mode 100644 index 0000000000..a3948c2ce8 --- /dev/null +++ b/sysdeps/unix/inet/setsockopt.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (setsockopt, 5) + ret diff --git a/sysdeps/unix/inet/shutdown.S b/sysdeps/unix/inet/shutdown.S new file mode 100644 index 0000000000..7ce3e6cd75 --- /dev/null +++ b/sysdeps/unix/inet/shutdown.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (shutdown, 2) + ret diff --git a/sysdeps/unix/inet/socket.S b/sysdeps/unix/inet/socket.S new file mode 100644 index 0000000000..b0f01cf9fb --- /dev/null +++ b/sysdeps/unix/inet/socket.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (socket, 3) + ret diff --git a/sysdeps/unix/inet/socketpair.S b/sysdeps/unix/inet/socketpair.S new file mode 100644 index 0000000000..fb352cff89 --- /dev/null +++ b/sysdeps/unix/inet/socketpair.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (socketpair, 4) + ret diff --git a/sysdeps/unix/ioctl.S b/sysdeps/unix/ioctl.S new file mode 100644 index 0000000000..d80fd68cdd --- /dev/null +++ b/sysdeps/unix/ioctl.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (ioctl, 3) + ret + +weak_alias (__ioctl, ioctl) diff --git a/sysdeps/unix/ioctls-tmpl.c b/sysdeps/unix/ioctls-tmpl.c new file mode 100644 index 0000000000..1c973c945a --- /dev/null +++ b/sysdeps/unix/ioctls-tmpl.c @@ -0,0 +1,134 @@ +/* On SVR4, this #define is necessary to make <sys/ioctl.h> define + many of the ioctls. */ +#define BSD_COMP + +#include <sys/types.h> +#include <sys/param.h> + +/* On SunOS 4.1, <sys/ioctl.h> and <sys/termios.h> define some symbols + with different values, but <sys/termios.h> defines some ioctl symbols + not in <sys/ioctl.h>, so we need it. Our <sys/ioctl.h> should define + them with the values from Sun's <sys/ioctl.h>, not <sys/termios.h>. + So we include <sys/termios.h> and let <sys/ioctl.h> redefine things. + This produces some spurious warnings. */ + +#ifdef HAVE_sys_termios_h +#include <sys/termios.h> +#endif + +/* This causes <sys/ioctl.h> to define some necessary data structure. */ +#ifdef sony_news +#define KANJI +#endif + +#include <sys/ioctl.h> + +#ifdef SIOCGIFCONF +#include <sys/socket.h> +#include <sys/time.h> +#include <net/if.h> +#include <net/route.h> +#if defined(SIOCGARP) && !defined(ARPOP_REQUEST) +#include <net/if_arp.h> +#endif +#ifdef SIOCGNIT +#ifdef HAVE_net_nit_h +#include <net/nit.h> +#else /* No net/nit.h. */ +#undef SIOCGNIT +#undef SIOCSNIT +#endif /* net/nit.h. */ +#endif /* SIOCGNIT. */ +#endif /* SIOCGIFCONF. */ + +/* These exist on Sequents. */ +#ifdef SMIOSTATS +#include <sec/sec.h> +#include <sec/sm.h> +#endif +#ifdef SMIOGETREBOOT0 +#include <i386/cfg.h> +#endif +#ifdef ZIOCBCMD +#include <zdc/zdc.h> +#endif + +/* These exist under Ultrix, but I figured there may be others. */ +#ifdef DIOCGETPT +#include <ufs/fs.h> /* for DIOC* */ +#endif +#ifdef DEVGETGEOM +#include <sys/devio.h> +#endif + +#ifdef ultrix +/* Ultrix has a conditional include that brings these in; we have to force + their inclusion when we actually compile them. */ +#undef TCGETA +#undef TCSETA +#undef TCSETAW +#undef TCSETAF +#undef TCGETP +#undef TCSANOW +#undef TCSADRAIN +#undef TCSAFLUSH +#ifdef ELSETPID +#include <sys/un.h> /* get sockaddr_un for elcsd.h */ +#include <elcsd.h> +#endif +#ifdef DKIOCDOP +#include <sys/dkio.h> +#endif +/* Couldn't find the header where the structures used by these are + defined; it looks like an unbundled LAT package or something. */ +#undef LIOCSOL +#undef LIOCRES +#undef LIOCCMD +#undef LIOCINI +#undef LIOCTTYI +#undef LIOCCONN +/* struct mtop hasn't been in sys/mtio.h since 4.1 */ +#undef MTIOCTOP +#undef MTIOCGET +#endif + +#if defined(__osf__) && defined(__alpha__) +#include <sys/ioctl_compat.h> /* To get TIOCGETP, etc. */ +#include <alpha/pt.h> /* for DIOC* */ +#include <sys/mtio.h> /* for MTIOC* */ +/* The binlog_getstatus structure doesn't seem to be defined. */ +#undef BINLOG_GETSTATUS +/* Can't find `struct ifdata' anywhere. */ +#undef SIOCMANREQ +#undef SIOCGETEVENTS +/* OSF/1 smells an awful lot like Ultrix. */ +#undef TCGETA +#undef TCSETA +#undef TCSETAF +#undef TCSETAW +/* This macro looks screwed in sys/devio.h. */ +#undef DEV_DISKPART +/* This is in sys/dkio.h, but we don't need it. */ +#undef DKIOCACC +#undef DKIOCDOP +#undef DKIOCEXCL +#undef DKIOCGET +#undef DKIOCHDR +/* Introduced by OSF/1 2.0. */ +#undef FIOPIPESTAT +#undef SIOCSRREQR +#undef SIOCSRREQW +#undef SRVC_REQUEST +#endif + +#define DEFINE(name, value) \ + printf("#define %s 0x%.8x\n", (name), (value)) + +int +main() +{ + REQUESTS + + exit(0); + return 0; +} diff --git a/sysdeps/unix/ioctls.awk b/sysdeps/unix/ioctls.awk new file mode 100644 index 0000000000..b05140af7a --- /dev/null +++ b/sysdeps/unix/ioctls.awk @@ -0,0 +1,10 @@ +BEGIN { special = 0 } + +/REQUESTS/ { nreqs = split(requests, reqs) + for (i = 1; i <= nreqs; ++i) + printf "#ifdef\t%s\n DEFINE(\"%s\", %s);\n#endif\n", \ + reqs[i], reqs[i], reqs[i] + special = 1 } + + +{ if (special == 0) print $0; special = 0 } diff --git a/sysdeps/unix/kill.S b/sysdeps/unix/kill.S new file mode 100644 index 0000000000..b4c646953c --- /dev/null +++ b/sysdeps/unix/kill.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (kill, 2) + ret + +weak_alias (__kill, kill) diff --git a/sysdeps/unix/link.S b/sysdeps/unix/link.S new file mode 100644 index 0000000000..e96c4d97c6 --- /dev/null +++ b/sysdeps/unix/link.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (link, 2) + ret + +weak_alias (__link, link) diff --git a/sysdeps/unix/lseek.S b/sysdeps/unix/lseek.S new file mode 100644 index 0000000000..66efe1c190 --- /dev/null +++ b/sysdeps/unix/lseek.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (lseek, 3) + ret + +weak_alias (__lseek, lseek) diff --git a/sysdeps/unix/make_errlist.c b/sysdeps/unix/make_errlist.c new file mode 100644 index 0000000000..40b4f820c0 --- /dev/null +++ b/sysdeps/unix/make_errlist.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdio.h> + + +/* Make a definition for sys_errlist. */ + +extern int sys_nerr; +extern char *sys_errlist[]; + +int +main () +{ + register int i; + + puts ("#include \"ansidecl.h\"\n#include <stddef.h>\n"); + puts ("\n/* This is a list of all known `errno' codes. */\n"); + + puts ("#ifndef HAVE_GNU_LD"); + puts ("#define _sys_nerr\tsys_nerr"); + puts ("#define _sys_errlist\tsys_errlist"); + puts ("#endif"); + + printf ("\nCONST int _sys_nerr = %d;\n\n", sys_nerr); + puts ("CONST char *CONST _sys_errlist[] =\n {"); + + for (i = 0; i < sys_nerr; ++i) + printf (" \"%s\",\n", sys_errlist[i]); + + puts (" NULL\n };\n"); + + puts ("weak_alias (_sys_errlist, sys_errlist)"); + puts ("weak_alias (_sys_nerr, sys_nerr)"); + + exit (0); +} diff --git a/sysdeps/unix/mips/brk.S b/sysdeps/unix/mips/brk.S new file mode 100644 index 0000000000..1754c0c4de --- /dev/null +++ b/sysdeps/unix/mips/brk.S @@ -0,0 +1,67 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef HAVE_GNU_LD +#define __end end +#endif + +.data +.sdata +ENTRY(__curbrk) + .word __end + +.text +.set noreorder +.set noat + +ENTRY(__brk) + /* Minimum is one page. */ + lui v0, 4096 + lw v0, __end + nop + + /* If they ask for less than a page, givvem the whole + thing anyway. */ + sltu AT, a0, v0 + beq AT, zero, down1 + nop + move a0, v0 +down1: + li v0, SYS_brk + syscall + bne a3, zero, error + + /* Update __curbrk and exit cleanly. */ + lui AT, 4096 + sw a0, __curbrk + j ra + move v0, zero + + /* What a horrible way to die. */ +error: j syscall_error + nop + nop + nop + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/mips/fork.S b/sysdeps/unix/mips/fork.S new file mode 100644 index 0000000000..2347bf4d50 --- /dev/null +++ b/sysdeps/unix/mips/fork.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fork, 0) + beq v1, zero, parent /* Branch if parent. */ + nop + /* We are the child. Return zero. */ + move v0, zero +parent: + ret + +weak_alias (__fork, fork) diff --git a/sysdeps/unix/mips/pipe.S b/sysdeps/unix/mips/pipe.S new file mode 100644 index 0000000000..f8ce56b118 --- /dev/null +++ b/sysdeps/unix/mips/pipe.S @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pipe, 1) + /* Plop in the two descriptors. */ + sw v0, 0(a0) + sw v1, 4(a0) + + /* Go out with a clean status. */ + j ra + move v0, zero + nop + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/mips/sigreturn.S b/sysdeps/unix/mips/sigreturn.S new file mode 100644 index 0000000000..1e76bf5f99 --- /dev/null +++ b/sysdeps/unix/mips/sigreturn.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_sigreturn +#define SYS_sigreturn 103 +#endif + +ENTRY(__sigreturn) + li v0, SYS_sigreturn + syscall + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/mips/sysdep.S b/sysdeps/unix/mips/sysdep.S new file mode 100644 index 0000000000..21bdf234f9 --- /dev/null +++ b/sysdeps/unix/mips/sysdep.S @@ -0,0 +1,41 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +/* .globl errno */ +.set noreorder + +ENTRY(syscall_error) +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + bne v0, EWOULDBLOCK_sys, skip + nop + li v0, EAGAIN +skip: +#endif + /* Store it in errno... */ + sw v0, errno + + /* And just kick back a -1. */ + j ra + li v0, -1 diff --git a/sysdeps/unix/mips/sysdep.h b/sysdeps/unix/mips/sysdep.h new file mode 100644 index 0000000000..c09c5af7d2 --- /dev/null +++ b/sysdeps/unix/mips/sysdep.h @@ -0,0 +1,52 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#include <regdef.h> + +#define ENTRY(name) \ + .globl name; \ + .align 2; \ + .ent name,0; \ + name##: + +/* Note that while it's better structurally, going back to call syscall_error + can make things confusing if you're debugging---it looks like it's jumping + backwards into the previous fn. */ +#define PSEUDO(name, syscall_name, args) \ + .set noreorder; \ + .align 2; \ + 99: j syscall_error; \ + nop; \ + ENTRY(name) \ + li v0, SYS_##syscall_name; \ + syscall; \ + bne a3, zero, 99b; \ + nop; \ +syse1: + +#define ret j ra ; nop +#define r0 v0 +#define r1 v1 +/* The mips move insn is d,s. */ +#define MOVE(x,y) move y , x + +#endif diff --git a/sysdeps/unix/mips/wait.S b/sysdeps/unix/mips/wait.S new file mode 100644 index 0000000000..63bce849d4 --- /dev/null +++ b/sysdeps/unix/mips/wait.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.set noreorder + +ENTRY(__wait) + /* Prep it for wait. */ + move a1, zero + move a2, zero + + li v0, SYS_wait + syscall + beq a3, zero, noerror + nop + j syscall_error + nop + +noerror: + /* If the arg is not NULL, store v1 there. */ + beq a0, zero, noarg + nop + sw v1, 0(a0) + nop +noarg: + ret + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/mk-local_lim.c b/sysdeps/unix/mk-local_lim.c new file mode 100644 index 0000000000..c9a1d3dfb8 --- /dev/null +++ b/sysdeps/unix/mk-local_lim.c @@ -0,0 +1,118 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stdio.h> +#include <sys/types.h> + +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#ifdef HAVE_SYS_LIMITS_H +#include <sys/limits.h> +#endif + +/* Generate local_lim.h from the values defined in the system's headers. */ + +struct param + { + char *name; + int value; + }; + +static struct param params[] = + { + +#if !defined (ARG_MAX) && defined (NCARGS) +#define ARG_MAX NCARGS +#endif +#ifdef ARG_MAX + { "ARG_MAX", ARG_MAX }, +#endif + +#if !defined (CHILD_MAX) && defined (MAXUPRC) +#define CHILD_MAX MAXUPRC +#endif +#ifdef CHILD_MAX + { "CHILD_MAX", CHILD_MAX }, +#endif + +#if !defined (LINK_MAX) && defined (MAXLINK) +#define LINK_MAX MAXLINK +#endif +#ifdef LINK_MAX + { "LINK_MAX", LINK_MAX }, +#endif + +#if !defined (OPEN_MAX) && defined (NOFILE) +#define OPEN_MAX NOFILE +#endif +#ifdef OPEN_MAX + { "OPEN_MAX", OPEN_MAX }, +#endif + +#if !defined (MAX_CANON) && defined (CANBSIZ) +#define MAX_CANON CANBSIZ +#endif +#ifdef MAX_CANON + { "MAX_CANON", MAX_CANON }, +#endif + +#if !defined (NAME_MAX) && defined (MAXNAMLEN) +#define NAME_MAX MAXNAMLEN +#endif +#ifndef NAME_MAX +#define NAME_MAX 255 /* XXX ? */ +#endif + { "NAME_MAX", NAME_MAX }, + +#if !defined (PATH_MAX) && defined (MAXPATHLEN) +#define PATH_MAX MAXPATHLEN +#endif +#ifdef PATH_MAX + { "PATH_MAX", PATH_MAX }, +#endif + + { NULL, 0 } + }; + +int +main() +{ + extern char *ctime (); + extern time_t time (); + time_t now = time ((time_t *) NULL); + register struct param *p; + + if (! params[0].name) + /* We have no information to give, so let the caller know. */ + exit (1); + + printf ("\ +/* Implementation-specific limits.\n\ + Generated at %.24s. */\n\n", ctime (&now)); + + for (p = params; p->name != NULL; ++p) + printf ("#define %s %d\n", p->name, p->value); + + exit (0); +} diff --git a/sysdeps/unix/mkfifo.c b/sysdeps/unix/mkfifo.c new file mode 100644 index 0000000000..776e981d93 --- /dev/null +++ b/sysdeps/unix/mkfifo.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> + +/* Create a named pipe (FIFO) named PATH with protections MODE. */ +int +DEFUN(mkfifo, (path, mode), CONST char *path AND mode_t mode) +{ + return __mknod (path, mode | S_IFIFO, 0); +} diff --git a/sysdeps/unix/mknod.S b/sysdeps/unix/mknod.S new file mode 100644 index 0000000000..76fab52ee1 --- /dev/null +++ b/sysdeps/unix/mknod.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (mknod, 3) + ret + +weak_alias (__mknod, mknod) diff --git a/sysdeps/unix/mman/madvise.S b/sysdeps/unix/mman/madvise.S new file mode 100644 index 0000000000..c22097f172 --- /dev/null +++ b/sysdeps/unix/mman/madvise.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (madvise, 3) + ret diff --git a/sysdeps/unix/mman/mmap.S b/sysdeps/unix/mman/mmap.S new file mode 100644 index 0000000000..dd60f43b34 --- /dev/null +++ b/sysdeps/unix/mman/mmap.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (mmap, 5) + ret diff --git a/sysdeps/unix/mman/mprotect.S b/sysdeps/unix/mman/mprotect.S new file mode 100644 index 0000000000..23869e158d --- /dev/null +++ b/sysdeps/unix/mman/mprotect.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (mprotect, 3) + ret diff --git a/sysdeps/unix/mman/msync.S b/sysdeps/unix/mman/msync.S new file mode 100644 index 0000000000..b165267ba3 --- /dev/null +++ b/sysdeps/unix/mman/msync.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (msync, 2) + ret diff --git a/sysdeps/unix/mman/munmap.S b/sysdeps/unix/mman/munmap.S new file mode 100644 index 0000000000..6b1ae163ee --- /dev/null +++ b/sysdeps/unix/mman/munmap.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (munmap, 2) + ret diff --git a/sysdeps/unix/nlist.c b/sysdeps/unix/nlist.c new file mode 100644 index 0000000000..5389f65e89 --- /dev/null +++ b/sysdeps/unix/nlist.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <a.out.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* Search the executable FILE for symbols matching those in NL, + which is terminated by an element with a NULL `n_un.n_name' member, + and fill in the elements of NL. */ +int +DEFUN(nlist, (file, nl), + CONST char *file AND struct nlist *nl) +{ + FILE *f; + struct exec header; + size_t nsymbols; + struct nlist *symbols; + unsigned long int string_table_size; + char *string_table; + register size_t i; + + if (nl == NULL) + { + errno = EINVAL; + return -1; + } + + f = fopen(file, "r"); + if (f == NULL) + return -1; + + if (fread((PTR) &header, sizeof(header), 1, f) != 1) + goto lose; + + if (fseek(f, N_SYMOFF(header), SEEK_SET) != 0) + goto lose; + + symbols = (struct nlist *) __alloca(header.a_syms); + nsymbols = header.a_syms / sizeof(symbols[0]); + + if (fread((PTR) symbols, sizeof(symbols[0]), nsymbols, f) != nsymbols) + goto lose; + + if (fread((PTR) &string_table_size, sizeof(string_table_size), 1, f) != 1) + goto lose; + string_table_size -= sizeof(string_table_size); + + string_table = (char *) __alloca(string_table_size); + if (fread((PTR) string_table, string_table_size, 1, f) != 1) + goto lose; + + for (i = 0; i < nsymbols; ++i) + { + register struct nlist *nlp; + for (nlp = nl; nlp->n_un.n_name != NULL; ++nlp) + if (!strcmp(nlp->n_un.n_name, + &string_table[symbols[i].n_un.n_strx - + sizeof(string_table_size)])) + { + char *CONST name = nlp->n_un.n_name; + *nlp = symbols[i]; + nlp->n_un.n_name = name; + } + } + + (void) fclose(f); + return 0; + + lose:; + (void) fclose(f); + return -1; +} diff --git a/sysdeps/unix/open.S b/sysdeps/unix/open.S new file mode 100644 index 0000000000..c999677886 --- /dev/null +++ b/sysdeps/unix/open.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (open, 3) + ret + +weak_alias (__open, open) diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c new file mode 100644 index 0000000000..d03f45e6af --- /dev/null +++ b/sysdeps/unix/opendir.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <dirent.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> + +#include "direct.h" /* This file defines `struct direct'. */ + +/* Open a directory stream on NAME. */ +DIR * +DEFUN(opendir, (name), CONST char *name) +{ + DIR *dirp; + struct stat statbuf; + int fd; + + if (name[0] == '\0') + { + /* POSIX.1-1990 says an empty name gets ENOENT; + but `open' might like it fine. */ + errno = ENOENT; + return NULL; + } + + fd = __open (name, O_RDONLY); + if (fd < 0) + return NULL; + + if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) + goto lose; + + if (fstat (fd, &statbuf) < 0) + goto lose; + if (! S_ISDIR (statbuf.st_mode)) + { + errno = ENOTDIR; + goto lose; + } + + dirp = (DIR *) calloc (1, sizeof (DIR) + NAME_MAX); /* Zero-fill. */ + if (dirp == NULL) + lose: + { + int save = errno; + (void) __close (fd); + errno = save; + return NULL; + } + +#ifdef _STATBUF_ST_BLKSIZE + if (statbuf.st_blksize < sizeof (struct direct)) + dirp->__allocation = sizeof (struct direct); + else + dirp->__allocation = statbuf.st_blksize; +#else + dirp->__allocation = (BUFSIZ < sizeof (struct direct) ? + sizeof (struct direct) : BUFSIZ); +#endif + dirp->__data = (char *) malloc (dirp->__allocation); + if (dirp->__data == NULL) + { + int save = errno; + free ((PTR) dirp); + (void) __close (fd); + errno = save; + return NULL; + } + + dirp->__fd = fd; + return dirp; +} diff --git a/sysdeps/unix/pipestream.c b/sysdeps/unix/pipestream.c new file mode 100644 index 0000000000..1d3308fe7c --- /dev/null +++ b/sysdeps/unix/pipestream.c @@ -0,0 +1,2 @@ +#define NO_WAITPID +#include <sysdeps/posix/pipestream.c> diff --git a/sysdeps/unix/ptrace.S b/sysdeps/unix/ptrace.S new file mode 100644 index 0000000000..dcdb041c39 --- /dev/null +++ b/sysdeps/unix/ptrace.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (ptrace, 4) + ret diff --git a/sysdeps/unix/read.S b/sysdeps/unix/read.S new file mode 100644 index 0000000000..016e4c7bfc --- /dev/null +++ b/sysdeps/unix/read.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (read, 3) + ret + +weak_alias (__read, read) diff --git a/sysdeps/unix/readdir.c b/sysdeps/unix/readdir.c new file mode 100644 index 0000000000..3ffa63e9f6 --- /dev/null +++ b/sysdeps/unix/readdir.c @@ -0,0 +1,82 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> + +#include "direct.h" /* This file defines `struct direct'. */ + +/* direct.h may have an alternate definition for this. */ +#ifndef D_RECLEN +#define D_RECLEN(dp) ((dp)->d_reclen) +#endif + + +/* Read a directory entry from DIRP. */ +struct dirent * +DEFUN(readdir, (dirp), DIR *dirp) +{ + if (dirp == NULL || dirp->__data == NULL) + { + errno = EINVAL; + return NULL; + } + + while (1) + { + struct direct *dp; + + if (dirp->__offset >= dirp->__size) + { + /* We've emptied out our buffer. Refill it. */ + + off_t base; + ssize_t bytes = __getdirentries (dirp->__fd, dirp->__data, + dirp->__allocation, &base); + if (bytes <= 0) + return NULL; + dirp->__size = (size_t) bytes; + + /* Reset the offset into the buffer. */ + dirp->__offset = 0; + } + + dp = (struct direct *) &dirp->__data[dirp->__offset]; + dirp->__offset += D_RECLEN (dp); + + if (dp->d_ino != 0) + { + /* Not a deleted file. */ + register struct dirent *d = &dirp->__entry; + register const char *p; + d->d_fileno = (ino_t) dp->d_ino; + /* On some systems the name length does not actually mean much. + But we always use it as a maximum. */ + p = memchr ((PTR) dp->d_name, '\0', D_NAMLEN (dp) + 1); + d->d_namlen = (p != NULL) ? p - dp->d_name : D_NAMLEN (dp); + memcpy (d->d_name, dp->d_name, d->d_namlen + 1); + return d; + } + } +} diff --git a/sysdeps/unix/reboot.S b/sysdeps/unix/reboot.S new file mode 100644 index 0000000000..4e2023b68b --- /dev/null +++ b/sysdeps/unix/reboot.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (reboot, 1) + ret diff --git a/sysdeps/unix/rewinddir.c b/sysdeps/unix/rewinddir.c new file mode 100644 index 0000000000..3b82895e60 --- /dev/null +++ b/sysdeps/unix/rewinddir.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <dirent.h> +#include <sys/types.h> +#include <unistd.h> + + +/* Rewind DIRP to the beginning of the directory. */ +void +DEFUN(rewinddir, (dirp), DIR *dirp) +{ + (void) lseek(dirp->__fd, (off_t) 0, SEEK_SET); + dirp->__offset = 0; + dirp->__size = 0; +} diff --git a/sysdeps/unix/seekdir.c b/sysdeps/unix/seekdir.c new file mode 100644 index 0000000000..b8d5c3c2ff --- /dev/null +++ b/sysdeps/unix/seekdir.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <unistd.h> + +/* Seek to position POS in DIRP. */ +void +DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos) +{ + pos -= dirp->__size - dirp->__offset; + (void) __lseek(dirp->__fd, pos, SEEK_SET); + dirp->__size = 0; + dirp->__offset = 0; +} diff --git a/sysdeps/unix/setgid.S b/sysdeps/unix/setgid.S new file mode 100644 index 0000000000..4fd02e1761 --- /dev/null +++ b/sysdeps/unix/setgid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setgid, 1) + ret + +weak_alias (__setgid, setgid) diff --git a/sysdeps/unix/setuid.S b/sysdeps/unix/setuid.S new file mode 100644 index 0000000000..d17961b87a --- /dev/null +++ b/sysdeps/unix/setuid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (setuid, 1) + ret + +weak_alias (__setuid, setuid) diff --git a/sysdeps/unix/siglist.c b/sysdeps/unix/siglist.c new file mode 100644 index 0000000000..c904e7f38d --- /dev/null +++ b/sysdeps/unix/siglist.c @@ -0,0 +1,46 @@ +#include <ansidecl.h> +#include <stddef.h> + +#ifndef HAVE_GNU_LD +#define _sys_siglist sys_siglist +#endif + +/* This is a list of all known signal numbers. */ + +CONST char *CONST _sys_siglist[] = + { + "Signal 0", + "Hangup", + "Interrupt", + "Quit", + "Illegal instruction", + "Trace/BPT trap", + "IOT trap", + "EMT trap", + "Floating point exception", + "Killed", + "Bus error", + "Segmentation fault", + "Bad system call", + "Broken pipe", + "Alarm clock", + "Terminated", + "Urgent I/O condition", + "Stopped (signal)", + "Stopped", + "Continued", + "Child exited", + "Stopped (tty input)", + "Stopped (tty output)", + "I/O possible", + "Cputime limit exceeded", + "Filesize limit exceeded", + "Virtual timer expired", + "Profiling timer expired", + "Window changed", + "Resource lost", + "User defined signal 1", + "User defined signal 2", + NULL + }; + diff --git a/sysdeps/unix/snarf-ioctls b/sysdeps/unix/snarf-ioctls new file mode 100755 index 0000000000..d2d02b1ca8 --- /dev/null +++ b/sysdeps/unix/snarf-ioctls @@ -0,0 +1,46 @@ +#!/bin/sh +# Copyright (C) 1991, 1992 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with the GNU C Library; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +sysincludedir=${sysincludedir-/usr/include} + +if [ ! "$snarfexclude" ]; then + # Filter out some headers which cause trouble. + snarfexclude="`echo !${sysincludedir}/sys/param.h! \ + !${sysincludedir}/sys/time.h! \ + !${sysincludedir}/sys/types.h! \ + | sed -e 's,/,\\\\/,g' \ + -e 's,!\\([^!]*\\)!,-e /\\1/d,g'`" +fi + +for file in $*; do + sed -n 's/^#define[ ]*\([A-Z][A-Z0-9_]*\)[ ][ ]*[^ ].*$/\1/p' \ + < $file + + snarfexclude="$snarfexclude \ + `echo $file | sed -e 's,/,\\\\/,g' -e 's,^.*$,-e /&/d,'`" + export snarfexclude + + included="`sed -n < $file \ + -e 's,^#include[ ]*<\(.*\)>.*$,'${sysincludedir}'/\1,p'\ + | sed $snarfexclude`" + if [ "$included" ]; then + $0 $included + fi +done + +exit 0 diff --git a/sysdeps/unix/sparc/brk.S b/sysdeps/unix/sparc/brk.S new file mode 100644 index 0000000000..7906695890 --- /dev/null +++ b/sysdeps/unix/sparc/brk.S @@ -0,0 +1,55 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_brk +#define SYS_brk 17 +#endif + +#ifndef C_SYMBOL_NAME +#define C_SYMBOL_NAME(name) _##name +#endif + +.data +.global C_SYMBOL_NAME(__curbrk) +C_LABEL(__curbrk) +#ifdef HAVE_GNU_LD + .long C_SYMBOL_NAME(_end) +#else + .long C_SYMBOL_NAME(end) +#endif + +.text +ENTRY (__brk) + add %o0, 7, %o0 + andn %o0, 7, %o0 + mov SYS_brk, %g1 + mov %o0, %o1 /* Save rounded value. */ + ta %g0 + bcs error + sethi %hi(C_SYMBOL_NAME(__curbrk)), %g1 + st %o1, [%g1 + %lo(C_SYMBOL_NAME(__curbrk))] + ret +error: sethi %hi(C_SYMBOL_NAME(errno)), %g1 + st %o0, [%g1 + %lo(C_SYMBOL_NAME(errno))] + sub %g0, 1, %o0 + retl + nop /* Fill the delay slot. */ + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/sparc/fork.S b/sysdeps/unix/sparc/fork.S new file mode 100644 index 0000000000..dee15ad701 --- /dev/null +++ b/sysdeps/unix/sparc/fork.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (fork, 0) + /* %o1 is now 0 for the parent and 1 for the child. Decrement it to + make it -1 (all bits set) for the parent, and 0 (no bits set) + for the child. Then AND it with %o0, so the parent gets + %o0&-1==0, and the child gets %o0&0==0. */ + sub %o1, 1, %o1 + retl + and %o0, %o1, %o0 + +weak_alias (__fork, fork) diff --git a/sysdeps/unix/sparc/pipe.S b/sysdeps/unix/sparc/pipe.S new file mode 100644 index 0000000000..3929413783 --- /dev/null +++ b/sysdeps/unix/sparc/pipe.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (__pipe) + mov %o0, %o2 /* Save PIPEDES. */ +PSEUDO (__Spipe, pipe, 1) + st %o0, [%o2] /* PIPEDES[0] = %o0; */ + st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */ + retl /* return 0; */ + clr %o0 + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/sparc/start.c b/sysdeps/unix/sparc/start.c new file mode 100644 index 0000000000..e0f39f5b73 --- /dev/null +++ b/sysdeps/unix/sparc/start.c @@ -0,0 +1,184 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> + +#ifndef NO_SHLIB +#include <sys/exec.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <link.h> +#include <syscall.h> +#endif + +#if !defined (__GNUC__) || __GNUC__ < 2 + #error This file uses GNU C extensions; you must compile with GCC version 2. +#endif + +/* The first piece of initialized data. */ +int __data_start = 0; +#ifdef HAVE_WEAK_SYMBOLS +weak_alias (__data_start, data_start) +#endif + +VOLATILE int errno; + +#ifdef HAVE_WEAK_SYMBOLS +weak_alias (__environ, environ) +#else +#undef environ +#define __environ environ +#endif + +char **__environ; + +extern void EXFUN(__libc_init, (int argc, char **argv, char **envp)); +extern int EXFUN(main, (int argc, char **argv, char **envp)); + +register long int sp asm("%sp"), fp asm("%fp"); + +#ifndef NO_SHLIB +static void EXFUN(init_shlib, (NOARGS)); +#endif + +#ifndef NO_EXPLICIT_START +/* Declare _start with an explicit assembly symbol name of `start' + (note no leading underscore). This is the name Sun's crt0.o uses, + and programs are often linked with `ld -e start'. */ +void _start (void) asm ("start"); +#endif + +void +_start (void) +{ + /* It is important that these be declared `register'. + Otherwise, when compiled without optimization, they are put on the + stack, which loses completely after we zero the FP. */ + register int argc; + register char **argv, **envp; + + /* Unwind the frame built when we entered the function. */ + asm("restore"); + + /* And clear the frame pointer. */ + fp = 0; + + /* The argument info starts after one register + window (64 bytes) past the SP. */ + argc = ((int *) sp)[16]; + argv = (char **) &((int *) sp)[17]; + envp = &argv[argc + 1]; + __environ = envp; + +#ifndef NO_SHLIB + init_shlib (); +#endif + + /* Allocate 24 bytes of stack space for the register save area. */ + sp -= 24; + __libc_init (argc, argv, envp); + + exit (main (argc, argv, envp)); +} + +#ifndef NO_SHLIB + +/* System calls for use by the bootstrap routine. + These are defined here since the usual calls may be dynamically linked. */ + +int syscall (int sysno, ...) asm ("init_syscall"); +asm ("init_syscall:\n" + " clr %g1\n" + " ta 0\n" + " bcc 1f\n" + " sethi %hi(_errno), %g1\n" + " st %o0, [%g1 + %lo(_errno)]\n" + " sub %g0, 1, %o0\n" + "1:retl\n" + " nop"); + +static void +DEFUN_VOID(init_shlib) +{ + extern struct link_dynamic _DYNAMIC; + int so, zf; + caddr_t somap; + caddr_t sodmap; + caddr_t sobssmap; + void (*ldstart) (int, int); + struct exec soexec; + struct + { + caddr_t crt_ba; + int crt_dzfd; + int crt_ldfd; + struct link_dynamic *crt_dp; + char **crt_ep; + caddr_t crt_bp; + } soarg; + + /* If not dynamically linked, do nothing. */ + if (&_DYNAMIC == 0) + return; + + /* Map in the dynamic linker. */ + so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY); + if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec) + || soexec.a_magic != ZMAGIC) + { + static CONST char emsg[] = "crt0: no /usr/lib/ld.so\n"; + + syscall (SYS_write, 2, emsg, sizeof (emsg) - 1); + syscall (SYS_exit, 127); + } + somap = (caddr_t) syscall (SYS_mmap, 0, + soexec.a_text + soexec.a_data + soexec.a_bss, + PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE, + so, 0); + sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data, + PROT_READ | PROT_WRITE | PROT_EXEC, + _MAP_NEW | MAP_FIXED | MAP_PRIVATE, + so, soexec.a_text); + zf = syscall (SYS_open, "/dev/zero", O_RDONLY); + if (soexec.a_bss != 0) + sobssmap = (caddr_t) syscall (SYS_mmap, + somap + soexec.a_text + soexec.a_data, + soexec.a_bss, + PROT_READ | PROT_WRITE | PROT_EXEC, + _MAP_NEW | MAP_FIXED | MAP_PRIVATE, + zf, 0); + + /* Call the entry point of the dynamic linker. */ + soarg.crt_ba = somap; + soarg.crt_dzfd = zf; + soarg.crt_ldfd = so; + soarg.crt_dp = &_DYNAMIC; + soarg.crt_ep = __environ; + soarg.crt_bp = (caddr_t) &&retaddr; + + ldstart = (__typeof (ldstart)) (somap + soexec.a_entry); + (*ldstart) (1, (char *) &soarg - (char *) sp); + + retaddr: +} + +#endif diff --git a/sysdeps/unix/sparc/sysdep.S b/sysdeps/unix/sparc/sysdep.S new file mode 100644 index 0000000000..d04a778794 --- /dev/null +++ b/sysdeps/unix/sparc/sysdep.S @@ -0,0 +1,47 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +.global C_SYMBOL_NAME(errno) +.global syscall_error + +.text +.align 2 +#undef syscall_error +#ifdef NO_UNDERSCORES +__syscall_error: +#else +syscall_error: +#endif +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmp %o0, EWOULDBLOCK_sys + be,a notblock + mov EAGAIN, %o0 +#endif +notblock: /* Store the error code in `errno'. */ + sethi %hi(C_SYMBOL_NAME(errno)), %g1 + st %o0, [%g1 + %lo(C_SYMBOL_NAME(errno))] + /* And return -1. */ + retl + mov -1, %o0 diff --git a/sysdeps/unix/sparc/sysdep.h b/sysdeps/unix/sparc/sysdep.h new file mode 100644 index 0000000000..eab661c1ab --- /dev/null +++ b/sysdeps/unix/sparc/sysdep.h @@ -0,0 +1,50 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error C_SYMBOL_NAME(__syscall_error) +#endif + +#define ENTRY(name) \ + .global C_SYMBOL_NAME(name); \ + .align 2; \ + C_LABEL(name) + +#define PSEUDO(name, syscall_name, args) \ + .global syscall_error; \ + ENTRY (name) \ + mov SYS_ify(syscall_name), %g1; \ + ta 0; \ + bcc 1f; \ + sethi %hi(syscall_error), %g1; \ + jmp %g1 + %lo(syscall_error); nop; \ +1: + +#define ret retl; nop +#define r0 %o0 +#define r1 %o1 +#define MOVE(x,y) mov x, y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/sparc/vfork.S b/sysdeps/unix/sparc/vfork.S new file mode 100644 index 0000000000..aeee3785f6 --- /dev/null +++ b/sysdeps/unix/sparc/vfork.S @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_vfork +#define SYS_vfork 66 +#endif + +SYSCALL__ (vfork, 0) + /* %o1 is now 0 for the parent and 1 for the child. Decrement it to + make it -1 (all bits set) for the parent, and 0 (no bits set) + for the child. Then AND it with %o0, so the parent gets + %o0&-1==0, and the child gets %o0&0==0. */ + sub %o1, 1, %o1 + retl + and %o0, %o1, %o0 + +weak_alias (__vfork, vfork) diff --git a/sysdeps/unix/start.c b/sysdeps/unix/start.c new file mode 100644 index 0000000000..da7ec71ffb --- /dev/null +++ b/sysdeps/unix/start.c @@ -0,0 +1,106 @@ +/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <sysdep.h> /* In case it wants to define anything. */ + +/* The first piece of initialized data. */ +int __data_start = 0; +#ifdef HAVE_WEAK_SYMBOLS +weak_alias (__data_start, data_start) +#endif + +#ifdef DUMMIES +#define ARG_DUMMIES DUMMIES, +#define DECL_DUMMIES int DUMMIES; +#else +#define ARG_DUMMIES +#define DECL_DUMMIES +#endif + +VOLATILE int errno; + +#ifdef HAVE_WEAK_SYMBOLS +weak_alias (__environ, environ) +#else +#undef environ +#define __environ environ +#endif + +char **__environ; + +extern void EXFUN(__libc_init, (int argc, char **argv, char **envp)); +extern int EXFUN(main, (int argc, char **argv, char **envp)); + + +/* Not a prototype because it gets called strangely. */ +static void start1(); + +#ifndef HAVE__start + +#if !defined (NO_UNDERSCORES) && defined (__GNUC__) +/* Declare _start with an explicit assembly symbol name of `start' + (note no leading underscore). This is the name vendor crt0.o's + tend to use, and thus the name most linkers expect. */ +void _start (void) asm ("start"); +#endif + +/* N.B.: It is important that this be the first function. + This file is the first thing in the text section. */ +void +DEFUN_VOID(_start) +{ + start1(); +} + +#if !defined (NO_UNDERSCORES) && defined (HAVE_GNU_LD) && !defined (__GNUC__) +/* Make an alias called `start' (no leading underscore, + so it can't conflict with C symbols) for `_start'. */ +asm(".stabs \"start\",11,0,0,0"); +asm(".stabs \"__start\",1,0,0,0"); +#endif + +#endif + +/* ARGSUSED */ +static void +start1(ARG_DUMMIES argc, argp) + DECL_DUMMIES + int argc; + char *argp; +{ + char **argv = &argp; + + /* The environment starts just after ARGV. */ + __environ = &argv[argc + 1]; + + /* If the first thing after ARGV is the arguments + themselves, there is no environment. */ + if ((char *) __environ == *argv) + /* The environment is empty. Make __environ + point at ARGV[ARGC], which is NULL. */ + --__environ; + + /* Do C library initializations. */ + __libc_init (argc, argv, __environ); + + /* Call the user program. */ + exit(main(argc, argv, __environ)); +} diff --git a/sysdeps/unix/stat.S b/sysdeps/unix/stat.S new file mode 100644 index 0000000000..8ffd60a464 --- /dev/null +++ b/sysdeps/unix/stat.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (stat, 2) + ret + +weak_alias (__stat, stat) diff --git a/sysdeps/unix/sync.S b/sysdeps/unix/sync.S new file mode 100644 index 0000000000..d82db0e251 --- /dev/null +++ b/sysdeps/unix/sync.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sync, 0) + ret diff --git a/sysdeps/unix/syscall.S b/sysdeps/unix/syscall.S new file mode 100644 index 0000000000..e3ef1775dc --- /dev/null +++ b/sysdeps/unix/syscall.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#ifndef SYS_syscall +#define SYS_syscall 0 +#endif + +/* This works if the kernel does an "indirect system call" for system call 0, + taking the first argument word off the stack as the system call number. */ + +SYSCALL (syscall, 1) + ret diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h new file mode 100644 index 0000000000..07c539b78a --- /dev/null +++ b/sysdeps/unix/sysdep.h @@ -0,0 +1,59 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <syscall.h> +#define HAVE_SYSCALLS + +/* Note that using a `PASTE' macro loses. */ +#ifdef __STDC__ +#define SYSCALL__(name, args) PSEUDO (__##name, name, args) +#else +#define SYSCALL__(name, args) PSEUDO (__/**/name, name, args) +#endif +#define SYSCALL(name, args) PSEUDO (name, name, args) + +/* Machine-dependent sysdep.h files are expected to define the macro + PSEUDO (function_name, syscall_name) to emit assembly code to define the + C-callable function FUNCTION_NAME to do system call SYSCALL_NAME. + r0 and r1 are the system call outputs. MOVE(x, y) should be defined as + an instruction such that "MOVE(r1, r0)" works. ret should be defined + as the return instruction. */ + +/* Define a macro we can use to construct the asm name for a C symbol. */ +#ifdef NO_UNDERSCORES +#define C_SYMBOL_NAME(name) name +#ifdef __STDC__ +#define C_LABEL(name) name##: +#else +#define C_LABEL(name) name/**/: +#endif +#else +#ifdef __STDC__ +#define C_SYMBOL_NAME(name) _##name +#define C_LABEL(name) _##name##: +#else +#define C_SYMBOL_NAME(name) _/**/name +#define C_LABEL(name) _/**/name/**/: +#endif +#endif + +#ifdef __STDC__ +#define SYS_ify(syscall_name) SYS_##syscall_name +#else +#define SYS_ify(syscall_name) SYS_/**/syscall_name +#endif diff --git a/sysdeps/unix/system.c b/sysdeps/unix/system.c new file mode 100644 index 0000000000..2c52ec81d3 --- /dev/null +++ b/sysdeps/unix/system.c @@ -0,0 +1,2 @@ +#define NO_WAITPID +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/sysv/Dist b/sysdeps/unix/sysv/Dist new file mode 100644 index 0000000000..f70fcf6728 --- /dev/null +++ b/sysdeps/unix/sysv/Dist @@ -0,0 +1,3 @@ +sysv_termio.h +utmp.h +s_getdents.S diff --git a/sysdeps/unix/sysv/Makefile b/sysdeps/unix/sysv/Makefile new file mode 100644 index 0000000000..b40766035d --- /dev/null +++ b/sysdeps/unix/sysv/Makefile @@ -0,0 +1,42 @@ +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir), misc) + +sysdep_headers := $(sysdep_headers) termio.h +generated := $(generated) termio.h + +# termio.h is just like sysv_termio.h except it uses the same names for +# everything that System V termio does. sysv_termio.h is necessary to +# include in __tcgetatr.c et al, because some of the names in termio.h +# conflict with termios.h. The C library doesn't actually use termio.h, +# but we generate it for those application programs which use it. +$(objpfx)termio.h: $(..)sysdeps/unix/sysv/sysv_termio.h + sed < $< > $@-tmp \ + -e 's/_SYSV_//' \ + -e 's/^#define[ ]*_T/#define T/'\ + -e 's/__sysv_termio/termio/' + mv $@-tmp $@ + +endif + +ifeq ($(subdir),dirent) + +sysdep_routines := $(sysdep_routines) s_getdents + +endif diff --git a/sysdeps/unix/sysv/alarm.S b/sysdeps/unix/sysv/alarm.S new file mode 100644 index 0000000000..6c002d4ccb --- /dev/null +++ b/sysdeps/unix/sysv/alarm.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (alarm, 1) + ret diff --git a/sysdeps/unix/sysv/direct.h b/sysdeps/unix/sysv/direct.h new file mode 100644 index 0000000000..dc1d77beed --- /dev/null +++ b/sysdeps/unix/sysv/direct.h @@ -0,0 +1,10 @@ +struct direct + { + unsigned short int d_fileno; + char d_name[14]; + }; + +#define D_NAMLEN(d) \ + ((d)->d_name[13] == '\0' ? strlen ((d)->d_name) : 14) + +#define D_RECLEN(d) (sizeof (*(d))) diff --git a/sysdeps/unix/sysv/fcntlbits.h b/sysdeps/unix/sysv/fcntlbits.h new file mode 100644 index 0000000000..d7dbd0c20a --- /dev/null +++ b/sysdeps/unix/sysv/fcntlbits.h @@ -0,0 +1,86 @@ +/* O_*, F_*, FD_* bit values for System V. +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 00400 /* Create file if it doesn't exist. */ +#define O_EXCL 02000 /* Fail if file already exists. */ +#define O_TRUNC 01000 /* Truncate file to zero length. */ +#if defined (__USE_BSD) || defined (__USE_SVID) +#define O_SYNC 00020 /* Synchronous writes. */ +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 000010 /* Writes append to the file. */ +#define O_NONBLOCK 000004 /* Non-blocking I/O. */ + +#ifdef __USE_BSD +/* System V doesn't support POSIX.1 O_NONBLOCK, but O_NDELAY is close. */ +#define O_NDELAY O_NONBLOCK +#endif + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#define F_GETLK 5 /* Get record locking info. */ +#define F_SETLK 6 /* Set record locking info. */ +#define F_SETLKW 7 /* Set record locking info, wait. */ + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_sysid; /* System ID where locking process resides. */ + short int l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/sysv/getdents.c b/sysdeps/unix/sysv/getdents.c new file mode 100644 index 0000000000..bb6c812647 --- /dev/null +++ b/sysdeps/unix/sysv/getdents.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> + +extern int __getdents __P ((int fd, char *buf, size_t nbytes)); + +int +DEFUN(__getdirentries, (fd, buf, nbytes, basep), + int fd AND char *buf AND size_t nbytes AND off_t *basep) +{ + if (basep) + *basep = __lseek (fd, (off_t) 0, SEEK_CUR); + + return __getdents (fd, buf, nbytes); +} + +weak_alias (__getdirentries, getdirentries) diff --git a/sysdeps/unix/sysv/gethostname.c b/sysdeps/unix/sysv/gethostname.c new file mode 100644 index 0000000000..509a3da1d9 --- /dev/null +++ b/sysdeps/unix/sysv/gethostname.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/utsname.h> + +/* Put the name of the current host in no more than LEN bytes of NAME. + The result is null-terminated if LEN is large enough for the full + name and the terminator. */ +int +DEFUN(__gethostname, (name, len), + char *name AND size_t len) +{ + struct utsname buf; + if (uname (&buf)) + return -1; + strncpy (name, buf.nodename, len); + return 0; +} + +weak_alias (__gethostname, gethostname) diff --git a/sysdeps/unix/sysv/i386/linux/socket.S b/sysdeps/unix/sysv/i386/linux/socket.S new file mode 100644 index 0000000000..9f59bad095 --- /dev/null +++ b/sysdeps/unix/sysv/i386/linux/socket.S @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.globl syscall_error + +/* The socket-oriented system calls are handled unusally in Linux. + They are all gated through the single `socketcall' system call number. + `socketcall' takes two arguments: the first is the subcode, specifying + which socket function is being called; and the second is a pointer to + the arguments to specific function. + + The .S files for the other calls just #define socket and #include this. */ + +ENTRY (socket) + + /* Save registers. */ + pushl %ebx + pushl %ecx + + movl $__NR_socketcall, %eax /* System call number in %eax. */ + + /* Use ## so `socket' is a separate token that might be #define'd. */ + movl $SYS_##socket, %ebx /* Subcode is first arg to syscall. */ + lea 12(%esp), %ecx /* Address of args in 2nd arg. */ + + /* Do the system call trap. */ + int $0x80 + + /* Restore registers. */ + popl %ecx + popl %ebx + + /* %eax is < 0 if there was an error. */ + testl %eax, %eax + jl syscall_error + + /* Successful; return the syscall's value. */ + ret diff --git a/sysdeps/unix/sysv/i386/linux/sysdep.S b/sysdeps/unix/sysv/i386/linux/sysdep.S new file mode 100644 index 0000000000..ed3a2782a9 --- /dev/null +++ b/sysdeps/unix/sysv/i386/linux/sysdep.S @@ -0,0 +1,38 @@ +/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +/* We jump here when a system call gets an error. + The error number is negated in %eax. */ +.globl syscall_error +syscall_error: + negl %eax /* Make it positive. */ +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmpl %eax, $EWOULDBLOCK_sys /* Is it the old EWOULDBLOCK? */ + jne 0f /* Branch if not. */ + move $EAGAIN, %eax /* Yes; translate it to EAGAIN. */ +#endif +0: movl %eax, _errno /* Store it in `errno'. */ + move $-1, %eax /* Return -1. */ + ret diff --git a/sysdeps/unix/sysv/i386/linux/sysdep.h b/sysdeps/unix/sysv/i386/linux/sysdep.h new file mode 100644 index 0000000000..298a0e4c5b --- /dev/null +++ b/sysdeps/unix/sysv/i386/linux/sysdep.h @@ -0,0 +1,57 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#define ENTRY(name) \ + .globl _##name; \ + .align 2; \ + _##name##: + +#define PSEUDO(name, syscall_name, args) \ + .text; \ + .globl syscall_error; \ + ENTRY (name) \ + XCHG_##args + movl $SYS_##syscall_name, %eax; \ + int $0x80; \ + test %eax, %eax; \ + jl syscall_error; \ + XCHG_##args + +/* Linux takes system call arguments in registers: + 1: %ebx + 2: %ecx + 3: %edx + 4: %esi + 5: %edi + We put the arguments into registers from the stack, + and save the registers, by using the 386 `xchg' instruction + to swap the values in both directions. */ + +#define XCHG_0 /* No arguments to frob. */ +#define XCHG_1 xchg 8(%esp), %ebx; XCHG_0 +#define XCHG_2 xchg 12(%esp), %ecx; XCHG_1 +#define XCHG_3 xchg 16(%esp), %edx; XCHG_2 +#define XCHG_4 xchg 20(%esp), %esi; XCHG_3 +#define XCHG_5 xchg 24(%esp), %edi; XCHG_3 + +#define r0 %eax /* Normal return-value register. */ +#define r1 %edx /* Secondary return-value register. */ +#define scratch %ecx /* Call-clobbered register for random use. */ +#define MOVE(x,y) movl x, y diff --git a/sysdeps/unix/sysv/i386/linux/wait.S b/sysdeps/unix/sysv/i386/linux/wait.S new file mode 100644 index 0000000000..4be64c47c9 --- /dev/null +++ b/sysdeps/unix/sysv/i386/linux/wait.S @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (__wait) + movl 0(%esp), %eax /* Fetch the return address. */ + movl $-1, 0(%esp) /* First arg is -1. */ + /* Second arg is our arg at 4(%esp). */ + pushl $0 /* Third arg is 0. */ + pushl %eax /* Push the return address. */ + + /* Jump to waitpid; it will return to our caller. */ + jmp ___waitpid + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/sysv/i386/signal.S b/sysdeps/unix/sysv/i386/signal.S new file mode 100644 index 0000000000..14ef77bdc5 --- /dev/null +++ b/sysdeps/unix/sysv/i386/signal.S @@ -0,0 +1,31 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* This is just a standard system call, except we need to load %edx + with the address of the `__sigreturn' function. */ + + .globl syscall_error + .globl C_SYMBOL_NAME(__sigreturn) +ENTRY (signal) + lea SYS_signal, %eax + lea C_SYMBOL_NAME(__sigreturn), %edx + .byte 0x9a, 0, 0, 0, 0, 7, 0 /* lcall $7, $0 -- GAS bug. */ + jb syscall_error + ret diff --git a/sysdeps/unix/sysv/i386/sigreturn.S b/sysdeps/unix/sysv/i386/sigreturn.S new file mode 100644 index 0000000000..be1c6b89bf --- /dev/null +++ b/sysdeps/unix/sysv/i386/sigreturn.S @@ -0,0 +1,27 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.text +ENTRY (__sigreturn) + addl $4, %esp /* Pop the return PC. */ + lcall $0xf, $0 /* Do the magic sigreturn trap. */ + /* NOTREACHED */ + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/sysv/i386/sysdep.h b/sysdeps/unix/sysv/i386/sysdep.h new file mode 100644 index 0000000000..fedd5ea825 --- /dev/null +++ b/sysdeps/unix/sysv/i386/sysdep.h @@ -0,0 +1,4 @@ +/* System V does not precede the asm names of C symbols with a `_'. */ +#define NO_UNDERSCORES + +#include <sysdeps/unix/i386/sysdep.h> diff --git a/sysdeps/unix/sysv/i386/time.S b/sysdeps/unix/sysv/i386/time.S new file mode 100644 index 0000000000..f492141c06 --- /dev/null +++ b/sysdeps/unix/sysv/i386/time.S @@ -0,0 +1,26 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (time, 1) + movl 4(%esp), %edx /* Put passed pointer in %edx. */ + testl %edx, %edx /* Is it non-nil? */ + je null + movl %eax, (%edx) /* Yes; store the time there. */ +null: ret diff --git a/sysdeps/unix/sysv/irix4/Dist b/sysdeps/unix/sysv/irix4/Dist new file mode 100644 index 0000000000..c5dd106b55 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/Dist @@ -0,0 +1,2 @@ +syssgi.S sysmp.S +__handler.S sigtramp.c diff --git a/sysdeps/unix/sysv/irix4/Implies b/sysdeps/unix/sysv/irix4/Implies new file mode 100644 index 0000000000..35e1edd830 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/Implies @@ -0,0 +1,4 @@ +# Irix 4 has the set of things which are also common to BSD and SVR4. +unix/common +# Irix 4 has the canonical set of <sys/mman.h> system calls. +unix/mman diff --git a/sysdeps/unix/sysv/irix4/Makefile b/sysdeps/unix/sysv/irix4/Makefile new file mode 100644 index 0000000000..a7f3ea8ce5 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/Makefile @@ -0,0 +1,25 @@ +# Copyright (C) 1993 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),signal) +sysdep_routines := $(sysdep_routines) sigtramp __handler +endif + +ifeq ($(subdir),misc) +sysdep_routines := $(sysdep_routines) syssgi sysmp +endif diff --git a/sysdeps/unix/sysv/irix4/__handler.S b/sysdeps/unix/sysv/irix4/__handler.S new file mode 100644 index 0000000000..bd756a4278 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/__handler.S @@ -0,0 +1,116 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@cs.widener.edu). + Also hacked by Ian Lance Taylor (ian@airs.com). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* This function saves all the registers, calls the + user function, and then executes a sigreturn system call. The + sigreturn call wants the address of a sigcontext structure. This + is all hideously system dependent and, for all intents and + purposes, undocumented. + + When we enter here, a3 holds the user's signal handler. We are + supposed to fill in the context given in a2, and then pass it and + the first two arguments to the user's function. If the user's + function returns, we execute a sigreturn system call. + + The sc_onstack, sc_mask and sc_pc elements of the context are + already set by the kernel. For some reason we don't have to save + the floating point state or the coprocessor state; the kernel may + have saved them for us, or it doesn't use them. */ + +.set noat +ENTRY (__handler) +#if 0 + /* Store zero and the asm temp reg. */ + sw $0, 12(a2) + sw AT, 16(a2) + + /* Put v1 in sc_regs[3]. */ + sw v1, 24(a2) + + /* Save the caller saved registers in sc_regs[8..15]. */ + sw t0, 44(a2) + sw t1, 48(a2) + sw t2, 52(a2) + sw t3, 56(a2) + sw t4, 60(a2) + sw t5, 64(a2) + sw t6, 68(a2) + sw t7, 72(a2) + + /* Save the callee saved registers in sc_regs[16..23]. */ + sw s0, 76(a2) + sw s1, 80(a2) + sw s2, 84(a2) + sw s3, 88(a2) + sw s4, 92(a2) + sw s5, 96(a2) + sw s6, 100(a2) + sw s7, 104(a2) + + /* Save the code generator registers in sc_regs[24] & sc_regs[25]. */ + sw t8, 108(a2) + sw t9, 112(a2) + + /* Save the kernel temp regs in sc_regs[26] & sc_regs[27]. */ + sw k0, 116(a2) + sw k1, 120(a2) + + /* Save the global pointer in sc_regs[28]. */ + sw gp, 124(a2) + + /* ... and also the return address in sc_regs[31]. */ + sw ra, 136(a2) + + /* Note: we don't save the stack pointer in sc_regs[29]; + instead, we use the one that was already there. */ +#if 0 + sw sp, 128(a2) +#endif + + /* Save the floating pointer in sc_regs[30]. */ + sw fp, 132(a2) + + /* Save the mul/div stuff in sc_mdlo and sc_mdhi. */ + mflo t0 + sw t0, 140(a2) + mfhi t0 + sw t0, 144(a2) + +#endif + /* Move the stack up six. This will save the context. */ + addu sp, sp, -24 + sw a2, 16(sp) + + /* Call their handler with the signal, code, and context; note + this will clobber the context. */ + .set noreorder + jal ra, a3 + nop + .set reorder + + /* When we come back, restore the context and pass it right + on into sigreturn(). */ + lw a0, 16(sp) + + /* Do a sigreturn syscall; this doesn't return. */ + li v0, SYS_sigreturn + syscall + nop diff --git a/sysdeps/unix/sysv/irix4/confname.h b/sysdeps/unix/sysv/irix4/confname.h new file mode 100644 index 0000000000..49d2f9c989 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/confname.h @@ -0,0 +1,80 @@ +/* `sysconf', `pathconf', and `confstr' NAME values. Irix 4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +enum + { + _PC_LINK_MAX = 1, + _PC_MAX_CANON, + _PC_MAX_INPUT, + _PC_NAME_MAX, + _PC_PATH_MAX, + _PC_PIPE_BUF, + _PC_CHOWN_RESTRICTED, + _PC_NO_TRUNC, + _PC_VDISABLE + }; + +/* Values for the argument to `sysconf'. */ +enum + { + _SC_ARG_MAX = 1, + _SC_CHILD_MAX, + _SC_CLK_TCK, + _SC_NGROUPS_MAX, + _SC_OPEN_MAX, + _SC_JOB_CONTROL, + _SC_SAVED_IDS, + _SC_VERSION, + + /* Above are done by the Irix system call. + The rest are done by the C library (or are not really implemented). */ + + _SC_STREAM_MAX, + _SC_TZNAME_MAX, + _SC_PAGESIZE, + + /* Values for the argument to `sysconf' + corresponding to _POSIX2_* symbols. */ + _SC_BC_BASE_MAX, + _SC_BC_DIM_MAX, + _SC_BC_SCALE_MAX, + _SC_BC_STRING_MAX, + _SC_COLL_WEIGHTS_MAX, + _SC_EQUIV_CLASS_MAX, + _SC_EXPR_NEST_MAX, + _SC_LINE_MAX, + _SC_RE_DUP_MAX, + + _SC_2_VERSION, + _SC_2_C_BIND, + _SC_2_C_DEV, + _SC_2_FORT_DEV, + _SC_2_FORT_RUN, + _SC_2_SW_DEV, + _SC_2_LOCALEDEF + }; + +#ifdef __USE_POSIX2 +/* Values for the NAME argument to `confstr'. */ +enum + { + _CS_PATH /* The default search path. */ + }; +#endif diff --git a/sysdeps/unix/sysv/irix4/direct.h b/sysdeps/unix/sysv/irix4/direct.h new file mode 100644 index 0000000000..153087fef5 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/direct.h @@ -0,0 +1,15 @@ +#ifndef MAXNAMLEN +#define MAXNAMLEN 255 +#endif + +struct direct + { + unsigned long int d_ino; + off_t d_off; + unsigned short int d_reclen; + char d_name[MAXNAMLEN + 1]; + }; + +#define D_NAMLEN(d) (strlen ((d)->d_name)) + +#define D_RECLEN(d) (d->d_reclen) diff --git a/sysdeps/unix/sysv/irix4/dup2.c b/sysdeps/unix/sysv/irix4/dup2.c new file mode 100644 index 0000000000..86720b1b70 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/dup2.c @@ -0,0 +1,3 @@ +#include <sysdeps/posix/__dup2.c> + +weak_alias (__dup2, dup2) diff --git a/sysdeps/unix/sysv/irix4/fcntlbits.h b/sysdeps/unix/sysv/irix4/fcntlbits.h new file mode 100644 index 0000000000..a8bb776cf4 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/fcntlbits.h @@ -0,0 +1,98 @@ +/* O_*, F_*, FD_* bit values for SGI Irix 4. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _FCNTLBITS_H + +#define _FCNTLBITS_H 1 + + +/* File access modes for `open' and `fcntl'. */ +#define O_RDONLY 0 /* Open read-only. */ +#define O_WRONLY 1 /* Open write-only. */ +#define O_RDWR 2 /* Open read/write. */ + + +/* Bits OR'd into the second argument to open. */ +#define O_CREAT 00400 /* Create file if it doesn't exist. */ +#define O_EXCL 02000 /* Fail if file already exists. */ +#define O_TRUNC 01000 /* Truncate file to zero length. */ +#ifdef __USE_MISC +#define O_SYNC 00020 /* Synchronous writes. */ +#define O_ASYNC 00100 /* Send SIGIO to owner when data is ready. */ +#endif + +/* File status flags for `open' and `fcntl'. */ +#define O_APPEND 000010 /* Writes append to the file. */ +#ifdef __USE_BSD +#define O_NDELAY 000004 /* Non-blocking I/O. */ +#endif +#define O_NONBLOCK 000200 /* POSIX.1 non-blocking I/O. */ + +/* Mask for file access modes. This is system-dependent in case + some system ever wants to define some other flavor of access. */ +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ +#define F_GETLK 5 /* Get record locking info. */ +#define F_SETLK 6 /* Set record locking info. */ +#define F_SETLKW 7 /* Set record locking info, wait. */ +#ifdef __USE_MISC +#define F_CHKFL 8 /* Check legality of file flag changes. */ +#define F_ALLOCSP 10 +#define F_FREESP 11 +#define F_SETBSDLK 12 /* Set Berkeley record lock. */ +#define F_SETBSDLKW 13 /* Set Berkeley record lock and wait. */ +#define F_RGETLK 20 /* Get info on a remote lock. */ +#define F_RSETLK 21 /* Set or unlock a remote lock. */ +#define F_RSETLKW 22 /* Set or unlock a remote lock and wait. */ +#define F_GETOWN 10 /* Get owner; only works on sockets. */ +#define F_SETOWN 11 /* Set owner; only works on sockets. */ +#endif + + +/* File descriptor flags used with F_GETFD and F_SETFD. */ +#define FD_CLOEXEC 1 /* Close on exec. */ + + +#include <gnu/types.h> + +/* The structure describing an advisory lock. This is the type of the third + argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests. */ +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ + short int l_sysid; /* System ID where locking process resides. */ + short int l_pid; /* Process holding the lock. */ + }; + +/* Values for the `l_type' field of a `struct flock'. */ +#define F_RDLCK 1 /* Read lock. */ +#define F_WRLCK 2 /* Write lock. */ +#define F_UNLCK 3 /* Remove lock. */ + + +#endif /* fcntlbits.h */ diff --git a/sysdeps/unix/sysv/irix4/fpathconf.c b/sysdeps/unix/sysv/irix4/fpathconf.c new file mode 100644 index 0000000000..3c9f1750ff --- /dev/null +++ b/sysdeps/unix/sysv/irix4/fpathconf.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <sys/syssgi.h> + +extern int __syssgi __P ((int, ...)); + +/* Get file-specific information about descriptor FD. */ +long int +DEFUN(__fpathconf, (fd, name), int fd AND int name) +{ + return __syssgi (SGI_PATHCONF, FPATHCONF, fd, name); +} + +weak_alias (__fpathconf, fpathconf) diff --git a/sysdeps/unix/sysv/irix4/getgroups.c b/sysdeps/unix/sysv/irix4/getgroups.c new file mode 100644 index 0000000000..714f66077f --- /dev/null +++ b/sysdeps/unix/sysv/irix4/getgroups.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/syssgi.h> +#include <ansidecl.h> +#include <sys/types.h> +#include <grp.h> + +extern int __syssgi __P ((int, ...)); + +/* Set the group set for the current user to GROUPS (N of them). */ +int +DEFUN(__getgroups, (n, groups), size_t n AND gid_t *groups) +{ + return __syssgi (SGI_GETGROUPS, n, groups); +} + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/unix/sysv/irix4/getpgid.S b/sysdeps/unix/sysv/irix4/getpgid.S new file mode 100644 index 0000000000..fbef7a2b27 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/getpgid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__getpgid, bsdgetpgrp, 1) + ret + +weak_alias (__getpgid, getpgid) diff --git a/sysdeps/unix/sysv/irix4/getpriority.c b/sysdeps/unix/sysv/irix4/getpriority.c new file mode 100644 index 0000000000..70a9431890 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/getpriority.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/resource.h> +#include <sys/sysmp.h> + +extern int __sysmp __P ((int, ...)); + +/* Return the highest priority of any process specified by WHICH and WHO + (see <sys/resource.h>); if WHO is zero, the current process, process group, + or user (as specified by WHO) is used. A lower priority number means higher + priority. Priorities range from PRIO_MIN to PRIO_MAX. */ +int +DEFUN(getpriority, (which, who), + enum __priority_which which AND int who) +{ + switch (which) + { + case PRIO_PROCESS: + return __sysmp (MP_SCHED, MPTS_GTNICE_PROC, who); + case PRIO_PGRP: + return __sysmp (MP_SCHED, MPTS_GTNICE_PGRP, who); + case PRIO_USER: + return __sysmp (MP_SCHED, MPTS_GTNICE_USER, who); + } + + errno = EINVAL; + return -1; +} diff --git a/sysdeps/unix/sysv/irix4/getrusage.c b/sysdeps/unix/sysv/irix4/getrusage.c new file mode 100644 index 0000000000..fdd3a24042 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/getrusage.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <errno.h> +#include <sys/syssgi.h> + +extern int __syssgi __P ((int, ...)); + +/* Return resource usage information on process indicated by WHO + and put it in *USAGE. Returns 0 for success, -1 for failure. */ +int +DEFUN(__getrusage, (who, usage), + enum __rusage_who who AND struct rusage *usage) +{ + return __syssgi (SGI_RUSAGE, who, usage); +} + +weak_alias (__getrusage, getrusage) diff --git a/sysdeps/unix/sysv/irix4/gettimeofday.c b/sysdeps/unix/sysv/irix4/gettimeofday.c new file mode 100644 index 0000000000..d7055be82e --- /dev/null +++ b/sysdeps/unix/sysv/irix4/gettimeofday.c @@ -0,0 +1 @@ +#include <sysdeps/posix/gettimeofday.c> diff --git a/sysdeps/unix/sysv/irix4/msync.S b/sysdeps/unix/sysv/irix4/msync.S new file mode 100644 index 0000000000..75b9f1531d --- /dev/null +++ b/sysdeps/unix/sysv/irix4/msync.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/sun/sunos4/msync.S> diff --git a/sysdeps/unix/sysv/irix4/pathconf.c b/sysdeps/unix/sysv/irix4/pathconf.c new file mode 100644 index 0000000000..698e30aab7 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/pathconf.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <unistd.h> +#include <sys/syssgi.h> + +extern int __syssgi __P ((int, ...)); + +/* Get file-specific information about PATH. */ +long int +DEFUN(__pathconf, (path, name), CONST char *path AND int name) +{ + return __syssgi (SGI_PATHCONF, PATHCONF, path, name); +} + +weak_alias (__pathconf, pathconf) diff --git a/sysdeps/unix/sysv/irix4/readv.c b/sysdeps/unix/sysv/irix4/readv.c new file mode 100644 index 0000000000..baa976da6d --- /dev/null +++ b/sysdeps/unix/sysv/irix4/readv.c @@ -0,0 +1 @@ +#include <sysdeps/posix/readv.c> diff --git a/sysdeps/unix/sysv/irix4/reboot.c b/sysdeps/unix/sysv/irix4/reboot.c new file mode 100644 index 0000000000..d7a3659d2b --- /dev/null +++ b/sysdeps/unix/sysv/irix4/reboot.c @@ -0,0 +1 @@ +#include <sysdeps/stub/reboot.c> diff --git a/sysdeps/unix/sysv/irix4/setgroups.c b/sysdeps/unix/sysv/irix4/setgroups.c new file mode 100644 index 0000000000..052df0f830 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/setgroups.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sys/syssgi.h> +#include <ansidecl.h> +#include <sys/types.h> +#include <grp.h> + +extern int __syssgi __P ((int, ...)); + +/* Set the group set for the current user to GROUPS (N of them). */ +int +DEFUN(setgroups, (n, groups), size_t n AND CONST gid_t *groups) +{ + return __syssgi (SGI_SETGROUPS, n, groups); +} diff --git a/sysdeps/unix/sysv/irix4/setpgid.S b/sysdeps/unix/sysv/irix4/setpgid.S new file mode 100644 index 0000000000..9267054fe9 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/setpgid.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__setpgid, bsdsetpgrp, 2) + ret + +weak_alias (__setpgid, setpgid) +weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/unix/sysv/irix4/setpriority.c b/sysdeps/unix/sysv/irix4/setpriority.c new file mode 100644 index 0000000000..a632953423 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/setpriority.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/resource.h> +#include <sys/sysmp.h> + +int +DEFUN(setpriority, (which, who, prio), + enum __priority_which which AND int who AND int prio) +{ + switch (which) + { + case PRIO_PROCESS: + return __sysmp (MP_SCHED, MPTS_RENICE_PROC, who, prio); + case PRIO_PGRP: + return __sysmp (MP_SCHED, MPTS_RENICE_PGRP, who, prio); + case PRIO_USER: + return __sysmp (MP_SCHED, MPTS_RENICE_USER, who, prio); + } + + errno = EINVAL; + return -1; +} + diff --git a/sysdeps/unix/sysv/irix4/signal.S b/sysdeps/unix/sysv/irix4/signal.S new file mode 100644 index 0000000000..b0c147dadb --- /dev/null +++ b/sysdeps/unix/sysv/irix4/signal.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__raw_signal, signal, 3) + ret diff --git a/sysdeps/unix/sysv/irix4/signum.h b/sysdeps/unix/sysv/irix4/signum.h new file mode 100644 index 0000000000..5d30ebb875 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/signum.h @@ -0,0 +1,67 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* This file defines the fake signal functions and signal + number constants for SGI Irix 4. */ + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) +#define SIG_DFL ((__sighandler_t) 0) +#define SIG_IGN ((__sighandler_t) 1) + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap. */ +#define SIGEMT 7 /* EMT trap. */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error. */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call*/ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define SIGCHLD 18 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGPWR 19 /* Power going down. */ +#define SIGSTOP 20 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 21 /* Keyboard stop (POSIX). */ +#define SIGPOLL 22 /* Same as SIGIO? (SVID). */ +#define SIGIO 23 /* I/O now possible. */ +#define SIGURG 24 /* Urgent condition on socket.*/ +#define SIGWINCH 25 /* Window size change. */ +#define SIGVTALRM 26 /* Virtual alarm clock. */ +#define SIGPROF 27 /* Profiling alarm clock. */ +#define SIGCONT 28 /* Continue (POSIX). */ +#define SIGTTIN 29 /* Background read from tty (POSIX). */ +#define SIGTTOU 30 /* Background write to tty (POSIX). */ +#define SIGXCPU 31 /* CPU limit exceeded. */ +#define SIGXFSZ 32 /* File size limit exceeded. */ + +#endif /* <signal.h> included. */ + +#define _NSIG 33 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/sysv/irix4/sigreturn.S b/sysdeps/unix/sysv/irix4/sigreturn.S new file mode 100644 index 0000000000..ebb5c1ae44 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/sigreturn.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@cs.widener.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY(__sigreturn) + li v0, SYS_sigreturn + syscall + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/sysv/irix4/sigtramp.c b/sysdeps/unix/sysv/irix4/sigtramp.c new file mode 100644 index 0000000000..85c2c3a9a9 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/sigtramp.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* The sigvec system call on MIPS Ultrix takes an additional + parameter, which is the address that is actually called when the + signal occurs. + + When a signal occurs, we arrange for the kernel to call __handler. + That will save the frame and stack pointers into the context, and + then jump to this routine. See __handler.S. + + This code is based on sysdeps/unix/bsd/sun4/sigtramp.c, but it's + different because since we get passed the user signal handler we + don't actually need a trampoline. */ + +#include <ansidecl.h> +#include <signal.h> +#include <stddef.h> +#include <errno.h> + +/* The user's signal handler is called with three arguments. */ +typedef void (*handler_type) (int sig, int code, struct sigcontext *); + +/* Defined in signal.S. */ +extern __sighandler_t EXFUN(__raw_signal, (int sig, __sighandler_t func, + void (*)(int sig, int code, + struct sigcontext *, + handler_type))); + +extern void EXFUN(__handler, (int sig, int code, + struct sigcontext *, + handler_type)); + +__sighandler_t +DEFUN(signal, (sig, func), + int sig AND __sighandler_t func) +{ + return __raw_signal (sig, func, __handler); +} diff --git a/sysdeps/unix/sysv/irix4/start.c b/sysdeps/unix/sysv/irix4/start.c new file mode 100644 index 0000000000..4382e6f855 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/start.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + +/* The first piece of initialized data. */ +int __data_start = 0; + +VOLATILE int errno = 0; + +#ifndef HAVE_GNU_LD +#undef environ +#define __environ environ +#endif + +char **__environ; + +extern void EXFUN(__libc_init, (int argc, char **argv, char **envp)); +extern int EXFUN(main, (int argc, char **argv, char **envp)); + +/* Use the stack pointer to access the arguments. This assumes that + we can guess how big the frame will be. */ +register long int sp asm("sp"); +#ifdef __OPTIMIZE__ +#define STACKSIZE 8 +#else +#define STACKSIZE 10 +#endif + +void +DEFUN_VOID(__start) +{ + int argc; + char **argv, **envp; + + /* Set up the global pointer. */ + asm volatile ("la $28,_gp"); + argc = ((int *) sp)[STACKSIZE]; + argv = (char **) &((int *) sp)[STACKSIZE + 1]; + envp = &argv[argc + 1]; + __environ = envp; + + __libc_init (argc, argv, envp); + errno = 0; + exit (main (argc, argv, envp)); +} diff --git a/sysdeps/unix/sysv/irix4/statbuf.h b/sysdeps/unix/sysv/irix4/statbuf.h new file mode 100644 index 0000000000..8b327bae11 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/statbuf.h @@ -0,0 +1,61 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H +#define _STATBUF_H + +struct stat + { + unsigned long st_ino; + short int st_dev; + unsigned short int st_mode; + short int st_nlink; + unsigned short int st_uid; + unsigned short int st_gid; + short int st_rdev; + long int st_size; + long int st_atime; + long int st_mtime; + long int st_ctime; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* These don't actually exist on System V, but having them doesn't hurt. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#endif /* statbuf.h */ diff --git a/sysdeps/unix/sysv/irix4/swapon.c b/sysdeps/unix/sysv/irix4/swapon.c new file mode 100644 index 0000000000..86a638fdc5 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/swapon.c @@ -0,0 +1 @@ +#include <sysdeps/stub/swapon.c> diff --git a/sysdeps/unix/sysv/irix4/sys/mman.h b/sysdeps/unix/sysv/irix4/sys/mman.h new file mode 100644 index 0000000000..ac50aab6dd --- /dev/null +++ b/sysdeps/unix/sysv/irix4/sys/mman.h @@ -0,0 +1,101 @@ +/* Definitions for BSD-style memory management. Irix 4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_MMAN_H + +#define _SYS_MMAN_H 1 +#include <features.h> + +#include <gnu/types.h> +#define __need_size_t +#include <stddef.h> + + +/* Protections are chosen from these bits, OR'd together. The + implementation does not necessarily support PROT_EXEC or PROT_WRITE + without PROT_READ. The only guarantees are that no writing will be + allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + +#define PROT_NONE 0x00 /* No access. */ +#define PROT_READ 0x04 /* Pages can be read. */ +#define PROT_WRITE 0x02 /* Pages can be written. */ +#define PROT_EXEC 0x01 /* Pages can be executed. */ +#define PROT_EXECUTE PROT_EXEC + + +/* Sharing types (must choose one and only one of these). */ +#define MAP_SHARED 0x01 /* Share changes. */ +#define MAP_PRIVATE 0x02 /* Changes private; copy pages on write. */ +#define MAP_TYPE 0x0f /* Mask for sharing type. */ + +/* Other flags. */ +#define MAP_FIXED 0x10 /* Map address must be exactly as requested. */ +#define MAP_RENAME 0x20 /* Rename private pages to file. */ +#define MAP_AUTOGROW 0x40 /* Grow file as pages are written. */ +#define MAP_LOCAL 0x80 /* Copy the mapped region on fork. */ + +/* Advice to `madvise'. */ +#define MADV_NORMAL 0 /* No further special treatment. */ +#define MADV_RANDOM 1 /* Expect random page references. */ +#define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define MADV_WILLNEED 3 /* Will need these pages. */ +#define MADV_DONTNEED 4 /* Don't need these pages. */ + +/* Flags to `msync'. */ +#define MS_ASYNC 0x1 /* Return immediately, don't fsync. */ +#define MS_INVALIDATE 0x2 /* Invalidate caches. */ + + +#include <sys/cdefs.h> + +__BEGIN_DECLS +/* Map addresses starting near ADDR and extending for LEN bytes. from + OFFSET into the file FD describes according to PROT and FLAGS. If ADDR + is nonzero, it is the desired mapping address. If the MAP_FIXED bit is + set in FLAGS, the mapping will be at ADDR exactly (which must be + page-aligned); otherwise the system chooses a convenient nearby address. + The return value is the actual mapping address chosen or (caddr_t) -1 + for errors (in which case `errno' is set). A successful `mmap' call + deallocates any previous mapping for the affected region. */ + +__caddr_t mmap __P ((__caddr_t __addr, size_t __len, + int __prot, int __flags, int __fd, __off_t __offset)); + +/* Deallocate any mapping for the region starting at ADDR and extending LEN + bytes. Returns 0 if successful, -1 for errors (and sets errno). */ +int munmap __P ((__caddr_t __addr, size_t __len)); + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors + (and sets errno). */ +int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); + +/* Synchronize the region starting at ADDR and extending LEN bytes with the + file it maps. Filesystem operations on a file being mapped are + unpredictable before this is done. */ +int msync __P ((caddr_t __addr, size_t __len, int __flags)); + +/* Advise the system about particular usage patterns the program follows + for the region starting at ADDR and extending LEN bytes. */ +int madvise __P ((__caddr_t __addr, size_t __len, int __advice)); + +__END_DECLS + + +#endif /* sys/mman.h */ diff --git a/sysdeps/unix/sysv/irix4/sysconf.c b/sysdeps/unix/sysv/irix4/sysconf.c new file mode 100644 index 0000000000..a310362239 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/sysconf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <unistd.h> +#include <sys/syssgi.h> + +extern int __syssgi __P ((int, ...)); + +/* Get the value of the system variable NAME. */ +long int +DEFUN(__sysconf, (name), int name) +{ + if (name == _SC_TZNAME_MAX) + return __tzname_max (); + + return __syssgi (SGI_SYSCONF, name); +} + +weak_alias (__sysconf, sysconf) diff --git a/sysdeps/unix/sysv/irix4/sysmp.S b/sysdeps/unix/sysv/irix4/sysmp.S new file mode 100644 index 0000000000..438da60d69 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/sysmp.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sysmp, 4) + ret diff --git a/sysdeps/unix/sysv/irix4/syssgi.S b/sysdeps/unix/sysv/irix4/syssgi.S new file mode 100644 index 0000000000..2715d2899c --- /dev/null +++ b/sysdeps/unix/sysv/irix4/syssgi.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (syssgi, 2) + ret diff --git a/sysdeps/unix/sysv/irix4/time.S b/sysdeps/unix/sysv/irix4/time.S new file mode 100644 index 0000000000..23bfe5deac --- /dev/null +++ b/sysdeps/unix/sysv/irix4/time.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/time.S> diff --git a/sysdeps/unix/sysv/irix4/uname.S b/sysdeps/unix/sysv/irix4/uname.S new file mode 100644 index 0000000000..fe912403b1 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/uname.S @@ -0,0 +1,26 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY(uname) + li a2, 0 + li a3, 0 +SYSCALL__ (utssys, 1) + j ra + move v0, zero diff --git a/sysdeps/unix/sysv/irix4/wait.S b/sysdeps/unix/sysv/irix4/wait.S new file mode 100644 index 0000000000..9f2afa7997 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/wait.S @@ -0,0 +1,42 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@cs.widener.edu). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.set noreorder + +ENTRY(__wait) + /* Prep it for wait */ + move a1, zero + move a2, zero + + li v0, SYS_wait + syscall + beq a3, zero, noerror + nop + j syscall_error + nop +noerror: + beq a0, zero, noarg + nop + sw v1, 0(a0) + nop +noarg: + ret + +weak_alias (__wait, wait) diff --git a/sysdeps/unix/sysv/irix4/wait3.S b/sysdeps/unix/sysv/irix4/wait3.S new file mode 100644 index 0000000000..54065aefdf --- /dev/null +++ b/sysdeps/unix/sysv/irix4/wait3.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/ultrix4/wait3.S> diff --git a/sysdeps/unix/sysv/irix4/waitpid.c b/sysdeps/unix/sysv/irix4/waitpid.c new file mode 100644 index 0000000000..8378982ac7 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/waitpid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/waitpid.c> diff --git a/sysdeps/unix/sysv/irix4/writev.c b/sysdeps/unix/sysv/irix4/writev.c new file mode 100644 index 0000000000..0dc6a76014 --- /dev/null +++ b/sysdeps/unix/sysv/irix4/writev.c @@ -0,0 +1 @@ +#include <sysdeps/posix/writev.c> diff --git a/sysdeps/unix/sysv/isc2.2/rename.S b/sysdeps/unix/sysv/isc2.2/rename.S new file mode 100644 index 0000000000..a4b2c4207c --- /dev/null +++ b/sysdeps/unix/sysv/isc2.2/rename.S @@ -0,0 +1 @@ +#include <sysdeps/unix/common/rename.S> diff --git a/sysdeps/unix/sysv/isc3/direct.h b/sysdeps/unix/sysv/isc3/direct.h new file mode 100644 index 0000000000..e6df21246e --- /dev/null +++ b/sysdeps/unix/sysv/isc3/direct.h @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sco3.2.4/direct.h> diff --git a/sysdeps/unix/sysv/linux/Implies b/sysdeps/unix/sysv/linux/Implies new file mode 100644 index 0000000000..fe7e1fde5e --- /dev/null +++ b/sysdeps/unix/sysv/linux/Implies @@ -0,0 +1,2 @@ +# Linux has the set of things which are also common to BSD and SVR4. +unix/common diff --git a/sysdeps/unix/sysv/linux/accept.S b/sysdeps/unix/sysv/linux/accept.S new file mode 100644 index 0000000000..5936a0185b --- /dev/null +++ b/sysdeps/unix/sysv/linux/accept.S @@ -0,0 +1,2 @@ +#define socket accept +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/bind.S b/sysdeps/unix/sysv/linux/bind.S new file mode 100644 index 0000000000..fc82b65a2f --- /dev/null +++ b/sysdeps/unix/sysv/linux/bind.S @@ -0,0 +1,2 @@ +#define socket bind +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/connect.S b/sysdeps/unix/sysv/linux/connect.S new file mode 100644 index 0000000000..3433043d8c --- /dev/null +++ b/sysdeps/unix/sysv/linux/connect.S @@ -0,0 +1,2 @@ +#define socket connect +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/getpeername.S b/sysdeps/unix/sysv/linux/getpeername.S new file mode 100644 index 0000000000..8429fcdf76 --- /dev/null +++ b/sysdeps/unix/sysv/linux/getpeername.S @@ -0,0 +1,2 @@ +#define socket getpeername +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/getpgrp.S b/sysdeps/unix/sysv/linux/getpgrp.S new file mode 100644 index 0000000000..f8d6e07106 --- /dev/null +++ b/sysdeps/unix/sysv/linux/getpgrp.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (getpgrp, 0) + ret diff --git a/sysdeps/unix/sysv/linux/getsockname.S b/sysdeps/unix/sysv/linux/getsockname.S new file mode 100644 index 0000000000..6782707f88 --- /dev/null +++ b/sysdeps/unix/sysv/linux/getsockname.S @@ -0,0 +1,2 @@ +#define socket getsockname +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/listen.S b/sysdeps/unix/sysv/linux/listen.S new file mode 100644 index 0000000000..d2cbec60a0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/listen.S @@ -0,0 +1,2 @@ +#define socket listen +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/rename.S b/sysdeps/unix/sysv/linux/rename.S new file mode 100644 index 0000000000..a5a8dfeeef --- /dev/null +++ b/sysdeps/unix/sysv/linux/rename.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/rename.S> diff --git a/sysdeps/unix/sysv/linux/setsid.S b/sysdeps/unix/sysv/linux/setsid.S new file mode 100644 index 0000000000..4930c56dcf --- /dev/null +++ b/sysdeps/unix/sysv/linux/setsid.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/setsid.S> diff --git a/sysdeps/unix/sysv/linux/socketpair.S b/sysdeps/unix/sysv/linux/socketpair.S new file mode 100644 index 0000000000..da71c57dea --- /dev/null +++ b/sysdeps/unix/sysv/linux/socketpair.S @@ -0,0 +1,2 @@ +#define socket socketpair +#include <socket.S> diff --git a/sysdeps/unix/sysv/linux/syscall.h b/sysdeps/unix/sysv/linux/syscall.h new file mode 100644 index 0000000000..b94d919e68 --- /dev/null +++ b/sysdeps/unix/sysv/linux/syscall.h @@ -0,0 +1,124 @@ +#ifndef _SYSCALL_H +#define _SYSCALL_H + +#define SYS_setup 0 /* Used only by init, to get system going. */ +#define SYS_exit 1 +#define SYS_fork 2 +#define SYS_read 3 +#define SYS_write 4 +#define SYS_open 5 +#define SYS_close 6 +#define SYS_waitpid 7 +#define SYS_creat 8 +#define SYS_link 9 +#define SYS_unlink 10 +#define SYS_execve 11 +#define SYS_chdir 12 +#define SYS_time 13 +#define SYS_mknod 14 +#define SYS_chmod 15 +#define SYS_chown 16 +#define SYS_brk 17 +#define SYS_oldstat 18 +#define SYS_lseek 19 +#define SYS_getpid 20 +#define SYS_mount 21 +#define SYS_umount 22 +#define SYS_setuid 23 +#define SYS_getuid 24 +#define SYS_stime 25 +#define SYS_ptrace 26 +#define SYS_alarm 27 +#define SYS_oldfstat 28 +#define SYS_pause 29 +#define SYS_utime 30 +#define SYS_stty 31 +#define SYS_gtty 32 +#define SYS_access 33 +#define SYS_nice 34 +#define SYS_ftime 35 +#define SYS_sync 36 +#define SYS_kill 37 +#define SYS_rename 38 +#define SYS_mkdir 39 +#define SYS_rmdir 40 +#define SYS_dup 41 +#define SYS_pipe 42 +#define SYS_times 43 +#define SYS_prof 44 +#if 0 +#define SYS_brk 45 /* Where did this bogosity crom from? */ +#endif +#define SYS_setgid 46 +#define SYS_getgid 47 +#define SYS_signal 48 +#define SYS_geteuid 49 +#define SYS_getegid 50 +#define SYS_acct 51 +#define SYS_phys 52 +#define SYS_lock 53 +#define SYS_ioctl 54 +#define SYS_fcntl 55 +#define SYS_mpx 56 +#define SYS_setpgrp 57 +#define SYS_ulimit 58 +#define SYS_olduname 59 +#define SYS_umask 60 +#define SYS_chroot 61 +#define SYS_ustat 62 +#define SYS_dup2 63 +#define SYS_getppid 64 +#define SYS_getpgrp 65 +#define SYS_setsid 66 +#define SYS_sigaction 67 +#define SYS_siggetmask 68 +#define SYS_sigsetmask 69 +#define SYS_setreuid 70 +#define SYS_setregid 71 +#define SYS_sigsuspend 72 +#define SYS_sigpending 73 +#define SYS_sethostname 74 +#define SYS_setrlimit 75 +#define SYS_getrlimit 76 +#define SYS_getrusage 77 +#define SYS_gettimeofday 78 +#define SYS_settimeofday 79 +#define SYS_getgroups 80 +#define SYS_setgroups 81 +#define SYS_select 82 +#define SYS_symlink 83 +#define SYS_oldlstat 84 +#define SYS_readlink 85 +#define SYS_uselib 86 +#define SYS_swapon 87 +#define SYS_reboot 88 +#define SYS_readdir 89 +#define SYS_mmap 90 +#define SYS_munmap 91 +#define SYS_truncate 92 +#define SYS_ftruncate 93 +#define SYS_fchmod 94 +#define SYS_fchown 95 +#define SYS_getpriority 96 +#define SYS_setpriority 97 +#define SYS_profil 98 +#define SYS_statfs 99 +#define SYS_fstatfs 100 +#define SYS_ioperm 101 +#define SYS_socketcall 102 +#define SYS_syslog 103 +#define SYS_setitimer 104 +#define SYS_getitimer 105 +#define SYS_stat 106 +#define SYS_lstat 107 +#define SYS_fstat 108 +#define SYS_uname 109 +#define SYS_iopl 110 +#define SYS_vhangup 111 +#define SYS_idle 112 +#define SYS_vm86 113 +#define SYS_wait4 114 +#define SYS_swapoff 115 + + +#endif /* syscall.h */ diff --git a/sysdeps/unix/sysv/linux/wait4.S b/sysdeps/unix/sysv/linux/wait4.S new file mode 100644 index 0000000000..e4c322341d --- /dev/null +++ b/sysdeps/unix/sysv/linux/wait4.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/bsd4.4/wait4.S> diff --git a/sysdeps/unix/sysv/linux/waitpid.S b/sysdeps/unix/sysv/linux/waitpid.S new file mode 100644 index 0000000000..20d9d669bb --- /dev/null +++ b/sysdeps/unix/sysv/linux/waitpid.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (waitpid, 3) + ret + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/unix/sysv/local_lim.h b/sysdeps/unix/sysv/local_lim.h new file mode 100644 index 0000000000..c2b0468ee7 --- /dev/null +++ b/sysdeps/unix/sysv/local_lim.h @@ -0,0 +1,32 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#define NGROUPS_MAX 0 /* No supplementary groups. */ +#define ARG_MAX 5120 +#define CHILD_MAX 25 +#define OPEN_MAX 60 +#define LINK_MAX 1000 +#define MAX_CANON 256 + +/* For SVR3, this is 14. For SVR4, it is 255, at least on ufs + file systems, even though the System V limits.h incorrectly + defines it as 14. Giving it a value which is too large + is harmless (it is a maximum). */ +#define NAME_MAX 255 + +#define PATH_MAX 1024 diff --git a/sysdeps/unix/sysv/minix/sigaction.h b/sysdeps/unix/sysv/minix/sigaction.h new file mode 100644 index 0000000000..9395206407 --- /dev/null +++ b/sysdeps/unix/sysv/minix/sigaction.h @@ -0,0 +1,49 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Structure describing the action to be taken when a signal arrives. */ +struct sigaction + { + /* Signal handler. */ + __sighandler_t sa_handler; + + /* Additional set of signals to be blocked. */ + __sigset_t sa_mask; + + /* Special flags. */ + int sa_flags; + }; + +/* Bits in `sa_flags'. */ +#ifdef __USE_MISC +#define SA_ONSTACK 0x1 /* Take signal on signal stack. */ +#define SA_RESETHAND 0x2 /* Reset signal handler when signal caught. */ +#define SA_NODEFER 0x4 /* Don't block signal while catching it. */ +#define SA_RESTART 0x8 /* Don't restart syscall on signal return. */ +#define SA_SIGINFO 0x10 /* Extended signal handling. */ +#define SA_NOCLDWAIT 0x20 /* Don't create zombies. */ +#define SA_COMPAT 0x80 /* Internal flag for old signal catchers. */ +#define SA_DISABLE 0x100 /* Disable alternate signal stack. */ +#endif +#define SA_NOCLDSTOP 0x40 /* Don't send SIGCHLD when children stop. */ + + +/* Values for the HOW argument to `sigprocmask'. */ +#define SIG_BLOCK 0 /* Block signals. */ +#define SIG_UNBLOCK 1 /* Unblock signals. */ +#define SIG_SETMASK 2 /* Set the set of blocked signals. */ diff --git a/sysdeps/unix/sysv/mkdir.c b/sysdeps/unix/sysv/mkdir.c new file mode 100644 index 0000000000..16713f9e48 --- /dev/null +++ b/sysdeps/unix/sysv/mkdir.c @@ -0,0 +1,97 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <string.h> + +/* Create a directory named PATH with protections MODE. */ +int +DEFUN(__mkdir, (path, mode), CONST char *path AND mode_t mode) +{ + char *cmd = __alloca (80 + strlen (path)); + char *p; + int status; + mode_t mask; + int save; + struct stat statbuf; + + if (path == NULL) + { + errno = EINVAL; + return -1; + } + + /* Check for some errors. */ + if (__stat (path, &statbuf) < 0) + { + if (errno != ENOENT) + return -1; + /* There is no file by that name. Good. */ + } + else + { + errno = EEXIST; + return -1; + } + + /* Race condition, but how else to do it? */ + mask = __umask (0777); + (void) __umask (mask); + + p = cmd; + *p++ = 'm'; + *p++ = 'k'; + *p++ = 'd'; + *p++ = 'i'; + *p++ = 'r'; + *p++ = ' '; + + mode &= ~mask; + *p++ = '-'; + *p++ = 'm'; + *p++ = ' '; + *p++ = ((mode & 07000) >> 9) + '0'; + *p++ = ((mode & 0700) >> 6) + '0'; + *p++ = ((mode & 070) >> 3) + '0'; + *p++ = ((mode & 07)) + '0'; + *p++ = ' '; + + strcpy (p, path); + + save = errno; + /* If system doesn't set errno, but the mkdir fails, we really + have no idea what went wrong. EIO is the vaguest error I + can think of, so I'll use that. */ + errno = EIO; + status = system (cmd); + if (WIFEXITED (status) && WEXITSTATUS (status) == 0) + { + errno = save; + return 0; + } + else + return -1; +} + +weak_alias (__mkdir, mkdir) diff --git a/sysdeps/unix/sysv/nice.S b/sysdeps/unix/sysv/nice.S new file mode 100644 index 0000000000..b04bb410a0 --- /dev/null +++ b/sysdeps/unix/sysv/nice.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (nice, 1) + ret diff --git a/sysdeps/unix/sysv/pause.S b/sysdeps/unix/sysv/pause.S new file mode 100644 index 0000000000..82441ff2c0 --- /dev/null +++ b/sysdeps/unix/sysv/pause.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (pause, 0) + ret diff --git a/sysdeps/unix/sysv/poll.S b/sysdeps/unix/sysv/poll.S new file mode 100644 index 0000000000..063236e7b9 --- /dev/null +++ b/sysdeps/unix/sysv/poll.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (poll, 3) + ret diff --git a/sysdeps/unix/sysv/rmdir.c b/sysdeps/unix/sysv/rmdir.c new file mode 100644 index 0000000000..52a130ce3e --- /dev/null +++ b/sysdeps/unix/sysv/rmdir.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <string.h> + +/* Create a directory named PATH with protections MODE. */ +int +DEFUN(__rmdir, (path), CONST char *path) +{ + char *cmd = __alloca (80 + strlen (path)); + char *p; + int status; + int save; + struct stat statbuf; + + if (path == NULL) + { + errno = EINVAL; + return -1; + } + + /* Check for some errors. */ + if (__stat (path, &statbuf) < 0) + return -1; + if (!S_ISDIR (statbuf.st_mode)) + { + errno = ENOTDIR; + return -1; + } + + p = cmd; + *p++ = 'r'; + *p++ = 'm'; + *p++ = 'd'; + *p++ = 'i'; + *p++ = 'r'; + *p++ = ' '; + + strcpy (p, path); + + save = errno; + /* If system doesn't set errno, but the rmdir fails, we really + have no idea what went wrong. EIO is the vaguest error I + can think of, so I'll use that. */ + errno = EIO; + status = system (cmd); + if (WIFEXITED (status) && WEXITSTATUS (status) == 0) + { + return 0; + errno = save; + } + else + return -1; +} + +weak_alias (__rmdir, rmdir) diff --git a/sysdeps/unix/sysv/s_getdents.S b/sysdeps/unix/sysv/s_getdents.S new file mode 100644 index 0000000000..6e60c08125 --- /dev/null +++ b/sysdeps/unix/sysv/s_getdents.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (getdents, 3) + ret diff --git a/sysdeps/unix/sysv/sco3.2.4/Dist b/sysdeps/unix/sysv/sco3.2.4/Dist new file mode 100644 index 0000000000..462b9fb1a6 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/Dist @@ -0,0 +1,2 @@ +pgrpsys.S +sco_getgrp.S diff --git a/sysdeps/unix/sysv/sco3.2.4/Makefile b/sysdeps/unix/sysv/sco3.2.4/Makefile new file mode 100644 index 0000000000..23525e527d --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/Makefile @@ -0,0 +1,3 @@ +ifeq (posix,$(subdir)) +sysdep_routines := $(sysdep_routines) pgrpsys sco_getgrp +endif diff --git a/sysdeps/unix/sysv/sco3.2.4/__setpgid.c b/sysdeps/unix/sysv/sco3.2.4/__setpgid.c new file mode 100644 index 0000000000..3c4304c633 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/__setpgid.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Get the process group ID of process PID. */ +int +DEFUN(__setpgid, (pid, pgid), pid_t pid AND pid_t pgid) +{ + return __pgrpsys (2, pid, pgid); +} diff --git a/sysdeps/unix/sysv/sco3.2.4/confname.h b/sysdeps/unix/sysv/sco3.2.4/confname.h new file mode 100644 index 0000000000..0408951863 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/confname.h @@ -0,0 +1,50 @@ +/* `sysconf', `pathconf', and `confstr' NAME values. Generic version. +Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Values for the NAME argument to `pathconf' and `fpathconf'. */ +#define _PC_LINK_MAX 0 +#define _PC_MAX_CANON 1 +#define _PC_MAX_INPUT 2 +#define _PC_NAME_MAX 3 +#define _PC_PATH_MAX 4 +#define _PC_PIPE_BUF 5 +#define _PC_CHOWN_RESTRICTED 6 +#define _PC_NO_TRUNC 7 +#define _PC_VDISABLE 8 + +/* Values for the argument to `sysconf'. */ +#define _SC_ARG_MAX 0 +#define _SC_CHILD_MAX 1 +#define _SC_CLK_TCK 2 +#define _SC_NGROUPS_MAX 3 +#define _SC_OPEN_MAX 4 +#define _SC_JOB_CONTROL 5 +#define _SC_SAVED_IDS 6 +#define _SC_VERSION 7 +#define _SC_PASS_MAX 8 +#define _SC_XOPEN_VERSION 9 +#define _SC_TZNAME_MAX 666 /* Not handled by SCO's system call. */ + +#ifdef __USE_POSIX2 +/* Values for the NAME argument to `confstr'. */ +enum + { + _CS_PATH /* The default search path. */ + }; +#endif diff --git a/sysdeps/unix/sysv/sco3.2.4/direct.h b/sysdeps/unix/sysv/sco3.2.4/direct.h new file mode 100644 index 0000000000..b3eaa54c8b --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/direct.h @@ -0,0 +1,22 @@ +#ifndef MAXNAMLEN +#define MAXNAMLEN 512 +#endif +#define DIRBUF 1048 /* minimum buffer size for call to getdents */ + +struct direct + { + unsigned short int d_fileno; + short int d_pad; + long int d_off; + unsigned short int d_reclen; + char d_name[1]; /* Actually longer. */ + }; + +#include <stddef.h> + +/* We calculate the length of the name by taking the length of the whole + `struct direct' record, subtracting the size of everything before the + name, and subtracting one for the terminating null. */ + +#define D_NAMLEN(d) \ + ((d)->d_reclen - offsetof (struct direct, d_name) - 1) diff --git a/sysdeps/unix/sysv/sco3.2.4/getgroups.c b/sysdeps/unix/sysv/sco3.2.4/getgroups.c new file mode 100644 index 0000000000..68966bc5df --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/getgroups.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <unistd.h> +#include <limits.h> +#include <alloca.h> + +extern int __sco_getgroups __P ((int size, unsigned short int *list)); + +int +DEFUN(__getgroups, (size, list), int size AND gid_t *list) +{ + int i; + unsigned short int *shortlist; + + if (size <= 0) + return __sco_getgroups (size, NULL); + + shortlist = __alloca (size * sizeof (*shortlist)); + + size = __sco_getgroups (size, shortlist); + for (i = 0; i < size; ++i) + list[i] = shortlist[i]; + + return size; +} + +weak_alias (__getgroups, getgroups) diff --git a/sysdeps/unix/sysv/sco3.2.4/getpgid.c b/sysdeps/unix/sysv/sco3.2.4/getpgid.c new file mode 100644 index 0000000000..3b47d9dee2 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/getpgid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/getpgid.c> diff --git a/sysdeps/unix/sysv/sco3.2.4/pathconf.S b/sysdeps/unix/sysv/sco3.2.4/pathconf.S new file mode 100644 index 0000000000..1c4dd9571c --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/pathconf.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pathconf, 2) + ret + +weak_alias (__pathconf, pathconf) diff --git a/sysdeps/unix/sysv/sco3.2.4/pgrpsys.S b/sysdeps/unix/sysv/sco3.2.4/pgrpsys.S new file mode 100644 index 0000000000..2c7d994c28 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/pgrpsys.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/pgrpsys.S> diff --git a/sysdeps/unix/sysv/sco3.2.4/pipestream.c b/sysdeps/unix/sysv/sco3.2.4/pipestream.c new file mode 100644 index 0000000000..b768e62043 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/pipestream.c @@ -0,0 +1,3 @@ +/* SCO 3.2v4 does have `waitpid'. + Avoid unix/pipestream.c, which says we don't. */ +#include <sysdeps/posix/pipestream.c> diff --git a/sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S b/sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S new file mode 100644 index 0000000000..e68c300821 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__sco_getgroups, getgroups, 2) + ret diff --git a/sysdeps/unix/sysv/sco3.2.4/setpgid.c b/sysdeps/unix/sysv/sco3.2.4/setpgid.c new file mode 100644 index 0000000000..cc9c4cd61b --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/setpgid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/setpgid.c> diff --git a/sysdeps/unix/sysv/sco3.2.4/setsid.c b/sysdeps/unix/sysv/sco3.2.4/setsid.c new file mode 100644 index 0000000000..6337652552 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/setsid.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/setsid.c> diff --git a/sysdeps/unix/sysv/sco3.2.4/sigaction.S b/sysdeps/unix/sysv/sco3.2.4/sigaction.S new file mode 100644 index 0000000000..dc1bb418d6 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sigaction.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.globl C_SYMBOL_NAME(__sigreturn) + +ENTRY (__sigaction) + movl $C_SYMBOL_NAME(__sigreturn), %ecx + DO_CALL (sigaction, 3) + jb syscall_error + ret + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/unix/sysv/sco3.2.4/sigaction.h b/sysdeps/unix/sysv/sco3.2.4/sigaction.h new file mode 100644 index 0000000000..c6344f0810 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sigaction.h @@ -0,0 +1,39 @@ +/* The proper definitions for SCO's sigaction. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Structure describing the action to be taken when a signal arrives. */ +struct sigaction + { + /* Signal handler. */ + __sighandler_t sa_handler; + + /* Additional set of signals to be blocked. */ + __sigset_t sa_mask; + + /* Special flags. */ + int sa_flags; + }; + +/* Bits in `sa_flags'. */ +#define SA_NOCLDSTOP 0x01 /* Don't send SIGCHLD when children stop. */ + +/* Values for the HOW argument to `sigprocmask'. */ +#define SIG_SETMASK 0 /* Set the set of blocked signals. */ +#define SIG_BLOCK 1 /* Block signals. */ +#define SIG_UNBLOCK 2 /* Unblock signals. */ diff --git a/sysdeps/unix/sysv/sco3.2.4/sigpending.S b/sysdeps/unix/sysv/sco3.2.4/sigpending.S new file mode 100644 index 0000000000..bc05b2ef6e --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sigpending.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sigpending, 1) + ret diff --git a/sysdeps/unix/sysv/sco3.2.4/sigprocmask.S b/sysdeps/unix/sysv/sco3.2.4/sigprocmask.S new file mode 100644 index 0000000000..ff199158a4 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sigprocmask.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigprocmask, 3) + ret + +weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/unix/sysv/sco3.2.4/sigsuspend.S b/sysdeps/unix/sysv/sco3.2.4/sigsuspend.S new file mode 100644 index 0000000000..9bce3878fd --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sigsuspend.S @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/sysv4/sigsuspend.S> diff --git a/sysdeps/unix/sysv/sco3.2.4/syscall.h b/sysdeps/unix/sysv/sco3.2.4/syscall.h new file mode 100644 index 0000000000..316bd0d0ce --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/syscall.h @@ -0,0 +1,107 @@ +/* From Scott Bartram. */ + +#ifndef _SYSCALL_H +#define _SYSCALL_H + +#define SYS_access 33 +#define SYS_acct 51 +#define SYS_advfs 70 +#define SYS_alarm 27 +#define SYS_break 17 +#define SYS_brk 17 +#define SYS_chdir 12 +#define SYS_chmod 15 +#define SYS_chown 16 +#define SYS_chroot 61 +#define SYS_chsize 0x0a28 +#define SYS_close 6 +#define SYS_creat 8 +#define SYS_dup 41 +#define SYS_exec 11 +#define SYS_exece 59 +#define SYS_exit 1 +#define SYS_fcntl 62 +#define SYS_fork 2 +#define SYS_fpathconf 0x2f28 +#define SYS_fstat 28 +#define SYS_fstatfs 38 +#define SYS_ftime 0x0b28 +#define SYS_getdents 81 +#define SYS_getgid 47 +#define SYS_getgroups 0x2b28 +#define SYS_getitimer 0x3728 +#define SYS_getmsg 85 +#define SYS_getpid 20 +#define SYS_getuid 24 +#define SYS_gtty 32 +#define SYS_ioctl 54 +#define SYS_kill 37 +#define SYS_link 9 +#define SYS_lock 45 +#define SYS_lseek 19 +#define SYS_lstat 91 +#define SYS_mkdir 80 +#define SYS_mknod 14 +#define SYS_mount 21 +#define SYS_msgsys 49 +#define SYS_nap 0x0c28 +#define SYS_nice 34 +#define SYS_open 5 +#define SYS_pathconf 0x2e28 +#define SYS_pause 29 +#define SYS_pgrpsys 39 +#define SYS_pipe 42 +#define SYS_plock 45 +#define SYS_poll 87 +#define SYS_prof 44 +#define SYS_ptrace 26 +#define SYS_putmsg 86 +#define SYS_rdebug 76 +#define SYS_read 3 +#define SYS_readlink 92 +#define SYS_rename 0x3028 +#define SYS_rfstart 74 +#define SYS_rfstop 77 +#define SYS_rfsys 78 +#define SYS_rmdir 79 +#define SYS_rmount 72 +#define SYS_rumount 73 +#define SYS_seek 19 +#define SYS_select 0x2428 +#define SYS_semsys 53 +#define SYS_setgid 46 +#define SYS_setgroups 0x2c28 +#define SYS_setitimer 0x3828 +#define SYS_setpgrp 39 +#define SYS_setuid 23 +#define SYS_shmsys 52 +#define SYS_sigaction 0x2728 +#define SYS_signal 48 +#define SYS_sigpending 0x2928 +#define SYS_sigprocmask 0x2828 +#define SYS_sigsuspend 0x2a28 +#define SYS_stat 18 +#define SYS_statfs 35 +#define SYS_stime 25 +#define SYS_stty 31 +#define SYS_symlink 90 +#define SYS_sync 36 +#define SYS_sys3b 50 +#define SYS_sysacct 51 +#define SYS_sysconf 0x2d28 +#define SYS_sysfs 84 +#define SYS_sysi86 50 +#define SYS_time 13 +#define SYS_times 43 +#define SYS_uadmin 55 +#define SYS_ulimit 63 +#define SYS_umask 60 +#define SYS_umount 22 +#define SYS_unadvfs 71 +#define SYS_unlink 10 +#define SYS_utime 30 +#define SYS_utssys 57 +#define SYS_wait 7 +#define SYS_write 4 + +#endif diff --git a/sysdeps/unix/sysv/sco3.2.4/sysconf.S b/sysdeps/unix/sysv/sco3.2.4/sysconf.S new file mode 100644 index 0000000000..631e5e977a --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/sysconf.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#include <confname.h> + +.globl __tzname_max +ENTRY (__sysconf) + cmpl $_SC_TZNAME_MAX, 4(%esp) /* Is the arg _SC_TZNAME_MAX? */ + je tzname + DO_CALL (sysconf, 1) /* No; use the SCO system call. */ + ret +tzname: jmp C_SYMBOL_NAME(__tzname_max) /* Yes; bounce to __tzname_max (). */ + +weak_alias (__sysconf, sysconf) diff --git a/sysdeps/unix/sysv/sco3.2.4/system.c b/sysdeps/unix/sysv/sco3.2.4/system.c new file mode 100644 index 0000000000..06dc066b88 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/system.c @@ -0,0 +1,10 @@ +/* SCO has a bug where `waitpid' will never return if SIGCHLD is blocked. + They have acknowledged that this is a bug but I have not seen nor heard + of any forthcoming fix. */ + +#define WAITPID_CANNOT_BLOCK_SIGCHLD + +/* SCO 3.2v4 does have `waitpid'. + Avoid unix/system.c, which says we don't. */ + +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/sysv/sco3.2.4/uname.S b/sysdeps/unix/sysv/sco3.2.4/uname.S new file mode 100644 index 0000000000..a22d18a3e6 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/uname.S @@ -0,0 +1,42 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. + Contributed by Scott Bartram. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* + before lcall, stack contents should be: + + 4(%esp) -> name + 8(%esp) -> unspecified + 12(%esp) -> 0 + */ + +ENTRY (uname) + pushl $0x0 /* Push the discriminator flag. */ + pushl $0x0 /* Push dummy placeholder. */ + pushl 12(%esp,1) /* Push NAME (ptr to struct utsname) */ + subl $0x4, %esp /* Adjust stack pointer. */ + DO_CALL (utssys, 3) + jb error /* Test for error. */ + addl $0x10, %esp /* Adjust the stack pointer. */ + xorl %eax, %eax /* Clear return value. */ + ret +error: addl $0x10, %esp /* Adjust the stack pointer. */ + jmp syscall_error diff --git a/sysdeps/unix/sysv/sco3.2.4/waitpid.S b/sysdeps/unix/sysv/sco3.2.4/waitpid.S new file mode 100644 index 0000000000..523ef37e53 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2.4/waitpid.S @@ -0,0 +1,36 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +ENTRY (__waitpid) + /* The `waitpid' system call is distinguished from plain + `wait' by setting lots of bits in the processor flags. */ + pushfl /* Push the flags word. */ + popl %eax /* Pop it into the accumulator. */ + orl $0x8c4, %eax /* Set lots of bits. */ + pushl %eax /* Push the new flags word. */ + popfl /* Pop it into the flags. */ + DO_CALL (wait, 2) + movl 8(%esp), scratch /* Put status pointer in scratch register. */ + testl scratch, scratch /* Is it non-nil? */ + je null + movl r1, (scratch) /* Yes; store the status there. */ +null: ret + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/unix/sysv/sco3.2/Dist b/sysdeps/unix/sysv/sco3.2/Dist new file mode 100644 index 0000000000..60fab2bdea --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2/Dist @@ -0,0 +1 @@ +__fltused.c diff --git a/sysdeps/unix/sysv/sco3.2/Makefile b/sysdeps/unix/sysv/sco3.2/Makefile new file mode 100644 index 0000000000..1be24e85e3 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2/Makefile @@ -0,0 +1,23 @@ +# Copyright (C) 1993 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),misc) + +sysdep_routines := $(sysdep_routines) __fltused + +endif diff --git a/sysdeps/unix/sysv/sco3.2/__fltused.c b/sysdeps/unix/sysv/sco3.2/__fltused.c new file mode 100644 index 0000000000..5d1d67f0b1 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2/__fltused.c @@ -0,0 +1,3 @@ +/* Code compiled by the SCO compiler apparently likes this to be defined. */ + +int __fltused = 1; diff --git a/sysdeps/unix/sysv/sco3.2/local_lim.h b/sysdeps/unix/sysv/sco3.2/local_lim.h new file mode 100644 index 0000000000..6d6c3b0ac8 --- /dev/null +++ b/sysdeps/unix/sysv/sco3.2/local_lim.h @@ -0,0 +1,37 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _LOCAL_LIM_H +#define _LOCAL_LIM_H 1 + +#define NGROUPS_MAX 8 /* Maximum number of supplementary groups. */ +#define ARG_MAX 5120 +#define CHILD_MAX 25 +#define OPEN_MAX 60 +#define LINK_MAX 1000 +#define MAX_CANON 256 + +/* For SVR3, this is 14. For SVR4, it is 255, at least on ufs + file systems, even though the System V limits.h incorrectly + defines it as 14. Giving it a value which is too large + is harmless (it is a maximum). */ +#define NAME_MAX 255 + +#define PATH_MAX 1024 + +#endif /* local_lim.h */ diff --git a/sysdeps/unix/sysv/setrlimit.c b/sysdeps/unix/sysv/setrlimit.c new file mode 100644 index 0000000000..be4158e16e --- /dev/null +++ b/sysdeps/unix/sysv/setrlimit.c @@ -0,0 +1,58 @@ +/* setrlimit function for systems with ulimit system call (SYSV). + +Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This only implements those functions which are available via ulimit. */ + +#include <ansidecl.h> +#include <sys/resource.h> +#include <stddef.h> +#include <errno.h> + +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int +DEFUN(setrlimit, (resource, rlimits), + enum __rlimit_resource resource AND struct rlimit *rlimits) +{ + if (rlimits == NULL) + { + errno = EINVAL; + return -1; + } + + switch (resource) + { + case RLIMIT_FSIZE: + return __ulimit(2, rlimits->rlim_cur); + + case RLIMIT_DATA: + case RLIMIT_CPU: + case RLIMIT_STACK: + case RLIMIT_CORE: + case RLIMIT_RSS: + errno = ENOSYS; + return -1; + + default: + errno = EINVAL; + return -1; + } +} diff --git a/sysdeps/unix/sysv/settimeofday.c b/sysdeps/unix/sysv/settimeofday.c new file mode 100644 index 0000000000..1217c6beee --- /dev/null +++ b/sysdeps/unix/sysv/settimeofday.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/time.h> + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +int +DEFUN(__settimeofday, (tv, tz), + CONST struct timeval *tv AND CONST struct timezone *tz) +{ + time_t when; + + if (tv == NULL) + { + errno = EINVAL; + return -1; + } + + if (tz != NULL || tv->tv_usec % 1000000 != 0) + { + errno = ENOSYS; + return -1; + } + + when = tv->tv_sec + (tv->tv_usec / 1000000); + return stime (&when); +} + +weak_alias (__settimeofday, settimeofday) diff --git a/sysdeps/unix/sysv/sigaction.c b/sysdeps/unix/sysv/sigaction.c new file mode 100644 index 0000000000..ebb42cf756 --- /dev/null +++ b/sysdeps/unix/sysv/sigaction.c @@ -0,0 +1,83 @@ +/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> + + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +DEFUN(__sigaction, (sig, act, oact), + int sig AND CONST struct sigaction *act AND struct sigaction *oact) +{ + sighandler_t handler; + int save; + + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return -1; + } + + if (act == NULL) + { + if (oact == NULL) + return 0; + /* Race condition, but this is the only way to do it. */ + handler = signal (sig, SIG_IGN); + if (handler == SIG_ERR) + return -1; + save = errno; + (void) signal (sig, handler); + errno = save; + } + else + { + int i; + + if (act->sa_flags != 0) + { + unimplemented: + errno = ENOSYS; + return -1; + } + + for (i = 1; i < NSIG; ++i) + if (__sigismember (&act->sa_mask, i)) + goto unimplemented; + + handler = signal (sig, act->sa_handler); + if (handler == SIG_ERR) + return -1; + } + + if (oact != NULL) + { + oact->sa_handler = handler; + __sigemptyset (&oact->sa_mask); + oact->sa_flags = 0; + } + + return 0; +} + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/unix/sysv/signal.S b/sysdeps/unix/sysv/signal.S new file mode 100644 index 0000000000..5230b3463d --- /dev/null +++ b/sysdeps/unix/sysv/signal.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (signal, 2) + ret diff --git a/sysdeps/unix/sysv/signum.h b/sysdeps/unix/sysv/signum.h new file mode 100644 index 0000000000..e28a62a287 --- /dev/null +++ b/sysdeps/unix/sysv/signum.h @@ -0,0 +1,56 @@ +/* Signal number definitions. System V version. +Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* This file defines the fake signal functions and signal + number constants for System V release 3. */ + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGEMT 7 /* EMT trap (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call (4.2 BSD)*/ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define SIGCHLD 18 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGPWR 19 /* Power failure restart (System V). */ + +#endif /* <signal.h> included. */ + +#define _NSIG 20 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/sysv/statbuf.h b/sysdeps/unix/sysv/statbuf.h new file mode 100644 index 0000000000..aa2cdfedcd --- /dev/null +++ b/sysdeps/unix/sysv/statbuf.h @@ -0,0 +1,61 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H +#define _STATBUF_H + +struct stat + { + short int st_dev; + unsigned short int st_ino; + unsigned short int st_mode; + short int st_nlink; + unsigned short int st_uid; + unsigned short int st_gid; + short int st_rdev; + long int st_size; + long int st_atime; + long int st_mtime; + long int st_ctime; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* These don't actually exist on System V, but having them doesn't hurt. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#endif /* statbuf.h */ diff --git a/sysdeps/unix/sysv/stime.S b/sysdeps/unix/sysv/stime.S new file mode 100644 index 0000000000..0ffb6bbb7c --- /dev/null +++ b/sysdeps/unix/sysv/stime.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (stime, 1) + ret diff --git a/sysdeps/unix/sysv/sysd-stdio.c b/sysdeps/unix/sysv/sysd-stdio.c new file mode 100644 index 0000000000..35dae27a37 --- /dev/null +++ b/sysdeps/unix/sysv/sysd-stdio.c @@ -0,0 +1,2 @@ +#define EINTR_REPEAT +#include <../sysdeps/generic/sysd-stdio.c> diff --git a/sysdeps/unix/sysv/sysv4/Dist b/sysdeps/unix/sysv/sysv4/Dist new file mode 100644 index 0000000000..f603d8b8ff --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/Dist @@ -0,0 +1,7 @@ +sysconfig.h +sysconfig.S +pgrpsys.S +__waitid.S +siginfo.h +__getpgid.c __setpgid.c +sysinfo.S diff --git a/sysdeps/unix/sysv/sysv4/Implies b/sysdeps/unix/sysv/sysv4/Implies new file mode 100644 index 0000000000..953822ea48 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/Implies @@ -0,0 +1,3 @@ +# The directory unix/common contains things which are common to both BSD +# and SVR4. +unix/common diff --git a/sysdeps/unix/sysv/sysv4/Makefile b/sysdeps/unix/sysv/sysv4/Makefile new file mode 100644 index 0000000000..0c149da85c --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/Makefile @@ -0,0 +1,36 @@ +# Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),posix) + +sysdep_routines := $(sysdep_routines) sysconfig pgrpsys __waitid + +endif + + +ifeq ($(subdir),signal) + +sysdep_routines := $(sysdep_routines) sys-sig + +endif + +ifeq ($(subdir),misc) + +sysdep_routines := $(sysdep_routines) sysinfo + +endif diff --git a/sysdeps/unix/sysv/sysv4/__getpgid.c b/sysdeps/unix/sysv/sysv4/__getpgid.c new file mode 100644 index 0000000000..76a6e80f59 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/__getpgid.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Get the process group ID of process PID. */ +int +DEFUN(__getpgid, (pid), pid_t pid) +{ + return __pgrpsys (4, pid); +} diff --git a/sysdeps/unix/sysv/sysv4/__setpgid.c b/sysdeps/unix/sysv/sysv4/__setpgid.c new file mode 100644 index 0000000000..594e4e9fe6 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/__setpgid.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Get the process group ID of process PID. */ +int +DEFUN(__setpgid, (pid, pgid), pid_t pid AND pid_t pgid) +{ + return __pgrpsys (5, pid, pgid); +} diff --git a/sysdeps/unix/sysv/sysv4/__waitid.S b/sysdeps/unix/sysv/sysv4/__waitid.S new file mode 100644 index 0000000000..845bec85e2 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/__waitid.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* XXX */ +#define SYS_waitid SYS_waitsys + +SYSCALL__ (waitid, 3) + ret diff --git a/sysdeps/unix/sysv/sysv4/dup2.c b/sysdeps/unix/sysv/sysv4/dup2.c new file mode 100644 index 0000000000..c7015fce7e --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/dup2.c @@ -0,0 +1,4 @@ +/* SVR4 uses the POSIX dup2. */ +#include <sysdeps/posix/__dup2.c> + +weak_alias (__dup2, dup2) diff --git a/sysdeps/unix/sysv/sysv4/fchdir.S b/sysdeps/unix/sysv/sysv4/fchdir.S new file mode 100644 index 0000000000..ef11d55bc0 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/fchdir.S @@ -0,0 +1,2 @@ +/* SVR4 uses the BSD 4.4 fchdir(2) syscall. */ +#include <sysdeps/unix/bsd/bsd4.4/fchdir.S> diff --git a/sysdeps/unix/sysv/sysv4/ftruncate.c b/sysdeps/unix/sysv/sysv4/ftruncate.c new file mode 100644 index 0000000000..45f2614257 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/ftruncate.c @@ -0,0 +1,37 @@ +/* ftruncate for SVR4 using the fcntl F_FREESP command. +Copyright (C) 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +/* Truncate the file FD refers to to LENGTH bytes. */ +int +DEFUN(ftruncate, (fd, length), + int fd AND off_t length) +{ + struct flock fl; + + memset (&fl, 0, sizeof fl); + fl.l_type = F_WRLCK; + fl.l_start = length; + return fcntl (fd, F_FREESP, &fl); +} diff --git a/sysdeps/unix/sysv/sysv4/getdtsz.c b/sysdeps/unix/sysv/sysv4/getdtsz.c new file mode 100644 index 0000000000..c1ae6108fb --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/getdtsz.c @@ -0,0 +1,2 @@ +/* Solaris uses sysconf ala POSIX.1. */ +#include <sysdeps/posix/getdtsz.c> diff --git a/sysdeps/unix/sysv/sysv4/gethostname.c b/sysdeps/unix/sysv/sysv4/gethostname.c new file mode 100644 index 0000000000..cce1149e7f --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/gethostname.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/systeminfo.h> + +extern int __sysinfo __P ((int command, char *buf, long count)); + +int +DEFUN(__gethostname, (name, namelen), char *name AND size_t namelen) +{ + return __sysinfo (SI_HOSTNAME, name, namelen); +} + +weak_alias (__gethostname, gethostname) diff --git a/sysdeps/unix/sysv/sysv4/getpagesize.c b/sysdeps/unix/sysv/sysv4/getpagesize.c new file mode 100644 index 0000000000..6119640758 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/getpagesize.c @@ -0,0 +1,2 @@ +/* Solaris uses sysconf ala POSIX.1. */ +#include <sysdeps/posix/getpagesize.c> diff --git a/sysdeps/unix/sysv/sysv4/getpgid.c b/sysdeps/unix/sysv/sysv4/getpgid.c new file mode 100644 index 0000000000..309e2f11e4 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/getpgid.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Get the process group ID of process PID. */ +int +DEFUN(__getpgid, (pid), pid_t pid) +{ + return __pgrpsys (4, pid); +} + +weak_alias (__getpgid, getpgid) diff --git a/sysdeps/unix/sysv/sysv4/i386/Dist b/sysdeps/unix/sysv/sysv4/i386/Dist new file mode 100644 index 0000000000..69d16ac6bf --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/Dist @@ -0,0 +1 @@ +sys-sig.S diff --git a/sysdeps/unix/sysv/sysv4/i386/Makefile b/sysdeps/unix/sysv/sysv4/i386/Makefile new file mode 100644 index 0000000000..56f0a37de1 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),signal) +sysdep_routines := $(sysdep_routines) sys-sig +endif diff --git a/sysdeps/unix/sysv/sysv4/i386/fstat.S b/sysdeps/unix/sysv/sysv4/i386/fstat.S new file mode 100644 index 0000000000..11743b3fc3 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/fstat.S @@ -0,0 +1,37 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* In SVR4 the `stat' call is actually done by the `xstat' system call, + which takes an additional first argument giving a version number for + `struct stat'. Likewise for `fstat' and `lstat' there are `fxstat' and + `lxstat' system calls. This macro gives the SVR4 version number that + corresponds to the definition of `struct stat' in <statbuf.h>. */ +#define _STAT_VER 2 + +.globl syscall_error +ENTRY (__fstat) + popl %eax /* Pop return address into %eax. */ + pushl $_STAT_VER /* Push extra first arg to syscall. */ + pushl %eax /* Push back the return address. */ + DO_CALL (fxstat, 3) /* Do the syscall. */ + jb syscall_error /* Check for error. */ + ret /* Return success. */ + +weak_alias (__fstat, fstat) diff --git a/sysdeps/unix/sysv/sysv4/i386/lstat.S b/sysdeps/unix/sysv/sysv4/i386/lstat.S new file mode 100644 index 0000000000..52ffdbadfd --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/lstat.S @@ -0,0 +1,37 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* In SVR4 the `stat' call is actually done by the `xstat' system call, + which takes an additional first argument giving a version number for + `struct stat'. Likewise for `fstat' and `lstat' there are `fxstat' and + `lxstat' system calls. This macro gives the SVR4 version number that + corresponds to the definition of `struct stat' in <statbuf.h>. */ +#define _STAT_VER 2 + +.globl syscall_error +ENTRY (__lstat) + popl %eax /* Pop return address into %eax. */ + pushl $_STAT_VER /* Push extra first arg to syscall. */ + pushl %eax /* Push back the return address. */ + DO_CALL (lxstat, 3) /* Do the syscall. */ + jb syscall_error /* Check for error. */ + ret /* Return success. */ + +weak_alias (__lstat, lstat) diff --git a/sysdeps/unix/sysv/sysv4/i386/mknod.S b/sysdeps/unix/sysv/sysv4/i386/mknod.S new file mode 100644 index 0000000000..21f932c921 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/mknod.S @@ -0,0 +1,36 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* In SVR4 the `mknod' call is actually done by the `xmknod' system call, + which takes an additional first argument giving a version number for + the interface. This macro gives the SVR4 version number that + corresponds to the modern interface. */ +#define _MKNOD_VER 2 + +.globl syscall_error +ENTRY (__mknod) + popl %eax /* Pop return address into %eax. */ + pushl $_MKNOD_VER /* Push extra first arg to syscall. */ + pushl %eax /* Push back the return address. */ + DO_CALL (xmknod, 3) /* Do the syscall. */ + jb syscall_error /* Check for error. */ + ret /* Return success. */ + +weak_alias (__mknod, mknod) diff --git a/sysdeps/unix/sysv/sysv4/i386/stat.S b/sysdeps/unix/sysv/sysv4/i386/stat.S new file mode 100644 index 0000000000..3a5107c267 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/stat.S @@ -0,0 +1,37 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* In SVR4 the `stat' call is actually done by the `xstat' system call, + which takes an additional first argument giving a version number for + `struct stat'. Likewise for `fstat' and `lstat' there are `fxstat' and + `lxstat' system calls. This macro gives the SVR4 version number that + corresponds to the definition of `struct stat' in <statbuf.h>. */ +#define _STAT_VER 2 + +.globl syscall_error +ENTRY (__stat) + popl %eax /* Pop return address into %eax. */ + pushl $_STAT_VER /* Push extra first arg to syscall. */ + pushl %eax /* Push back the return address. */ + DO_CALL (xstat, 3) /* Do the syscall. */ + jb syscall_error /* Check for error. */ + ret /* Return success. */ + +weak_alias (__stat, stat) diff --git a/sysdeps/unix/sysv/sysv4/i386/statbuf.h b/sysdeps/unix/sysv/sysv4/i386/statbuf.h new file mode 100644 index 0000000000..6f1bfed850 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/statbuf.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H +#define _STATBUF_H + +#include <gnu/types.h> + +/* Structure describing file characteristics. */ +struct stat + { + unsigned long st_dev; /* Device. */ + long st_filler1[3]; + unsigned long st_ino; /* File serial number. */ + unsigned long st_mode; /* File mode. */ + unsigned long st_nlink; /* Link count. */ + long st_uid; /* User ID of the file's owner. */ + long st_gid; /* Group ID of the file's group.*/ + unsigned long st_rdev; /* Device number, if device. */ + long st_filler2[2]; + + long st_size; /* Size of file, in bytes. */ + /* SVR4 added this extra long to allow for expansion of off_t. */ + long st_filler3; + + long st_atime; /* Time of last access. */ + unsigned long st_atime_usec; + long st_mtime; /* Time of last modification. */ + unsigned long st_mtime_usec; + long st_ctime; /* Time of last status change. */ + unsigned long st_ctime_usec; + + long st_blksize; /* Optimal block size for I/O. */ +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + + long st_blocks; /* Number of 512-byte blocks allocated. */ + char st_fstype[16]; /* The type of this filesystem. */ + int st_aclcnt; + unsigned long st_level; + unsigned long st_flags; + unsigned long st_cmwlevel; + long st_filler4[4]; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* These don't actually exist on System V, but having them doesn't hurt. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#endif /* statbuf.h */ diff --git a/sysdeps/unix/sysv/sysv4/i386/sys-sig.S b/sysdeps/unix/sysv/sysv4/i386/sys-sig.S new file mode 100644 index 0000000000..58430e494f --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/sys-sig.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.globl C_SYMBOL_NAME(__sigreturn) + +ENTRY (__sigaction_syscall) + movl $C_SYMBOL_NAME(__sigreturn), %edx + DO_CALL (sigaction, 3) + jb syscall_error + ret + +PSEUDO (__context_syscall, context, 2) + ret diff --git a/sysdeps/unix/sysv/sysv4/i386/sysdep.h b/sysdeps/unix/sysv/sysv4/i386/sysdep.h new file mode 100644 index 0000000000..1e0cd69f74 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/sysdep.h @@ -0,0 +1,38 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysv/i386/sysdep.h> + +/* In SVR4 some system calls can fail with the error ERESTART, + and this means the call should be retried. */ + +#ifndef _ERRNO_H +#define _ERRNO_H +#endif +#include <errnos.h> + +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jae noerror; \ + cmpb $ERESTART, %al; \ + je C_SYMBOL_NAME (name); \ + jmp syscall_error; \ + noerror: diff --git a/sysdeps/unix/sysv/sysv4/i386/vfork.S b/sysdeps/unix/sysv/sysv4/i386/vfork.S new file mode 100644 index 0000000000..bbe99fbc41 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/i386/vfork.S @@ -0,0 +1 @@ +#include <sysdeps/unix/bsd/i386/vfork.S> diff --git a/sysdeps/unix/sysv/sysv4/pgrpsys.S b/sysdeps/unix/sysv/sysv4/pgrpsys.S new file mode 100644 index 0000000000..dcfb487e54 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/pgrpsys.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (pgrpsys, 3) + ret diff --git a/sysdeps/unix/sysv/sysv4/pipestream.c b/sysdeps/unix/sysv/sysv4/pipestream.c new file mode 100644 index 0000000000..6a32f9507c --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/pipestream.c @@ -0,0 +1,2 @@ +/* We deliberately avoid having NO_WAITPID set. */ +#include <sysdeps/posix/pipestream.c> diff --git a/sysdeps/unix/sysv/sysv4/setegid.S b/sysdeps/unix/sysv/sysv4/setegid.S new file mode 100644 index 0000000000..f8fd7633a5 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/setegid.S @@ -0,0 +1,2 @@ +/* SVR4 uses the BSD 4.4 setegid() system call. */ +#include <sysdeps/unix/bsd/bsd4.4/setegid.S> diff --git a/sysdeps/unix/sysv/sysv4/seteuid.S b/sysdeps/unix/sysv/sysv4/seteuid.S new file mode 100644 index 0000000000..4ff110610f --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/seteuid.S @@ -0,0 +1,2 @@ +/* SVR4 uses the BSD 4.4 seteuid() system call. */ +#include <sysdeps/unix/bsd/bsd4.4/seteuid.S> diff --git a/sysdeps/unix/sysv/sysv4/sethostname.c b/sysdeps/unix/sysv/sysv4/sethostname.c new file mode 100644 index 0000000000..4cebc456e1 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sethostname.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/systeminfo.h> + +extern int __sysinfo __P ((int command, const char *buf, long count)); + +int +DEFUN(sethostname, (name, namelen), const char *name AND size_t namelen) +{ + return __sysinfo (SI_SET_HOSTNAME, name, namelen); +} diff --git a/sysdeps/unix/sysv/sysv4/setpgid.c b/sysdeps/unix/sysv/sysv4/setpgid.c new file mode 100644 index 0000000000..b9e06dc719 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/setpgid.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Set the process group ID of the process matching PID to PGID. + If PID is zero, the current process's process group ID is set. + If PGID is zero, the process ID of the process is used. */ +int +DEFUN(__setpgid, (pid, pgid), int pid AND int pgid) +{ + return __pgrpsys (5, pid, pgid); +} + +weak_alias (__setpgid, setpgid) +weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/unix/sysv/sysv4/setsid.c b/sysdeps/unix/sysv/sysv4/setsid.c new file mode 100644 index 0000000000..f0d6c8a4cd --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/setsid.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <unistd.h> + +extern int __pgrpsys __P ((int type, ...)); + +/* Create a new session with the calling process as its leader. + The process group IDs of the session and the calling process + are set to the process ID of the calling process, which is returned. */ +int +DEFUN_VOID(__setsid) +{ + return __pgrpsys (3); +} + +weak_alias (__setsid, setsid) diff --git a/sysdeps/unix/sysv/sysv4/sigaction.c b/sysdeps/unix/sysv/sysv4/sigaction.c new file mode 100644 index 0000000000..68fd7a1846 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigaction.c @@ -0,0 +1,79 @@ +/* Copyright (C) 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <signal.h> +#include <stddef.h> + +static __sighandler_t user_handlers[NSIG]; + +extern int __context_syscall (int, struct sigcontext *); +extern int __sigaction_syscall (int, + const struct sigaction *, struct sigaction *); + +static void +trampoline (int sig, int code, struct sigcontext *context) +{ + (*(void (*) (int, int, struct sigcontext *)) user_handlers[sig]) + (sig, code, context); + __context_syscall (1, context); +} + +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int +DEFUN(__sigaction, (sig, act, oact), + int sig AND CONST struct sigaction *act AND struct sigaction *oact) +{ + struct sigaction myact; + __sighandler_t ohandler; + + if (sig <= 0 || sig >= NSIG) + { + errno = EINVAL; + return -1; + } + + ohandler = user_handlers[sig]; + + if (act != NULL) + { + user_handlers[sig] = act->sa_handler; + if (act->sa_handler != SIG_DFL && act->sa_handler != SIG_IGN) + { + myact = *act; + act = &myact; + act->sa_handler = (__sighandler_t) trampoline; + } + } + + if (__sigaction_syscall (sig, act, oact) < 0) + { + /* The syscall got an error. Restore the old handler and return -1. */ + user_handlers[sig] = ohandler; + return -1; + } + + if (oact != NULL && oact->sa_handler == (__sighandler_t) trampoline) + oact->sa_handler = ohandler; + + return 0; +} + +weak_alias (__sigaction, sigaction) diff --git a/sysdeps/unix/sysv/sysv4/sigaction.h b/sysdeps/unix/sysv/sysv4/sigaction.h new file mode 100644 index 0000000000..dbb31f1077 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigaction.h @@ -0,0 +1,51 @@ +/* The proper definitions for SVR4's sigaction. +Copyright (C) 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Structure describing the action to be taken when a signal arrives. */ +struct sigaction + { + /* Special flags. */ + int sa_flags; + + /* Signal handler. */ + __sighandler_t sa_handler; + + /* Additional set of signals to be blocked. */ + __sigset_t sa_mask; + + /* Padding. */ + int sa_resv[2]; + }; + +/* Bits in `sa_flags'. */ +#ifdef __USE_MISC +#define SA_ONSTACK 0x1 /* Take signal on signal stack. */ +#define SA_RESETHAND 0x2 /* Reset to SIG_DFL on entry to handler. */ +#define SA_RESTART 0x4 /* Don't restart syscall on signal return. */ +#define SA_SIGINFO 0x8 /* Provide additional info to the handler. */ +#define SA_NODEFER 0x10 /* Don't automatically block the signal when + its handler is being executed. */ +#define SA_NOCLDWAIT 0x10000 /* Don't save zombie processes. */ +#endif +#define SA_NOCLDSTOP 0x20000 /* Don't send SIGCHLD when children stop. */ + +/* Values for the HOW argument to `sigprocmask'. */ +#define SIG_BLOCK 1 /* Block signals. */ +#define SIG_UNBLOCK 2 /* Unblock signals. */ +#define SIG_SETMASK 3 /* Set the set of blocked signals. */ diff --git a/sysdeps/unix/sysv/sysv4/sigaltstack.S b/sysdeps/unix/sysv/sysv4/sigaltstack.S new file mode 100644 index 0000000000..e7e4060fba --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigaltstack.S @@ -0,0 +1,2 @@ +/* SVR4 uses the BSD 4.4 sigaltstack syscall. */ +#include <sysdeps/unix/bsd/bsd4.4/sigaltstk.S> diff --git a/sysdeps/unix/sysv/sysv4/siginfo.h b/sysdeps/unix/sysv/sysv4/siginfo.h new file mode 100644 index 0000000000..ce8dd35bf1 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/siginfo.h @@ -0,0 +1,58 @@ +/* Definitions of the siginfo structure. + Copyright (C) 1993, 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SIGINFO_H +#define _SIGINFO_H 1 + +#ifdef __USE_SVID +/* SVR4 puts a ton of other stuff in this structure. For now, we'll just + define the two things we really need out of it, and hope for the best. */ + +/* These define the different states a child can have on exit. + We need these to build the status return for things like waitpid. */ +#define EXITED 1 +#define KILLED 2 +#define CORED 3 +#define TRAPPED 4 +#define STOPPED 5 +#define CONTINUED 6 + +typedef struct __siginfo + { + int filler1; + + /* Code indicating child's status */ + int __code; + + int filler2; + + /* The PID of the child. */ + long __pid; + + int filler3; + + /* The child's status. */ + int __status; + + int filler4[26]; + + } __siginfo_t; + +#endif /* __USE_SVID */ +#endif /* siginfo.h */ diff --git a/sysdeps/unix/sysv/sysv4/signum.h b/sysdeps/unix/sysv/sysv4/signum.h new file mode 100644 index 0000000000..aa3dc7fa25 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/signum.h @@ -0,0 +1,66 @@ +/* Signal number definitions. SVR4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGEMT 7 /* EMT trap (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call (4.2 BSD)*/ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define SIGCHLD 18 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGPWR 19 /* Power failure restart (System V). */ +#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */ +#define SIGURG 21 /* Urgent condition on socket (4.2 BSD).*/ +#define SIGPOLL 22 /* Pollable event occurred (System V). */ +#define SIGIO SIGPOLL /* I/O now possible (4.2 BSD). */ +#define SIGSTOP 23 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 24 /* Keyboard stop (POSIX). */ +#define SIGCONT 25 /* Continue (POSIX). */ +#define SIGTTIN 26 /* Background read from tty (POSIX). */ +#define SIGTTOU 27 /* Background write to tty (POSIX). */ +#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */ +#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */ + +#endif /* <signal.h> included. */ + +#define _NSIG 32 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/sysv/sysv4/sigprocmask.S b/sysdeps/unix/sysv/sysv4/sigprocmask.S new file mode 100644 index 0000000000..51fddb0bee --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigprocmask.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sigprocmask, 3) + ret + +weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/unix/sysv/sysv4/sigset.h b/sysdeps/unix/sysv/sysv4/sigset.h new file mode 100644 index 0000000000..a007a43470 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigset.h @@ -0,0 +1,97 @@ +/* __sig_atomic_t, __sigset_t, and related definitions. SVR4 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SIGSET_H_types +#define _SIGSET_H_types 1 + +typedef int __sig_atomic_t; + +/* A `sigset_t' has a bit for each signal. */ +typedef struct + { + unsigned long int __sigbits[4]; + } __sigset_t; + +#endif /* ! _SIGSET_H_types */ + +/* We only want to define these functions if <signal.h> was actually + included; otherwise we were included just to define the types. Since we + are namespace-clean, it wouldn't hurt to define extra macros. But + trouble can be caused by functions being defined (e.g., any global + register vars declared later will cause compilation errors). */ + +#if !defined (_SIGSET_H_fns) && defined (_SIGNAL_H) +#define _SIGSET_H_fns 1 + +/* Return a mask that includes SIG only. */ +#define __sigmask(sig) (1 << ((sig) - 1)) + + +/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */ +#define __NSSBITS (sizeof (__sigset_t) * 8) +#define __SSELT(s) ((s) / __NSSBITS) +#define __SSMASK(s) (1 << ((s) % __NSSBITS)) + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +_EXTERN_INLINE int +__sigemptyset (__sigset_t *__set) +{ + __set->__sigbits[0] = __set->__sigbits[1] = + __set->__sigbits[2] = __set->__sigbits[3] = 0L; + return 0; +} + +_EXTERN_INLINE int +__sigfillset (__sigset_t *__set) +{ + /* SVR4 has a system call for `sigfillset' (!), and it only sets the bits + for signals [1,31]. Setting bits for unimplemented signals seems + harmless (and we will find out if it really is). */ + __set->__sigbits[0] = __set->__sigbits[1] = + __set->__sigbits[2] = __set->__sigbits[3] = -1; + return 0; +} + +_EXTERN_INLINE int +__sigaddset (__sigset_t *__set, int __sig) +{ + __set->__sigbits[__SSELT (__sig)] |= __SSMASK (__sig); + return 0; +} + +_EXTERN_INLINE int +__sigdelset (__sigset_t *__set, int __sig) +{ + __set->__sigbits[__SSELT (__sig)] &= ~__SSMASK (__sig); + return 0; +} + +_EXTERN_INLINE int +__sigismember (__const __sigset_t *__set, int __sig) +{ + if (__set->__sigbits[__SSELT (__sig)] & __SSMASK (__sig)) + return 1; + return 0; +} + +#endif /* ! _SIGSET_H_fns */ + diff --git a/sysdeps/unix/sysv/sysv4/sigsuspend.S b/sysdeps/unix/sysv/sysv4/sigsuspend.S new file mode 100644 index 0000000000..85d36017b8 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sigsuspend.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (sigsuspend, 1) + ret diff --git a/sysdeps/unix/sysv/sysv4/solaris2/Makefile b/sysdeps/unix/sysv/sysv4/solaris2/Makefile new file mode 100644 index 0000000000..3f86c46cc8 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/Makefile @@ -0,0 +1,6 @@ +# The linker supplied with Solaris looks in the current directory +# before searching others. Compiling the various programs that come +# along the way (e.g., glue-ctype) will fail because it'll try to link +# with the libc.a being *constructed* in $(objdir). As a work-around, +# we add this to each native-compile. +BUILD_CFLAGS := $(BUILD_CFLAGS) -L/lib diff --git a/sysdeps/unix/sysv/sysv4/solaris2/direct.h b/sysdeps/unix/sysv/sysv4/solaris2/direct.h new file mode 100644 index 0000000000..f9822dcbc5 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/direct.h @@ -0,0 +1,39 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _BSDDIR_H +#define _BSDDIR_H 1 + +#include <limits.h> + +/* This is the Solaris direct; it's the same as that in + sysdeps/unix/sysv/sysv4/direct.h, but it uses the length given by d_namlen, + since we can't reliably use tyhe sysv4/direct.h method of computing + the length. */ + +struct direct + { + unsigned long int d_fileno; + long int d_off; + unsigned short int d_reclen; + char d_name[NAME_MAX + 1]; + }; + +#define D_NAMLEN(d) (strlen ((d)->d_name)) + +#endif diff --git a/sysdeps/unix/sysv/sysv4/solaris2/fsync.S b/sysdeps/unix/sysv/sysv4/solaris2/fsync.S new file mode 100644 index 0000000000..aefa3e3af7 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/fsync.S @@ -0,0 +1,29 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* Solaris uses fdsync for the normal fsync. */ +ENTRY(fsync) + mov 16, %i1 + mov SYS_ify(fdsync), %g1 + ta 8 + bcs syscall_error + nop + mov %g0, %o0 + ret diff --git a/sysdeps/unix/sysv/sysv4/solaris2/signum.h b/sysdeps/unix/sysv/sysv4/solaris2/signum.h new file mode 100644 index 0000000000..8219626c3e --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/signum.h @@ -0,0 +1,73 @@ +/* Signal number definitions. Solaris 2 version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifdef _SIGNAL_H + +/* Fake signal functions. */ +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + + +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGABRT SIGIOT /* Abort (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGEMT 7 /* EMT trap (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGBUS 10 /* Bus error (4.2 BSD). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGSYS 12 /* Bad argument to system call (4.2 BSD)*/ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define SIGCHLD 18 /* Child status has changed (POSIX). */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGPWR 19 /* Power failure restart (System V). */ +#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */ +#define SIGURG 21 /* Urgent condition on socket (4.2 BSD).*/ +#define SIGPOLL 22 /* Pollable event occurred (System V). */ +#define SIGIO SIGPOLL /* I/O now possible (4.2 BSD). */ +#define SIGSTOP 23 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 24 /* Keyboard stop (POSIX). */ +#define SIGCONT 25 /* Continue (POSIX). */ +#define SIGTTIN 26 /* Background read from tty (POSIX). */ +#define SIGTTOU 27 /* Background write to tty (POSIX). */ +#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */ +#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */ +/* The following signals are new in Solaris 2. */ +#define SIGWAITING 32 /* Process's lwps are blocked. */ +#define SIGLWP 33 /* Special signal used by thread library. */ +#define SIGFREEZE 34 /* Special signal used by CPR. */ +#define SIGTHAW 35 /* Special signal used by CPR. */ +#define _SIGRTMIN 36 /* First (highest-priority) realtime signal. */ +#define _SIGRTMAX 43 /* Last (lowest-priority) realtime signal. */ + +#endif /* <signal.h> included. */ + +#define _NSIG 44 /* Biggest signal number + 1. */ diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/Dist b/sysdeps/unix/sysv/sysv4/solaris2/sparc/Dist new file mode 100644 index 0000000000..69d16ac6bf --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/Dist @@ -0,0 +1 @@ +sys-sig.S diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile b/sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile new file mode 100644 index 0000000000..7ad4bb1633 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/Makefile @@ -0,0 +1,5 @@ +# This flag is necessary because GCC now tries to call _Q_{mul, etc...} +# instead of doing the stuff the hard way. For now, printf_fp.o, __vfscanf.o, +# and difftime.o don't work because of this. The long-term fix is to actually +# implement what they're doing, but for the short-term, we must do this. +sysdep-CFLAGS := $(sysdep-CFLAGS) -mhard-quad-float diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/start.c b/sysdeps/unix/sysv/sysv4/solaris2/sparc/start.c new file mode 100644 index 0000000000..afdfaaa2e5 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/start.c @@ -0,0 +1,4 @@ +#define NO_SHLIB +/* Solaris needs start named `_start', not `start'. */ +#define NO_EXPLICIT_START +#include <sysdeps/unix/sparc/start.c> diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S new file mode 100644 index 0000000000..8baa997e80 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S @@ -0,0 +1,25 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__sigaction_syscall, sigaction, 3) + ret + +PSEUDO (__context_syscall, context, 2) + ret diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.S b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.S new file mode 100644 index 0000000000..da3cd6b8be --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.S @@ -0,0 +1,46 @@ +/* Copyright (C) 1993, 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +ENTRY(syscall_error) + /* If it was a syscall that got interrupted, but can + be restarted, drop EINTR in. */ + cmp %o0, ERESTART + be,a notint + mov EINTR, %o0 + +notint: +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmp %o0, EWOULDBLOCK_sys + be,a notblock + mov EAGAIN, %o0 +#endif + +notblock:/* Store it in errno... */ + sethi %hi(C_SYMBOL_NAME(errno)), %g1 + st %o0, [%g1 + %lo(C_SYMBOL_NAME(errno))] + + /* And just kick back a -1. */ + retl + mov -1, %o0 diff --git a/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h new file mode 100644 index 0000000000..edb98309e6 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h @@ -0,0 +1,51 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Solaris 2 does not precede the asm names of C symbols with a `_'. */ +#define NO_UNDERSCORES + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +/* As of gcc-2.6.0, it complains about pound signs in front of things + that aren't arguments to the macro. So we use this to pull it off + instead. */ +#define cat(a,b) a##b +#define poundfnc cat(#,function) + +#define ENTRY(name) \ + .section ".text"; \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type C_SYMBOL_NAME(name), poundfnc; \ + C_LABEL(name) + +#define PSEUDO(name, syscall_name, args) \ + ENTRY (name) \ + mov SYS_ify(syscall_name), %g1; \ + ta 8; \ + bcs C_SYMBOL_NAME(syscall_error); \ + nop + +#define ret retl; nop +#define r0 %o0 +#define r1 %o1 +#define MOVE(x,y) mov x, y + +#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/sysv/sysv4/solaris2/statbuf.h b/sysdeps/unix/sysv/sysv4/solaris2/statbuf.h new file mode 100644 index 0000000000..ac74cdffa7 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/statbuf.h @@ -0,0 +1,82 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _STATBUF_H +#define _STATBUF_H + +#include <gnu/types.h> + +/* Structure describing file characteristics. */ +struct stat + { + unsigned long int st_dev; + long st_filler1[3]; + __ino_t st_ino; /* File serial number. */ + unsigned long int st_mode; /* File mode. */ + /* This is unsigned long instead of __nlink_t, since SVR4 has + a long nlink_t, not a short one. */ + unsigned long int st_nlink; /* Link count. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + unsigned long int st_rdev; /* Device number, if device. */ + long st_filler2[2]; + + __off_t st_size; /* Size of file, in bytes. */ + /* SVR4 added this extra long to allow for expansion of off_t. */ + long st_filler3; + + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atime_usec; + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtime_usec; + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctime_usec; + + long st_blksize; /* Optimal block size for I/O. */ +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + + long st_blocks; /* Number of 512-byte blocks allocated. */ + char st_fstype[16]; + long st_filler4[8]; + }; + +/* Encoding of the file mode. */ + +#define __S_IFMT 0170000 /* These bits determine file type. */ + +/* File types. */ +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ + +/* These don't actually exist on System V, but having them doesn't hurt. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + +/* Protection bits. */ + +#define __S_ISUID 04000 /* Set user ID on execution. */ +#define __S_ISGID 02000 /* Set group ID on execution. */ +#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */ +#define __S_IREAD 0400 /* Read by owner. */ +#define __S_IWRITE 0200 /* Write by owner. */ +#define __S_IEXEC 0100 /* Execute by owner. */ + +#endif /* statbuf.h */ diff --git a/sysdeps/unix/sysv/sysv4/solaris2/utimes.S b/sysdeps/unix/sysv/sysv4/solaris2/utimes.S new file mode 100644 index 0000000000..54a043c835 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/solaris2/utimes.S @@ -0,0 +1,2 @@ +/* Solaris has the BSD `utimes' function. */ +#include <sysdeps/unix/bsd/utimes.S> diff --git a/sysdeps/unix/sysv/sysv4/sysconf.c b/sysdeps/unix/sysv/sysv4/sysconf.c new file mode 100644 index 0000000000..607cd05d14 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sysconf.c @@ -0,0 +1,181 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <limits.h> +#include <unistd.h> +#include <stdio.h> +#include <time.h> +#include <sysconfig.h> + +extern int EXFUN(__sysconfig, (int)); + +/* Get the value of the system variable NAME. */ +long int +DEFUN(__sysconf, (name), int name) +{ + switch (name) + { + default: + errno = EINVAL; + return -1; + + case _SC_ARG_MAX: +#ifdef ARG_MAX + return ARG_MAX; +#else + return -1; +#endif + + case _SC_CHILD_MAX: +#ifdef CHILD_MAX + return CHILD_MAX; +#else + return -1; +#endif + + case _SC_CLK_TCK: + return __sysconfig (_CONFIG_CLK_TCK); + + case _SC_NGROUPS_MAX: +#ifdef NGROUPS_MAX + return NGROUPS_MAX; +#else + return -1; +#endif + + /* Both of these are looking for _CONFIG_OPEN_FILES. */ + case _SC_OPEN_MAX: + case _SC_STREAM_MAX: + return __sysconfig (_CONFIG_OPEN_FILES); + + case _SC_TZNAME_MAX: + return __tzname_max (); + + case _SC_JOB_CONTROL: +#ifdef _POSIX_JOB_CONTROL + return 1; +#else + return -1; +#endif + case _SC_SAVED_IDS: +#ifdef _POSIX_SAVED_IDS + return 1; +#else + return -1; +#endif + case _SC_VERSION: + return _POSIX_VERSION; + + case _SC_PAGESIZE: + return __sysconfig (_CONFIG_PAGESIZE); + + case _SC_BC_BASE_MAX: +#ifdef BC_BASE_MAX + return BC_BASE_MAX; +#else + return -1; +#endif + + case _SC_BC_DIM_MAX: +#ifdef BC_DIM_MAX + return BC_DIM_MAX; +#else + return -1; +#endif + + case _SC_BC_SCALE_MAX: +#ifdef BC_SCALE_MAX + return BC_SCALE_MAX; +#else + return -1; +#endif + + case _SC_BC_STRING_MAX: +#ifdef BC_STRING_MAX + return BC_STRING_MAX; +#else + return -1; +#endif + + case _SC_EQUIV_CLASS_MAX: +#ifdef EQUIV_CLASS_MAX + return EQUIV_CLASS_MAX; +#else + return -1; +#endif + + case _SC_EXPR_NEST_MAX: +#ifdef EXPR_NEST_MAX + return EXPR_NEST_MAX; +#else + return -1; +#endif + + case _SC_LINE_MAX: +#ifdef LINE_MAX + return LINE_MAX; +#else + return -1; +#endif + + case _SC_RE_DUP_MAX: +#ifdef RE_DUP_MAX + return RE_DUP_MAX; +#else + return -1; +#endif + + + case _SC_2_VERSION: + /* This is actually supposed to return the version + of the 1003.2 utilities on the system {POSIX2_VERSION}. */ + return _POSIX2_C_VERSION; + + case _SC_2_C_BIND: +#ifdef _POSIX2_C_BIND + return _POSIX2_C_BIND; +#else + return -1; +#endif + + case _SC_2_C_DEV: +#ifdef _POSIX2_C_DEV + return _POSIX2_C_DEV; +#else + return -1; +#endif + + case _SC_2_FORT_DEV: +#ifdef _POSIX2_FORT_DEV + return _POSIX2_FORT_DEV; +#else + return -1; +#endif + + case _SC_2_SW_DEV: +#ifdef _POSIX2_SW_DEV + return _POSIX2_SW_DEV; +#else + return -1; +#endif + } +} + +weak_alias (__sysconf, sysconf) diff --git a/sysdeps/unix/sysv/sysv4/sysconfig.S b/sysdeps/unix/sysv/sysv4/sysconfig.S new file mode 100644 index 0000000000..034e012e84 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sysconfig.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (sysconfig, 1) + ret diff --git a/sysdeps/unix/sysv/sysv4/sysconfig.h b/sysdeps/unix/sysv/sysv4/sysconfig.h new file mode 100644 index 0000000000..77c84c7af6 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sysconfig.h @@ -0,0 +1,28 @@ +/* `__sysconfig' NAME values. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef __SYSCONFIG_H +#define __SYSCONFIG_H + +#define _CONFIG_OPEN_FILES 4 /* process limit on open files */ +#define _CONFIG_PAGESIZE 6 /* MMU page size */ +#define _CONFIG_CLK_TCK 7 /* all times are in CLK_TCKths of a second */ + +#endif + diff --git a/sysdeps/unix/sysv/sysv4/sysinfo.S b/sysdeps/unix/sysv/sysv4/sysinfo.S new file mode 100644 index 0000000000..c279c96e9c --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/sysinfo.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +PSEUDO (__sysinfo, systeminfo, 3) + ret diff --git a/sysdeps/unix/sysv/sysv4/system.c b/sysdeps/unix/sysv/sysv4/system.c new file mode 100644 index 0000000000..fbfe43f19a --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/system.c @@ -0,0 +1,2 @@ +/* SVR4 does have `waitpid'. Avoid unix/system.c, which says we don't. */ +#include <sysdeps/posix/system.c> diff --git a/sysdeps/unix/sysv/sysv4/time.S b/sysdeps/unix/sysv/sysv4/time.S new file mode 100644 index 0000000000..61f3514fb7 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/time.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (time, 1) + ret diff --git a/sysdeps/unix/sysv/sysv4/utsnamelen.h b/sysdeps/unix/sysv/sysv4/utsnamelen.h new file mode 100644 index 0000000000..9dcc618068 --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/utsnamelen.h @@ -0,0 +1 @@ +#define _UTSNAME_LENGTH 257 diff --git a/sysdeps/unix/sysv/sysv4/waitflags.h b/sysdeps/unix/sysv/sysv4/waitflags.h new file mode 100644 index 0000000000..cdb6f29e1d --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/waitflags.h @@ -0,0 +1,34 @@ +/* Definitions of flag bits for `waitpid' et al. + Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _WAITFLAGS_H + +#define _WAITFLAGS_H 1 + +/* Bits in the third argument to `waitpid'. */ +#define WNOHANG 64 /* Don't block waiting. */ +#define WUNTRACED 4 /* Report status of stopped children. */ + +#ifdef __USE_SVID +#define WEXITED 1 /* Look for children that have exited. */ +#define WTRAPPED 2 /* Look for processes that stopped + while tracing. */ +#endif + +#endif /* waitflags.h */ diff --git a/sysdeps/unix/sysv/sysv4/waitpid.c b/sysdeps/unix/sysv/sysv4/waitpid.c new file mode 100644 index 0000000000..f54df4bf6b --- /dev/null +++ b/sysdeps/unix/sysv/sysv4/waitpid.c @@ -0,0 +1,120 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <stddef.h> +#include "siginfo.h" + +typedef enum __idtype + { + /* Look for processes based upon a given PID. */ + P_PID, + + /* Look for processes based upon a given process-group ID. */ + P_PGID = 2, + + /* Look for any process. */ + P_ALL = 7, + } __idtype_t; + +extern __pid_t __getpgid __P ((__pid_t pid)); +extern int __waitid __P ((__idtype_t idtype, __pid_t id, + __siginfo_t *infop, int options)); + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS, + return status for stopped children; otherwise don't. */ + +__pid_t +DEFUN(__waitpid, (pid, stat_loc, options), + __pid_t pid AND int *stat_loc AND int options) +{ + __idtype_t idtype; + __pid_t tmp_pid = pid; + __siginfo_t infop; + + if (pid <= WAIT_MYPGRP) + { + if (pid == WAIT_ANY) + { + /* Request the status for any child. */ + idtype = P_ALL; + } + else if (pid == WAIT_MYPGRP) + { + /* Request the status for any child process that has + a pgid that's equal to that of our parent. */ + tmp_pid = __getpgid (0); + idtype = P_PGID; + } + else /* PID < -1 */ + { + /* Request the status for any child whose pgid is equal + to the absolute value of PID. */ + tmp_pid = pid & ~0; /* XXX not pseudo-insn */ + idtype = P_PGID; + } + } + else + { + /* Request the status for the child whose pid is PID. */ + idtype = P_PID; + } + + if (__waitid (idtype, tmp_pid, &infop, options | WEXITED | WTRAPPED) < 0) + return -1; + + switch (infop.__code) + { + case EXITED: + *stat_loc = W_EXITCODE (infop.__status, 0); + break; + case STOPPED: + case TRAPPED: + *stat_loc = W_STOPCODE (infop.__status); + break; + case KILLED: + /* Don't know what to do with continue, since it isn't documented. + Putting it here seemed the right place though. */ + case CONTINUED: + *stat_loc = infop.__status; + /* FALLTHROUGH */ + case CORED: + *stat_loc |= WCOREFLAG; + break; + } + + /* Return the PID out of the INFOP structure instead of the one we were + called with, to account for cases of being called with -1 to signify + any PID. */ + return infop.__pid; +} + +weak_alias (__waitpid, waitpid) diff --git a/sysdeps/unix/sysv/sysv_termio.h b/sysdeps/unix/sysv/sysv_termio.h new file mode 100644 index 0000000000..c1c5d72b4f --- /dev/null +++ b/sysdeps/unix/sysv/sysv_termio.h @@ -0,0 +1,155 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* In various parts of this file we define the System V values for + things as _SYSV_<whatever>. Those are the values that System V + uses for termio, and also (SVR4) termios. Not necessarily the + same as the GNU termios that the library user sees. */ + +/* Number of elements of c_cc. termio only. */ +#define _SYSV_NCC 8 + +#define _SYSV_VINTR 0 +#define _SYSV_VQUIT 1 +#define _SYSV_VERASE 2 +#define _SYSV_VKILL 3 +#define _SYSV_VEOF 4 +/* This field means VEOF if ICANON, VMIN if not. */ +#define _SYSV_VMIN 4 +#define _SYSV_VEOL 5 +/* This field means VEOL if ICANON, VTIME if not. */ +#define _SYSV_VTIME 5 +#define _SYSV_VEOL2 6 + +/* Flags in c_iflag. */ +#define _SYSV_IGNBRK 1 +#define _SYSV_BRKINT 2 +#define _SYSV_IGNPAR 4 +#define _SYSV_PARMRK 8 +#define _SYSV_INPCK 0x10 +#define _SYSV_ISTRIP 0x20 +#define _SYSV_INLCR 0x40 +#define _SYSV_IGNCR 0x80 +#define _SYSV_ICRNL 0x100 +#define _SYSV_IUCLC 0x200 +#define _SYSV_IXON 0x400 +#define _SYSV_IXANY 0x800 +#define _SYSV_IXOFF 0x1000 +#define _SYSV_IMAXBEL 0x2000 + +/* Flags in c_cflag. */ +#define _SYSV_CBAUD 0xf +#define _SYSV_CIBAUD 0xf0000 /* termios only. */ +#define _SYSV_IBSHIFT 16 +/* Values for CBAUD and CIBAUD. */ +#define _SYSV_B0 0 +#define _SYSV_B50 1 +#define _SYSV_B75 2 +#define _SYSV_B110 3 +#define _SYSV_B134 4 +#define _SYSV_B150 5 +#define _SYSV_B200 6 +#define _SYSV_B300 7 +#define _SYSV_B600 8 +#define _SYSV_B1200 9 +#define _SYSV_B1800 10 +#define _SYSV_B2400 11 +#define _SYSV_B4800 12 +#define _SYSV_B9600 13 +#define _SYSV_B19200 14 +#define _SYSV_B38400 15 + +#define _SYSV_CS5 0 +#define _SYSV_CS6 0x10 +#define _SYSV_CS7 0x20 +#define _SYSV_CS8 0x30 +#define _SYSV_CSIZE 0x30 +#define _SYSV_CSTOPB 0x40 +#define _SYSV_CREAD 0x80 +#define _SYSV_PARENB 0x100 +#define _SYSV_PARODD 0x200 +#define _SYSV_HUPCL 0x400 +#define _SYSV_CLOCAL 0x800 + +/* Flags in c_lflag. */ +#define _SYSV_ISIG 1 +#define _SYSV_ICANON 2 +#define _SYSV_ECHO 8 +#define _SYSV_ECHOE 0x10 +#define _SYSV_ECHOK 0x20 +#define _SYSV_ECHONL 0x40 +#define _SYSV_NOFLSH 0x80 +#define _SYSV_TOSTOP 0x100 +#define _SYSV_ECHOCTL 0x200 +#define _SYSV_ECHOPRT 0x400 +#define _SYSV_ECHOKE 0x800 +#define _SYSV_FLUSHO 0x2000 +#define _SYSV_PENDIN 0x4000 +#define _SYSV_IEXTEN 0x8000 + +/* Flags in c_oflag. */ +#define _SYSV_OPOST 1 +#define _SYSV_OLCUC 2 +#define _SYSV_ONLCR 4 +#define _SYSV_NLDLY 0x100 +#define _SYSV_NL0 0 +#define _SYSV_NL1 0x100 +#define _SYSV_CRDLY 0x600 +#define _SYSV_CR0 0 +#define _SYSV_CR1 0x200 +#define _SYSV_CR2 0x400 +#define _SYSV_CR3 0x600 +#define _SYSV_TABDLY 0x1800 +#define _SYSV_TAB0 0 +#define _SYSV_TAB1 0x0800 +#define _SYSV_TAB2 0x1000 +/* TAB3 is an obsolete name for XTABS. But we provide it since some + programs expect it to exist. */ +#define _SYSV_TAB3 0x1800 +#define _SYSV_XTABS 0x1800 +#define _SYSV_BSDLY 0x2000 +#define _SYSV_BS0 0 +#define _SYSV_BS1 0x2000 +#define _SYSV_VTDLY 0x4000 +#define _SYSV_VT0 0 +#define _SYSV_VT1 0x4000 +#define _SYSV_FFDLY 0x8000 +#define _SYSV_FF0 0 +#define _SYSV_FF1 0x8000 + +/* ioctl's. */ + +#define _TCGETA 0x5401 +#define _TCSETA 0x5402 +#define _TCSETAW 0x5403 +#define _TCSETAF 0x5404 +#define _TCSBRK 0x5405 +#define _TCXONC 0x5406 +#define _TCFLSH 0x5407 +#define _TIOCGPGRP 0x7414 +#define _TIOCSPGRP 0x7415 + +struct __sysv_termio + { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + char c_line; + unsigned char c_cc[_SYSV_NCC]; + }; diff --git a/sysdeps/unix/sysv/tcdrain.c b/sysdeps/unix/sysv/tcdrain.c new file mode 100644 index 0000000000..37144799e4 --- /dev/null +++ b/sysdeps/unix/sysv/tcdrain.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> +#include <sysv_termio.h> +#include <sys/ioctl.h> + +/* Wait for pending output to be written on FD. */ +int +DEFUN(tcdrain, (fd), int fd) +{ + /* With an argument of 1, TCSBRK just waits for output to drain. */ + return __ioctl (fd, _TCSBRK, 1); +} diff --git a/sysdeps/unix/sysv/tcflow.c b/sysdeps/unix/sysv/tcflow.c new file mode 100644 index 0000000000..fecb40dd82 --- /dev/null +++ b/sysdeps/unix/sysv/tcflow.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> +#include <sys/ioctl.h> + +#include "sysv_termio.h" + +/* Suspend or restart transmission on FD. */ +int +DEFUN(tcflow, (fd, action), int fd AND int action) +{ + switch (action) + { + case TCOOFF: + return __ioctl (fd, _TCXONC, 0); + case TCOON: + return __ioctl (fd, _TCXONC, 1); + case TCIOFF: + return __ioctl (fd, _TCXONC, 2); + case TCION: + return __ioctl (fd, _TCXONC, 3); + default: + errno = EINVAL; + return -1; + } +} diff --git a/sysdeps/unix/sysv/tcflush.c b/sysdeps/unix/sysv/tcflush.c new file mode 100644 index 0000000000..88574a5c4b --- /dev/null +++ b/sysdeps/unix/sysv/tcflush.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <unistd.h> +#include <sys/ioctl.h> + +#include <sysv_termio.h> + +/* Flush pending data on FD. */ +int +DEFUN(tcflush, (fd, queue_selector), int fd AND int queue_selector) +{ + switch (queue_selector) + { + case TCIFLUSH: + return __ioctl (fd, _TCFLSH, 0); + case TCOFLUSH: + return __ioctl (fd, _TCFLSH, 1); + case TCIOFLUSH: + return __ioctl (fd, _TCFLSH, 2); + default: + errno = EINVAL; + return -1; + } +} diff --git a/sysdeps/unix/sysv/tcgetattr.c b/sysdeps/unix/sysv/tcgetattr.c new file mode 100644 index 0000000000..dd914a2955 --- /dev/null +++ b/sysdeps/unix/sysv/tcgetattr.c @@ -0,0 +1,171 @@ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <sysv_termio.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* Put the state of FD into *TERMIOS_P. */ +int +DEFUN(__tcgetattr, (fd, termios_p), + int fd AND struct termios *termios_p) +{ + struct __sysv_termio buf; + int termio_speed; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + if (__ioctl (fd, _TCGETA, &buf) < 0) + return -1; + + termio_speed = buf.c_cflag & _SYSV_CBAUD; + termios_p->__ospeed = + (termio_speed == _SYSV_B0 ? 0 : + termio_speed == _SYSV_B50 ? 50 : + termio_speed == _SYSV_B75 ? 75 : + termio_speed == _SYSV_B110 ? 110 : + termio_speed == _SYSV_B134 ? 134 : + termio_speed == _SYSV_B150 ? 150 : + termio_speed == _SYSV_B200 ? 200 : + termio_speed == _SYSV_B300 ? 300 : + termio_speed == _SYSV_B600 ? 600 : + termio_speed == _SYSV_B1200 ? 1200 : + termio_speed == _SYSV_B1800 ? 1800 : + termio_speed == _SYSV_B2400 ? 2400 : + termio_speed == _SYSV_B4800 ? 4800 : + termio_speed == _SYSV_B9600 ? 9600 : + termio_speed == _SYSV_B19200 ? 19200 : + termio_speed == _SYSV_B38400 ? 38400 : + -1); + termios_p->__ispeed = termios_p->__ospeed; + + termios_p->c_iflag = 0; + if (buf.c_iflag & _SYSV_IGNBRK) + termios_p->c_iflag |= IGNBRK; + if (buf.c_iflag & _SYSV_BRKINT) + termios_p->c_iflag |= BRKINT; + if (buf.c_iflag & _SYSV_IGNPAR) + termios_p->c_iflag |= IGNPAR; + if (buf.c_iflag & _SYSV_PARMRK) + termios_p->c_iflag |= PARMRK; + if (buf.c_iflag & _SYSV_INPCK) + termios_p->c_iflag |= INPCK; + if (buf.c_iflag & _SYSV_ISTRIP) + termios_p->c_iflag |= ISTRIP; + if (buf.c_iflag & _SYSV_INLCR) + termios_p->c_iflag |= INLCR; + if (buf.c_iflag & _SYSV_IGNCR) + termios_p->c_iflag |= IGNCR; + if (buf.c_iflag & _SYSV_ICRNL) + termios_p->c_iflag |= ICRNL; + if (buf.c_iflag & _SYSV_IXON) + termios_p->c_iflag |= IXON; + if (buf.c_iflag & _SYSV_IXOFF) + termios_p->c_iflag |= IXOFF; + if (buf.c_iflag & _SYSV_IXANY) + termios_p->c_iflag |= IXANY; + if (buf.c_iflag & _SYSV_IMAXBEL) + termios_p->c_iflag |= IMAXBEL; + + termios_p->c_oflag = 0; + if (buf.c_oflag & OPOST) + termios_p->c_oflag |= OPOST; + if (buf.c_oflag & ONLCR) + termios_p->c_oflag |= ONLCR; + termios_p->c_cflag = 0; + switch (buf.c_cflag & _SYSV_CSIZE) + { + case _SYSV_CS5: + termios_p->c_cflag |= CS5; + break; + case _SYSV_CS6: + termios_p->c_cflag |= CS6; + break; + case _SYSV_CS7: + termios_p->c_cflag |= CS7; + break; + case _SYSV_CS8: + termios_p->c_cflag |= CS8; + break; + } + if (buf.c_cflag & _SYSV_CSTOPB) + termios_p->c_cflag |= CSTOPB; + if (buf.c_cflag & _SYSV_CREAD) + termios_p->c_cflag |= CREAD; + if (buf.c_cflag & _SYSV_PARENB) + termios_p->c_cflag |= PARENB; + if (buf.c_cflag & _SYSV_PARODD) + termios_p->c_cflag |= PARODD; + if (buf.c_cflag & _SYSV_HUPCL) + termios_p->c_cflag |= HUPCL; + if (buf.c_cflag & _SYSV_CLOCAL) + termios_p->c_cflag |= CLOCAL; + termios_p->c_lflag = 0; + if (buf.c_lflag & _SYSV_ISIG) + termios_p->c_lflag |= _ISIG; + if (buf.c_lflag & _SYSV_ICANON) + termios_p->c_lflag |= _ICANON; + if (buf.c_lflag & _SYSV_ECHO) + termios_p->c_lflag |= _ECHO; + if (buf.c_lflag & _SYSV_ECHOE) + termios_p->c_lflag |= _ECHOE; + if (buf.c_lflag & _SYSV_ECHOK) + termios_p->c_lflag |= _ECHOK; + if (buf.c_lflag & _SYSV_ECHONL) + termios_p->c_lflag |= _ECHONL; + if (buf.c_lflag & _SYSV_NOFLSH) + termios_p->c_lflag |= _NOFLSH; + if (buf.c_lflag & _SYSV_TOSTOP) + termios_p->c_lflag |= _TOSTOP; + if (buf.c_lflag & _SYSV_ECHOKE) + termios_p->c_lflag |= ECHOKE; + if (buf.c_lflag & _SYSV_ECHOPRT) + termios_p->c_lflag |= ECHOPRT; + if (buf.c_lflag & _SYSV_ECHOCTL) + termios_p->c_lflag |= ECHOCTL; + if (buf.c_lflag & _SYSV_FLUSHO) + termios_p->c_lflag |= FLUSHO; + if (buf.c_lflag & _SYSV_PENDIN) + termios_p->c_lflag |= PENDIN; + if (buf.c_lflag & _SYSV_IEXTEN) + termios_p->c_lflag |= IEXTEN; + + termios_p->c_cc[VEOF] = buf.c_cc[_SYSV_VEOF]; + termios_p->c_cc[VEOL] = buf.c_cc[_SYSV_VEOL]; + termios_p->c_cc[VEOL2] = buf.c_cc[_SYSV_VEOL2]; + termios_p->c_cc[VERASE] = buf.c_cc[_SYSV_VERASE]; + termios_p->c_cc[VKILL] = buf.c_cc[_SYSV_VKILL]; + termios_p->c_cc[VINTR] = buf.c_cc[_SYSV_VINTR]; + termios_p->c_cc[VQUIT] = buf.c_cc[_SYSV_VQUIT]; + termios_p->c_cc[VSTART] = '\021'; /* XON (^Q). */ + termios_p->c_cc[VSTOP] = '\023'; /* XOFF (^S). */ + termios_p->c_cc[VSUSP] = '\0'; /* System V release 3 lacks job control. */ + termios_p->c_cc[VMIN] = buf.c_cc[_SYSV_VMIN]; + termios_p->c_cc[VTIME] = buf.c_cc[_SYSV_VTIME]; + + return 0; +} + +weak_alias (__tcgetattr, tcgetattr) diff --git a/sysdeps/unix/sysv/tcgetpgrp.c b/sysdeps/unix/sysv/tcgetpgrp.c new file mode 100644 index 0000000000..d4c47227d0 --- /dev/null +++ b/sysdeps/unix/sysv/tcgetpgrp.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <termios.h> +#include <sysv_termio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/ioctl.h> + +/* Return the foreground process group ID of FD. */ +pid_t +DEFUN(tcgetpgrp, (fd), int fd) +{ + int pgrp; + if (__ioctl(fd, _TIOCGPGRP, &pgrp) < 0) + return (pid_t) -1; + return (pid_t) pgrp; +} diff --git a/sysdeps/unix/sysv/tcsendbrk.c b/sysdeps/unix/sysv/tcsendbrk.c new file mode 100644 index 0000000000..78fe2c542a --- /dev/null +++ b/sysdeps/unix/sysv/tcsendbrk.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <signal.h> +#include <termios.h> +#include <unistd.h> +#include <sysv_termio.h> +#include <sys/ioctl.h> + +/* Send zero bits on FD. */ +int +DEFUN(tcsendbreak, (fd, duration), int fd AND int duration) +{ + /* The break lasts 0.25 to 0.5 seconds if DURATION is zero, + and an implementation-defined period if DURATION is nonzero. + We define a positive DURATION to be number of milliseconds to break. */ + if (duration <= 0) + return __ioctl (fd, _TCSBRK, 0); + + /* ioctl can't send a break of any other duration for us. + This could be changed to use trickery (e.g. lower speed and + send a '\0') to send the break, but for now just return an error. */ + errno = EINVAL; + return -1; +} diff --git a/sysdeps/unix/sysv/tcsetattr.c b/sysdeps/unix/sysv/tcsetattr.c new file mode 100644 index 0000000000..30e1b0b48d --- /dev/null +++ b/sysdeps/unix/sysv/tcsetattr.c @@ -0,0 +1,208 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <sys/ioctl.h> + +#include <sysv_termio.h> + + +CONST speed_t __unix_speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + }; + + +/* Set the state of FD to *TERMIOS_P. */ +int +DEFUN(tcsetattr, (fd, optional_actions, termios_p), + int fd AND int optional_actions AND CONST struct termios *termios_p) +{ + struct __sysv_termio buf; + int ioctl_function; + size_t i; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + switch (optional_actions) + { + case TCSANOW: + ioctl_function = _TCSETA; + break; + case TCSADRAIN: + ioctl_function = _TCSETAW; + break; + case TCSAFLUSH: + ioctl_function = _TCSETAF; + break; + default: + errno = EINVAL; + return -1; + } + + if (termios_p->__ispeed != termios_p->__ospeed) + { + errno = EINVAL; + return -1; + } + buf.c_cflag = -1; + for (i = 0; i <= sizeof (__unix_speeds) / sizeof (__unix_speeds[0]); ++i) + { + if (__unix_speeds[i] == termios_p->__ispeed) + buf.c_cflag = i; + } + if (buf.c_cflag == -1) + { + errno = EINVAL; + return -1; + } + + buf.c_iflag = 0; + if (termios_p->c_iflag & IGNBRK) + buf.c_iflag |= _SYSV_IGNBRK; + if (termios_p->c_iflag & BRKINT) + buf.c_iflag |= _SYSV_BRKINT; + if (termios_p->c_iflag & IGNPAR) + buf.c_iflag |= _SYSV_IGNPAR; + if (termios_p->c_iflag & PARMRK) + buf.c_iflag |= _SYSV_PARMRK; + if (termios_p->c_iflag & INPCK) + buf.c_iflag |= _SYSV_INPCK; + if (termios_p->c_iflag & ISTRIP) + buf.c_iflag |= _SYSV_ISTRIP; + if (termios_p->c_iflag & INLCR) + buf.c_iflag |= _SYSV_INLCR; + if (termios_p->c_iflag & IGNCR) + buf.c_iflag |= _SYSV_IGNCR; + if (termios_p->c_iflag & ICRNL) + buf.c_iflag |= _SYSV_ICRNL; + if (termios_p->c_iflag & IXON) + buf.c_iflag |= _SYSV_IXON; + if (termios_p->c_iflag & IXOFF) + buf.c_iflag |= _SYSV_IXOFF; + if (termios_p->c_iflag & IXANY) + buf.c_iflag |= _SYSV_IXANY; + if (termios_p->c_iflag & IMAXBEL) + buf.c_iflag |= _SYSV_IMAXBEL; + + buf.c_oflag = 0; + if (termios_p->c_oflag & OPOST) + buf.c_oflag = _SYSV_OPOST; + if (termios_p->c_oflag & ONLCR) + buf.c_oflag = _SYSV_ONLCR; + + /* So far, buf.c_cflag contains the speed in CBAUD. */ + if (termios_p->c_cflag & CSTOPB) + buf.c_cflag |= _SYSV_CSTOPB; + if (termios_p->c_cflag & CREAD) + buf.c_cflag |= _SYSV_CREAD; + if (termios_p->c_cflag & PARENB) + buf.c_cflag |= _SYSV_PARENB; + if (termios_p->c_cflag & PARODD) + buf.c_cflag |= _SYSV_PARODD; + if (termios_p->c_cflag & HUPCL) + buf.c_cflag |= _SYSV_HUPCL; + if (termios_p->c_cflag & CLOCAL) + buf.c_cflag |= _SYSV_CLOCAL; + switch (termios_p->c_cflag & CSIZE) + { + case CS5: + buf.c_cflag |= _SYSV_CS5; + break; + case CS6: + buf.c_cflag |= _SYSV_CS6; + break; + case CS7: + buf.c_cflag |= _SYSV_CS7; + break; + case CS8: + buf.c_cflag |= _SYSV_CS8; + break; + } + + buf.c_lflag = 0; + if (termios_p->c_lflag & ISIG) + buf.c_lflag |= _SYSV_ISIG; + if (termios_p->c_lflag & ICANON) + buf.c_lflag |= _SYSV_ICANON; + if (termios_p->c_lflag & ECHO) + buf.c_lflag |= _SYSV_ECHO; + if (termios_p->c_lflag & ECHOE) + buf.c_lflag |= _SYSV_ECHOE; + if (termios_p->c_lflag & ECHOK) + buf.c_lflag |= _SYSV_ECHOK; + if (termios_p->c_lflag & ECHONL) + buf.c_lflag |= _SYSV_ECHONL; + if (termios_p->c_lflag & NOFLSH) + buf.c_lflag |= _SYSV_NOFLSH; + if (termios_p->c_lflag & TOSTOP) + buf.c_lflag |= _SYSV_TOSTOP; + if (termios_p->c_lflag & ECHOCTL) + buf.c_lflag |= _SYSV_ECHOCTL; + if (termios_p->c_lflag & ECHOPRT) + buf.c_lflag |= _SYSV_ECHOPRT; + if (termios_p->c_lflag & ECHOKE) + buf.c_lflag |= _SYSV_ECHOKE; + if (termios_p->c_lflag & FLUSHO) + buf.c_lflag |= _SYSV_FLUSHO; + if (termios_p->c_lflag & PENDIN) + buf.c_lflag |= _SYSV_PENDIN; + if (termios_p->c_lflag & IEXTEN) + buf.c_lflag |= _SYSV_IEXTEN; + + buf.c_cc[_SYSV_VINTR] = termios_p->c_cc[VINTR]; + buf.c_cc[_SYSV_VQUIT] = termios_p->c_cc[VQUIT]; + buf.c_cc[_SYSV_VERASE] = termios_p->c_cc[VERASE]; + buf.c_cc[_SYSV_VKILL] = termios_p->c_cc[VKILL]; + if (buf.c_lflag & _SYSV_ICANON) + { + buf.c_cc[_SYSV_VEOF] = termios_p->c_cc[VEOF]; + buf.c_cc[_SYSV_VEOL] = termios_p->c_cc[VEOL]; + } + else + { + buf.c_cc[_SYSV_VMIN] = termios_p->c_cc[VMIN]; + buf.c_cc[_SYSV_VTIME] = termios_p->c_cc[VTIME]; + } + buf.c_cc[_SYSV_VEOL2] = termios_p->c_cc[VEOL2]; + + if (__ioctl (fd, ioctl_function, &buf) < 0) + return -1; + return 0; +} diff --git a/sysdeps/unix/sysv/tcsetpgrp.c b/sysdeps/unix/sysv/tcsetpgrp.c new file mode 100644 index 0000000000..da83f3bd6c --- /dev/null +++ b/sysdeps/unix/sysv/tcsetpgrp.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sys/types.h> +#include <sysv_termio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ioctl.h> + +/* Set the foreground process group ID of FD set PGRP_ID. */ +int +DEFUN(tcsetpgrp, (fd, pgrp_id), int fd AND pid_t pgrp_id) +{ + return __ioctl (fd, _TIOCSPGRP, &pgrp_id); +} diff --git a/sysdeps/unix/sysv/times.S b/sysdeps/unix/sysv/times.S new file mode 100644 index 0000000000..c2bb1685f5 --- /dev/null +++ b/sysdeps/unix/sysv/times.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (times, 1) + ret + +weak_alias (__times, times) diff --git a/sysdeps/unix/sysv/ulimit.S b/sysdeps/unix/sysv/ulimit.S new file mode 100644 index 0000000000..1bc6dc910a --- /dev/null +++ b/sysdeps/unix/sysv/ulimit.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (ulimit, 2) + ret diff --git a/sysdeps/unix/sysv/uname.S b/sysdeps/unix/sysv/uname.S new file mode 100644 index 0000000000..ab4879fa40 --- /dev/null +++ b/sysdeps/unix/sysv/uname.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (uname, 1) + ret diff --git a/sysdeps/unix/sysv/utime.S b/sysdeps/unix/sysv/utime.S new file mode 100644 index 0000000000..e24db03b5e --- /dev/null +++ b/sysdeps/unix/sysv/utime.S @@ -0,0 +1,22 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL (utime, 2) + ret diff --git a/sysdeps/unix/sysv/utmp.h b/sysdeps/unix/sysv/utmp.h new file mode 100644 index 0000000000..4c3d33e987 --- /dev/null +++ b/sysdeps/unix/sysv/utmp.h @@ -0,0 +1,23 @@ +#ifndef _UTMP_H + +#define _UTMP_H 1 + +#include <time.h> + +struct utmp + { +#define ut_name ut_user + char ut_user[8]; + char ut_id[4]; + char ut_line[12]; + short ut_pid; + short ut_type; + struct exit_status + { + short e_termination; + short e_exit; + } ut_exit; + time_t ut_time; + }; + +#endif /* utmp.h. */ diff --git a/sysdeps/unix/sysv/utsnamelen.h b/sysdeps/unix/sysv/utsnamelen.h new file mode 100644 index 0000000000..31473cf4ea --- /dev/null +++ b/sysdeps/unix/sysv/utsnamelen.h @@ -0,0 +1 @@ +#define _UTSNAME_LENGTH 9 diff --git a/sysdeps/unix/telldir.c b/sysdeps/unix/telldir.c new file mode 100644 index 0000000000..c473bbc29d --- /dev/null +++ b/sysdeps/unix/telldir.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <errno.h> +#include <stddef.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> + +/* Return the current position of DIRP. */ +off_t +DEFUN(telldir, (dirp), DIR *dirp) +{ + register off_t pos; + + if (dirp == NULL) + { + errno = EINVAL; + return (off_t) -1; + } + + pos = __lseek(dirp->__fd, (off_t) 0, SEEK_CUR); + if (pos == (off_t) -1) + return (off_t) -1; + return pos + (dirp->__size - dirp->__offset); +} diff --git a/sysdeps/unix/umask.S b/sysdeps/unix/umask.S new file mode 100644 index 0000000000..bb2b89982e --- /dev/null +++ b/sysdeps/unix/umask.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (umask, 1) + ret + +weak_alias (__umask, umask) diff --git a/sysdeps/unix/unlink.S b/sysdeps/unix/unlink.S new file mode 100644 index 0000000000..8f496ce94b --- /dev/null +++ b/sysdeps/unix/unlink.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (unlink, 1) + ret + +weak_alias (__unlink, unlink) diff --git a/sysdeps/unix/write.S b/sysdeps/unix/write.S new file mode 100644 index 0000000000..881d1276fd --- /dev/null +++ b/sysdeps/unix/write.S @@ -0,0 +1,24 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +SYSCALL__ (write, 3) + ret + +weak_alias (__write, write) diff --git a/sysdeps/vax/DEFS.h b/sysdeps/vax/DEFS.h new file mode 100644 index 0000000000..01f1f0cdd0 --- /dev/null +++ b/sysdeps/vax/DEFS.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1982, 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. + * + * @(#)DEFS.h 8.1 (Berkeley) 6/4/93 + */ + +#define R0 0x001 +#define R1 0x002 +#define R2 0x004 +#define R3 0x008 +#define R4 0x010 +#define R5 0x020 +#define R6 0x040 +#define R7 0x080 +#define R8 0x100 +#define R9 0x200 +#define R10 0x400 +#define R11 0x800 + +#ifdef PROF +#define ENTRY(x, regs) \ + .globl _/**/x; .align 2; _/**/x: .word regs; \ + .data; 1:; .long 0; .text; moval 1b,r0; jsb mcount +#define ASENTRY(x, regs) \ + .globl x; .align 2; x: .word regs; \ + .data; 1:; .long 0; .text; moval 1b,r0; jsb mcount +#else +#define ENTRY(x, regs) \ + .globl _/**/x; .align 2; _/**/x: .word regs +#define ASENTRY(x, regs) \ + .globl x; .align 2; x: .word regs +#endif diff --git a/sysdeps/vax/Dist b/sysdeps/vax/Dist new file mode 100644 index 0000000000..9830be29a4 --- /dev/null +++ b/sysdeps/vax/Dist @@ -0,0 +1 @@ +DEFS.h diff --git a/sysdeps/vax/Makefile b/sysdeps/vax/Makefile new file mode 100644 index 0000000000..a6149a9524 --- /dev/null +++ b/sysdeps/vax/Makefile @@ -0,0 +1,32 @@ +# Copyright (C) 1991, 1994 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +ifeq ($(subdir),math) +ifndef math-twiddled + +elided-routines := $(elided-routines) acos asin cos sin ceil rint hypot \ + __copysign __scalb __drem __logb __finite +sysdep_routines := $(sysdep_routines) asincos sincos argred \ + support exp__E log__L + +math-twiddled := t +endif + +bsdmath_dirs := $(bsdmath_dirs) vax + +endif diff --git a/sysdeps/vax/__longjmp.c b/sysdeps/vax/__longjmp.c new file mode 100644 index 0000000000..0ee040ab25 --- /dev/null +++ b/sysdeps/vax/__longjmp.c @@ -0,0 +1,100 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. + Derived from @(#)_setjmp.s 5.7 (Berkeley) 6/27/88, + Copyright (c) 1980 Regents of the University of California. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <setjmp.h> + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#endif + + +#define REI 02 /* Vax `rei' opcode. */ + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +__NORETURN +void +DEFUN(__longjmp, (env, val), CONST __jmp_buf env AND int val) +{ + register long int *fp asm("fp"); + long int *regsave; + unsigned long int flags; + + if (env.__fp == NULL) + __libc_fatal("longjmp: Invalid ENV argument.\n"); + + if (val == 0) + val = 1; + + asm volatile("loop:"); + + flags = *(long int *) (6 + (char *) fp); + regsave = (long int *) (20 + (char *) fp); + if (flags & 1) + /* R0 was saved by the caller. + Store VAL where it will be restored from. */ + *regsave++ = val; + if (flags & 2) + /* R1 was saved by the caller. + Store ENV where it will be restored from. */ + *regsave = env; + + /* Was the FP saved in the last call the same one in ENV? */ + asm volatile("cmpl %0, 12(fp);" + /* Yes, return to it. */ + "beql done;" + /* The FP in ENV is less than the one saved in the last call. + This means we have already returned from the function that + called `setjmp' with ENV! */ + "blssu latejump;" : /* No outputs. */ : "g" (env.__fp)); + + /* We are more than one level below the state in ENV. + Return to where we will pop another stack frame. */ + asm volatile("movl $loop, 16(fp);" + "ret"); + + asm volatile("done:"); + { + char return_insn asm("*16(fp)"); + if (return_insn == REI) + /* We're returning with an `rei' instruction. + Do a return with PSL-PC pop. */ + asm volatile("movab 0f, 16(fp)"); + else + /* Do a standard return. */ + asm volatile("movab 1f, 16(fp)"); + + /* Return. */ + asm volatile("ret"); + } + + asm volatile("0:" /* `rei' return. */ + /* Compensate for PSL-PC push. */ + "addl2 %0, sp;" + "1:" /* Standard return. */ + /* Return to saved PC. */ + "jmp %1" : /* No outputs. */ : + "g" (8), "g" (env.__pc)); + + /* Jump here when the FP saved in ENV points + to a function that has already returned. */ + asm volatile("latejump:"); + __libc_fatal("longjmp: Attempt to jump to a function that has returned.\n"); +} diff --git a/sysdeps/vax/bcmp.s b/sysdeps/vax/bcmp.s new file mode 100644 index 0000000000..d980feb8e4 --- /dev/null +++ b/sysdeps/vax/bcmp.s @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)bcmp.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* bcmp(s1, s2, n) */ + +#include "DEFS.h" + +ENTRY(bcmp, 0) + movl 4(ap),r1 + movl 8(ap),r3 + movl 12(ap),r4 +1: + movzwl $65535,r0 + cmpl r4,r0 + jleq 2f + subl2 r0,r4 + cmpc3 r0,(r1),(r3) + jeql 1b + addl2 r4,r0 + ret +2: + cmpc3 r4,(r1),(r3) + ret diff --git a/sysdeps/vax/bcopy.s b/sysdeps/vax/bcopy.s new file mode 100644 index 0000000000..43bb93d216 --- /dev/null +++ b/sysdeps/vax/bcopy.s @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)bcopy.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* bcopy(from, to, size) */ + +#include "DEFS.h" + +ENTRY(bcopy, R6) + movl 4(ap),r1 + movl 8(ap),r3 + movl 12(ap),r6 + cmpl r1,r3 + bgtr 2f # normal forward case + blss 3f # overlapping, must do backwards + ret # equal, nothing to do +1: + subl2 r0,r6 + movc3 r0,(r1),(r3) +2: + movzwl $65535,r0 + cmpl r6,r0 + jgtr 1b + movc3 r6,(r1),(r3) + ret +3: + addl2 r6,r1 + addl2 r6,r3 + movzwl $65535,r0 + jbr 5f +4: + subl2 r0,r6 + subl2 r0,r1 + subl2 r0,r3 + movc3 r0,(r1),(r3) + movzwl $65535,r0 + subl2 r0,r1 + subl2 r0,r3 +5: + cmpl r6,r0 + jgtr 4b + subl2 r6,r1 + subl2 r6,r3 + movc3 r6,(r1),(r3) + ret diff --git a/sysdeps/vax/bsd-_setjmp.S b/sysdeps/vax/bsd-_setjmp.S new file mode 100644 index 0000000000..039fd71fdb --- /dev/null +++ b/sysdeps/vax/bsd-_setjmp.S @@ -0,0 +1,32 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Vax version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + popl r0 /* Pop return PC. */ + popl r1 /* Pop jmp_buf argument. */ + pushl $0 /* Push second argument of zero. */ + pushl r1 /* Push back first argument. */ + pushl r0 /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/vax/bsd-setjmp.S b/sysdeps/vax/bsd-setjmp.S new file mode 100644 index 0000000000..379a65c0e5 --- /dev/null +++ b/sysdeps/vax/bsd-setjmp.S @@ -0,0 +1,32 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Vax version. +Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + +#include <sysdep.h> + +ENTRY (setjmp) + popl r0 /* Pop return PC. */ + popl r1 /* Pop jmp_buf argument. */ + pushl $1 /* Push second argument of one. */ + pushl r1 /* Push back first argument. */ + pushl r0 /* Push back return PC. */ + jmp C_SYMBOL_NAME (__sigsetjmp) diff --git a/sysdeps/vax/bzero.s b/sysdeps/vax/bzero.s new file mode 100644 index 0000000000..5f90763d41 --- /dev/null +++ b/sysdeps/vax/bzero.s @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)bzero.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* bzero(base, length) */ + +#include "DEFS.h" + +ENTRY(bzero, 0) + movl 4(ap),r3 + jbr 2f +1: + subl2 r0,8(ap) + movc5 $0,(r3),$0,r0,(r3) +2: + movzwl $65535,r0 + cmpl 8(ap),r0 + jgtr 1b + movc5 $0,(r3),$0,8(ap),(r3) + ret diff --git a/sysdeps/vax/ffs.s b/sysdeps/vax/ffs.s new file mode 100644 index 0000000000..49faffb060 --- /dev/null +++ b/sysdeps/vax/ffs.s @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)ffs.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* bit = ffs(value) */ + +#include "DEFS.h" + +ENTRY(ffs, 0) + ffs $0,$32,4(ap),r0 + bneq 1f + mnegl $1,r0 +1: + incl r0 + ret diff --git a/sysdeps/vax/fl.h b/sysdeps/vax/fl.h new file mode 100644 index 0000000000..49e745697a --- /dev/null +++ b/sysdeps/vax/fl.h @@ -0,0 +1,68 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef __need_HUGE_VAL + +/* Floating-point constants for Vaxen. */ + +#define FLT_RADIX 2 + +#define FLT_ROUNDS _FLT_ROUNDS_TONEAREST + +#define FLT_MANT_DIG 23 +#define DBL_MANT_DIG 55 +#define LDBL_MANT_DIG 55 + +#define FLT_DIG 6 +#define DBL_DIG 16 +#define LDBL_DIG 16 + +#define FLT_MIN_EXP (-128) +#define DBL_MIN_EXP (-128) +#define LDBL_MIN_EXP (-128) + +#define FLT_MIN_10_EXP (-38) +#define DBL_MIN_10_EXP (-38) +#define LDBL_MIN_10_EXP (-38) + +#define FLT_MAX_EXP 127 +#define DBL_MAX_EXP 127 +#define LDBL_MAX_EXP 127 + +#define FLT_MAX_10_EXP 38 +#define DBL_MAX_10_EXP 38 +#define LDBL_MAX_10_EXP 38 + +#define FLT_MAX 1.7014116e38 +#define DBL_MAX 1.70141182460469227e38 +#define LDBL_MAX DBL_MAX + +#define FLT_EPSILON 2.384186e-7 +#define DBL_EPSILON 5.55111512312578270e-17 +#define LDBL_EPSILON DBL_EPSILON + +#define FLT_MIN 0.2938736e-38 +#define DBL_MIN 0.29387358770557187e-38 +#define LDBL_MIN DBL_MIN + +#else /* Need HUGE_VAL. */ + +/* Used by <stdlib.h> and <math.h> functions for overflow. */ +#define HUGE_VAL 1.70141182460469227e38 + +#endif /* Don't need HUGE_VAL. */ diff --git a/sysdeps/vax/htonl.s b/sysdeps/vax/htonl.s new file mode 100644 index 0000000000..af5b96c22f --- /dev/null +++ b/sysdeps/vax/htonl.s @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)htonl.s 5.5 (Berkeley) 6/27/88" +#endif /* LIBC_SCCS and not lint */ + +/* netorder = htonl(hostorder) */ + +#include "DEFS.h" + +ENTRY(htonl, 0) + rotl $-8,4(ap),r0 + insv r0,$16,$8,r0 + movb 7(ap),r0 + ret diff --git a/sysdeps/vax/htons.s b/sysdeps/vax/htons.s new file mode 100644 index 0000000000..c500e84506 --- /dev/null +++ b/sysdeps/vax/htons.s @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)htons.s 5.5 (Berkeley) 6/27/88" +#endif /* LIBC_SCCS and not lint */ + +/* hostorder = htons(netorder) */ + +#include "DEFS.h" + +ENTRY(htons, 0) + rotl $8,4(ap),r0 + movb 5(ap),r0 + movzwl r0,r0 + ret diff --git a/sysdeps/vax/huge_val.h b/sysdeps/vax/huge_val.h new file mode 100644 index 0000000000..58f5415446 --- /dev/null +++ b/sysdeps/vax/huge_val.h @@ -0,0 +1,27 @@ +/* `HUGE_VAL' constant for Vaxen. + Used by <stdlib.h> and <math.h> functions for overflow. + +Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _HUGE_VAL_H +#define _HUGE_VAL_H 1 + +#define HUGE_VAL 1.70141182460469227e38 + +#endif /* huge_val.h */ diff --git a/sysdeps/vax/index.s b/sysdeps/vax/index.s new file mode 100644 index 0000000000..e599b276f0 --- /dev/null +++ b/sysdeps/vax/index.s @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1980 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) + .asciz "@(#)index.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the first occurence of c in the string cp. + * Return pointer to match or null pointer. + * + * char * + * index(cp, c) + * char *cp, c; + */ +#include "DEFS.h" + +ENTRY(index, 0) + movq 4(ap),r1 # r1 = cp; r2 = c + tstl r2 # check for special case c == '\0' + bneq 2f +1: + locc $0,$65535,(r1) # just find end of string + beql 1b # still looking + movl r1,r0 # found it + ret +2: + moval tbl,r3 # r3 = address of table + bbss $0,(r3),5f # insure not reentering + movab (r3)[r2],r5 # table entry for c + incb (r5) + movzwl $65535,r4 # fast access +3: + scanc r4,(r1),(r3),$1 # look for c or '\0' + beql 3b # still looking + movl r1,r0 # return pointer to char + tstb (r0) # if have found '\0' + bneq 4f + clrl r0 # else return 0 +4: + clrb (r5) # clean up table + clrb (r3) + ret + + .data +tbl: .space 256 + .text + +/* + * Reentrant, but slower version of index + */ +5: + movl r1,r3 +6: + locc $0,$65535,(r3) # look for '\0' + bneq 7f + locc r2,$65535,(r3) # look for c + bneq 8f + movl r1,r3 # reset pointer and ... + jbr 6b # ... try again +7: + subl3 r3,r1,r4 # length of short block + incl r4 # +1 for '\0' + locc r2,r4,(r3) # look for c + bneq 8f + ret +8: + movl r1,r0 # return pointer to char + ret diff --git a/sysdeps/vax/infnan.c b/sysdeps/vax/infnan.c new file mode 100644 index 0000000000..62ec9dca0f --- /dev/null +++ b/sysdeps/vax/infnan.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef __GNUC__ + #error This file uses GNU C extensions; you must compile with GCC. +#else + +#include <ansidecl.h> +#include <errno.h> +#include <math.h> + +/* Deal with an infinite or NaN result. + If ERROR is ERANGE, result is +Inf; + if ERROR is - ERANGE, result is -Inf; + otherwise result is NaN. + This will set `errno' to either ERANGE or EDOM, + and may return an infinity or NaN, or may do something else. */ +double +DEFUN(__infnan, (error), int error) +{ + switch (error) + { + case ERANGE: + errno = ERANGE; + break; + + case - ERANGE: + errno = ERANGE; + break; + + default: + errno = EDOM; + break; + } + + /* Trigger a reserved operand fault. */ + { + double result; + asm volatile("emodd %1, %1, %2, %0, %0" : "=r" (result) : + "i" (0), "i" (0x8000)); + return result; + } +} + +#endif + +weak_alias (__infnan, infnan) diff --git a/sysdeps/vax/jmp_buf.h b/sysdeps/vax/jmp_buf.h new file mode 100644 index 0000000000..7adecd9a17 --- /dev/null +++ b/sysdeps/vax/jmp_buf.h @@ -0,0 +1,7 @@ +/* Define the machine-dependent type `jmp_buf'. Vax version. */ + +typedef struct + { + PTR __fp; + PTR __pc; + } __jmp_buf[1]; diff --git a/sysdeps/vax/log10.c b/sysdeps/vax/log10.c new file mode 100644 index 0000000000..08741779eb --- /dev/null +++ b/sysdeps/vax/log10.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> + +#ifndef FPCONST +#define FPCONST(hi0, lo0, hi1, lo1) { (lo0), (hi0), (lo1), (hi1) } +#endif + +static CONST short int ln10[] = FPCONST(0x4113, 0x5d8d, 0xddaa, 0xa8ac); +#define LN10 (*(CONST double *) ln10) + +#include <../sysdeps/generic/log10.c> diff --git a/sysdeps/vax/memccpy.c b/sysdeps/vax/memccpy.c new file mode 100644 index 0000000000..9849761f13 --- /dev/null +++ b/sysdeps/vax/memccpy.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <string.h> + + +/* Copy no more than N bytes of SRC to DEST, stopping when C is found. + Return the position in DEST one byte past where C was copied, + or NULL if C was not found in the first N bytes of SRC. */ +PTR +DEFUN(__memccpy, (dest, src, c, n), + PTR dest AND CONST PTR src AND int c AND size_t nbytes) +{ + /* Except when N > 65535, this is what a hand-coded version would + do anyway. */ + + PTR found = memchr (src, c, n); + + if (found == NULL) + { + (void) memcpy (dest, src, n); + return NULL; + } + + (void) memcpy (dest, src, (char *) found + 1 - (char *) src); + return (PTR) ((char *) dest + ((char *) found + 1 - (char *) src)); +} + +weak_alias (__memccpy, memccpy) diff --git a/sysdeps/vax/memchr.s b/sysdeps/vax/memchr.s new file mode 100644 index 0000000000..c7793fb5f8 --- /dev/null +++ b/sysdeps/vax/memchr.s @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)memchr.s 5.1 (Berkeley) 5/29/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the first occurence of c in the memory at cp (length n). + * Return pointer to match or null pointer. + * + * This code optimises the usual case (0 < n < 65535). + * + * void * + * memchr(cp, c, n) + * char *cp, c; + * size_t n; + */ + +#include "DEFS.h" + +ENTRY(memchr, 0) + movq 4(ap),r1 # r1 = cp; r2 = c + movl 12(ap),r0 # r0 = n + movzwl $65535,r4 # handy constant +0: + cmpl r0,r4 # check for annoying locc limit + bgtru 3f + + /* n <= 65535 */ + locc r2,r0,(r1) # search n bytes for c + beql 2f # done if not found (r0 already 0) +1: /* found character c at (r1) */ + movl r1,r0 +2: + ret + +3: /* n > 65535 */ + locc r2,r4,(r1) # search 65535 bytes for c + beql 1b # done if found + decw r0 # from 0 to 65535 + subl2 r0,r4 # adjust n + brb 0b # and loop diff --git a/sysdeps/vax/memcmp.s b/sysdeps/vax/memcmp.s new file mode 100644 index 0000000000..3854fd8e4a --- /dev/null +++ b/sysdeps/vax/memcmp.s @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)memcmp.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* int memcmp(s1, s2, n) */ + +#include "DEFS.h" + +ENTRY(memcmp, 0) + movl 4(ap),r1 /* r1 = s1 */ + movq 8(ap),r3 /* r3 = s2; r4 = n */ + movzwl $65535,r5 +0: + cmpl r4,r5 + jgtru 3f /* handle stupid cmpc3 limitation */ + cmpc3 r4,(r1),(r3) /* compare */ + beql 2f /* done if same (r0 = 0) */ +1: + movzbl (r1),r0 + movzbl (r3),r2 + subl2 r2,r0 /* return *s1 - *s2; s1,s2 unsigned chars */ +2: + ret +3: + subl2 r5,r4 /* do 64K; adjust count */ + cmpc3 r5,(r1),(r3) + jeql 0b /* loop if same */ + jbr 1b diff --git a/sysdeps/vax/memmove.s b/sysdeps/vax/memmove.s new file mode 100644 index 0000000000..8f897fa3f4 --- /dev/null +++ b/sysdeps/vax/memmove.s @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)memmove.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * void *memmove(dst, src, size) + * returns dst + * + * This optimises the usual case (count < 65536) at the expense + * of some extra memory references and branches when count >= 65536. + */ + +#include "DEFS.h" + +ENTRY(memmove, 0) + movzwl $65535,r0 /* r0 = 64K (needed below) */ + movq 8(ap),r1 /* r1 = src, r2 = length */ + movl 4(ap),r3 /* r3 = dst */ + cmpl r1,r3 + bgtru 1f /* normal forward case */ + beql 2f /* equal, nothing to do */ + addl2 r2,r1 /* overlaps iff src<dst but src+len>dst */ + cmpl r1,r3 + bgtru 4f /* overlapping, must move backwards */ + subl2 r2,r1 + +1: /* move forward */ + cmpl r2,r0 + bgtru 3f /* stupid movc3 limitation */ + movc3 r2,(r1),(r3) /* move it all */ +2: + movl 4(ap),r0 /* return original dst */ + ret +3: + subl2 r0,12(ap) /* adjust length by 64K */ + movc3 r0,(r1),(r3) /* move 64K */ + movl 12(ap),r2 + decw r0 /* from 0 to 65535 */ + brb 1b /* retry */ + +4: /* move backward */ + addl2 r2,r3 +5: + cmpl r2,r0 + bgtru 6f /* stupid movc3 limitation */ + subl2 r2,r1 + subl2 r2,r3 + movc3 r2,(r1),(r3) /* move it all */ + movl 4(ap),r0 /* return original dst */ + ret +6: + subl2 r0,12(ap) /* adjust length by 64K */ + subl2 r0,r1 + subl2 r0,r3 + movc3 r0,(r1),(r3) /* move 64K */ + movl 12(ap),r2 + decw r0 + subl2 r0,r1 + subl2 r0,r3 + brb 5b diff --git a/sysdeps/vax/memset.s b/sysdeps/vax/memset.s new file mode 100644 index 0000000000..12b1f74fe3 --- /dev/null +++ b/sysdeps/vax/memset.s @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)memset.s 5.2 (Berkeley) 5/12/91" +#endif /* LIBC_SCCS and not lint */ + +/* void *memset(base, c, length) */ + +#include "DEFS.h" + +ENTRY(memset, 0) + movl 4(ap),r3 +1: + movzwl $65535,r0 + movq 8(ap),r1 + cmpl r2,r0 + jgtru 2f + movc5 $0,(r3),r1,r2,(r3) + movl r1,r0 + ret +2: + subl2 r0,12(ap) + movc5 $0,(r3),r1,r0,(r3) + jbr 1b diff --git a/sysdeps/vax/ntohl.s b/sysdeps/vax/ntohl.s new file mode 100644 index 0000000000..0fcaa2f8e4 --- /dev/null +++ b/sysdeps/vax/ntohl.s @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)ntohl.s 5.5 (Berkeley) 6/27/88" +#endif /* LIBC_SCCS and not lint */ + +/* hostorder = ntohl(netorder) */ + +#include "DEFS.h" + +ENTRY(ntohl, 0) + rotl $-8,4(ap),r0 + insv r0,$16,$8,r0 + movb 7(ap),r0 + ret diff --git a/sysdeps/vax/ntohs.s b/sysdeps/vax/ntohs.s new file mode 100644 index 0000000000..626a37bf09 --- /dev/null +++ b/sysdeps/vax/ntohs.s @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)ntohs.s 5.5 (Berkeley) 6/27/88" +#endif /* LIBC_SCCS and not lint */ + +/* hostorder = ntohs(netorder) */ + +#include "DEFS.h" + +ENTRY(ntohs, 0) + rotl $8,4(ap),r0 + movb 5(ap),r0 + movzwl r0,r0 + ret diff --git a/sysdeps/vax/rindex.s b/sysdeps/vax/rindex.s new file mode 100644 index 0000000000..76d7e29597 --- /dev/null +++ b/sysdeps/vax/rindex.s @@ -0,0 +1,113 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)rindex.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the last occurence of c in the string cp. + * Return pointer to match or null pointer. + * + * char * + * rindex(cp, c) + * char *cp, c; + */ +#include "DEFS.h" + +ENTRY(rindex, 0) + movq 4(ap),r1 # r1 = cp; r2 = c + tstl r2 # check for special case c == '\0' + bneq 2f +1: + locc $0,$65535,(r1) # just find end of string + beql 1b # still looking + movl r1,r0 # found it + ret +2: + moval tbl,r3 # r3 = address of table + bbss $0,(r3),5f # insure not reentering + movab (r3)[r2],r5 # table entry for c + incb (r5) + clrl r4 # last found +3: + scanc $65535,(r1),(r3),$1 # look for c or '\0' + beql 3b # keep looking + tstb (r1) # if have found '\0' + beql 4f # we are done + movl r1,r4 # save most recently found + incl r1 # skip over character + jbr 3b # keep looking +4: + movl r4,r0 # return last found (if any) + clrb (r5) # clean up table + clrb (r3) + ret + + .data +tbl: .space 256 + .text + +/* + * Reentrant, but slower version of rindex + */ +5: + movl r1,r3 + clrl r4 # r4 = pointer to last match +6: + locc $0,$65535,(r3) # look for '\0' + bneq 8f + decw r0 # r0 = 65535 +1: + locc r2,r0,(r3) # look for c + bneq 7f + movl r1,r3 # reset pointer and ... + jbr 6b # ... try again +7: + movl r1,r4 # stash pointer ... + addl3 $1,r1,r3 # ... skip over match and ... + decl r0 # ... decrement count + jbr 6b # ... try again +8: + subl3 r3,r1,r0 # length of short block + incl r0 # +1 for '\0' +9: + locc r2,r0,(r3) # look for c + beql 0f + movl r1,r4 # stash pointer ... + addl3 $1,r1,r3 # ... skip over match ... + decl r0 # ... adjust count and ... + jbr 9b # ... try again +0: + movl r4,r0 # return stashed pointer + ret diff --git a/sysdeps/vax/setjmp.c b/sysdeps/vax/setjmp.c new file mode 100644 index 0000000000..9d711cbfda --- /dev/null +++ b/sysdeps/vax/setjmp.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. + Derived from @(#)_setjmp.s 5.7 (Berkeley) 6/27/88, + Copyright (c) 1980 Regents of the University of California. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <setjmp.h> + + +/* Save the current program position in ENV and return 0. */ +int +__sigsetjmp (jmp_buf env, int savemask) +{ + /* Save our caller's FP and PC. */ + asm ("movl 12(fp), %0" : "=g" (env[0].__jmpbuf[0].__fp)); + asm ("movl 16(fp), %0" : "=g" (env[0].__jmpbuf[0].__pc)); + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} diff --git a/sysdeps/vax/strcat.s b/sysdeps/vax/strcat.s new file mode 100644 index 0000000000..7cf8884204 --- /dev/null +++ b/sysdeps/vax/strcat.s @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strcat.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Concatenate string s2 to the end of s1 + * and return the base of s1. + * + * char * + * strcat(s1, s2) + * char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strcat, R6|R7) + movq 4(ap), r6 # r6 = s1; r7 = s2 + movl r6,r1 +0: + locc $0,$65535,(r1) # look for '\0' + beql 0b + movl r1,r3 # save end of s1 +1: + locc $0,$65535,(r7) # find length of s2 + bneq 2f + movc3 $65535,(r7),(r3)# copy full block + movl r1,r7 + jbr 1b +2: + subl2 r7,r1 # calculate length + incl r1 + movc3 r1,(r7),(r3) # copy remainder + movl r6,r0 + ret diff --git a/sysdeps/vax/strchr.s b/sysdeps/vax/strchr.s new file mode 100644 index 0000000000..18b53838ec --- /dev/null +++ b/sysdeps/vax/strchr.s @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1988 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) + .asciz "@(#)strchr.s 5.4 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the first occurence of c in the string cp. + * Return pointer to match or null pointer. + * + * char * + * strchr(cp, c) + * char *cp, c; + */ +#include "DEFS.h" + + .lcomm tbl,256 + +ENTRY(strchr, 0) + movzwl $65535,r4 /* handy constant */ + movq 4(ap),r1 /* r1 = cp; r2 = c */ + movzbl r2,r2 + beql Lzero /* special case for c == '\0' */ + +/* + * Fancy scanc version. Alas, it is not reentrant. + */ + movab tbl,r3 /* r3 = base of table */ + bbss $0,(r3),Lreent /* ensure not reentering */ + movab (r3)[r2],r5 + incb (r5) /* mark both '\0' and c */ +0: + scanc r4,(r1),(r3),$1 /* look for c or '\0' */ + beql 0b /* still looking */ + movl r1,r0 /* return whatever we found */ + tstb (r0) + bneq 1f # unless it was '\0': + clrl r0 # then return NULL +1: + clrb (r5) /* clean up table */ + clrb (r3) + ret + +/* + * Special case for \0. + */ +Lzero: + locc r2,r4,(r1) /* just find end of string */ + beql Lzero /* still looking */ + movl r1,r0 /* found it */ + ret + +/* + * Slower reentrant version is two two-step searches. The first + * phase runs until we know where the string ends; it locates the + * first occurrence of c within a 65535-byte block. If we find + * the end of the string first, we switch to the second phase, + * were we look only up to the known end of string. + */ +Lreent: +0: /* first phase */ + movl r1,r3 + locc $0,r4,(r3) /* look for '\0' */ + bneq 1f + locc r2,r4,(r3) /* look for c */ + beql 0b /* not found: reset pointer and loop */ + movl r1,r0 /* found: return it */ + ret +1: /* second phase */ + subl3 r3,r1,r0 /* length of short block */ + locc r2,r0,(r3) /* look for c */ + beql 2f /* not found: return NULL */ + movl r1,r0 +2: ret diff --git a/sysdeps/vax/strcpy.s b/sysdeps/vax/strcpy.s new file mode 100644 index 0000000000..56dbe5741c --- /dev/null +++ b/sysdeps/vax/strcpy.s @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strcpy.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Copy string s2 over top of s1. + * Return base of s1. + * + * char * + * strcpy(s1, s2) + * char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strcpy, R6) + movl 4(ap), r3 # r3 = s1 + movl 8(ap), r6 # r6 = s2 +1: + locc $0,$65535,(r6) # find length of s2 + bneq 2f + movc3 $65535,(r6),(r3)# copy full block + movl r1,r6 + jbr 1b +2: + subl2 r6,r1 # calculate length + incl r1 + movc3 r1,(r6),(r3) # copy remainder + movl 4(ap),r0 # return base of s1 + ret diff --git a/sysdeps/vax/strcspn.s b/sysdeps/vax/strcspn.s new file mode 100644 index 0000000000..f7b0a99792 --- /dev/null +++ b/sysdeps/vax/strcspn.s @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)strcspn.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Span the complement of string s2 (skip characters that are not in s2). + * Return the number of characters in s1 that were skipped. + * + * size_t + * strcspn(s1, s2) + * const char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strcspn, 0) + subl2 $32,sp /* make 256 bit table */ + movc5 $0,(sp),$0,$32,(sp) + movq 4(ap),r1 /* r1 = s1, r2 = s2 */ + + /* turn on bit for each character in s2, including '\0' */ +1: + movzbl (r2)+,r0 + bbss r0,(sp),1b + bneq 1b + movl r1,r0 /* r0 = s (current pos in s1) */ + + /* look for a character that is in s2 */ +2: + movzbl (r0)+,r2 /* c = *s++ */ + bbc r2,(sp),2b /* loop until c is in table */ + decl r0 /* s-- */ + subl2 r1,r0 /* r0 = s - s1 = count */ + ret diff --git a/sysdeps/vax/strlen.s b/sysdeps/vax/strlen.s new file mode 100644 index 0000000000..2b7e0a7ef4 --- /dev/null +++ b/sysdeps/vax/strlen.s @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strlen.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Return the length of cp (not counting '\0'). + * + * strlen(cp) + * char *cp; + */ +#include "DEFS.h" + +ENTRY(strlen, 0) + movl 4(ap),r1 +1: + locc $0,$65535,(r1) # look for '\0' + beql 1b + subl3 4(ap),r1,r0 # len = cp - base + ret diff --git a/sysdeps/vax/strncat.s b/sysdeps/vax/strncat.s new file mode 100644 index 0000000000..bcf29c16c7 --- /dev/null +++ b/sysdeps/vax/strncat.s @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strncat.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Concatenate string s2 on the end of s1 + * and return the base of s1. The parameter + * n is the maximum length of string s2 to + * concatenate. + * + * char * + * strncat(s1, s2, n) + * char *s1, *s2; + * int n; + */ +#include "DEFS.h" + +ENTRY(strncat, R6) + movl 12(ap),r6 # r6 = n + bleq done # n <= 0 + movl 4(ap),r3 # r3 = s1 + movl r3,r1 +0: + locc $0,$65535,(r1) + beql 0b + movl r1,r3 # r3 = index(s1, '\0'); + movl 8(ap),r1 # r1 = s2 +1: + movzwl $65535,r2 # r2 = bytes in first chunk + cmpl r6,r2 # r2 = min(bytes in chunk, n); + jgeq 2f + movl r6,r2 +2: + subl2 r2,r6 # update n + locc $0,r2,(r1) # '\0' found? + jneq 3f + subl2 r2,r1 # back up pointer updated by locc + movc3 r2,(r1),(r3) # copy in next piece + tstl r6 # run out of space? + jneq 1b + clrb (r3) # force '\0' termination + jbr done +3: + subl2 r0,r2 # r2 = number of bytes to move + subl2 r2,r1 # back up pointer updated by locc + incl r2 # copy '\0' as well + movc3 r2,(r1),(r3) # copy in last piece +done: + movl 4(ap),r0 # return s1 + ret diff --git a/sysdeps/vax/strncmp.s b/sysdeps/vax/strncmp.s new file mode 100644 index 0000000000..e5bfcf2a73 --- /dev/null +++ b/sysdeps/vax/strncmp.s @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strncmp.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Compare at most n characters of string + * s1 lexicographically to string s2. + * Return: + * 0 s1 == s2 + * > 0 s1 > s2 + * < 0 s2 < s2 + * + * strncmp(s1, s2, n) + * char *s1, *s2; + * int n; + */ +#include "DEFS.h" + +ENTRY(strncmp, 0) + movl 4(ap),r1 # r1 = s1 + movq 8(ap),r3 # r3 = s2; r4 = n +1: + clrl r5 # calculate min bytes to next page boundry + subb3 r1,$255,r5 # r5 = (bytes - 1) to end of page for s1 + subb3 r3,$255,r0 # r0 = (bytes - 1) to end of page for s2 + cmpb r0,r5 # r5 = min(r0, r5); + bgtru 2f + movb r0,r5 +2: + incl r5 # r5 = min bytes to next page boundry + cmpl r4,r5 # r5 = min(n, r5); + bgeq 3f + movl r4,r5 +3: + cmpc3 r5,(r1),(r3) # compare strings + bneq 4f + subl2 r5,r4 # check for end of comparison + beql 5f + subl2 r5,r1 # check if found null yet + locc $0,r5,(r1) + beql 1b # not yet done, continue checking + subl2 r0,r3 + mnegb (r3),r0 # r0 = '\0' - *s2 + cvtbl r0,r0 + ret +4: + subl2 r0,r5 # check for null in matching string + subl2 r5,r1 + locc $0,r5,(r1) + bneq 5f + subb3 (r3),(r1),r0 # r0 = *s1 - *s2 + cvtbl r0,r0 + ret +5: + clrl r0 # both the same to null + ret diff --git a/sysdeps/vax/strncpy.s b/sysdeps/vax/strncpy.s new file mode 100644 index 0000000000..03a09b7bda --- /dev/null +++ b/sysdeps/vax/strncpy.s @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1983 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) + .asciz "@(#)strncpy.s 5.6 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Copy string s2 over top of string s1. + * Truncate or null-pad to n bytes. + * + * char * + * strncpy(s1, s2, n) + * char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strncpy, R6) + movl 12(ap),r6 # r6 = n + bleq done # n <= 0 + movl 4(ap),r3 # r3 = s1 + movl 8(ap),r1 # r1 = s2 +1: + movzwl $65535,r2 # r2 = bytes in first chunk + cmpl r6,r2 # r2 = min(bytes in chunk, n); + jgeq 2f + movl r6,r2 +2: + subl2 r2,r6 # update n + locc $0,r2,(r1) # '\0' found? + jneq 3f + subl2 r2,r1 # back up pointer updated by locc + movc3 r2,(r1),(r3) # copy in next piece + tstl r6 # run out of space? + jneq 1b + jbr done +3: # copy up to '\0' logic + addl2 r0,r6 # r6 = number of null-pad bytes + subl2 r0,r2 # r2 = number of bytes to move + subl2 r2,r1 # back up pointer updated by locc + movc3 r2,(r1),(r3) # copy in last piece +4: # null-pad logic + movzwl $65535,r2 # r2 = bytes in first chunk + cmpl r6,r2 # r2 = min(bytes in chunk, n); + jgeq 5f + movl r6,r2 +5: + subl2 r2,r6 # update n + movc5 $0,(r3),$0,r2,(r3)# pad with '\0's + tstl r6 # finished padding? + jneq 4b +done: + movl 4(ap),r0 # return s1 + ret diff --git a/sysdeps/vax/strpbrk.s b/sysdeps/vax/strpbrk.s new file mode 100644 index 0000000000..0d1b25e22f --- /dev/null +++ b/sysdeps/vax/strpbrk.s @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)strpbrk.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find in s1 the first occurrence of any character from s2. + * If there are none, return NULL. + * + * char * + * strpbrk(s1, s2) + * const char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strpbrk, 0) + subl2 $32,sp /* make 256 bit table */ + movc5 $0,(sp),$0,$32,(sp) + movq 4(ap),r0 /* r0 = s1, r1 = s2 */ + + /* turn on bit for each character in s2, including '\0' */ +1: + movzbl (r1)+,r2 + bbss r2,(sp),1b + bneq 1b + + /* look for a character that is in s2 */ +2: + movzbl (r0)+,r2 /* c = *s++ */ + bbc r2,(sp),2b /* loop until c is in table */ + beql 3f /* if c==0, go return NULL */ + decl r0 /* s-- */ + ret +3: + clrl r0 + ret diff --git a/sysdeps/vax/strrchr.s b/sysdeps/vax/strrchr.s new file mode 100644 index 0000000000..f292eaceab --- /dev/null +++ b/sysdeps/vax/strrchr.s @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1988 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) + .asciz "@(#)strrchr.s 5.4 (Berkeley) 6/1/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the last occurence of c in the string cp. + * Return pointer to match or null pointer. + * + * char * + * strrchr(cp, c) + * char *cp, c; + */ +#include "DEFS.h" + + .lcomm tbl,256 + +ENTRY(strrchr, 0) + movzwl $65535,r4 /* handy 65535 */ + movq 4(ap),r1 /* r1 = cp; r2 = c */ + movzbl r2,r2 + beql Lzero /* special case for c == '\0' */ + + clrl r5 /* r5 = pointer to last match */ + +/* + * Fancy scanc version. Alas, it is not reentrant. + */ + movab tbl,r3 /* r3 = address of table */ + bbss $0,(r3),Lreent /* ensure not reentering */ + movab (r3)[r2],r4 + incb (r4) /* mark both '\0' and c */ +0: + scanc $65535,(r1),(r3),$1 /* look for c or '\0' */ + beql 0b /* keep looking */ + tstb (r1) + beql 1f /* done if '\0' */ + movab (r1)+,r5 /* save most recently found, and skip over it */ + jbr 0b /* keep looking */ +1: + movl r5,r0 /* return last found (if any) */ + clrb (r4) /* clean up table */ + clrb (r3) + ret + +/* + * Special case for \0. + */ +Lzero: + locc $0,r4,(r1) /* just find end of string */ + beql Lzero /* still looking */ + movl r1,r0 /* found it */ + ret + +/* + * Slower reentrant version is two two-step searches. The first + * phase runs until we know where the string ends; it locates any + * occurrences of c within a 65535-byte block. Once we have found + * the end of the string, we find any further occurrences before + * that location. + */ +Lreent: +0: /* first phase */ + movl r1,r3 + locc $0,r4,(r3) /* look for '\0' */ + bneq 1f + locc r2,r4,(r3) /* continue phase 1 search for c */ + beql 0b + movab (r1)+,r5 /* found c: save and increment pointer */ + brb 0b /* and continue */ + +1: /* second phase */ + subl3 r3,r1,r0 /* length of short block */ + movl r3,r1 +2: + locc r2,r0,(r1) /* look for c */ + beql 3f /* skip if not found */ + movab (r1)+,r5 /* save pointer as before */ + sobgtr r0,2b /* adjust count and loop */ +3: + movl r5,r0 /* return stashed pointer */ + ret diff --git a/sysdeps/vax/strsep.s b/sysdeps/vax/strsep.s new file mode 100644 index 0000000000..9751acc699 --- /dev/null +++ b/sysdeps/vax/strsep.s @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)strsep.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Get next word from string *stringp, where words are + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strtoken returns NULL. + * + * char * + * strtoken(stringp, delim) + * register char **stringp; + * register char const *delim; + */ +#include "DEFS.h" + +ENTRY(strsep, 0) + tstl *4(ap) /* if (*stringp == NULL) */ + bneq 0f + clrl r0 # return (NULL); + ret + +0: + subl2 $32,sp /* make room for 256 bit table */ + movc5 $0,(sp),$0,$32,(sp) + movq 4(ap),r1 /* r1 = stringp, r2 = delim */ + + /* turn on bit for each character in s2, including '\0' */ +1: + movzbl (r2)+,r0 + bbss r0,(sp),1b + bneq 1b + + movl (r1),r3 /* r3 = s = *stringp */ + movl r3,r0 /* save return value */ + + /* scan for delimiters */ +2: + movzbl (r3)+,r2 /* c = *s++ */ + bbc r2,(sp),2b /* loop until c is in table */ + beql 3f + clrb -1(r3) /* if c!='\0', s[-1] = 0 */ + movl r3,(r1) /* and *stringp = s */ + ret +3: + clrl (r1) /* else *stringp = NULL */ + ret diff --git a/sysdeps/vax/strspn.s b/sysdeps/vax/strspn.s new file mode 100644 index 0000000000..fc86af7c37 --- /dev/null +++ b/sysdeps/vax/strspn.s @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)strspn.s 5.1 (Berkeley) 5/15/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Span the string s2 (skip characters that are in s2). + * Return the number of characters in s1 that were skipped. + * + * size_t + * strspn(s1, s2) + * const char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strspn, 0) + subl2 $32,sp /* make 256 bit table */ + movc5 $0,(sp),$0,$32,(sp) + movq 4(ap),r1 /* r1 = s1, r2 = s2 */ + + /* turn on bit for each character in s2, including '\0' */ +1: + movzbl (r2)+,r0 + bbss r0,(sp),1b + bneq 1b + + /* now clear bit for '\0' */ + /* (this is easier than avoiding setting it in the first place) */ + bicb2 $1,(sp) /* stop at '\0' */ + movl r1,r0 /* r0 = s (current pos in s1) */ + + /* look for a character that is not in s2 */ +2: + movzbl (r0)+,r2 /* c = *s++ */ + bbs r2,(sp),2b /* loop while c is in table */ + decl r0 /* s-- */ + subl2 r1,r0 /* r0 = s - s1 = count */ + ret diff --git a/sysdeps/vax/strstr.s b/sysdeps/vax/strstr.s new file mode 100644 index 0000000000..2e5337595d --- /dev/null +++ b/sysdeps/vax/strstr.s @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 1990 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) + .asciz "@(#)strstr.s 5.2 (Berkeley) 8/21/90" +#endif /* LIBC_SCCS and not lint */ + +/* + * Find the first occurrence of s2 as a substring in s1. + * If s2 is empty, return s1. + * + * char *strstr(s1, s2) + * const char *s1, *s2; + */ +#include "DEFS.h" + +ENTRY(strstr, 0) + movq 4(ap),r3 /* r3 = s1, r4 = s2 */ + movzwl $65535,r2 /* r2 = locc/matchc limit */ + locc $0,r2,(r4) /* find '\0' in s2 */ + beql 4f + subl3 r4,r1,r5 /* r5 = strlen(s2) */ + beql 1f /* if r5 == 0, return s1 */ + + /* + * s2 is short enough to apply matchc. + * If s1 is long, we have to do it in stages. + */ +0: locc $0,r2,(r3) /* find '\0' in s1 */ + beql 3f + + /* + * Both strings are `short'; we can use matchc directly. + */ + subl3 r3,r1,r1 /* r1 = strlen(s1) */ + matchc r5,(r4),r1,(r3) /* find substring */ + bneq 2f + + /* + * r3 points r5 bytes past match. Return the match. + */ +1: subl3 r5,r3,r0 /* return (byte_past_match - strlen(s2)) */ + ret + + /* + * There is no matching substring. + */ +2: clrl r0 /* return NULL */ + ret + + /* + * s1 is too long (> 65535 bytes) to apply matchc directly, + * but s2 is short enough. Apply s2 to s1, then (if not + * found yet) advancing s1 by (65536-strlen(s2)) bytes and + * loop. + */ +3: matchc r5,(r4),r2,(r3) /* search */ + beql 1b /* if found, go return it */ + decw r2 /* from 0 to 65535 */ + incl r3 /* already advanced 65535, now 65536 */ + subl2 r5,r3 /* ... minus strlen(s2) */ + brb 0b + + /* + * s2 is too long (> 65535 bytes) to bother with matchc. + */ +4: locc $0,r2,(r1) /* continue working on strlen(s2) */ + beql 4b + subl3 r1,r4,r5 /* r5 = strlen(s2) */ + movb (r4)+,r2 /* r2 = *s2++ */ + decl r5 /* fix up length */ +5: movb (r3)+,r0 /* r0 = *s1++ */ + beql 2b /* if '\0', return NULL */ + cmpb r0,r2 + bneq 5b /* loop until first char found */ + pushr R5|R4|R3|R2 /* save c, s1, s2, n */ + pushr R5|R4|R3 /* strncmp(s1, s2, n) */ + calls $3,_strncmp + popr R2|R3|R4|R5 /* restore */ + tstl r0 + bneq 5b /* loop until strncmp says rest same too */ + subl3 $1,r3,r0 /* return previous s1 */ + ret diff --git a/sysdeps/z8000/gmp-mparam.h b/sysdeps/z8000/gmp-mparam.h new file mode 100644 index 0000000000..73df5b9d4e --- /dev/null +++ b/sysdeps/z8000/gmp-mparam.h @@ -0,0 +1,26 @@ +/* gmp-mparam.h -- Compiler/machine parameter header file. + +Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define BITS_PER_MP_LIMB 16 +#define BYTES_PER_MP_LIMB 2 +#define BITS_PER_LONGINT 32 +#define BITS_PER_INT 16 +#define BITS_PER_SHORTINT 16 +#define BITS_PER_CHAR 8 diff --git a/syslog.h b/syslog.h new file mode 100644 index 0000000000..4cfb7723bb --- /dev/null +++ b/syslog.h @@ -0,0 +1 @@ +#include <misc/syslog.h> @@ -0,0 +1 @@ +#include <posix/tar.h> diff --git a/termios.h b/termios.h new file mode 100644 index 0000000000..3f754ac900 --- /dev/null +++ b/termios.h @@ -0,0 +1 @@ +#include <termios/termios.h> diff --git a/termios/Makefile b/termios/Makefile new file mode 100644 index 0000000000..bf534d7a66 --- /dev/null +++ b/termios/Makefile @@ -0,0 +1,28 @@ +# Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for the terminal I/O functions. +# +subdir := termios + +headers := termios.h termbits.h sys/ttydefaults.h sys/termios.h +routines := speed cfsetspeed tcsetattr tcgetattr tcgetpgrp tcsetpgrp \ + tcdrain tcflow tcflush tcsendbrk cfmakeraw + +include ../Rules diff --git a/termios/cfmakeraw.c b/termios/cfmakeraw.c new file mode 100644 index 0000000000..09f630b906 --- /dev/null +++ b/termios/cfmakeraw.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <termios.h> + +/* Set *T to indicate raw mode. */ +void +DEFUN(cfmakeraw, (termios_p), struct termios *t) +{ + t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8; + t->c_cc[VMIN] = 0; + /* t->c_cc[VTIME] = ?; */ +} diff --git a/termios/cfsetspeed.c b/termios/cfsetspeed.c new file mode 100644 index 0000000000..a4a205b52f --- /dev/null +++ b/termios/cfsetspeed.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <termios.h> +#include <errno.h> +#include <stddef.h> + +/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */ +void +DEFUN(cfsetspeed, (termios_p, speed), + struct termios *termios_p AND speed_t speed) +{ + cfsetispeed (termios_p, speed); + cfsetospeed (termios_p, speed); +} diff --git a/termios/sys/termios.h b/termios/sys/termios.h new file mode 100644 index 0000000000..3e18805ab4 --- /dev/null +++ b/termios/sys/termios.h @@ -0,0 +1,4 @@ +#ifndef _SYS_TERMIOS_H +#define _SYS_TERMIOS_H +#include <termios.h> +#endif diff --git a/termios/sys/ttydefaults.h b/termios/sys/ttydefaults.h new file mode 100644 index 0000000000..1a8aaa5bd0 --- /dev/null +++ b/termios/sys/ttydefaults.h @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ttydefaults.h 8.4 (Berkeley) 1/21/94 + */ + +/* + * System wide defaults for terminal state. + */ +#ifndef _SYS_TTYDEFAULTS_H_ +#define _SYS_TTYDEFAULTS_H_ + +/* + * Defaults on "first" open. + */ +#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY) +#define TTYDEF_OFLAG (OPOST | ONLCR | OXTABS) +#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) +#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL) +#define TTYDEF_SPEED (B9600) + +/* + * Control Character Defaults + */ +#define CTRL(x) (x&037) +#define CEOF CTRL('d') +#define CEOL ((unsigned char)'\377') /* XXX avoid _POSIX_VDISABLE */ +#define CERASE 0177 +#define CINTR CTRL('c') +#define CSTATUS ((unsigned char)'\377') /* XXX avoid _POSIX_VDISABLE */ +#define CKILL CTRL('u') +#define CMIN 1 +#define CQUIT 034 /* FS, ^\ */ +#define CSUSP CTRL('z') +#define CTIME 0 +#define CDSUSP CTRL('y') +#define CSTART CTRL('q') +#define CSTOP CTRL('s') +#define CLNEXT CTRL('v') +#define CDISCARD CTRL('o') +#define CWERASE CTRL('w') +#define CREPRINT CTRL('r') +#define CEOT CEOF +/* compat */ +#define CBRK CEOL +#define CRPRNT CREPRINT +#define CFLUSH CDISCARD + +/* PROTECTED INCLUSION ENDS HERE */ +#endif /* !_SYS_TTYDEFAULTS_H_ */ + +/* + * #define TTYDEFCHARS to include an array of default control characters. + */ +#ifdef TTYDEFCHARS +cc_t ttydefchars[NCCS] = { + CEOF, CEOL, CEOL, CERASE, CWERASE, CKILL, CREPRINT, + _POSIX_VDISABLE, CINTR, CQUIT, CSUSP, CDSUSP, CSTART, CSTOP, CLNEXT, + CDISCARD, CMIN, CTIME, CSTATUS, _POSIX_VDISABLE +}; +#undef TTYDEFCHARS +#endif diff --git a/termios/termios.h b/termios/termios.h new file mode 100644 index 0000000000..f2e83a56f9 --- /dev/null +++ b/termios/termios.h @@ -0,0 +1,98 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 7.1-2 General Terminal Interface <termios.h> + */ + +#ifndef _TERMIOS_H + +#define _TERMIOS_H 1 +#include <features.h> + +__BEGIN_DECLS + +/* Get the system-dependent definitions of `struct termios', `tcflag_t', + `cc_t', `speed_t', and all the macros specifying the flag bits. */ +#include <termbits.h> + +#ifdef __USE_BSD +/* Compare a character C to a value VAL from the `c_cc' array in a + `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. */ +#define CCEQ(val, c) ((c) == (val) && (val) != _POSIX_VDISABLE) +#endif + +/* Return the output baud rate stored in *TERMIOS_P. */ +extern speed_t cfgetospeed __P ((__const struct termios *__termios_p)); + +/* Return the input baud rate stored in *TERMIOS_P. */ +extern speed_t cfgetispeed __P ((__const struct termios *__termios_p)); + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +extern int cfsetospeed __P ((struct termios *__termios_p, speed_t __speed)); + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. */ +extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed)); + +#ifdef __USE_BSD +/* Set both the input and output baud rates in *TERMIOS_OP to SPEED. */ +extern void cfsetspeed __P ((struct termios *__termios_p, speed_t __speed)); +#endif + + +/* Put the state of FD into *TERMIOS_P. */ +extern int __tcgetattr __P ((int __fd, struct termios *__termios_p)); +extern int tcgetattr __P ((int __fd, struct termios *__termios_p)); + +#ifdef __OPTIMIZE__ +#define tcgetattr(fd, termios_p) __tcgetattr((fd), (termios_p)) +#endif /* Optimizing. */ + +/* Set the state of FD to *TERMIOS_P. + Values for OPTIONAL_ACTIONS (TCSA*) are in <termbits.h>. */ +extern int tcsetattr __P ((int __fd, int __optional_actions, + __const struct termios *__termios_p)); + + +#ifdef __USE_BSD +/* Set *TERMIOS_P to indicate raw mode. */ +extern void cfmakeraw __P ((struct termios *__termios_p)); +#endif + +/* Send zero bits on FD. */ +extern int tcsendbreak __P ((int __fd, int __duration)); + +/* Wait for pending output to be written on FD. */ +extern int tcdrain __P ((int __fd)); + +/* Flush pending data on FD. + Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <termbits.h>. */ +extern int tcflush __P ((int __fd, int __queue_selector)); + +/* Suspend or restart transmission on FD. + Values for ACTION (TC[IO]{OFF,ON}) are in <termbits.h>. */ +extern int tcflow __P ((int __fd, int __action)); + + +#ifdef __USE_BSD +#include <sys/ttydefaults.h> +#endif + +__END_DECLS + +#endif /* termios.h */ diff --git a/time.h b/time.h new file mode 100644 index 0000000000..b2a33bf5c3 --- /dev/null +++ b/time.h @@ -0,0 +1 @@ +#include <time/time.h> diff --git a/time/.cvsignore b/time/.cvsignore new file mode 100644 index 0000000000..1f69fd919a --- /dev/null +++ b/time/.cvsignore @@ -0,0 +1,4 @@ +*.gz *.Z *.tar *.tgz +=* +TODO COPYING* AUTHORS copyr-* copying.* +glibc-* diff --git a/time/Makefile b/time/Makefile new file mode 100644 index 0000000000..684fa51a53 --- /dev/null +++ b/time/Makefile @@ -0,0 +1,126 @@ +# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., 675 Mass Ave, +# Cambridge, MA 02139, USA. + +# +# Makefile for time routines +# +subdir := time + +headers := time.h sys/time.h sys/timeb.h +distribute := tzfile.h private.h scheck.c ialloc.c emkdir.c yearistype +extra-objs = scheck.o ialloc.o emkdir.o zonenames $(tzfiles:%=z.%) + +routines := offtime asctime clock ctime difftime gmtime \ + localtime mktime strftime time tzset tzfile \ + gettimeofday settimeofday adjtime \ + getitimer setitimer \ + stime dysize timegm ftime + +others := ap zdump zic +tests := test_time clocktest + +tzfiles := africa antarctica asia australasia europe northamerica \ + southamerica etcetera factory systemv backward +# pacificnew doesn't compile; if it is to be used, it should be included in +# northamerica. +distribute := $(distribute) $(tzfiles) leapseconds pacificnew + +install-sbin := zic zdump + +include ../Makeconfig # Get objpfx defined so we can use it below. + +# zonenames uses this variable. +define nl + + +endef +include $(objpfx)zonenames + +# Make these absolute file names. +installed-localtime-file := $(firstword $(filter /%,$(localtime-file)) \ + $(addprefix $(zonedir)/, \ + $(localtime-file))) +installed-posixrules-file := $(firstword $(filter /%,$(posixrules-file)) \ + $(addprefix $(zonedir)/, \ + $(posixrules-file))) + +ifndef cross-compiling +# Don't try to install the zoneinfo files since we can't run zic. +install-others = $(addprefix $(zonedir)/,$(zonenames)) \ + $(installed-localtime-file) $(installed-posixrules-file) +endif + +include ../Rules + + +$(tzfiles:%=$(objpfx)z.%): $(objpfx)z.%: % Makefile +# Kludge alert: we use an implicit rule (in what we are generating here) +# because that is the only way to tell Make that the one command builds all +# the files. + (echo 'define $*-zones' ;\ + awk '$$1 == "Zone" { print $$2 } $$1 == "Link" { print $$3 }' $^;\ + echo 'endef' ;\ + echo '$*-zones := $$(subst $$(nl), ,$$($*-zones))' ;\ + echo 'ifdef $*-zones' ;\ + echo '$$(addprefix $$(datadir)/zone%/,$$($*-zones)): \' ;\ + echo '$< $$(objpfx)zic leapseconds yearistype' ;\ + echo ' $$(tzcompile)' ;\ + echo 'endif' ;\ + echo 'zonenames := $$(zonenames) $$($*-zones)' ;\ + ) > $@.new + mv $@.new $@ +$(objpfx)zonenames: Makefile + (for file in $(tzfiles); do \ + echo "include \$$(objpfx)z.$$file"; \ + done) > $@.new + mv $@.new $@ + +.PHONY: echo-zonenames +echo-zonenames: zonenames + @echo 'Known zones: $(zonenames)' + + +# Although $(zonedir) gets compiled into zic, it is useful to always +# specify it with -d on the command line so that it can be overridden on +# the command line of `make install' (e.g., "make install prefix=/foo"). +zic-cmd = $(dir $(word 2,$^))$(notdir $(word 2,$^)) -d $(zonedir) +define tzcompile +$(zic-cmd) -L $(word 3,$^) -y $(dir $(word 4,$^))$(notdir $(word 4,$^)) $< +endef + +ifdef localtime +$(installed-localtime-file): $(zonedir)/$(localtime) $(objpfx)zic + $(zic-cmd) -l $(localtime) +endif +ifdef posixrules +$(installed-posixrules-file): $(zonedir)/$(posixrules) $(objpfx)zic + $(zic-cmd) -p $(posixrules) +endif + + +$(objpfx)zic: $(objpfx)scheck.o $(objpfx)ialloc.o $(objpfx)emkdir.o + +$(objpfx)tzfile.o: tzfile.c; $(tz-cc) +$(objpfx)zic.o: zic.c; $(tz-cc) + +# Some versions of GNU make have a bug with backslashes in define directives. +tz-cc = $(COMPILE.c) $(+gcc-nowarn) \ + -DTZDIR='"$(zonedir)"' \ + -DTZDEFAULT='"$(localtime-file)"' \ + -DTZDEFRULES='"$(posixrules-file)"' \ + $< $(OUTPUT_OPTION) diff --git a/time/africa b/time/africa new file mode 100644 index 0000000000..a9786670b5 --- /dev/null +++ b/time/africa @@ -0,0 +1,603 @@ +# @(#)africa 7.6 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I added so many Zone names that the old, mostly flat name space was unwieldy. +# So I renamed the Zones to have the form AREA/LOCATION, where +# AREA is the name of a continent or ocean, and +# LOCATION is the name of a specific location within that region. +# For example, the old zone name `Egypt' is now `Africa/Cairo'. +# +# Here are the general rules I used for choosing location names, +# in decreasing order of importance: +# +# Use only valid Posix file names. Use only Ascii letters, digits, `.', +# `-' and `_'. Do not exceed 14 characters or start with `-'. +# E.g. prefer `Brunei' to `Bandar_Seri_Begawan'. +# Include at least one location per time zone rule set per country. +# One such location is enough. +# If a name is ambiguous, use a less ambiguous alternative; +# e.g. many cities are named San Jose and Georgetown, so +# prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'. +# Keep locations compact. Use cities or small islands, not countries +# or regions, so that any future time zone changes do not split +# locations into different time zones. E.g. prefer `Paris' +# to `France', since France has had multiple time zones. +# Use traditional English spelling, e.g. prefer `Rome' to `Roma', and +# prefer `Athens' to the true name (which uses Greek letters). +# The Posix file name restrictions encourage this rule. +# Use the most populous among locations in a country's time zone, +# e.g. prefer `Shanghai' to `Beijing'. Among locations with +# similar populations, pick the best-known location, +# e.g. prefer `Rome' to `Milan'. +# Use the singular form, e.g. prefer `Canary' to `Canaries'. +# Omit common suffixes like `_Islands' and `_City', unless that +# would lead to ambiguity. E.g. prefer `Cayman' to +# `Cayman_Islands' and `Guatemala' to `Guatemala_City', +# but prefer `Mexico_City' to `Mexico' because the country +# of Mexico has several time zones. +# Use `_' to represent a space. +# Omit `.' from abbreviations in names, e.g. prefer `St_Helena' +# to `St._Helena'. +# +# We typically use traditional English time zone abbreviations, +# and assume that applications translate them to other languages +# as part of the normal localization process. +# +# I made up the following time zone abbreviations; corrections are welcome! +# LMT Local Mean Time +# -2:00 CVT Cape Verde Time (no longer used) +# -1:00 AAT Atlantic Africa Time +# 0:00 WAT West Africa Time +# 1:00 CAT Central Africa Time +# 2:00 SAT South Africa Time +# 3:00 EAT East Africa Time +# 4:00 SMT Seychelles and Mascarene Time +# The final `T' is replaced by `ST' for summer time, e.g. `SAST'. +# BEAT is British East Africa Time, which was 2:30 before 1948 and 2:45 after. + + +# Algeria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Algeria 1911 only - Jan 1 0:00s 0 - +Rule Algeria 1916 only - Jun 14 23:00s 1:00 " DST" +Rule Algeria 1916 1919 - Oct Sun<=7 23:00s 0 - +Rule Algeria 1917 only - Mar 24 23:00s 1:00 " DST" +Rule Algeria 1918 only - Mar 9 23:00s 1:00 " DST" +Rule Algeria 1919 only - Mar 1 23:00s 1:00 " DST" +Rule Algeria 1920 only - Feb 14 23:00s 1:00 " DST" +Rule Algeria 1920 only - Oct 23 23:00s 0 - +Rule Algeria 1921 only - Mar 14 23:00s 1:00 " DST" +Rule Algeria 1921 only - Jun 21 23:00s 0 - +Rule Algeria 1939 only - Sep 11 23:00s 1:00 " DST" +Rule Algeria 1939 only - Nov 19 1:00 0 - +Rule Algeria 1944 1945 - Apr Mon<=7 2:00 1:00 " DST" +Rule Algeria 1944 only - Oct 8 2:00 0 - +Rule Algeria 1945 only - Sep 16 1:00 0 - +Rule Algeria 1971 only - Apr 25 23:00s 1:00 " DST" +Rule Algeria 1971 only - Sep 26 23:00s 0 - +Rule Algeria 1977 only - May 6 0:00 1:00 " DST" +Rule Algeria 1977 only - Oct 21 0:00 0 - +Rule Algeria 1978 only - Mar 24 1:00 1:00 " DST" +Rule Algeria 1978 only - Sep 22 3:00 0 - +Rule Algeria 1980 only - Apr 25 0:00 1:00 " DST" +Rule Algeria 1980 only - Oct 31 2:00 0 - +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:01 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 Algeria WET%s 1940 Feb 25 2:00 + 1:00 Algeria MET%s 1946 Oct 7 + 0:00 - WET 1956 Jan 29 + 1:00 - MET 1963 Apr 14 + 0:00 Algeria WET%s 1977 Oct 21 + 1:00 Algeria MET%s 1979 Oct 26 + 0:00 Algeria WET%s 1981 May + 1:00 - MET + +# Angola +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Luanda 0:52:56 - LMT 1892 + 0:52 - LMT 1911 May 26 # Luanda Mean Time + 1:00 - CAT + +# Benin +# Whitman says they switched to 1:00 in 1946, not 1934; go with Shanks. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Porto-Novo 0:10:28 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + 1:00 - CAT + +# Botswana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Gaborone 1:43:40 - LMT 1885 + 2:00 - SAT 1943 Sep 19 2:00 + 2:00 1:00 SAST 1944 Mar 19 2:00 + 2:00 - SAT + +# Burkina Faso +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Ouagadougou -0:06:04 - LMT 1912 + 0:00 - WAT + +# Burundi +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bujumbura 1:57:28 - LMT 1890 + 2:00 - SAT + +# Cameroon +# Whitman says they switched to 1:00 in 1920; go with Shanks. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Douala 0:38:48 - LMT 1912 + 1:00 - CAT + +# Cape Verde +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Cape_Verde -1:34:04 - LMT 1907 # Praia + -2:00 - CVT 1942 Sep + -2:00 1:00 CVST 1945 Oct 15 + -2:00 - CVT 1975 Nov 25 2:00 + -1:00 - AAT + +# Central African Republic +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bangui 1:14:20 - LMT 1912 + 1:00 - CAT + +# Chad +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Ndjamena 1:00:12 - LMT 1912 + 1:00 - CAT 1979 Oct 14 + 1:00 1:00 CAST 1980 Mar 8 + 1:00 - CAT + +# Comoros +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro + 3:00 - EAT + +# Congo +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Brazzaville 1:01:08 - LMT 1912 + 1:00 - CAT + +# Cote D'Ivoire +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Abidjan -0:16:08 - LMT 1912 + 0:00 - WAT + +# Djibouti +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Djibouti 2:52:36 - LMT 1911 Jul + 3:00 - EAT + +############################################################################### + +# Egypt + +# From Bob Devine (January 28, 1988): +# Egypt: DST from first day of May to first of October (ending may +# also be on Sept 30th not 31st -- you might want to ask one of the +# soc.* groups, you might hit someone who could ask an embassy). +# DST since 1960 except for 1981-82. + +# From U. S. Naval Observatory (January 19, 1989): +# EGYPT 2 H AHEAD OF UTC +# EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +# EGYPT RAMADAN) + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Egypt 1900 only - Oct 1 0:00 0 - +Rule Egypt 1940 only - Jul 15 0:00 1:00 " DST" +Rule Egypt 1940 only - Oct 1 0:00 0 - +Rule Egypt 1941 only - Apr 15 0:00 1:00 " DST" +Rule Egypt 1941 only - Sep 16 0:00 0 - +Rule Egypt 1942 1944 - Apr 1 0:00 1:00 " DST" +Rule Egypt 1942 only - Oct 27 0:00 0 - +Rule Egypt 1943 1945 - Nov 1 0:00 0 - +Rule Egypt 1945 only - Apr 16 0:00 1:00 " DST" +Rule Egypt 1957 only - May 10 0:00 1:00 " DST" +Rule Egypt 1957 1958 - Oct 1 0:00 0 - +Rule Egypt 1958 only - May 1 0:00 1:00 " DST" +Rule Egypt 1959 1981 - May 1 1:00 1:00 " DST" +Rule Egypt 1959 1965 - Sep 30 3:00 0 - +Rule Egypt 1966 max - Oct 1 3:00 0 - +Rule Egypt 1982 only - Jul 25 1:00 1:00 " DST" +Rule Egypt 1983 only - Jul 12 1:00 1:00 " DST" +Rule Egypt 1984 1988 - May 1 1:00 1:00 " DST" +Rule Egypt 1989 only - May 6 1:00 1:00 " DST" +Rule Egypt 1990 max - May 1 1:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Cairo 2:05:00 - LMT 1900 Oct + 2:00 Egypt EET%s + +# Equatorial Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Malabo 0:35:08 - LMT 1912 + 0:00 - WAT 1963 Dec 15 + 1:00 - CAT + +# Eritrea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Asmera 2:35:32 - LMT 1870 + 2:36 - AMT 1890 # Asmera Mean Time + 2:35 - AAMT 1936 May 5 # Addis Ababa MT + 3:00 - EAT + +# Ethiopia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Addis_Ababa 2:34:48 - LMT 1870 + 2:35 - AAMT 1936 May 5 # Addis Ababa MT + 3:00 - EAT + +# Gabon +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Libreville 0:37:48 - LMT 1912 + 1:00 - CAT + +# Gambia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Banjul -1:06:36 - LMT 1912 + -1:07 - BMT 1935 # Banjul Mean Time + -1:00 - AAT 1964 + 0:00 - WAT + +# Ghana +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# WATDT is my invention for ``West Africa one-Third Daylight Time''. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Ghana 1918 only - Jan 1 0:00 0 WAT +# Whitman says DST was observed from 1931 to ``the present''; go with Shanks. +Rule Ghana 1936 1942 - Sep 1 0:00 0:20 WATDT +Rule Ghana 1936 1942 - Dec 31 0:00 0 WAT +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Accra -0:00:52 - LMT 1918 + 0:00 Ghana %s + +# Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Conakry -0:54:52 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + 1:00 - CAT 1960 + 0:00 - WAT + +# Guinea-Bissau +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bissau -1:02:20 - LMT 1911 May 26 + 1:00 - CAT 1975 + 0:00 - WAT + +# Kenya +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks says the transition to 2:45 was in 1940, but it must have been 1948. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Nairobi 2:27:16 - LMT 1928 Jul + 3:00 - EAT 1930 + 2:30 - BEAT 1948 + 2:45 - BEAT 1960 + 3:00 - EAT + +# Lesotho +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Maseru 1:50:00 - LMT 1903 Mar + 2:00 - SAT 1943 Sep 19 2:00 + 2:00 1:00 SAST 1944 Mar 19 2:00 + 2:00 - SAT + +# Liberia +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# In 1972 Liberia was the last country to switch +# from a GMT offset that was not a multiple of 15 minutes. +# Time magazine reported that it was in honor of their leader's birthday. +# For Liberia before 1972, Shanks reports -0:44, and Whitman reports -0:44:30; +# go with Whitman. +# +# From Shanks (1991), as corrected by Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Monrovia -0:43:08 - LMT 1882 + -0:43:08 - MMT 1919 Mar # Monrovia Mean Time + -0:44:30 - LST 1972 May # Liberia Standard Time + 0:00 - WAT + +############################################################################### + +# Libya + +# From Bob Devine (January 28 1988): +# Libya: Since 1982 April 1st to September 30th (?) + +# From U. S. Naval Observatory (January 19, 1989): +# LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +# LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Libya 1920 only - Jan 1 0:00 0 - +Rule Libya 1951 only - Oct 14 2:00 1:00 " DST" +Rule Libya 1952 only - Jan 1 0:00 0 - +Rule Libya 1953 only - Oct 9 2:00 1:00 " DST" +Rule Libya 1954 only - Jan 1 0:00 0 - +Rule Libya 1955 only - Sep 30 0:00 1:00 " DST" +Rule Libya 1956 only - Jan 1 0:00 0 - +Rule Libya 1982 1984 - Apr 1 0:00 1:00 " DST" +Rule Libya 1982 1985 - Oct 1 0:00 0 - +Rule Libya 1985 only - Apr 6 0:00 1:00 " DST" +Rule Libya 1986 only - Apr 4 0:00 1:00 " DST" +Rule Libya 1986 only - Oct 3 0:00 0 - +Rule Libya 1987 1989 - Apr 1 0:00 1:00 " DST" +Rule Libya 1987 1990 - Oct 1 0:00 0 - +Rule Libya 1990 only - May 4 0:00 1:00 " DST" +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Here's a guess for years starting with 1991. +Rule Libya 1991 max - Apr 1 0:00 1:00 " DST" +Rule Libya 1991 max - Oct 1 0:00 0 - + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Tripoli 0:52:44 - LMT 1920 + 1:00 Libya MET%s 1959 + 2:00 - EET 1982 + 1:00 Libya MET%s + +# Madagascar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul + 3:00 - EAT 1954 Feb 27 23:00s + 3:00 1:00 EAST 1954 May 29 23:00s + 3:00 - EAT + +# Malawi +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Blantyre 2:20:00 - LMT 1903 Mar + 2:00 - SAT + +# Mali +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Bamako -0:32:00 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + -1:00 - AAT 1960 Jun 20 + 0:00 - WAT +# no longer different from Bamako, but too famous to omit +Zone Africa/Timbuktu -0:12:04 - LMT 1912 + 0:00 - WAT + +# Mauritania +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Nouakchott -1:03:48 - LMT 1912 + 0:00 - WAT 1934 Feb 26 + -1:00 - AAT 1960 Jun 20 + 0:00 - WAT + +# Mauritius +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis + 4:00 - SMT +# Agalega Is, Rodriguez +# no information; probably like Indian/Mauritius + +# Mayotte +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mayotte 3:01:08 - LMT 1911 Jul # Dzaoudzi + 3:00 - EAT + +# Morocco +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Morocco 1913 only - Oct 26 0:00 0 - +Rule Morocco 1939 only - Sep 12 0:00 1:00 " DST" +Rule Morocco 1939 only - Nov 19 0:00 0 - +Rule Morocco 1940 only - Feb 25 0:00 1:00 " DST" +Rule Morocco 1945 only - Nov 18 0:00 0 - +Rule Morocco 1950 only - Jun 11 0:00 1:00 " DST" +Rule Morocco 1950 only - Oct 29 0:00 0 - +Rule Morocco 1967 only - Jun 3 12:00 1:00 " DST" +Rule Morocco 1967 only - Oct 1 0:00 0 - +Rule Morocco 1974 only - Jun 24 0:00 1:00 " DST" +Rule Morocco 1974 only - Sep 1 0:00 0 - +Rule Morocco 1976 1977 - May 1 0:00 1:00 " DST" +Rule Morocco 1976 only - Aug 1 0:00 0 - +Rule Morocco 1977 only - Sep 28 0:00 0 - +Rule Morocco 1978 only - Jun 1 0:00 1:00 " DST" +Rule Morocco 1978 only - Aug 4 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Casablanca -0:30:20 - LMT 1913 Oct 26 + 0:00 Morocco WET%s 1984 Mar 16 + 1:00 - MET 1986 + 0:00 - WET +# The following are controlled by Spain, and are like Europe/Madrid: +# Alboran, Alhucemas Is, Ceuta, Chafarinas Is, Mellila. + +# Mozambique +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Maputo 2:10:20 - LMT 1903 Mar + 2:00 - SAT + +# Namibia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 + 1:30 - SWAT 1903 Mar # SW Africa Time + 2:00 - SAT 1942 Sep 20 2:00 + 2:00 1:00 SAST 1943 Mar 21 2:00 + 2:00 - SAT + +# Niger +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Niamey 0:08:28 - LMT 1912 + 1:00 - CAT 1934 Feb 26 + 0:00 - WAT 1960 + 1:00 - CAT + +# Nigeria +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lagos 0:13:36 - LMT 1919 Sep + 1:00 - CAT + +# Reunion +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Reunion 3:41:52 - LMT 1911 Jun # St Denis + 4:00 - SMT + +# Rwanda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kigali 2:00:16 - LMT 1935 Jun + 2:00 - SAT + +# St Helena +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/St_Helena -0:22:48 - LMT 1890 # Jamestown + -0:06 - ?MT 1951 # a typo in Shanks? + 0:00 - GMT +# Whitman says Tristan da Cunha is on GMT, like Atlantic/St_Helena. +# +# Ascension, Gough, Inaccessible, Nightingale +# no information; probably like Atlantic/St_Helena + +# Sao Tome and Principe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Sao_Tome 0:26:56 - LMT 1884 + -0:37 - ?MT 1912 # a typo in Shanks? + 0:00 - WAT + +# Senegal +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Dakar -1:09:44 - LMT 1912 + -1:00 - AAT 1941 Jun + 0:00 - WAT + +# Seychelles +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Mahe 3:41:48 - LMT 1906 Jun # Victoria + 4:00 - SMT + +# Sierra Leone +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SL 1913 only - Oct 26 0:00 0 - +# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks. +Rule SL 1935 1942 - Jun 1 0:00 1:00 S +Rule SL 1935 1942 - Oct 1 0:00 0 - +Rule SL 1957 1962 - Jun 1 0:00 1:00 S +Rule SL 1957 1962 - Sep 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Freetown -0:53:00 - LMT 1882 + -0:53 - FMT 1913 Jun + -1:00 SL AA%sT 1957 + 0:00 SL WA%sT + +# Somalia +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks omits the 1948 transition to 2:45; this is probably a typo. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Mogadishu 3:01:28 - LMT 1893 Nov + 3:00 - EAT 1931 + 2:30 - BEAT 1948 + 2:45 - BEAT 1957 # not in Shanks + 3:00 - EAT + +# South Africa +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SA 1892 only - Feb 8 0:00 0 - +Rule SA 1942 1943 - Sep Sun>=15 2:00 1:00 S +Rule SA 1943 1944 - Mar Sun>=15 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 + 1:30 - SAT 1903 Mar + 2:00 SA SA%sT +# Prince Edward Is +# no information + +# Sudan +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Sudan 1931 only - Feb 8 0:00 0 - +Rule Sudan 1970 only - May 1 0:00 1:00 " DST" +Rule Sudan 1970 max - Oct 15 0:00 0 - +Rule Sudan 1971 only - Apr 30 0:00 1:00 " DST" +Rule Sudan 1972 max - Apr lastSun 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Khartoum 2:10:08 - LMT 1931 + 2:00 Sudan EET%s + +# Swaziland +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Mbabane 2:04:24 - LMT 1903 Mar + 2:00 - SAT + +# Tanzania +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Dar_es_Salaam 2:37:08 - LMT 1931 + 3:00 - EAT 1948 + 2:45 - BEAT 1961 + 3:00 - EAT + +# Togo +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lome 0:04:52 - LMT 1893 + 0:00 - WAT + +# Tunisia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Tunisia 1911 only - Mar 9 0:00 0 - +Rule Tunisia 1939 only - Apr 15 23:00s 1:00 " DST" +Rule Tunisia 1939 only - Nov 18 23:00s 0 - +Rule Tunisia 1940 only - Feb 25 23:00s 1:00 " DST" +Rule Tunisia 1941 only - Oct 6 0:00 0 - +Rule Tunisia 1942 only - Mar 9 0:00 1:00 " DST" +Rule Tunisia 1942 only - Nov 2 3:00 0 - +Rule Tunisia 1943 only - Mar 29 2:00 1:00 " DST" +Rule Tunisia 1943 only - Apr 17 2:00 0 - +Rule Tunisia 1943 only - Apr 25 2:00 1:00 " DST" +Rule Tunisia 1943 only - Oct 4 2:00 0 - +Rule Tunisia 1944 1945 - Apr Mon>=1 2:00 1:00 " DST" +Rule Tunisia 1944 only - Oct 8 0:00 0 - +Rule Tunisia 1945 only - Sep 16 0:00 0 - +Rule Tunisia 1977 only - Apr 30 0:00s 1:00 " DST" +Rule Tunisia 1977 only - Sep 24 0:00s 0 - +Rule Tunisia 1978 only - May 1 0:00s 1:00 " DST" +Rule Tunisia 1978 only - Oct 1 0:00s 0 - +Rule Tunisia 1988 only - Jun 1 0:00s 1:00 " DST" +Rule Tunisia 1988 max - Sep lastSun 0:00s 0 - +Rule Tunisia 1989 only - Mar 26 0:00s 1:00 " DST" +Rule Tunisia 1990 only - May 1 0:00s 1:00 " DST" +Rule Tunisia 1991 max - Mar lastSun 0:00s 1:00 " DST" +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Tunis 0:40:44 - LMT 1881 May 12 + 0:09:05 - PMT 1911 Mar 9 # Paris Mean Time + 1:00 Tunisia MET%s + +# Uganda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kampala 2:09:40 - LMT 1928 Jul + 3:00 - EAT 1930 + 2:30 - BEAT 1948 + 2:45 - BEAT 1957 + 3:00 - EAT + +# Zaire +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kinshasa 1:01:12 - LMT 1897 Nov 9 + 1:00 - CAT +Zone Africa/Lumumbashi 1:49:52 - LMT 1897 Nov 9 + 2:00 - SAT + +# Zambia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar + 2:00 - SAT + +# Zimbabwe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Harare 2:04:12 - LMT 1903 Mar + 2:00 - SAT diff --git a/time/antarctica b/time/antarctica new file mode 100644 index 0000000000..f5ed31370d --- /dev/null +++ b/time/antarctica @@ -0,0 +1,19 @@ +# @(#)antarctica 7.2 + +# From Arthur David Olson (February 13, 1988): +# No data available. + +# Balleny Is + +# British Antarctic Territories include +# South Orkney Is +# South Shetland Is + +# Amsterdam Island +# Bouvet +# Crozet Is +# Heard and McDonald Is +# Kerguelen Is +# St Paul Island +# Peter I Island +# Scott Island diff --git a/time/ap.c b/time/ap.c new file mode 100644 index 0000000000..c982bd66bb --- /dev/null +++ b/time/ap.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <malloc.h> + +/* Prints the time in the form "hh:mm ?M", where ? is A or P. + A simple test for strftime(). */ +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + char buf[20]; + time_t t; + + mcheck (NULL); + + if (argc != 1) + fprintf(stderr, "Usage: %s\n", argv[0]); + + t = time((time_t *) NULL); + if (strftime(buf, sizeof(buf), "%I:%M %p", localtime(&t)) == 0) + exit(EXIT_FAILURE); + + puts(buf); + + exit(EXIT_SUCCESS); + return EXIT_SUCCESS; +} diff --git a/time/asctime.c b/time/asctime.c new file mode 100644 index 0000000000..3337c74388 --- /dev/null +++ b/time/asctime.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <errno.h> +#include <stdio.h> +#include <time.h> + + +/* Returns a string of the form "Day Mon dd hh:mm:ss yyyy\n" + which is the representation of TP in that form. */ +char * +DEFUN(asctime, (tp), CONST struct tm *tp) +{ + static const char format[] = "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"; + static char result[ 3+1+ 3+1+20+1+20+1+20+1+20+1+20+1 + 1]; + + if (tp == NULL) + { + errno = EINVAL; + return NULL; + } + + if (sprintf (result, format, + (tp->tm_wday < 0 || tp->tm_wday >= 7 ? + "???" : _time_info->abbrev_wkday[tp->tm_wday]), + (tp->tm_mon < 0 || tp->tm_mon >= 12 ? + "???" : _time_info->abbrev_month[tp->tm_mon]), + tp->tm_mday, tp->tm_hour, tp->tm_min, + tp->tm_sec, 1900 + tp->tm_year) < 0) + return NULL; + + return result; +} diff --git a/time/asia b/time/asia new file mode 100644 index 0000000000..78ecb30d93 --- /dev/null +++ b/time/asia @@ -0,0 +1,803 @@ +# @(#)asia 7.12 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 18, 1994): +# +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# LST Local Star Time (Russian ``mestnoe zvezdnoe vremya'') +# 2:00 EET EET DST Eastern European Time +# 2:00 IST IDT Israel +# 3:00 AST ADT Arabia* +# 3:00 MSK MSD Moscow +# 3:30 IST IDT Iran +# 4:00 BSK BSD Baku* +# 4:00 GST GDT Gulf* +# 4:30 AFT Afghanistan* +# 5:00 ASK ASD Ashkhabad* +# 5:00 PKT Pakistan* +# 5:30 IST IST India +# 5:45 NPT Nepal* +# 6:00 BGT Bengal, Bangladesh* +# 6:00 TSK TSD Tashkent* +# 6:30 BMT Burma* +# 7:00 ICT Indochina* +# 7:00 JVT Java* +# 8:00 BNT Borneo, Brunei* +# 8:00 CST CDT China +# 8:00 HKT HKST Hong Kong +# 8:00 PST PDT Philippines* +# 8:00 SGT Singapore +# 8:00 UST UDT Ulan Bator* +# 9:00 JST Japan +# 9:00 KST KDT Korea +# 9:00 MLT Moluccas* +# 9:30 CST Australian Central Standard Time +# +# See the `europe' file for Russia and Turkey in Asia. +# +# See the `africa' file for Zone naming conventions. + +# From Guy Harris: +# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as +# additional information from Tom Yap, Sun Microsystems Intercontinental +# Technical Support (including a page from the Official Airline Guide - +# Worldwide Edition). The names for time zones are guesses. + +############################################################################### + +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# We don't know what happened to the clocks in the Caucausus and the ex-Soviet +# Central Asia after 1990. Until we get more info, stick with the pre-1991 rules. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Russia 1981 1984 - Apr 1 0:00 1:00 D +Rule Russia 1981 1983 - Oct 1 0:00 0 K +Rule Russia 1984 max - Sep lastSun 3:00 0 K +Rule Russia 1985 max - Mar lastSun 2:00 1:00 D + +# Afghanistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kabul 4:36:48 - LMT 1890 + 4:00 - GST 1945 + 4:30 - AFT + +# Armenia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# Azerbaijan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Baku 3:19:24 - LMT 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# Bahrain +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bahrain 3:22:20 - LMT 1920 # Al-Manamah + 4:00 - GST 1972 Jun + 3:00 - AST + +# Bangladesh +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dacca 6:01:40 - LMT 1890 + 5:53 - CMT 1941 Oct # Calcutta Mean Time + 6:30 - BMT 1942 May 15 + 5:30 - IST 1942 Sep + 6:30 - BMT 1951 Sep 30 + 6:00 - BGT + +# Bhutan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Thimbu 5:58:36 - LMT 1947 Aug 15 + 5:30 - IST 1987 Oct + 6:00 - BGT + +# British Indian Ocean Territory +# From Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Chagos 5:00 - PKT + +# Brunei +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan + 7:30 - BNT 1933 + 8:00 - BNT + +# Burma +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Rangoon 6:24:40 - LMT 1880 + 6:25 - RMT 1920 + 6:30 - BMT 1942 May + 9:00 - JST 1945 May 3 + 6:30 - BMT + +# Cambodia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# People's Republic of China + +# From Guy Harris: +# People's Republic of China. Yes, they really have only one time zone. + +# From Bob Devine (January 28, 1988): +# No they don't. See TIME mag, February 17, 1986 p.52. Even though +# China is across 4 physical time zones, before Feb 1, 1986 only the +# Peking (Bejing) time zone was recognized. Since that date, China +# has two of 'em -- Peking's and Urumqi (named after the capital of +# the Xinjiang Uighur Autonomous Region). I don't know about DST for it. +# +# . . .I just deleted the DST table and this editor makes it too +# painful to suck in another copy.. So, here is what I have for +# DST start/end dates for Peking's time zone (info from AP): +# +# 1986 May 4 - Sept 14 +# 1987 mid-April - ?? + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# According to Shanks, China started using DST in 1986, +# but it's still all one big happy time zone. + +# From U. S. Naval Observatory (January 19, 1989): +# CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +# CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks writes that China switched from the Chinese calendar on 1912 Feb 12. +# He also writes that China has had a single time zone since 1980 May 1, +# and that they instituted DST on 1986 May 4; this contradicts Devine's +# note about Time magazine, though apparently _something_ happened in 1986. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Shang 1928 only - Jan 1 0:00 0 S +Rule Shang 1940 only - Jun 3 0:00 1:00 D +Rule Shang 1940 1941 - Oct 1 0:00 0 S +Rule Shang 1941 only - Mar 16 0:00 1:00 D +Rule PRC 1949 only - Jan 1 0:00 0 S +Rule PRC 1986 only - May 4 0:00 1:00 D +Rule PRC 1986 max - Sep Sun>=11 0:00 0 S +Rule PRC 1987 max - Apr Sun>=10 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Shanghai 8:05:52 - LMT 1928 + 8:00 Shang C%sT 1949 + 8:00 PRC C%sT + +############################################################################### + +# Republic of China + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Taiwan 1896 only - Jan 1 0:00 0 S +Rule Taiwan 1945 1951 - May 1 0:00 1:00 D +Rule Taiwan 1945 1951 - Oct 1 0:00 0 S +Rule Taiwan 1952 only - Mar 1 0:00 1:00 D +Rule Taiwan 1952 1954 - Nov 1 0:00 0 S +Rule Taiwan 1953 1959 - Apr 1 0:00 1:00 D +Rule Taiwan 1955 1961 - Oct 1 0:00 0 S +Rule Taiwan 1960 1961 - Jun 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Apr 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Oct 1 0:00 0 S +Rule Taiwan 1980 only - Jun 30 0:00 1:00 D +Rule Taiwan 1980 only - Sep 30 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Taipei 8:06:00 - LMT 1896 + 8:00 Taiwan C%sT + +############################################################################### +# Hong Kong +# Presumably Hong Kong will have DST again when it merges with China, +# but it's too early to predict the details. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule HK 1904 only - Oct 30 0:00 0 - +Rule HK 1946 only - Apr 20 3:30 1:00 S +Rule HK 1946 only - Dec 1 3:30 0 - +Rule HK 1947 only - Apr 13 3:30 1:00 S +Rule HK 1947 only - Dec 30 3:30 0 - +Rule HK 1948 only - May 2 3:30 1:00 S +Rule HK 1948 1952 - Oct lastSun 3:30 0 - +Rule HK 1949 1953 - Apr Sun>=1 3:30 1:00 S +Rule HK 1953 only - Nov 1 3:30 0 - +Rule HK 1954 1964 - Mar Sun>=18 3:30 1:00 S +Rule HK 1954 only - Oct 31 3:30 0 - +Rule HK 1955 1964 - Nov Sun>=1 3:30 0 - +Rule HK 1965 1977 - Apr Sun>=16 3:30 1:00 S +Rule HK 1965 1977 - Oct Sun>=16 3:30 0 - +Rule HK 1979 1980 - May Sun>=8 3:30 1:00 S +Rule HK 1979 1980 - Oct Sun>=16 3:30 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Hong_Kong 7:36:36 - LMT 1904 Oct 30 + 8:00 HK HK%sT + +# Macao +# Presumably Macao will have DST again when it merges with China, +# but it's too early to predict the details. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Macao 1912 only - Jan 1 0:00 0 S +Rule Macao 1961 1962 - Mar Sun>=16 3:30 1:00 D +Rule Macao 1961 1964 - Nov Sun>=1 3:30 0 S +Rule Macao 1963 only - Mar Sun>=16 0:00 1:00 D +Rule Macao 1964 only - Mar Sun>=16 3:30 1:00 D +Rule Macao 1965 only - Mar Sun>=16 0:00 1:00 D +Rule Macao 1965 only - Oct 31 0:00 0 S +Rule Macao 1966 1971 - Apr Sun>=16 3:30 1:00 D +Rule Macao 1966 1971 - Oct Sun>=16 3:30 0 S +Rule Macao 1972 1974 - Apr Sun>=15 0:00 1:00 D +Rule Macao 1972 1973 - Oct Sun>=15 0:00 0 S +Rule Macao 1974 1977 - Oct Sun>=15 3:30 0 S +Rule Macao 1975 1977 - Apr Sun>=15 3:30 1:00 D +Rule Macao 1978 1980 - Apr Sun>=15 0:00 1:00 D +Rule Macao 1978 1980 - Oct Sun>=15 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Macao 7:34:20 - LMT 1912 + 8:00 Macao C%sT + + +############################################################################### + +# Cyprus +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cyprus 1921 only - Nov 14 0:00 0 - +Rule Cyprus 1975 only - Apr 13 0:00 1:00 " DST" +Rule Cyprus 1975 only - Oct 12 0:00 0 - +Rule Cyprus 1976 only - May 15 0:00 1:00 " DST" +Rule Cyprus 1976 only - Oct 11 0:00 0 - +Rule Cyprus 1977 1980 - Apr Sun>=1 0:00 1:00 " DST" +Rule Cyprus 1977 only - Sep 25 0:00 0 - +Rule Cyprus 1978 only - Oct 2 0:00 0 - +Rule Cyprus 1979 max - Sep lastSun 0:00 0 - +Rule Cyprus 1981 max - Mar lastSun 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Nicosia 2:13:28 - LMT 1921 Nov 14 + 2:00 Cyprus EET%s + +# Georgia +# From Paul Eggert <eggert@twinsun.com> (1994-11-19): +# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward +# an hour recently, due to a law proposed by Zurab Murvanidze, +# an MP who went on a hunger strike for 11 days to force discussion about it! +# Alas, we have no details. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tbilisi 2:59:16 - LMT 1880 + 2:59 - LST 1924 May 2 + 3:00 - MSK 1957 Mar + 4:00 Russia BS%s + +# India +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Calcutta 5:53:28 - LMT 1880 + 5:53 - CMT 1941 Oct # Calcutta Mean Time + 6:30 - BMT 1942 May 15 + 5:30 - IST 1942 Sep + 5:30 1:00 IST 1945 Oct 15 + 5:30 - IST +# The following are like Asia/Calcutta: +# Andaman Is +# Lakshadweep (Laccadive, Minicoy and Amindivi Is) +# Nicobar Is + +# Indonesia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Jakarta 7:07:12 - LMT 1867 Aug 10 + 7:07 - JMT 1924 Jan 1 0:13 + 7:20 - JVT 1932 Nov + 7:30 - JVT 1942 Mar 23 + 9:00 - JST 1945 Aug + 7:30 - JVT 1948 May + 8:00 - JVT 1950 May + 7:30 - JVT 1964 + 7:00 - JVT +Zone Asia/Ujung_Pandang 7:57:36 - LMT 1920 + 7:58 - MMT 1932 Nov # Macassar Mean Time + 8:00 - BNT 1942 Feb 9 + 9:00 - JST 1945 Aug + 8:00 - BNT +Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov + 9:00 - MLT 1944 + 9:30 - CST 1964 + 9:00 - MLT + +# Iran + +# Shanks has no record of DST after 1980. + +# From Bob Devine (January 28, 1988): +# Iran: Last Sunday in March to third (?) Sunday in +# September. Since the revolution, the official calendar is Monarchic +# calendar; I have no idea what the correspondence between dates are. + +# From U. S. Naval Observatory (January 19, 1989): +# IRAN 3.5H AHEAD OF UTC + +# From Shanks (1991), with corrections from Devine: +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iran 1977 only - Nov 1 0:00 0 S +Rule Iran 1978 1980 - Mar 21 0:00 1:00 D +Rule Iran 1978 only - Oct 21 0:00 0 S +Rule Iran 1979 only - Sep 19 0:00 0 S +Rule Iran 1980 only - Sep 23 0:00 0 S +Rule Iran 1988 max - Mar lastSun 2:00 1:00 D +Rule Iran 1988 max - Sep Sun>=15 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tehran 3:25:44 - LMT 1916 + 3:26 - TMT 1946 + 3:30 - IST 1977 Nov + 4:00 Iran G%sT 1979 + 3:30 Iran I%sT + +# Iraq +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iraq 1982 only - May 1 0:00 1:00 D +Rule Iraq 1982 1984 - Oct 1 0:00 0 S +Rule Iraq 1983 only - Mar 31 0:00 1:00 D +Rule Iraq 1984 1985 - Apr 1 0:00 1:00 D +Rule Iraq 1985 max - Sep lastSun 1:00s 0 S +Rule Iraq 1986 max - Mar lastSun 1:00s 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Baghdad 2:57:40 - LMT 1890 + 2:58 - BMT 1918 # Baghdad Mean Time + 3:00 - AST 1982 May + 3:00 Iraq A%sT + + +############################################################################### + +# Israel + +# From U. S. Naval Observatory (January 19, 1989): +# ISRAEL 2 H AHEAD OF UTC +# ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# Shanks gives the following rules for Jerusalem from 1918 through 1991. +# After 1989 Shanks often disagrees with Silverberg; we go with Silverberg. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1918 only - Jan 1 0:00 0 S +Rule Zion 1940 only - Jun 1 0:00 1:00 D +Rule Zion 1942 1944 - Nov 1 0:00 0 S +Rule Zion 1943 only - Apr 1 2:00 1:00 D +Rule Zion 1944 only - Apr 1 0:00 1:00 D +Rule Zion 1945 only - Apr 16 0:00 1:00 D +Rule Zion 1945 only - Nov 1 2:00 0 S +Rule Zion 1946 only - Apr 16 2:00 1:00 D +Rule Zion 1946 only - Nov 1 0:00 0 S +Rule Zion 1948 only - May 23 0:00 2:00 DD +Rule Zion 1948 only - Sep 1 0:00 1:00 D +Rule Zion 1948 1949 - Nov 1 2:00 0 S +Rule Zion 1949 only - May 1 0:00 1:00 D +Rule Zion 1950 only - Apr 16 0:00 1:00 D +Rule Zion 1950 only - Sep 15 3:00 0 S +Rule Zion 1951 only - Apr 1 0:00 1:00 D +Rule Zion 1951 only - Nov 11 3:00 0 S +Rule Zion 1952 only - Apr 20 2:00 1:00 D +Rule Zion 1952 only - Oct 19 3:00 0 S +Rule Zion 1953 only - Apr 12 2:00 1:00 D +Rule Zion 1953 only - Sep 13 3:00 0 S +Rule Zion 1954 only - Jun 13 0:00 1:00 D +Rule Zion 1954 only - Sep 12 0:00 0 S +Rule Zion 1955 only - Jun 11 2:00 1:00 D +Rule Zion 1955 only - Sep 11 0:00 0 S +Rule Zion 1956 only - Jun 3 0:00 1:00 D +Rule Zion 1956 only - Sep 30 3:00 0 S +Rule Zion 1957 only - Apr 29 2:00 1:00 D +Rule Zion 1957 only - Sep 22 0:00 0 S +Rule Zion 1974 only - Jul 7 0:00 1:00 D +Rule Zion 1974 only - Oct 13 0:00 0 S +Rule Zion 1975 only - Apr 20 0:00 1:00 D +Rule Zion 1975 only - Aug 31 0:00 0 S +Rule Zion 1985 only - Apr 14 0:00 1:00 D +Rule Zion 1985 only - Sep 15 0:00 0 S +Rule Zion 1986 only - May 18 0:00 1:00 D +Rule Zion 1986 only - Sep 7 0:00 0 S +Rule Zion 1987 only - Apr 15 0:00 1:00 D +Rule Zion 1987 only - Sep 13 0:00 0 S +Rule Zion 1988 only - Apr 9 0:00 1:00 D +Rule Zion 1988 only - Sep 3 0:00 0 S +#Rule Zion 1989 only - Apr 29 0:00 1:00 D +#Rule Zion 1989 only - Sep 2 0:00 0 S +#Rule Zion 1990 only - Mar 25 0:00 1:00 D +#Rule Zion 1990 only - Aug 26 0:00 0 S +#Rule Zion 1991 only - Mar 10 0:00 1:00 D +#Rule Zion 1991 only - Sep 1 0:00 0 S + +# From Ephraim Silverberg (September 5, 1993): +# +# According to the Office of the Secretary General of the Ministry of +# Interior, there is NO set rule for Daylight-Savings/Standard time changes. +# Each year they decide anew what havoc to wreak on the country. However, +# there is a "supposed" set of rules which is subject to change depending +# on the party the Minister of Interior, the size of the coalition +# government, the phase of the moon and the direction of the wind. Hence, +# changes may need to be made on a semi-annual basis. One thing is entrenched +# in law, however: that there must be at least 150 days on daylight savings +# time annually. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1989 only - Apr 30 0:00 1:00 D +Rule Zion 1989 only - Sep 3 0:00 0:00 S +Rule Zion 1990 only - Mar 25 0:00 1:00 D +Rule Zion 1990 only - Aug 26 0:00 0:00 S +Rule Zion 1991 only - Mar 24 0:00 1:00 D +Rule Zion 1991 only - Sep 1 0:00 0:00 S +Rule Zion 1992 only - Mar 29 0:00 1:00 D +Rule Zion 1992 only - Sep 6 0:00 0:00 S +Rule Zion 1993 only - Apr 2 0:00 1:00 D +Rule Zion 1993 only - Sep 5 0:00 0:00 S + +# The dates for 1994-1995 were obtained from Office of the Spokeswoman for +# the Ministry of Interior, Jerusalem. There are no dates yet for 1996 and +# beyond so your guess is as good as theirs (those who are interested can +# call 972-2-701411 and ask for the spokeswoman). + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Zion 1994 only - Apr 1 0:00 1:00 D +Rule Zion 1994 only - Aug 28 0:00 0:00 S +Rule Zion 1995 only - Mar 31 0:00 1:00 D +Rule Zion 1995 only - Aug 27 0:00 0:00 S + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tel_Aviv 2:19:04 - LMT 1880 + 2:21 - JMT 1918 + 2:00 Zion I%sT + + +############################################################################### + +# Japan + +# `9:00' and `JST' is from Guy Harris. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks says that the far southern Ryukyu Is (Nansei-Shoto) are 8:00, +# but we don't have a good location name for them; +# we don't even know the name of the principal town. +# There is no information for Marcus. +# Other Japanese possessions are probably like Asia/Tokyo. + +# From Shanks (1991): +# Japan switched from the Japanese calendar on 1893 Jan 1. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tokyo 9:19:04 - LMT 1896 + 9:00 - JST +#Zone Asia/South_Ryukyu 8:14:44 - LMT 1896 # Amitori +# 8:00 - CST + +# Jordan +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Most likely Shanks is merely guessing dates from 1992 on. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Jordan 1931 only - Jan 1 0:00 0 - +Rule Jordan 1973 only - Jun 6 0:00 1:00 " DST" +Rule Jordan 1973 1975 - Oct 1 0:00 0 - +Rule Jordan 1974 1977 - May 1 0:00 1:00 " DST" +Rule Jordan 1976 only - Nov 1 0:00 0 - +Rule Jordan 1977 only - Oct 1 0:00 0 - +Rule Jordan 1978 only - Apr 30 0:00 1:00 " DST" +Rule Jordan 1978 only - Sep 30 0:00 0 - +Rule Jordan 1985 only - Apr 1 0:00 1:00 " DST" +Rule Jordan 1985 only - Oct 1 0:00 0 - +Rule Jordan 1986 1988 - Apr Fri>=1 0:00 1:00 " DST" +Rule Jordan 1986 1990 - Oct Fri>=1 0:00 0 - +Rule Jordan 1989 only - May 8 0:00 1:00 " DST" +Rule Jordan 1990 only - Apr 27 0:00 1:00 " DST" +Rule Jordan 1991 only - Apr 19 0:00 1:00 " DST" +Rule Jordan 1991 only - Sep 27 0:00 0 - +Rule Jordan 1992 max - Apr Fri>=1 0:00 1:00 " DST" +Rule Jordan 1992 max - Oct Fri>=1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Amman 2:23:44 - LMT 1931 + 2:00 Jordan EET%s + +# Kazakhstan +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Alma-Ata 5:07:48 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Kirgizstan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +############################################################################### + +# Korea + +# From Guy Harris: +# According to someone at the Korean Times in San Francisco, +# Daylight Savings Time was not observed until 1987. He did not know +# at what time of day DST starts or ends. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule ROK 1960 only - May 15 0:00 1:00 D +Rule ROK 1960 only - Sep 13 0:00 0 S +Rule ROK 1987 1988 - May Sun<=14 0:00 1:00 D +Rule ROK 1987 1988 - Oct Sun<=14 0:00 0 S + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Seoul 8:27:52 - LMT 1890 + 8:30 - KST 1904 Dec + 9:00 - KST 1928 + 8:30 - KST 1932 + 9:00 - KST 1954 Mar 21 + 8:00 ROK K%sT 1961 Aug 10 + 8:30 - KST 1968 Oct + 9:00 ROK K%sT +Zone Asia/Pyongyang 8:23:00 - LMT 1890 + 8:30 - KST 1904 Dec + 9:00 - KST 1928 + 8:30 - KST 1932 + 9:00 - KST 1954 Mar 21 + 8:00 - KST 1961 Aug 10 + 9:00 - KST + +############################################################################### + +# Kuwait +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kuwait 3:11:56 - LMT 1950 + 3:00 - AST + +# Laos +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Vientiane 6:50:24 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# Lebanon +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Lebanon 1880 only - Jan 1 0:00 0 - +Rule Lebanon 1920 only - Mar 28 0:00 1:00 " DST" +Rule Lebanon 1920 only - Oct 25 0:00 0 - +Rule Lebanon 1921 only - Apr 3 0:00 1:00 " DST" +Rule Lebanon 1921 only - Oct 3 0:00 0 - +Rule Lebanon 1922 only - Mar 26 0:00 1:00 " DST" +Rule Lebanon 1922 only - Oct 8 0:00 0 - +Rule Lebanon 1923 only - Apr 22 0:00 1:00 " DST" +Rule Lebanon 1923 only - Sep 16 0:00 0 - +Rule Lebanon 1957 1961 - May 1 0:00 1:00 " DST" +Rule Lebanon 1957 1961 - Oct 1 0:00 0 - +Rule Lebanon 1972 only - Jun 22 0:00 1:00 " DST" +Rule Lebanon 1972 1977 - Oct 1 0:00 0 - +Rule Lebanon 1973 1977 - May 1 0:00 1:00 " DST" +Rule Lebanon 1978 only - Apr 30 0:00 1:00 " DST" +Rule Lebanon 1978 only - Sep 30 0:00 0 - +Rule Lebanon 1984 1987 - May 1 0:00 1:00 " DST" +Rule Lebanon 1984 max - Oct 16 0:00 0 - +Rule Lebanon 1988 only - Jun 1 0:00 1:00 " DST" +Rule Lebanon 1989 only - May 10 0:00 1:00 " DST" +Rule Lebanon 1990 max - May 1 0:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Beirut 2:22:00 - LMT 1880 + 2:00 Lebanon EET%s + +# Malaysia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Kuala_Lumpur 6:46:48 - LMT 1880 + 6:55 - SMT 1905 Jun + 7:00 - SGT 1933 + 7:20 - SGT 1942 Feb 15 + 9:00 - JST 1945 Sep 2 + 7:20 - SGT 1950 + 7:30 - SGT 1982 May + 8:00 - SGT + +# Maldives +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Maldives 4:54:00 - LMT 1880 # Male + 4:54 - MMT 1960 + 5:00 - PKT + +# Mongolia +# Let's comment out the western and eastern Mongolian time zones +# till we know what their principal towns are. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mongol 1978 only - Jan 1 0:00 0 S +Rule Mongol 1981 1984 - Apr 1 0:00 1:00 T +Rule Mongol 1981 1984 - Oct 1 0:00 0 S +Rule Mongol 1985 max - Mar lastSun 2:00 1:00 T +Rule Mongol 1985 max - Sep lastSun 3:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +#Zone Asia/Dariv 6:14:32 - LMT 1905 Aug +# 6:00 - DST 1978 +# 7:00 Mongol D%sT +Zone Asia/Ulan_Bator 7:07:32 - LMT 1905 Aug + 7:00 - UST 1978 + 8:00 Mongol U%sT +#Zone Asia/Baruun-Urt 7:33:00 - LMT 1905 Aug +# 8:00 - BST 1978 +# 9:00 Mongol B%sT + +# Nepal +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Katmandu 5:41:16 - LMT 1920 + 5:30 - IST 1986 + 5:45 - NPT + +# Oman +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Muscat 3:54:20 - LMT 1920 + 4:00 - GST + +# Pakistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Karachi 4:28:12 - LMT 1907 + 5:30 - IST 1942 Sep + 5:30 1:00 IST 1945 Oct 15 + 5:30 - IST 1951 Sep 30 + 5:00 - PKT + +# Palestine +# These rules for Egypt are stolen from the `africa' file. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Egypt 1957 only - May 10 0:00 1:00 " DST" +Rule Egypt 1957 1958 - Oct 1 0:00 0 - +Rule Egypt 1958 only - May 1 0:00 1:00 " DST" +Rule Egypt 1959 1981 - May 1 1:00 1:00 " DST" +Rule Egypt 1959 1965 - Sep 30 3:00 0 - +Rule Egypt 1966 max - Oct 1 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Gaza 2:17:52 - LMT 1900 Oct + 2:00 - EET 1957 May 10 + 2:00 Egypt EET%s 1967 Jun 30 + 2:00 Zion I%sT +# This will undoubtedly change soon. + +# Philippines +# Howse writes (p 162) that until 1844 the Philippines kept American date. +# The rest of this data is from Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Phil 1899 only - May 11 0:00 0 S +Rule Phil 1936 only - Nov 1 0:00 1:00 D +Rule Phil 1937 only - Feb 1 0:00 0 S +Rule Phil 1954 only - Apr 12 0:00 1:00 D +Rule Phil 1954 only - Jul 1 0:00 0 S +Rule Phil 1978 only - Mar 22 0:00 1:00 D +Rule Phil 1978 only - Sep 21 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Manila -15:56:00 - LMT 1844 + 8:04:00 - LMT 1899 May 11 + 8:00 Phil P%sT 1942 May + 9:00 - JST 1944 Nov + 8:00 Phil P%sT + +# Qatar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah + 4:00 - GST 1972 Jun + 3:00 - AST + +# Saudi Arabia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Riyadh 3:06:52 - LMT 1950 + 3:00 - AST + +# Singapore +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Singapore 6:55:24 - LMT 1880 + 6:55 - SMT 1905 Jun + 7:00 - SGT 1933 + 7:20 - SGT 1942 Feb 15 + 9:00 - JST 1945 Sep 2 + 7:20 - SGT 1950 + 7:30 - SGT 1982 May + 8:00 - SGT + +# Sri Lanka +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Colombo 5:19:24 - LMT 1880 + 5:20 - JMT 1906 + 5:30 - IST 1942 Jan 5 + 5:30 0:30 IHST 1942 Sep + 5:30 1:00 IST 1945 Oct 16 2:00 + 5:30 - IST + +# Syria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Syria 1920 only - Jan 1 0:00 0 - +Rule Syria 1920 1923 - Apr Sun>=15 2:00 1:00 " DST" +Rule Syria 1920 1923 - Oct Sun>=1 2:00 0 - +Rule Syria 1962 only - Apr 29 2:00 1:00 " DST" +Rule Syria 1962 only - Oct 1 2:00 0 - +Rule Syria 1963 1965 - May 1 2:00 1:00 " DST" +Rule Syria 1963 only - Sep 30 2:00 0 - +Rule Syria 1964 only - Oct 1 2:00 0 - +Rule Syria 1965 only - Sep 30 2:00 0 - +Rule Syria 1966 only - Apr 24 2:00 1:00 " DST" +Rule Syria 1966 1976 - Oct 1 2:00 0 - +Rule Syria 1967 1978 - May 1 2:00 1:00 " DST" +Rule Syria 1977 1978 - Sep 1 2:00 0 - +Rule Syria 1983 1984 - Apr 9 2:00 1:00 " DST" +Rule Syria 1983 1984 - Oct 1 2:00 0 - +Rule Syria 1986 only - Feb 16 2:00 1:00 " DST" +Rule Syria 1986 only - Oct 9 2:00 0 - +Rule Syria 1987 only - Mar 1 2:00 1:00 " DST" +Rule Syria 1987 1988 - Oct 31 2:00 0 - +Rule Syria 1988 only - Mar 15 2:00 1:00 " DST" +Rule Syria 1989 only - Mar 31 2:00 1:00 " DST" +Rule Syria 1989 only - Oct 1 2:00 0 - +Rule Syria 1990 max - Apr 1 2:00 1:00 " DST" +Rule Syria 1990 max - Sep 30 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Damascus 2:25:12 - LMT 1920 + 2:00 Syria EET%s + +# Tajikistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Thailand +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Bangkok 6:42:04 - LMT 1880 + 6:42 - BMT 1920 Apr + 7:00 - ICT + +# Turkmenistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Ashkhabad 3:53:32 - LMT 1924 May 2 + 4:00 - ASK 1957 Mar + 5:00 Russia AS%s + +# United Arab Emirates +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Dubai 3:41:12 - LMT 1920 + 4:00 - GST + +# Uzbekistan +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Tashkent 4:37:12 - LMT 1924 May 2 + 5:00 - TSK 1957 Mar + 6:00 Russia TS%s + +# Vietnam +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Saigon's official name is Thanh-Pho Ho Chi Minh, but it's too long. +# We'll stick with the traditional name for now. +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Saigon 7:06:40 - LMT 1906 Jun 9 + 7:06 - SMT 1911 Mar 11 0:01 # Saigon MT + 7:00 - ICT 1912 May + 8:00 - ICT 1931 May + 7:00 - ICT + +# Yemen +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Aden 3:00:48 - LMT 1950 + 3:00 - AST diff --git a/time/australasia b/time/australasia new file mode 100644 index 0000000000..f9cde459e6 --- /dev/null +++ b/time/australasia @@ -0,0 +1,783 @@ +# @(#)australasia 7.21 +# This file also includes Pacific islands. + +# Notes are at the end of this file + +############################################################################### + +# Australia + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Aus 1895 only - Jan 1 0:00 0 - +# Shanks gives 1917 Jan 1 0:01; go with Whitman (and guess 2:00). +Rule Aus 1916 only - Oct 1 2:00 1:00 - +Rule Aus 1917 only - Mar 25 2:00 0 - +Rule Aus 1942 only - Jan 1 2:00 1:00 - +Rule Aus 1942 only - Mar 29 2:00 0 - +Rule Aus 1942 only - Sep 27 2:00 1:00 - +Rule Aus 1943 1944 - Mar lastSun 2:00 0 - +Rule Aus 1943 only - Oct 3 2:00 1:00 - +# Whitman says W Australia didn't use DST in 1943/1944, and that +# 1944/1945 was just like 1943/1944; go with Shanks. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +# Northern Territory +Zone Australia/Darwin 8:43:20 - LMT 1895 Feb + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST +# Western Australia +Zone Australia/Perth 7:43:24 - LMT 1895 Dec + 8:00 - WST 1917 Jan 1 0:01 + 8:00 Aus WST 1974 Oct lastSun 2:00 + 8:00 1:00 WST 1975 Mar Sun>=1 3:00 + 8:00 - WST 1983 Oct lastSun 2:00 + 8:00 1:00 WST 1984 Mar Sun>=1 3:00 + 8:00 - WST 1991 Nov 17 2:00 + 8:00 1:00 WST 1992 Mar Sun>=1 3:00 + 8:00 - WST +# Queensland +Zone Australia/Brisbane 10:12:08 - LMT 1895 + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct lastSun 2:00 + 10:00 1:00 EST 1972 Feb lastSun 3:00 + 10:00 - EST 1989 Oct lastSun 2:00 + 10:00 1:00 EST 1990 Mar Sun>=1 3:00 + 10:00 - EST 1990 Oct lastSun 2:00 + 10:00 1:00 EST 1991 Mar Sun>=1 3:00 + 10:00 - EST 1991 Oct lastSun 2:00 + 10:00 1:00 EST 1992 Mar Sun>=1 3:00 + 10:00 - EST + +# South Australia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AS 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AS 1986 only - Oct 19 2:00 1:00 - +Rule AS 1987 max - Oct lastSun 2:00 1:00 - +Rule AS 1972 only - Feb 27 3:00 0 - +Rule AS 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AS 1986 1989 - Mar Sun>=15 3:00 0 - +Rule AS 1990 1994 even Mar Sun>=18 3:00 0 - +Rule AS 1990 1994 odd Mar Sun>=1 3:00 0 - +Rule AS 1995 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Adelaide 9:14:20 - LMT 1895 Feb + 9:00 - CST 1899 May + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST 1971 Oct lastSun 2:00 + 9:30 AS CST + +# Tasmania +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AT 1967 only - Oct 1 2:00 1:00 - +Rule AT 1968 only - Mar 31 3:00 0 - +Rule AT 1968 1985 - Oct lastSun 2:00 1:00 - +Rule AT 1969 1971 - Mar Sun>=8 3:00 0 - +Rule AT 1972 only - Feb 27 3:00 0 - +Rule AT 1973 1981 - Mar Sun>=1 3:00 0 - +Rule AT 1982 1983 - Mar lastSun 3:00 0 - +Rule AT 1984 1986 - Mar Sun>=1 3:00 0 - +Rule AT 1986 only - Oct 19 2:00 1:00 - +Rule AT 1987 1990 - Mar Sun>=15 3:00 0 - +Rule AT 1987 1990 - Oct lastSun 2:00 1:00 - +Rule AT 1991 max - Oct Sun>=1 2:00 1:00 - +Rule AT 1991 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Hobart 9:49:16 - LMT 1895 Sep + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1967 Oct 1 2:00 + 10:00 AT EST + +# Victoria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AV 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AV 1972 only - Feb 27 3:00 0 - +Rule AV 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AV 1986 1990 - Mar Sun>=15 3:00 0 - +Rule AV 1986 only - Oct 19 2:00 1:00 - +Rule AV 1987 max - Oct lastSun 2:00 1:00 - +Rule AV 1991 1994 - Mar Sun>=1 3:00 0 - +Rule AV 1995 max - Mar lastSun 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Melbourne 9:39:52 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AV EST + +# New South Wales +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule AN 1971 1985 - Oct lastSun 2:00 1:00 - +Rule AN 1972 only - Feb 27 3:00 0 - +Rule AN 1973 1985 - Mar Sun>=1 3:00 0 - +Rule AN 1986 1989 - Mar Sun>=15 3:00 0 - +Rule AN 1986 only - Oct 19 2:00 1:00 - +Rule AN 1987 max - Oct lastSun 2:00 1:00 - +Rule AN 1990 max - Mar Sun>=1 3:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Sydney 10:04:52 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AN EST +Zone Australia/Broken_Hill 9:25:48 - LMT 1895 Feb + 10:00 - EST 1896 Aug 23 + 9:00 - CST 1899 May + 9:30 - CST 1917 Jan 1 0:01 + 9:30 Aus CST 1971 Oct 31 2:00 + 9:30 AN CST + +# Australian Capital Territory +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Canberra 9:56:32 - LMT 1895 Feb + 10:00 - EST 1917 Jan 1 0:01 + 10:00 Aus EST 1971 Oct 31 2:00 + 10:00 AN EST 1981 Oct 25 2:00 + 10:00 1:00 EST 1982 Apr 4 3:00 + 10:00 AN EST + +# Australian miscellany +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Australia/Lord_Howe 10:36:20 - LMT 1895 Feb + 10:00 - EST 1981 Mar + 10:30 AN LHST +Zone Indian/Christmas 7:02:52 - LMT 1895 Feb + 7:00 - JVT +# +# Ashmore Is, Cartier +# no information; probably like Australia/Perth +# +# Macquarie, Manihiki, Penrhyn, Rakehanga +# no information + + +# Cook Is +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cook 1978 only - Nov 12 0:00 0:30 HD +Rule Cook 1979 max - Mar Sun>=1 0:00 0 H +Rule Cook 1979 max - Oct lastSun 0:00 0:30 HD +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Rarotonga -10:39:04 - LMT 1901 # Avarua + -10:30 - CIST 1978 Nov 12 # Cook Is ST + -10:00 Cook T%sT + +# Cocos +# From USNO (1989): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Indian/Cocos 6:30 - CCT + +# Fiji +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Fiji 11:53:40 - LMT 1915 Oct 26 # Suva + 12:00 - NZST + +# French Polynesia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Gambier -8:59:48 - LMT 1912 Oct # Rikitea + -9:00 - GBT +Zone Pacific/Marquesas -9:18:00 - LMT 1912 Oct + -9:30 - MQT +Zone Pacific/Tahiti -9:58:16 - LMT 1912 Oct # Papeete + -10:00 - THT + +# Guam +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Guam 9:39:00 - LMT 1901 # Agana + 10:00 - GST + +# Howland, Baker +# no information; probably like Pacific/Samoa + +# Jarvis +# no information; probably like Pacific/Kiritimati + +# Johnston +# no information; probably like Pacific/Honolulu + +# Kiribati +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki + 12:00 - NZST +Zone Pacific/Enderbury -11:24:20 - LMT 1901 + -12:00 - KJT 1979 Oct + -11:00 - SST +Zone Pacific/Kiritimati -10:29:20 - LMT 1901 + -10:40 - LIT 1979 Oct # Line Is Time + -10:00 - THT + +# Nauru +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Nauru 11:07:40 - LMT 1921 Jan 15 # Uaobe + 11:30 - NST 1942 Mar 15 + 9:00 - JST 1944 Aug 15 + 11:30 - NST 1979 May + 12:00 - NZST + +# New Caledonia +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule NC 1912 only - Jan 13 0:00 0 S +Rule NC 1977 1978 - Dec Sun>=1 0:00 1:00 D +Rule NC 1978 1979 - Feb 27 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Noumea 11:05:48 - LMT 1912 Jan 13 + 11:00 NC NC%sT + + +############################################################################### + +# New Zealand + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule NZ 1868 only - Jan 1 0:00 0 S +# Shanks gives 1927 Nov 6 - 1928 Mar 4, 1928 Oct 14 - 1929 Mar 17, +# 1929 Oct 13 - 1930 Mar 16; go with Whitman. +Rule NZ 1927 only - Nov 26 2:00 1:00 D +Rule NZ 1928 1929 - Mar Sun>=1 2:00 0 S +Rule NZ 1928 only - Nov 4 2:00 1:00 D +Rule NZ 1929 only - Oct 30 2:00 1:00 D +Rule NZ 1930 1933 - Mar Sun>=15 2:00 0 S +Rule NZ 1930 1933 - Oct Sun>=8 2:00 1:00 D +# Shanks says DST stopped 1940 Sep lastSun; go with Whitman for war years. +Rule NZ 1934 1944 - Apr lastSun 2:00 0 S +Rule NZ 1934 1944 - Sep lastSun 2:00 1:00 D +Rule NZ 1974 only - Nov 3 2:00s 1:00 D +Rule NZ 1975 1988 - Oct lastSun 2:00s 1:00 D +Rule NZ 1989 only - Oct 8 2:00s 1:00 D +Rule NZ 1990 max - Oct Sun>=1 2:00s 1:00 D +Rule NZ 1975 only - Feb 23 2:00s 0 S +Rule NZ 1976 1989 - Mar Sun>=1 2:00s 0 S +Rule NZ 1990 max - Mar Sun>=15 2:00s 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Auckland 11:39:04 - LMT 1868 + # Shanks gives 1940 Sep 29 2:00; + # go with Whitman. + 11:30 NZ NZ%sT 1945 Apr 29 2:00 + 12:00 NZ NZ%sT +Zone Pacific/Chatham 12:45 - NZ-CHAT + + +# Antipodes Is, Kermadec Is +# no information; probably like Pacific/Auckland + +############################################################################### + + +# Niue +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Niue -11:19:40 - LMT 1901 # Alofi + -11:20 - NIT 1951 # Niue I Time + -11:30 - NIT 1978 Oct 1 + -11:00 - SST + +# Norfolk +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Norfolk 11:11:52 - LMT 1901 # Kingston + 11:12 - NMT 1951 + 11:30 - NRFT + +# Pacific Islands Trust Territories +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Majuro 11:24:48 - LMT 1901 + 11:00 - NCST 1969 Oct + 12:00 - NZST +Zone Pacific/Kwajalein 11:09:20 - LMT 1901 + 11:00 - NCST 1969 Oct + -12:00 - KJT 1993 Aug 20 + 12:00 - NZST +Zone Pacific/Truk 10:07:08 - LMT 1901 + 10:00 - GST 1978 Oct + 11:00 - NCST +Zone Pacific/Ponape 10:33:00 - LMT 1901 + 11:00 - NCST +Zone Pacific/Yap 9:12:24 - LMT 1901 + 9:00 - PLT 1969 Oct + 10:00 - GST + +# Palau +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Palau 8:57:56 - LMT 1901 # Koror + 9:00 - PLT + +# Palmyra +# no information; probably like Pacific/Kiritmati + +# Papua New Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 + 9:49 - PMMT 1895 + 10:00 - EST + +# Pitcairn +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Pitcairn -8:40:20 - LMT 1901 # Adamstown + -8:30 - PIT + +# Solomon Is +# excludes Bougainville, for which see Papua New Guinea +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara + 11:00 - NCST + +# Tokelau Is +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Fakaofo -11:24:56 - LMT 1901 + -10:00 - THT + +# Tonga +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Tongatapu 12:19:20 - LMT 1901 + 12:20 - TMT 1968 Oct + 13:00 - TGT + +# Tuvalu +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Funafuti 11:56:52 - LMT 1901 + 12:00 - NZST + +# Vanuatu +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Vanuatu 1912 only - Jan 13 0:00 0 S +Rule Vanuatu 1983 only - Sep 25 0:00 1:00 D +Rule Vanuatu 1984 max - Mar Sun>=23 0:00 0 S +Rule Vanuatu 1984 only - Oct 23 0:00 1:00 D +Rule Vanuatu 1985 max - Sep Sun>=23 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila + 11:00 - NCST + +# Wake +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Wake 11:06:28 - LMT 1901 + 12:00 - NZST + +# Wallis and Futuna +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Pacific/Wallis 12:15:20 - LMT 1901 + 12:00 - NZST + +# Western Samoa +# See Pacific/Samoa in the `northamerica' file, of all places. + +############################################################################### + +# NOTES + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 18, 1994): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where noted, it is the source for the data above. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# 6:30 CCT Cocos* +# 7:00 JVT Java* +# 8:00 WST WST Western Australia +# 9:00 JST Japan +# 9:00 PLT Palau* +# 9:30 CST CST Central Australia +# 10:00 EST EST Eastern Australia +# 10:00 GST Guam* +# 10:30 LHST LHST Lord Howe* +# 11:00 NCST NCDT New Caledonia* +# 11:30 NRFT Norfolk* +# 12:00 NZST NZDT New Zealand +# 12:45 NZ-CHAT Chatham +# 13:00 TGT Tongatapu* +# -12:00 KJT Kwajalein (no longer used)* +# -11:00 SST Samoa +# -10:40 LIT Line Is (no longer used)* +# -10:00 THT Tahiti* +# - 9:30 MQT Marquesas* +# - 9:00 GBT Gambier* +# - 8:30 PIT Pitcairn* +# +# See the `northamerica' file for Hawaii and Samoa. +# See the `southamerica' file for Easter I and the Galapagos Is. +# +# See the `africa' file for Zone naming conventions. + +############################################################################### + +# Australia + +# From John Mackin (March 6, 1991): +# We in Australia have _never_ referred to DST as `daylight' time. +# It is called `summer' time. Now by a happy coincidence, `summer' +# and `standard' happen to start with the same letter; hence, the +# abbreviation does _not_ change... +# The legislation does not actually define abbreviations, at least +# in this State, but the abbreviation is just commonly taken to be the +# initials of the phrase, and the legislation here uniformly uses +# the phrase `summer time' and does not use the phrase `daylight +# time'. +# Announcers on the Commonwealth radio network, the ABC (for Australian +# Broadcasting Commission), use the phrases `Eastern Standard Time' +# or `Eastern Summer Time'. (Note, though, that as I say in the +# current australasia file, there is really no such thing.) Announcers +# on its overseas service, Radio Australia, use the same phrases +# prefixed by the word `Australian' when referring to local times; +# time announcements on that service, naturally enough, are made in UTC. + +# From Arthur David Olson (March 8 1992): +# Given the above, what's chosen for year-round use is: +# CST for any place operating at a GMTOFF of 9:30 +# WST for any place operating at a GMTOFF of 8:00 +# EST for any place operating at a GMTOFF of 10:00 + +# From Paul Eggert (November 8, 1994): +# Shanks reports 2:00 for all autumn changes in Australia and New Zealand. +# Mark Prior <mrp@itd.adelaide.edu.au> writes that his newspaper +# reports that NSW's fall 1995 change will occur at 2:00, +# but Robert Elz says it's been 3:00 in Victoria since 1970 +# and perhaps the newspaper's `2:00' is referring to standard time. +# And Robert Uzgalis <buz@cs.aukuni.ac.nz> says that the New Zealand Daylight +# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard +# time on both the first Sunday in October and the third Sunday in March. +# For now we'll continue to assume 3:00 for changes since 1970. + +# Northern Territory + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The NORTHERN TERRITORY.. [ Courtesy N.T. Dept of the Chief Minister ] +# # [ Nov 1990 ] +# # N.T. have never utilised any DST due to sub-tropical/tropical location. +# ... +# Zone Australia/North 9:30 - CST + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# the Northern Territory do[es] not have daylight saving. + +# Western Australia + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of WESTERN AUSTRALIA.. [ Courtesy W.A. dept Premier+Cabinet ] +# # [ Nov 1990 ] +# # W.A. suffers from a great deal of public and political opposition to +# # DST in principle. A bill is brought before parliament in most years, but +# # usually defeated either in the upper house, or in party caucus +# # before reaching parliament. +# ... +# Zone Australia/West 8:00 AW %sST +# ... +# Rule AW 1974 only - Oct lastSun 2:00 1:00 D +# Rule AW 1975 only - Mar Sun>=1 3:00 0 W +# Rule AW 1983 only - Oct lastSun 2:00 1:00 D +# Rule AW 1984 only - Mar Sun>=1 3:00 0 W + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# Western Australia...do[es] not have daylight saving. + +# From John D. Newman via Bradley White (November 2, 1991): +# Western Australia is still on "winter time". Some DH in Sydney +# rang me at home a few days ago at 6.00am. (He had just arrived at +# work at 9.00am.) +# W.A. is switching to Summer Time on Nov 17th just to confuse +# everybody again. + +# From Arthur David Olson (March 8, 1992): +# The 1992 ending date used in the rules is a best guess; +# it matches what was used in the past. + +# Queensland +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ] +# # [ Dec 1990 ] +# ... +# Zone Australia/Queensland 10:00 AQ %sST +# ... +# Rule AQ 1971 only - Oct lastSun 2:00 1:00 D +# Rule AQ 1972 only - Feb lastSun 3:00 0 E +# Rule AQ 1989 max - Oct lastSun 2:00 1:00 D +# Rule AQ 1990 max - Mar Sun>=1 3:00 0 E + +# From Bradley White (December 24, 1989): +# "Australia/Queensland" now observes daylight time (i.e. from +# October 1989). + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Queensland...[has] agreed to end daylight saving +# at 3am tomorrow (March 3)... + +# From John Mackin (March 6, 1991): +# I can certainly confirm for my part that Daylight Saving in NSW did in fact +# end on Sunday, 3 March. I don't know at what hour, though. (It surprised +# me.) + +# From Bradley White (March 8, 1992): +# ...there was recently a referendum in Queensland which resulted +# in the experimental daylight saving system being abandoned. So, ... +# ... +# Rule QLD 1989 1991 - Oct lastSun 2:00 1:00 D +# Rule QLD 1990 1992 - Mar Sun>=1 3:00 0 S +# ... + +# From Arthur David Olson (March 8, 1992): +# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes. + +# South Australia, Tasmania, Victoria + +# From Arthur David Olson (March 8, 1992): +# The rules from version 7.1 follow. +# There are lots of differences between these rules and +# the Shepherd et al. rules. Since the Shepherd et al. rules +# and Bradley White's newspaper article are in agreement on +# current DST ending dates, no worries. +# +# Rule Oz 1971 1985 - Oct lastSun 2:00 1:00 - +# Rule Oz 1986 max - Oct Sun<=24 2:00 1:00 - +# Rule Oz 1972 only - Feb 27 3:00 0 - +# Rule Oz 1973 1986 - Mar Sun>=1 3:00 0 - +# Rule Oz 1987 max - Mar Sun<=21 3:00 0 - +# Zone Australia/Tasmania 10:00 Oz EST +# Zone Australia/South 9:30 Oz CST +# Zone Australia/Victoria 10:00 Oz EST 1985 Oct lastSun 2:00 +# 10:00 1:00 EST 1986 Mar Sun<=21 3:00 +# 10:00 Oz EST + +# From Robert Elz (March 6, 1991): +# I believe that the current start date for DST is "lastSun" in Oct... +# that changed Oct 89. That is, we're back to the +# original rule, and that rule currently applies in all the states +# that have dst, incl Qld. (Certainly it was true in Vic). +# The file I'm including says that happened in 1988, I think +# that's incorrect, but I'm not 100% certain. + +# South Australia + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...South Australia...[has] agreed to end daylight saving +# at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ] +# # [ Nov 1990 ] +# ... +# Zone Australia/South 9:30 AS %sST +# ... +# Rule AS 1971 max - Oct lastSun 2:00 1:00 D +# Rule AS 1972 1985 - Mar Sun>=1 3:00 0 C +# Rule AS 1986 1990 - Mar Sun<=21 3:00 0 C +# Rule AS 1991 max - Mar Sun>=1 3:00 0 C + +# From Bradley White (March 11, 1992): +# Recent correspondence with a friend in Adelaide +# contained the following exchange: "Due to the Adelaide Festival, +# South Australia delays setting back our clocks for a few weeks." + +# From Robert Elz (March 13, 1992): +# I heard that apparently (or at least, it appears that) +# South Aus will have an extra 3 weeks daylight saving every even +# numbered year (from 1990). That's when the Adelaide Festival +# is on... + +# From Robert Elz (March 16, 1992, 00:57:07 +1000): +# DST didn't end in Adelaide today (yesterday).... +# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever... +# (it's just as likely to be "the Sunday we pick for this year"...). + +# From Bradley White (April 11, 1994): +# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March, +# 1994 was at +0930 as John Connolly's customer seems to assert, then I can +# only conclude that the actual rule is more complicated.... + +# From John Warburton <jwarb@SACBH.com.au> (1994-10-07): +# The new Daylight Savings dates for South Australia ... +# was gazetted in the Government Hansard on Sep 26 1994.... +# start on last Sunday in October and end in last sunday in March. + +# Tasmania + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Tasmania will revert to Australian Eastern Standard Time on March 31... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ] +# # [ Nov 1990 ] +# ... +# Zone Australia/Tasmania 10:00 AT %sST +# ... +# Rule AT 1967 only - Oct Sun>=1 2:00 1:00 D +# Rule AT 1968 only - Mar lastSun 3:00 0 E +# Rule AT 1968 1985 - Oct lastSun 2:00 1:00 D +# Rule AT 1969 1971 - Mar Sun>=8 3:00 0 E +# Rule AT 1972 only - Feb lastSun 3:00 0 E +# Rule AT 1973 1981 - Mar Sun>=1 3:00 0 E +# Rule AT 1982 1983 - Mar lastSun 3:00 0 E +# Rule AT 1984 1986 - Mar Sun>=1 3:00 0 E +# Rule AT 1986 only - Oct Sun>=15 2:00 1:00 D +# Rule AT 1987 1990 - Mar Sun>=15 3:00 0 E +# Rule AT 1987 only - Oct Sun>=22 2:00 1:00 D +# Rule AT 1988 1990 - Oct lastSun 2:00 1:00 D +# Rule AT 1991 max - Oct Sun>=1 2:00 1:00 D +# Rule AT 1991 max - Mar lastSun 3:00 0 E + +# From Bill Hart via Alexander Dupuy and Guy Harris (October 10, 1991): +# My state Government in there eagerness to get a few more bucks for the +# tourist industry industry decided to change the daylight savings times +# yet again (we now have almost 6 months per year)... +# ... +# Rule Oz 1986 1990 - Oct Sun<=24 2:00 1:00 - +# Rule Oz 1991 max - Oct Sun>=1 2:00 1:00 - +# ... +# Rule Oz 1987 1990 - Mar Sun<=21 3:00 0 - +# Rule Oz 1991 max - Mar Sun<=31 3:00 0 - + +# From Bill Hart via Guy Harris (October 10, 1991): +# Oh yes, the new daylight savings rules are uniquely tasmanian, we have +# 6 weeks a year now when we are out of sync with the rest of Australia +# (but nothing new about that). + +# Victoria + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# ...Victoria...[has] agreed to end daylight saving at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ] +# # [ Nov 1990 ] +# ... +# Zone Australia/Victoria 10:00 AV %sST +# ... +# Rule AV 1971 1985 - Oct lastSun 2:00 1:00 D +# Rule AV 1972 only - Feb lastSun 3:00 0 E +# Rule AV 1973 1985 - Mar Sun>=1 3:00 0 E +# Rule AV 1986 1990 - Mar Sun>=15 3:00 0 E +# Rule AV 1986 1987 - Oct Sun>=15 2:00 1:00 D +# Rule AV 1988 max - Oct lastSun 2:00 1:00 D +# Rule AV 1991 max - Mar Sun>=1 3:00 0 E + +# New South Wales + +# From Arthur David Olson: +# New South Wales and subjurisdictions have their own ideas of a fun time. +# Based on law library research by John Mackin (john@basser.cs.su.oz), +# who notes: +# In Australia, time is not legislated federally, but rather by the +# individual states. Thus, while such terms as ``Eastern Standard Time'' +# [I mean, of course, Australian EST, not any other kind] are in common +# use, _they have NO REAL MEANING_, as they are not defined in the +# legislation. This is very important to understand. +# I have researched New South Wales time only... + +# From Dave Davey (March 3, 1990): +# Rule NSW 1988 only - Mar Sun>=1 3:00 0 - +# Rule NSW 1989 only - Mar Sun<=21 3:00 0 - + +# From Bradley White (March 4, 1991): +# A recent excerpt from an Australian newspaper... +# NSW...[has] agreed to end daylight saving at 3am tomorrow (March 3)... + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The state of NEW SOUTH WALES.. [confirmed by Attorney General's Dept N.S.W] +# # [ Dec 1990 ] +# ... +# Rule AN 1988 1989 - Mar Sun<=21 3:00 0 E +# ... + +# From John Mackin (March 9, 1991) +# I have confirmed the accuracy of the historical data for NSW in the +# file Robert forwarded + +# From Arthur David Olson (March 8, 1992): +# Sources differ on whether DST ended March 6 or March 20 in 1988; +# March 20 (the "confirmed" date) is in the chosen rules. + +# Yancowinna + +# From John Basser (January 4, 1989): +# `Broken Hill' means the County of Yancowinna. + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # YANCOWINNA.. [ Confirmation courtesy of Broken Hill Postmaster ] +# # [ Dec 1990 ] +# ... +# # Yancowinna uses Central Standard Time, despite it's location on the +# # New South Wales side of the S.A. border. Most business and social dealings +# # are with CST zones, therefore CST is legislated by local government +# # although the switch to Summer Time occurs in line with N.S.W. There have +# # been years when this did not apply, but the historical data is not +# # presently available. +# Zone Australia/Yancowinna 9:30 AY %sST +# ... +# Rule AY 1971 1985 - Oct lastSun 2:00 1:00 D +# Rule AY 1972 only - Feb lastSun 3:00 0 C +# [followed by other Rules] + +# Lord Howe Island + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# LHI... [ Courtesy of Pauline Van Winsen.. pauline@Aus ] +# [ Dec 1990 ] +# Lord Howe Island is located off the New South Wales coast, and is half an +# hour ahead of NSW time. + +############################################################################### + +# New Zealand, from Elz' asia 1.1 +# Elz says "no guarantees" + +# From Mark Davies (October 3, 1990): +# the 1989/90 year was a trial of an extended "daylight saving" period. +# This trial was deemed successful and the extended period adopted for +# subsequent years (with the addition of a further week at the start). +# source -- phone call to Ministry of Internal Affairs Head Office. + +# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991): +# # The Country of New Zealand (Australia's east island -) Gee they hate that! +# # or is Australia the west island of N.Z. +# # [ courtesy of Geoff Tribble.. Geofft@Aus.. Auckland N.Z. ] +# # [ Nov 1990 ] +# ... +# Rule NZ 1974 1988 - Oct lastSun 2:00 1:00 D +# Rule NZ 1989 max - Oct Sun>=1 2:00 1:00 D +# Rule NZ 1975 1989 - Mar Sun>=1 3:00 0 S +# Rule NZ 1990 max - Mar lastSun 3:00 0 S +# ... +# Zone NZ 12:00 NZ NZ%sT # New Zealand +# Zone NZ-CHAT 12:45 - NZ-CHAT # Chatham Island + +# From Arthur David Olson (March 8, 1992): +# The chosen rules use the Davies October 8 values for the start of DST in 1989 +# rather than the October 1 value. + +############################################################################### + +# Fiji + +# Howse writes (p 162) that in 1879 the British governor of Fiji +# enacted an ordinance standardizing the islands on +12:00. +# Perhaps it didn't take. We go with Shanks's more precise date in 1915. + +# Kwajalein + +# In comp.risks 14.87 (26 August 1993), Peter Neumann writes: +# I wonder what happened in Kwajalein, where there was NO Friday, +# August 20, 1993. Thursday night at midnight Kwajalein switched sides with +# respect to the International Date Line, to rejoin its fellow islands, +# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink. + +# Pacific Islands Trust Territories + +# Howse writes (p 162) ``The Spaniards, on the other hand, reached the +# Philippines and the Ladrones from America,'' and implies that the Ladrones +# (now called the Marianas) kept American date for quite some time. +# Ignore this for now, as we have no hard data. See also Asia/Manila. diff --git a/time/backward b/time/backward new file mode 100644 index 0000000000..9298788b30 --- /dev/null +++ b/time/backward @@ -0,0 +1,75 @@ +# @(#)backward 7.6 + +# This file provides links between late-1993-vintage names for time zones +# and their previous names. + +Link Australia/Sydney Australia/ACT +Link Australia/Lord_Howe Australia/LHI +Link Australia/Sydney Australia/NSW +Link Australia/Darwin Australia/North +Link Australia/Brisbane Australia/Queensland +Link Australia/Adelaide Australia/South +Link Australia/Hobart Australia/Tasmania +Link Australia/Melbourne Australia/Victoria +Link Australia/Perth Australia/West +Link Australia/Broken_Hill Australia/Yancowinna +Link America/Porto_Acre Brazil/Acre +Link America/Noronha Brazil/DeNoronha +Link America/Sao_Paulo Brazil/East +Link America/Manaus Brazil/West +Link America/Halifax Canada/Atlantic +Link America/Winnipeg Canada/Central +Link America/Regina Canada/East-Saskatchewan +Link America/Montreal Canada/Eastern +Link America/Edmonton Canada/Mountain +Link America/St_Johns Canada/Newfoundland +Link America/Vancouver Canada/Pacific +Link America/Regina Canada/Saskatchewan +Link America/Whitehorse Canada/Yukon +Link America/Santiago Chile/Continental +Link Pacific/Easter Chile/EasterIsland +Link America/Havana Cuba +Link Africa/Cairo Egypt +Link Europe/Dublin Eire +Link Europe/London GB +Link Etc/GMT GMT +Link Etc/GMT+0 GMT+0 +Link Etc/GMT-0 GMT-0 +Link Etc/GMT0 GMT0 +Link Etc/Greenwich Greenwich +Link Asia/Hong_Kong Hongkong +Link Atlantic/Reykjavik Iceland +Link Asia/Tehran Iran +Link Asia/Tel_Aviv Israel +Link America/Jamaica Jamaica +Link Asia/Tokyo Japan +Link Pacific/Kwajalein Kwajalein +Link Africa/Tripoli Libya +Link America/Tijuana Mexico/BajaNorte +Link America/Mazatlan Mexico/BajaSur +Link America/Mexico_City Mexico/General +Link Pacific/Auckland NZ +Link Pacific/Chatham NZ-CHAT +Link Asia/Shanghai PRC +Link Europe/Warsaw Poland +Link Europe/Lisbon Portugal +Link Asia/Taipei ROC +Link Asia/Seoul ROK +Link Asia/Singapore Singapore +Link Europe/Istanbul Turkey +Link Etc/UCT UCT +Link America/Anchorage US/Alaska +Link America/Atka US/Aleutian +Link America/Phoenix US/Arizona +Link America/Chicago US/Central +Link America/Fort_Wayne US/East-Indiana +Link America/New_York US/Eastern +Link Pacific/Honolulu US/Hawaii +Link America/Knox_IN US/Indiana-Starke +Link America/Detroit US/Michigan +Link America/Denver US/Mountain +Link America/Los_Angeles US/Pacific +Link Pacific/Samoa US/Samoa +Link Etc/UTC UTC +Link Etc/Universal Universal +Link Etc/Zulu Zulu diff --git a/time/clocktest.c b/time/clocktest.c new file mode 100644 index 0000000000..0a248aa181 --- /dev/null +++ b/time/clocktest.c @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <time.h> + +main () +{ + volatile int i; + double t1, t2, t; + + t1 = (double) clock (); + for (i = 0; i < 100000; ++i) ; + t2 = (double) clock (); + + t = (t2 - t1) / ((double) CLOCKS_PER_SEC); + printf ("%f - %f = %f\n",t2,t1,t); + return 0; +} diff --git a/time/ctime.c b/time/ctime.c new file mode 100644 index 0000000000..24f565d006 --- /dev/null +++ b/time/ctime.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#undef __OPTIMIZE__ /* Avoid inline `ctime' function. */ +#include <time.h> + +#undef ctime + + +/* Return a string as returned by asctime which + is the representation of *T in that form. */ +char * +DEFUN(ctime, (t), CONST time_t *t) +{ + register struct tm *tp = localtime(t); + if (tp == NULL) + return NULL; + return asctime(tp); +} diff --git a/time/date.c b/time/date.c new file mode 100644 index 0000000000..2bb5c71b37 --- /dev/null +++ b/time/date.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + + +/* Prints the date in the form "Day Mon dd hh:mm:ss ZZZ yyyy\n". + A simple test for localtime and strftime. */ +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + time_t t = time(NULL); + register struct tm *tp = localtime(&t); + register char good = tp != NULL; + + if (good) + { + char buf[BUFSIZ]; + good = strftime(buf, sizeof(buf), "%a %b %d %X %Z %Y", tp); + if (good) + puts(buf); + else + perror("strftime"); + } + else + perror("localtime"); + + exit(good ? EXIT_SUCCESS : EXIT_FAILURE); + return(good ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/time/difftime.c b/time/difftime.c new file mode 100644 index 0000000000..49c5bfbc5c --- /dev/null +++ b/time/difftime.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1991, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <time.h> + + +/* Return the difference between TIME1 and TIME0. */ +double +DEFUN(difftime, (time1, time0), time_t time1 AND time_t time0) +{ + /* Algorithm courtesy Paul Eggert (eggert@twinsun.com). */ + + time_t delta, hibit; + + if (sizeof (time_t) < sizeof (double)) + return (double) time1 - (double) time0; + if (sizeof (time_t) < sizeof (LONG_DOUBLE)) + return (LONG_DOUBLE) time1 - (LONG_DOUBLE) time0; + + if (time1 < time0) + return - difftime (time0, time1); + + /* As much as possible, avoid loss of precision by computing the + difference before converting to double. */ + delta = time1 - time0; + if (delta >= 0) + return delta; + + /* Repair delta overflow. */ + hibit = 1; + while ((hibit <<= 1) > 0) + continue; + + /* The following expression rounds twice, which means the result may not + be the closest to the true answer. For example, suppose time_t is + 64-bit signed int, long_double is IEEE 754 double with default + rounding, time1 = 9223372036854775807 and time0 = -1536. Then the + true difference is 9223372036854777343, which rounds to + 9223372036854777856 with a total error of 513. But delta overflows to + -9223372036854774273, which rounds to -9223372036854774784, and + correcting this by subtracting 2 * (long_double) hibit (i.e. by adding + 2**64 = 18446744073709551616) yields 9223372036854776832, which rounds + to 9223372036854775808 with a total error of 1535 instead. This + problem occurs only with very large differences. It's too painful to + fix this portably. We are not alone in this problem; many C compilers + round twice when converting large unsigned types to small floating + types, so if time_t is unsigned the "return delta" above has the same + double-rounding problem. */ + return delta - 2 * (LONG_DOUBLE) hibit; +} diff --git a/time/dysize.c b/time/dysize.c new file mode 100644 index 0000000000..1f8f624556 --- /dev/null +++ b/time/dysize.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <time.h> + +int +dysize (year) + int year; +{ + return __isleap (year) ? 366 : 365; +} diff --git a/time/emkdir.c b/time/emkdir.c new file mode 100644 index 0000000000..5cc62d29e2 --- /dev/null +++ b/time/emkdir.c @@ -0,0 +1,85 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)emkdir.c 8.23"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#ifndef emkdir + +/*LINTLIBRARY*/ + +#include "private.h" + +extern char * imalloc P((int n)); +extern void ifree P((char * p)); + +static char * +quoted(name) +register const char * name; +{ + register char * result; + register char * cp; + register int c; + + if (name == NULL) + name = ""; + result = imalloc((int) (4 * strlen(name) + 3)); + if (result == NULL) + return NULL; + cp = result; +#ifdef unix + *cp++ = '\''; + while ((c = *name++) != '\0') + if (c == '\'') { + *cp++ = c; + *cp++ = '\\'; + *cp++ = c; + *cp++ = c; + } else *cp++ = c; + *cp++ = '\''; +#endif /* defined unix */ +#ifndef unix + while ((c = *name++) != '\0') + if (c == '/') + *cp++ = '\\'; + else *cp++ = c; +#endif /* !defined unix */ + *cp = '\0'; + return result; +} + +int +emkdir(name, mode) +const char * name; +const int mode; +{ + register int result; + register const char * format; + register char * command; + register char * qname; + + if ((qname = quoted(name)) == NULL) + return -1; +#ifdef unix + format = "mkdir 2>&- %s && chmod 2>&- %o %s"; +#endif /* defined unix */ +#ifndef unix + format = "mkdir %s"; +#endif /* !defined unix */ + command = imalloc((int) (strlen(format) + 2 * strlen(qname) + 20 + 1)); + if (command == NULL) { + ifree(qname); + return -1; + } + (void) sprintf(command, format, qname, mode, qname); + ifree(qname); + result = system(command); + ifree(command); + return (result == 0) ? 0 : -1; +} + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +*/ + +#endif /* !defined emkdir */ diff --git a/time/etcetera b/time/etcetera new file mode 100644 index 0000000000..ed619aecfa --- /dev/null +++ b/time/etcetera @@ -0,0 +1,54 @@ +# @(#)etcetera 7.4 + +# All of these are set up just so people can "zic -l" to a timezone +# that's right for their area, even if it doesn't have a name or DST rules +# (half hour zones are too much to bother with -- when someone asks!) + +Zone Etc/GMT 0 - GMT +Link Etc/GMT Etc/UTC +Link Etc/GMT Etc/UCT +Link Etc/GMT Etc/Universal +Link Etc/GMT Etc/Greenwich +Link Etc/GMT Etc/Zulu +Link Etc/GMT Etc/GMT-0 +Link Etc/GMT Etc/GMT+0 +Link Etc/GMT Etc/GMT0 + +# We use POSIX-style signedness in the names and output, +# internal-style signedness in the specifications. +# For example, TZ=Etc/GMT+4 corresponds to 4 hours _behind_ GMT; +# it is equivalent to TZ=GMT+4, which is implemented directly as per POSIX. + +# Earlier incarnations of this package were not POSIX-compliant, +# and had lines such as +# Zone GMT-12 -12 - GMT-1200 +# We did not want things to change quietly if someone accustomed to the old +# way does a +# zic -l GMT-12 +# so we moved the names into the Etc subdirectory. + +Zone Etc/GMT-13 13 - GMT-13 # 12 hours ahead of GMT, plus DST +Zone Etc/GMT-12 12 - GMT-12 +Zone Etc/GMT-11 11 - GMT-11 +Zone Etc/GMT-10 10 - GMT-10 +Zone Etc/GMT-9 9 - GMT-9 +Zone Etc/GMT-8 8 - GMT-8 +Zone Etc/GMT-7 7 - GMT-7 +Zone Etc/GMT-6 6 - GMT-6 +Zone Etc/GMT-5 5 - GMT-5 +Zone Etc/GMT-4 4 - GMT-4 +Zone Etc/GMT-3 3 - GMT-3 +Zone Etc/GMT-2 2 - GMT-2 +Zone Etc/GMT-1 1 - GMT-1 +Zone Etc/GMT+1 -1 - GMT+1 +Zone Etc/GMT+2 -2 - GMT+2 +Zone Etc/GMT+3 -3 - GMT+3 +Zone Etc/GMT+4 -4 - GMT+4 +Zone Etc/GMT+5 -5 - GMT+5 +Zone Etc/GMT+6 -6 - GMT+6 +Zone Etc/GMT+7 -7 - GMT+7 +Zone Etc/GMT+8 -8 - GMT+8 +Zone Etc/GMT+9 -9 - GMT+9 +Zone Etc/GMT+10 -10 - GMT+10 +Zone Etc/GMT+11 -11 - GMT+11 +Zone Etc/GMT+12 -12 - GMT+12 diff --git a/time/europe b/time/europe new file mode 100644 index 0000000000..a802cfec8c --- /dev/null +++ b/time/europe @@ -0,0 +1,2072 @@ +# @(#)europe 7.17 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# The starred Russian names are dubious. Corrections are welcome! +# std dst +# LMT Local Mean Time +# LST Local Star Time (Russian ``mestnoe zvezdnoe vremya'') +# -4:00 AST Atlantic +# -3:00 WGT+DST Western Greenland* +# -2:00 MGT+DST Middle Greenland* +# -1:00 EGT+DST Eastern Greenland* +# -1:00 ACT+DST Azores and Canaries* +# -1:00 IST IDT Iceland (no longer used)* +# 0:00 GMT BST Greenwich, British Summer +# 0:00 WET+DST Western Europe +# 1:00 MET+DST Middle Europe +# 2:00 EET+DST Eastern Europe +# 3:00 MSK MSD Moscow +# 3:00 TUR+DST Turkey (no longer used)* +# 4:00 KSK KSD Kuybyshev* +# 5:00 ESK ESD Yekaterinburg* +# 6:00 OSK OSD Omsk* +# 6:00 NSK NSD Novosibirsk (was 7:00 until 1994) +# 7:00 TSK TSD Tomsk* +# 8:00 ISK ISD Irkutsk* +# 9:00 YSK YSD Yakutsk* +# 10:00 VSK VSD Vladivostok* +# 11:00 GSK GSD Magadan* +# 12:00 PSK PSD Petropavlovsk-Kamchatski* +# 13:00 ASK ASD Anadyr* +# +# See the `africa' file for Zone naming conventions. +# +# A reliable and entertaining source about time zones, especially in Britain, +# is Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). + +# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993): +# LST is Local Star Time (``mestnoe zvezdnoe vremya''). + +# From Peter Ilieve <peter@memex.co.uk> (December 4, 1994), +# The original six [EU members]: Belguim, France, (West) Germany, Italy, +# Luxembourg, the Netherlands. +# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom. +# Plus, from 1 Jan 81: Greece. +# Plus, from 1 Jan 86: Spain, Portugal. +# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for +# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8% +# on a turnout of 88.6%. This was almost the same result as Norway's previous +# referendum in 1972, they are the only country to have said No twice. +# Referendums in the other three countries voted Yes.) +# ... +# The only [current nonmember using EU rules] I can speak for is Estonia, +# which uses EU dates but not at 01:00 GMT, they use midnight GMT. I don't +# think they know yet what they will do from 1996 onwards. +# ... +# There shouldn't be any [current members who are not using EU rules]. +# A Directive has the force of law, member states are obliged to enact +# national law to implement it. The only contentious issue was the +# different end date for the UK and Ireland, and this was always allowed +# in the Directive. + +############################################################################### + +# United Kingdom + +# From Peter Ilieve <peter@memex.co.uk> (July 6, 1994): +# +# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about +# historical vistas along the Thames in west London. There was a photo +# and a sketch map showing some of the sightlines involved. One paragraph +# of the text said: +# +# `An old stone obelisk marking a forgotten terrestrial meridian stands +# beside the river at Kew. In the 18th century, before time and longditude +# was standardised by the Royal Observatory in Greenwich, scholars observed +# this stone and the movement of stars from Kew Observatory nearby. They +# made their calculations and set the time for the Horse Guards and Parliament, +# but now the stone is obscured by scrubwood and can only be seen by walking +# along the towpath within a few yards of it.' +# +# I have a one inch to one mile map of London and my estimate of the stone's +# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longditude should +# be within about +-2". The Ordnance Survey grid reference is TQ172761. +# +# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.] + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# Howse writes that Britain was the first country to use standard time. +# The railways cared most about the inconsistencies of local mean time, +# and it was they who forced a uniform time on the country. +# The original idea was credited to Dr. William Hyde Wollaston (1766-1828); +# it was popularized in 1840 by Capt. Basil Hall, RN (1788-1844), +# famed explorer and former Commissioner for Longitude. +# The first railway to adopt London time was the Great Western Railway +# in November 1840; other railways followed suit, and by 1847 most +# (though not all) railways used London time. On 1847 Sep 22 the +# Railway Clearing House, an industry standards body, recommended that GMT be +# adopted at all stations; the January 1848 Bradshaw's lists most major +# railways as using GMT. By 1855 the vast majority of public +# clocks in Britain were set to GMT (though some, like the Great Clock +# in Tom Tower at Christ Church, Oxford, were fitted with two minute hands, +# one for local time and one for GMT). The last major holdout was the legal +# system, which stubbornly stuck to local time for many years, leading +# to oddities like polls opening at 08:13 and closing at 16:13. +# The legal system finally switched to GMT when the Statutes (Definition +# of Time) Act took effect; it received the Royal Assent on 1880 Aug 2. +# +# In the tables below, we condense this complicated story into a single +# transition date for London, namely 1847 Sep 22. We don't know as much +# about Dublin, so we use 1880 Aug 2, the legal transition time. + +# From Arthur David Olson (January 19, 1989): +# +# A source at the British Information Office in New York avers that it's +# known as "British" Summer Time in all parts of the United Kingdom. + +# Date: 4 Jan 89 08:57:25 GMT (Wed) +# From: Jonathan Leffler <nih-csl!uunet!mcvax!sphinx.co.uk!john> +# [British Summer Time] is fixed annually by Act of Parliament. +# If you can predict what Parliament will do, you should be in +# politics making a fortune, not computing. + +# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993): +# +# Our Government...couldn't...make a decision after the 1989 consultation +# exercise about the UK changing its timezone so it just let things drift +# (different from deciding to keep the status quo). According to the +# Summer Time Order 1992 (SI 1992/1729) the dates of Summer Time for 1993 +# and 1994 are: +# Start End +# 1993 28 March 24 October +# 1994 27 March 23 October +# All start and end times are at 01:00 GMT. +# +# There [was] an error in your tables for the start and end times prior to 1981. +# The UK always used to change at 02:00 GMT. In 1981 it changed to 01:00 GMT +# as a part of EC harmonisation and has remained at that time since. +# +# I have found the default algorithm for UK Summer Time, it is in the +# Summer Time Act 1972. Section 1 states that in the absence of an Order +# in Council Summer Time starts at 02:00 GMT on the morning of the day +# after the third Saturday in March, unless that day is Easter Day, in +# which case it is the morning of the day after the second Saturday. +# It ends at 02:00 GMT on the morning of the day after the fourth Saturday +# in October. (All the redundant `morning of the day ...' is in the Act.) +# This is only of passing interest now as it will always be overridden by +# an Order in Council (a Statutary Instrument, the SI thing mentioned above) +# to specify the EC specified dates. + +# From Peter Ilieve <peter@memex.co.uk> (October 18, 1993): +# +# My contact in the Ministry of Defence Public Relations department +# accepted the challenge of looking into this and produced the following, +# from Hansard (the official record of the UK Parliament), Oral Answers, +# 1 March 1945, cols 1559--60: +# +# `58. Major Sir Goronwy Owen asked the Secretary of State for the Home +# Department if he is now able to state the Government's proposals +# regarding double summer time. +# +# [two other similar questions omitted] +# +# Mr. H. Morrison: The Government, in reviewing the matter, have +# considered, [...] the conclusion has been reached that the adoption of +# double summer time from the beginning of April is essential to the +# maintenance of the war effort. [...] As 1st April is Easter Sunday, +# when very early services are held in many churches, it is proposed that +# double summer time shall start not in the night preceding Easter +# Sunday, but in the night of Sunday- Monday so that it will operate from +# Monday, 2nd April.' + +# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993): +# +# > # Current rules +# > Rule GB-Eire 1981 max - Mar lastSun 1:00s 1:00 BST +# > Rule GB-Eire 1981 max - Oct Sun>=23 1:00s 0 GMT +# +# The ending rule here doesn't match the EC rules, which specify the fourth +# Sunday in October for the UK and Eire. The `fourth Sunday' rule wasn't +# followed in 1989, but then the sixth EC directive wasn't in force then +# and I don't know what previous ones said. 1995 is the next year with +# the 4th Sun on 22 Oct, but that year isn't covered by the UK Summer Time +# Order or the sixth EC directive. Your Oct Sun>=23 rule matches history +# and with things only announced for 2 years or so in advance who knows +# what will happen. +# +# There are renewed rumours that the Government here will make another +# attempt at resolving this issue, which is what prompted me to start +# asking the Home Office and the EC about it again. The EC categorically +# state they are not asking anybody to change timezone, they only want +# common start/end dates. The UK Govt. seem to want to change our zone +# and blame the resulting fuss on the EC. Me, I think we should scrap +# summer time completely, noon is when the Sun is overhead, and that should +# be the end of it. + +# From Peter Ilieve <peter@memex.co.uk> (October 22, 1993): +# +# I now have the text of the Summer Time Act 1916, the granddaddy of them all. +# It is headed: `An Act to provide for the Time in Great Britain and Ireland +# being in advance of Greenwich and Dublin mean time respectively in the +# summer months'. +# +# It specifies 21 May and 1 October for 1916 (both at 02:00 GMT) and whatever +# dates an Order in Council may specify for subsequent years. +# +# Section 4 states: `This act shall apply to Ireland in like manner as it +# applies to Great Britain, with the substitution however of references +# to Dublin mean time for references to Greenwich mean time.' +# +# Lorna, my learned legal friend who supplied it, also offers this quote +# from Halsbury's Statutes on the extent of Acts: +# +# `An Act of the United Kingdom Parliament is to be construed prima facie +# to apply to the whole of the United Kingdom and not to any place outside. +# [...] The expression "United Kingdom" for this purpose includes (since +# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland, +# but it does not include the Channel Islands or the Isle of Man.' +# +# She goes on to say the seminal event of 1922 was the establishment of +# the Irish Free State, now called Eire. +# +# The Act doesn't say anything about Wales (or Scotland) so I would assert +# that Shanks is wrong here. I would like to know why he thinks Wales +# was different. +# +# It also confirms the fact that Ireland followed Dublin time back then, +# and 25 minutes behind Greenwich, as Shanks has it, would be correct. + +# From Peter Ilieve <peter@memex.co.uk> (October 28, 1993): +# +# I now have before me, thanks to my learned legal friend Lorna, the text of +# the Time (Ireland) Act 1916. +# +# It says that as from 2 AM Dublin Mean Time on 1 October 1916 the time +# for general purposes in Ireland shall be the same as the rest of Great +# Britain (ie. GMT with the Summer Time periods specified by the Summer Time +# Act 1916).... As Ireland was behind GMT/BST at 02:00 DMT on 1 Oct GB would +# have already put the clocks back. Using DST as Dublin Summer Time the +# sequence would have been: +# Dublin London +# 02:34 DST 02:59 BST +# 02:35 DST 02:00 GMT +# 02:59 DST 02:24 GMT +# 02:25 GMT 02:25 GMT +# with the transition 03:00 DST -> 02:00 DMT -> 02:25 GMT all at once. +# +# In a table of repeals in the Schedule to the Act it mentions the +# Statutes (Definition of Time) Act 1880. This is presumably the source +# of the 1880 date in Shanks. The little bit of it that is repealed +# also refers solely to Ireland and Dublin Mean Time. + +# From Peter Ilieve <peter@memex.co.uk> (October 29, 1993): +# +# My case is that, with the sole exception of Ireland in 1916 using Dublin +# Mean Time, Summer Time has been uniform throughout the United Kingdom +# ever since it first started in 1916. +# +# The United Kingdom is England, Wales and Scotland plus all of Ireland from +# 1916 up to and including 1921, or plus Northern Ireland from 1922 to date. +# +# The dates used are those specified in the table in Summer Time: A Consultation +# Document (Cm 722, 1989) that are now included in the europe file, with a +# change to a single date, the start in 1924. I made a typo in my 1989 mail +# and the table itself is also wrong. The correct date is 13 April. +# The times were 02:00 GMT up to and including 1980, 01:00 GMT from 1981 on, +# except for wartime double summer time. +# +# As evidence I would cite: +# +# - The Summer Time Act, 1916. +# +# This specifically states that it applies to Ireland, specifies dates of +# 21 May and 1 October and times of 02:00, and says that in Ireland the +# times relate to Dublin mean time. It specifies an offset of 1 hour. +# +# - The Time (Ireland) Act, 1916 +# +# This abolishes Dublin mean time on 02:00 DMT 1 October 1916. +# It repeals that section of the Statutes (Definition of Time) Act, 1880 +# that specifies DMT. It is therefore a safe bet that DMT existed at least +# from 1880 and was the only alternative standard time in the UK. +# +# - The Summer Time Act, 1922 +# +# This specifies an offset of 1 hour and dates of the day after the third +# Saturday in April, unless that be Easter, in which case it is the day after +# the second Saturday, and the day after the third Saturday in September. +# The time is 02:00 GMT. It applied in 1922 and 1923, and longer if Parliament +# so approved. +# +# It specifically states that it applies to Northern Ireland, the Channel +# Islands, and the Isle of Man. +# +# - The Summer Time Act, 1925 +# +# This makes the 1922 Act permanent, with a change to the end date to the +# day after the first Saturday in October. It says nothing about extent, +# so that part of the 1922 Act will still apply. +# +# - The Defence (Summer Time) Regulations, 1939, SR&O 1939 No. 1379 +# [SR&O == Statutary Regulation and Order] +# +# These were made under the Emergency Powers (Defence) Act, 1939. +# It changes the end date to be the day after the third Saturday in November. +# It makes consequential changes to some vehicle lighting legislation, +# which includes the Motor Vehicles and Road Traffic (Northern Ireland) Act, +# 1934, so it seems clear it applies in Northern Ireland. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1940 No. 1883 +# +# This continues summer time throughout the year after it starts in 1940. +# It says nothing about extent and has no consequential changes. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1941 No. 476 +# +# This introduces double summer time, starting at 01:00 GMT on the day after +# the first Saturday in May and ending at 01:00 GMT on the day after the +# second Saturday in August, offset another hour from normal summer time, +# which continues throughout the rest of the year. It goes on a lot about +# consequential changes to agricultural wages legislation, and says in part +# `... and in its application to Northern Ireland have effect as +# if for the references to the Agricultural Wages (Regulation) Acts, 1924 and +# 1940, there were substituted references to the Agricultural Wages (Regulation) +# Acts (Northern Ireland), 1939 and 1940, ...'. It also has a similar section +# for Scotland. Both sections substitute the local Agricultural Wages Board +# for the Agricultural Wages Board for England and Wales, showing that +# England and Wales were indivisible. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1942 No. 506 +# +# This changes the start date of double summer time to the day after the first +# Saturday in April. It says nothing about extent. +# +# - An Order in Council amending the The Defence (Summer Time) Regulations, +# 1939, SR&O 1944 No. 932 +# +# This changed the end date of double summer time to 17 September 1944. +# (I don't have the text of this, just a note of what it did, the text almost +# certainly had the `day after the nth Saturday' form.) +# +# (I am missing whatever regulations there were to change things in 1945 +# and the Summer Time Act, 1947.) +# +# - The British Standard Time Act, 1968 +# +# This came into force on 27 October 1968 and continued summer time throughout +# the year as an experiment until it expired on 31 October 1971. +# There was no double summer time so we didn't have to change the clocks at all. +# It specifically said it applied to Northern Ireland. It also said it +# applied to Jersey, Guernsey and the Isle of Man unless they passed +# measures saying it didn't. +# +# - The Manx Time Act, 1968 +# +# This is an Act of Tynwald (the Isle of Man Parliament) that said that +# henceforth Manx time would be the same as the time in Great Britain. +# +# - The Summer Time Act, 1972 +# +# This specified a reversion to normal summer time behaviour with a start +# date of the day after the third Saturday in March, unless that is Easter, +# when it is the day after the second Saturday, and an end date of the day +# after the fourth Saturday in October. Times are at 02:00 GMT, offset is +# 1 hour. +# +# It has the same wording about extent as the British Standard Time Act, 1968, +# applying to Northern Ireland unconditionally and to Jersey, Guernsey and the +# Isle of Man if they don't do something about it. +# +# (I am missing various Summer Time Orders that modified the 1972 Act to +# harmonise with the EC since 1981. The major change is that the time changes +# to 01:00 GMT.) +# +# - The Summer Time Order, 1992, SI 1992/1729 [SI == Statutary Instrument] +# +# This specifies dates of: +# Start End +# 1993 28 March 24 October +# 1994 27 March 23 October +# All start and end times are at 01:00 GMT.... +# +# - Some text on the extent of Acts, from Halsbury's Statutes +# +# `An Act of the United Kingdom Parliament is to be construed prima facie +# to apply to the whole of the United Kingdom and not to any place outside. +# [...] The expression "United Kingdom" for this purpose includes (since +# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland, +# but it does not include the Channel Islands or the Isle of Man.' +# +# So, many of these measures specifically include Northern Ireland, +# the Channel Islands and the Isle of Man. None of them exclude any +# part of the UK. The default interpretation of Acts is that they apply +# throughout the UK. +# +# With that, I rest my case Milud :-) +# +# Thanks are due to my learned legal friend Lorna Montgomerie, who dug out +# the dusty old statutes, and to Melanie Allison of the Ministry of Defence, +# who provided the wartime regulations and a snippet of Hansard explaining +# why double summer time started on a Monday in 1945 (it was Easter). + +# From Peter Ilieve <peter@memex.co.uk> (November 18, 1993) +# +# Here is a revised version of my tabrules file for the perl script I sent +# before. I have personally verified the various Orders back to 1953 and +# all the Acts. +# +# There are no changes to the dates we already have. +# +# My doubt about an early start in 1967 on 18 Feb was misplaced, the Order +# does say 18 Feb. This is an interesting case as the first Order gave a +# different date of 7 April 1967 for the Isle of Man but this was changed +# before it came into effect by another Order for the Isle of Man alone. +# +# I don't think I will be able to find any more of the earlier Orders. +# The annual volumes for 1949--52 do not contain the various Summer Time +# Orders. They therefore don't appear in the index. They rate a mention in +# italics in the numerical list at the start but that is all. +# I think what happens is that the annual volume is produced well after the +# end of the year in question, by which time the Summer Time Order is spent. +# They assume that nobody would ever be stupid enough to want to see it +# again so they leave it out. +# +# It might be a good idea to put this table, or the output of tabscript +# showing all the moves because of Easter, in the europe file comments in +# place of my old transcription of the Green Paper table [the UK Government +# paper "Summer Time: A Consultation Document" (HMSO Cm722 June 1989)]. +# +# Peter Ilieve peter@memex.co.uk +# +# +# ## control file for tabscript, a program to generate UK summer time dates +# ## matching the table in Cm 722, the 1989 Green Paper. +# ## Lines like this are comments. +# ## Lines with a single # at the start are copied into the output +# ## Control lines are of the form +# ## <years> <start date> <end date> <flags> <double start> <double end> +# ## <years> is either a single year or a hyphen separated range, with -- +# ## also accepted as I use this in TeX a lot. +# ## <start date> and <end date> are a digit followed bu a month name. +# ## It is either an nth Saturday or an explicit date, depending on <flags>. +# ## 0 and/or none are used when there is no date, as during 1968--71. +# ## <flags> can contain `fixed' to indicate explicit dates and `double' +# ## to indicate double summer time dates are present. +# ## At present double requires fixed as well. +# ## <double start> and <double end> are like the start and end dates, with +# ## the exception of the 0 and/or none feature. +# +# ## Blank lines are also ignored. +# +# ## Places where I am uncertain, not having personally verified the dates +# ## against the Act or Order, are marked ??? +# ## These dates are taken from the Cm 722 table. +# +# # Summer Time Act, 1916 +# 1916 21 May 1 October fixed +# +# ## I haven't yet looked for Orders for 1916--22 and I doubt I will find them. +# # unknown Order or Orders ??? +# 1917 8 apr 17 sep fixed +# 1918 24 mar 30 sep fixed +# 1919 30 mar 29 sep fixed +# # end date extended in 1920 from 27 Sep because of coal strike (from Cm 722) +# 1920 28 mar 25 oct fixed +# 1921 3 apr 3 oct fixed +# +# # Summer Time Act, 1922 +# # came into force 22 July 1922, too late for 1922, so missing Order ??? +# 1922 26 mar 8 oct fixed +# 1923-1924 3 April 3 September +# +# # Summer Time Act, 1925 +# 1925--1938 3 April 1 October +# +# # Defence (Summer Time) Regulations, 1939 +# 1939 3 April 3 November +# # 1940 amendment (SR&O 1940 Nos. 172 & 1883) +# 1940 4 feb 0 none +# # 1941 amendment (SR&O 1941 No. 476) +# 1941 0 none 0 none fixed,double 4 may 10 aug +# # 1942 amendment (SR&O 1942 No. 506) +# 1942 0 none 0 none fixed,double 5 apr 9 aug +# 1943 0 none 0 none fixed,double 4 apr 15 aug +# # 1944 amendment (SR&O 1944 No. 932) +# 1944 0 none 0 none fixed,double 2 apr 17 sep +# # 1945 dates from Hansard, Oral Answers, 1 March 1945 +# 1945 0 none 7 oct fixed,double 2 apr 15 jul +# +# # reversion to Summer Time Act, 1925 +# 1946 3 April 1 October +# +# # Summer Time Act, 1947 +# # Fixed dates for 1947 only, gives power to have double summer time +# 1947 16 mar 2 nov fixed,double 13 apr 10 aug +# ## I can't find any trace of the Order for 1948. +# # Unknown Order ??? +# 1948 14 mar 31 oct fixed +# ## I know the numbers for the 1949--52 ones but the text is missing from the +# ## annual volumes. I also don't know if the 49 Order was for 49 or 50, etc. +# # Summer Time Order, 1949 (SI1949/373) ??? +# 1949 3 apr 30 oct fixed +# # Summer Time Order, 1950 (SI1950/518) ??? +# 1950 16 apr 22 oct fixed +# # Summer Time Order, 1951 (SI1951/430) ??? +# 1951 15 apr 21 oct fixed +# # Summer Time Order, 1952 (SI1952/451) ??? +# 1952 20 apr 26 oct fixed +# +# # reversion to Summer Time Act, 1925 +# 1953--1960 3 April 1 October +# +# ## All Orders from here on specify fixed dates, not day after nth Sunday +# ## Start pattern looks like Mar lastSun up to 1963, Mar Sun>=19 up to 1967. +# ## End pattern looks like Oct Sun>=23 up to 1967. +# # Summer Time Order, 1961 (SI1961/71) +# 1961 26 March 29 October fixed +# # Summer Time (1962) Order, 1961 (SI1961/2465) +# 1962 25 Mar 28 Oct fixed +# # Summer Time Order, 1963 (SI1963/81) +# 1963 31 March 27 October fixed +# # Summer Time (1964) Order, 1963 (SI1963/2101) +# 1964 22 March 25 October fixed +# # Summer Time Order, 1964 (SI1964/1201) +# 1965 21 Mar 24 Oct fixed +# 1966 20 Mar 23 Oct fixed +# 1967 19 Mar 29 Oct fixed +# # Summer Time Order, 1967 (SI1967/1148) +# # Specifies different start date of 7 April for Isle of Man +# # Summer Time Order, 1968 (SI1968/117) +# # Changes Isle of Man start date to 18 Feb to match rest of UK +# # British Standard Time Act, 1968 +# 1968 18 feb 0 none fixed +# 1969--1970 0 none 0 none +# 1971 0 none 31 oct fixed +# +# # Summer Time Act, 1972 +# 1972-1980 3 March 4 October +# +# # The pattern here looks like Last Sun in Mar, day after 4th Sat in Oct +# # First EC Directive ??? +# # Summer Time Order, 1980 (SI1980/1089) +# 1981 29 Mar 25 Oct fixed +# 1982 28 Mar 24 Oct fixed +# # Second EC Directive ??? +# # Summer Time Order, 1982 (SI1982/1673) +# 1983 27 Mar 23 Oct fixed +# 1984 25 Mar 28 Oct fixed +# 1985 31 Mar 27 Oct fixed +# # Third EC Directive ??? +# # Summer Time Order, 1986 (SI1986/223) +# 1986 30 Mar 26 Oct fixed +# 1987 29 Mar 25 Oct fixed +# 1988 27 Mar 23 Oct fixed +# # Fourth EC Directive ??? +# # Summer Time Order, 1988 (SI1988/931) +# 1989 26 Mar 29 Oct fixed +# # Fifth EC Directive ??? +# # Summer Time Order, 1989 (SI1989/985) +# 1990 25 Mar 28 Oct fixed +# 1991 31 Mar 27 Oct fixed +# 1992 29 Mar 25 Oct fixed +# # Sixth EC Directive +# # Summer Time Order, 1992 (SI1992/1729) +# 1993 28 Mar 24 Oct fixed +# 1994 27 Mar 23 Oct fixed + +# From Peter Ilieve <peter@memex.co.uk> (August 18, 1994): +# I now have the text of the 7th EC directive on summer time arrangements +# (94/21/EC), which was approved on 30 May.... +# The major changes from existing practice are that 1995 will be the last year +# that the UK and Eire finish on a different date from everyone else, +# and the common end date from 1996 onwards will be the last Sunday in October. +# Year Start End End (UK & Eire, 1995 only) +# (rule) (last Sun) (last Sun) (4th Sun) +# 1995 26 March 24 September 22 October +# 1996 31 March 27 October +# 1997 30 March 26 October +# +# From Peter Ilieve <peter@memex.co.uk> (1994-12-01): +# The final piece of the legislative jigsaw for summer time in the UK for +# 1995-97 is now in place. The Summer Time Order 1994 (SI 1994/2798) +# came into force on 16 November. It restates the dates from the EC +# seventh Summer Time Directive.... + +# From Peter Ilieve <peter@memex.co.uk> (March 28, 1994): +# The UK/Eire end date of 22 October [1995] conflicts with your current rule of +# Oct Sun>=23, and the historical UK formula of Sun after 4th Sat. +# The last time 4th Sun and Sun after 4th Sat differed was in 1989, +# when 29 October was used. That year was covered by a UK Summer Time Order +# for only a single year and it looks as though there was a matching 4th EC +# directive for just this year. I don't have the text of the 5th EC +# directive (for 1990--92) but my guess would be it said 4th Sun. +# To maintain strict historical accuracy you could start a new UK ending rule +# of Oct Sun>=22 in 1990. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# +# As Ilieve remarks, the date `20 April 1924' in the table of ``Summer Time: A +# Consultation Document'' (Cm 722, 1989) table is a transcription error; +# 20 April was an Easter Sunday. Shanks has 13 April, the correct date. +# Also, the table is not quite right for 1925 through 1938; the correct rules +# (which Shanks uses) are given in the Summer Time Acts of 1922 and 1925. +# Shanks and the UK Government paper disagree about the Apr 1956 transition; +# since we have no other data, and since Shanks was correct in the other +# points of disagreement about London, we'll believe Shanks for now. +# Also, for lack of other data, we'll follow Shanks for Eire in 1940-1948. +# +# Given Peter Ilieve's comments, the following claims by Shanks are incorrect: +# * Wales did not switch from GMT to daylight savings time until +# 1921 Apr 3, when they began to conform with the rest of Great Britain. +# Actually, Wales was identical after 1880. +# * Eire had two transitions on 1916 Oct 1. +# It actually just had one transition. +# * Northern Ireland used single daylight savings time throughout WW II. +# Actually, it conformed to Britain. +# +# The following claim by Shanks is possible though doubtful; +# we'll ignore it for now. +# * Jersey, Guernsey, and the Isle of Man did not switch from GMT +# to daylight savings time until 1921 Apr 3, when they began to +# conform with Great Britain. +# +# Whitman says Dublin Mean Time was -0:25:21, which is more precise than Shanks. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule GB-Eire 1847 only - Sep 22 0:00 0 GMT +# 1916 to 1925--irregular +Rule GB-Eire 1916 only - May 21 2:00s 1:00 BST +Rule GB-Eire 1916 only - Oct 1 2:00s 0 GMT +Rule GB-Eire 1917 only - Apr 8 2:00s 1:00 BST +Rule GB-Eire 1917 only - Sep 17 2:00s 0 GMT +Rule GB-Eire 1918 only - Mar 24 2:00s 1:00 BST +Rule GB-Eire 1918 only - Sep 30 2:00s 0 GMT +Rule GB-Eire 1919 only - Mar 30 2:00s 1:00 BST +Rule GB-Eire 1919 only - Sep 29 2:00s 0 GMT +Rule GB-Eire 1920 only - Mar 28 2:00s 1:00 BST +Rule GB-Eire 1920 only - Oct 25 2:00s 0 GMT +Rule GB-Eire 1921 only - Apr 3 2:00s 1:00 BST +Rule GB-Eire 1921 only - Oct 3 2:00s 0 GMT +Rule GB-Eire 1922 only - Mar 26 2:00s 1:00 BST +Rule GB-Eire 1922 only - Oct 8 2:00s 0 GMT +Rule GB-Eire 1923 only - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1923 1924 - Sep Sun>=16 2:00s 0 GMT +Rule GB-Eire 1924 only - Apr 13 2:00s 1:00 BST +# 1925 to 1939 start--regular, except for avoiding Easter +Rule GB-Eire 1925 1926 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1925 1938 - Oct Sun>=2 2:00s 0 GMT +Rule GB-Eire 1927 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1928 1929 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1930 only - Apr 13 2:00s 1:00 BST +Rule GB-Eire 1931 1932 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1933 only - Apr 9 2:00s 1:00 BST +Rule GB-Eire 1934 only - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1935 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1936 1937 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1938 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1939 only - Apr Sun>=16 2:00s 1:00 BST +# 1939 end to 1947--irregular, and with double summer time +Rule GB-Eire 1939 only - Nov 19 2:00s 0 GMT +Rule GB-Eire 1940 only - Feb 25 2:00s 1:00 BST +Rule GB-Eire 1941 only - May Sun>=2 1:00s 2:00 DST +Rule GB-Eire 1941 1943 - Aug Sun>=9 1:00s 1:00 BST +Rule GB-Eire 1942 1944 - Apr Sun>=2 1:00s 2:00 DST +Rule GB-Eire 1944 only - Sep Sun>=16 1:00s 1:00 BST +# Double daylight starts on a Monday in 1945--see above. +Rule GB-Eire 1945 only - Apr 2 1:00s 2:00 DST +Rule GB-Eire 1945 only - Jul 15 1:00s 1:00 BST +Rule GB-Eire 1945 only - Oct 7 2:00s 0 GMT +Rule GB-Eire 1946 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1946 only - Oct 6 2:00s 0 GMT +Rule GB-Eire 1947 only - Mar 16 2:00s 1:00 BST +Rule GB-Eire 1947 only - Apr 13 1:00s 2:00 DST +Rule GB-Eire 1947 only - Aug 10 1:00s 1:00 BST +Rule GB-Eire 1947 only - Nov 2 2:00s 0 GMT +# So much for double saving time. 1948 and 1949, irregular. +Rule GB-Eire 1948 only - Mar 14 2:00s 1:00 BST +Rule GB-Eire 1948 1949 - Oct lastSun 2:00s 0 GMT +Rule GB-Eire 1949 only - Apr 3 2:00s 1:00 BST +# 1950 through start of 1953, regular. +Rule GB-Eire 1950 1953 - Apr Sun>=14 2:00s 1:00 BST +Rule GB-Eire 1950 1952 - Oct Sun>=21 2:00s 0 GMT +# 1954 to 1980, starting rules +Rule GB-Eire 1954 only - Apr 11 2:00s 1:00 BST +Rule GB-Eire 1955 1956 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1957 only - Apr 14 2:00s 1:00 BST +Rule GB-Eire 1958 1959 - Apr Sun>=16 2:00s 1:00 BST +Rule GB-Eire 1960 only - Apr 10 2:00s 1:00 BST +Rule GB-Eire 1961 1963 - Mar lastSun 2:00s 1:00 BST +Rule GB-Eire 1964 1967 - Mar Sun>=19 2:00s 1:00 BST +Rule GB-Eire 1972 1980 - Mar Sun>=16 2:00s 1:00 BST +# 1953 to 1980, ending rules +Rule GB-Eire 1953 1960 - Oct Sun>=1 2:00s 0 GMT +Rule GB-Eire 1961 1967 - Oct Sun>=23 2:00s 0 GMT +Rule GB-Eire 1971 only - Oct 31 3:00 0 GMT +Rule GB-Eire 1972 1980 - Oct Sun>=23 2:00s 0 GMT +# 1981 on +Rule GB-Eire 1981 max - Mar lastSun 1:00s 1:00 BST +Rule GB-Eire 1981 1989 - Oct Sun>=23 1:00s 0 GMT +Rule GB-Eire 1990 1995 - Oct Sun>=22 1:00s 0 GMT +Rule GB-Eire 1996 max - Oct lastSun 1:00s 0 GMT +#Rule GB-Eire 1981 max - Mar lastSun 1:00u 1:00 BST +#Rule GB-Eire 1981 1989 - Oct Sun>=23 1:00u 0 GMT +#Rule GB-Eire 1990 1995 - Oct Sun>=22 1:00u 0 GMT +#Rule GB-Eire 1996 max - Oct lastSun 1:00u 0 GMT +# Also see W-Eur, which (starting 1996) differs only in LETTER/S. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/London -0:01:15 - LMT 1847 Sep 22 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 2:00 + 0:00 GB-Eire %s +Zone Europe/Belfast -0:23:40 - LMT 1880 Aug 2 + -0:25:21 - DMT 1916 May 21 2:00 # Dublin MT + -0:25:21 1:00 DST 1916 Oct 1 3:00 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 3:00 + 0:00 GB-Eire %s +Zone Europe/Dublin -0:25:21 - LMT 1880 Aug 2 + -0:25:21 - DMT 1916 May 21 2:00 # Dublin MT + -0:25:21 1:00 DST 1916 Oct 1 3:00 + 0:00 GB-Eire %s 1940 Feb 25 2:00 + 0:00 1:00 BST 1946 Oct 6 2:00 + 0:00 - GMT 1947 Mar 16 2:00 + 0:00 1:00 BST 1947 Nov 2 2:00 + 0:00 - GMT 1948 Apr 18 2:00 + 0:00 GB-Eire %s 1968 Feb 18 2:00 + 1:00 - BST 1971 Oct 31 3:00 + 0:00 GB-Eire %s + +############################################################################### + +# Continental Europe + +# The *-Eur rules now correspond to the European Community (EC). +# Three rulesets are used because the EC changes at 01:00 UTC, not local time. +# Older *-Eur rules are for convenience in the tables. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule W-Eur 1800 only - Jan 1 0:00 0 - +Rule W-Eur 1977 1980 - Apr Sun>=1 1:00s 1:00 " DST" +Rule W-Eur 1977 only - Sep lastSun 1:00s 0 - +Rule W-Eur 1978 only - Oct 1 1:00s 0 - +Rule W-Eur 1979 1995 - Sep lastSun 1:00s 0 - +Rule W-Eur 1981 max - Mar lastSun 1:00s 1:00 " DST" +Rule W-Eur 1996 max - Oct lastSun 1:00s 0 - +# Also see GB-Eire, which (starting 1996) differs only in LETTER/S. + +Rule M-Eur 1800 only - Jan 1 0:00 0 - +Rule M-Eur 1916 only - Apr 30 23:00 1:00 " DST" +Rule M-Eur 1916 only - Oct 1 1:00 0 - +Rule M-Eur 1917 1918 - Apr Mon>=15 2:00s 1:00 " DST" +Rule M-Eur 1917 1918 - Sep Mon>=15 2:00s 0 - +Rule M-Eur 1940 only - Apr 1 2:00s 1:00 " DST" +# Shanks says DST was continuous from 1940 Apr 1 to 1942 Nov 2; go with Whitman. +Rule M-Eur 1940 only - Dec 31 2:00s 0 - +Rule M-Eur 1941 only - Feb 25 2:00s 1:00 " DST" +Rule M-Eur 1941 only - Oct 5 2:00s 0 - +Rule M-Eur 1942 only - Jan 1 2:00s 1:00 " DST" +Rule M-Eur 1942 only - Nov 2 2:00s 0 - +Rule M-Eur 1943 only - Mar 29 2:00s 1:00 " DST" +Rule M-Eur 1943 only - Oct 4 2:00s 0 - +Rule M-Eur 1944 only - Apr 3 2:00s 1:00 " DST" +# Whitman gives 1944 Oct 7; go with Shanks. +Rule M-Eur 1944 only - Oct 2 2:00s 0 - +Rule M-Eur 1977 1980 - Apr Sun>=1 2:00s 1:00 " DST" +Rule M-Eur 1977 only - Sep lastSun 2:00s 0 - +Rule M-Eur 1978 only - Oct 1 2:00s 0 - +Rule M-Eur 1979 1995 - Sep lastSun 2:00s 0 - +Rule M-Eur 1981 max - Mar lastSun 2:00s 1:00 " DST" +Rule M-Eur 1996 max - Oct lastSun 2:00s 0 - + +Rule E-Eur 1981 max - Mar lastSun 3:00s 1:00 " DST" +Rule E-Eur 1981 1995 - Sep lastSun 3:00s 0 - +Rule E-Eur 1996 max - Oct lastSun 3:00s 0 - + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Russia 1880 only - Jan 1 0:00 0 - +Rule Russia 1917 only - Jul 1 23:00 1:00 " DST" +Rule Russia 1917 only - Dec 28 0:00 0 - +Rule Russia 1918 only - May 31 22:00 2:00 " DDST" +Rule Russia 1918 only - Sep 17 0:00 1:00 " DST" +Rule Russia 1919 only - May 31 23:00 2:00 " DDST" +Rule Russia 1919 only - Jul 1 2:00 1:00 D +Rule Russia 1919 only - Aug 16 0:00 0 K +Rule Russia 1921 only - Feb 14 23:00 1:00 D +# Shanks gives 1921 Mar 21 for the following transition. +# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993): +# My sources says, that it is Mar 20, not 21. +Rule Russia 1921 only - Mar 20 23:00 2:00 DD +Rule Russia 1921 only - Sep 1 0:00 1:00 D +Rule Russia 1921 only - Oct 1 0:00 0 K +Rule Russia 1981 1984 - Apr 1 0:00 1:00 D +Rule Russia 1981 1983 - Oct 1 0:00 0 K +Rule Russia 1984 max - Sep lastSun 2:00s 0 K +Rule Russia 1985 max - Mar lastSun 2:00s 1:00 D + +# These are for backward compatibility with older versions. + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone WET 0:00 W-Eur WET%s +Zone MET 1:00 M-Eur MET%s +Zone EET 2:00 E-Eur EET%s +Zone W-SU 3:00 M-Eur ???? + +# Tom Hoffman says that MET is also known as Central European Time + +Link MET CET + +# Albania +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Albania 1940 only - Jun 16 0:00 1:00 " DST" +Rule Albania 1942 only - Nov 2 3:00 0 - +Rule Albania 1943 only - Mar 29 2:00 1:00 " DST" +Rule Albania 1943 only - Apr 10 3:00 0 - +Rule Albania 1974 only - May 4 0:00 1:00 " DST" +Rule Albania 1974 only - Oct 2 0:00 0 - +Rule Albania 1975 only - May 1 0:00 1:00 " DST" +Rule Albania 1975 only - Oct 2 0:00 0 - +Rule Albania 1976 only - May 2 0:00 1:00 " DST" +Rule Albania 1976 only - Oct 3 0:00 0 - +Rule Albania 1977 only - May 8 0:00 1:00 " DST" +Rule Albania 1977 only - Oct 2 0:00 0 - +Rule Albania 1978 only - May 6 0:00 1:00 " DST" +Rule Albania 1978 only - Oct 1 0:00 0 - +Rule Albania 1979 only - May 5 0:00 1:00 " DST" +Rule Albania 1979 only - Sep 30 0:00 0 - +Rule Albania 1980 only - May 3 0:00 1:00 " DST" +Rule Albania 1980 only - Oct 4 0:00 0 - +Rule Albania 1981 only - Apr 26 0:00 1:00 " DST" +Rule Albania 1981 only - Sep 27 0:00 0 - +Rule Albania 1982 only - May 2 0:00 1:00 " DST" +Rule Albania 1982 only - Oct 3 0:00 0 - +Rule Albania 1983 only - Apr 18 0:00 1:00 " DST" +Rule Albania 1983 only - Oct 1 0:00 0 - +Rule Albania 1984 only - Apr 1 0:00 1:00 " DST" +Rule Albania 1984 only - Oct 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Tirane 1:19:20 - LMT 1914 + 1:00 - MET 1940 Jun 16 + 1:00 Albania MET%s 1985 Mar 31 1:00 + 1:00 W-Eur MET%s +# This may change to `M-Eur' soon, for EC compatibility. + +# Andorra +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Andorra 0:06:04 - LMT 1901 + 0:00 - WET 1946 Sep 30 + 1:00 - MET 1985 Mar 31 2:00 + 1:00 M-Eur MET%s + +# Austria +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Austria 1918 only - Jun 16 3:00 0 - +Rule Austria 1920 only - Apr 5 2:00s 1:00 " DST" +Rule Austria 1920 only - Sep 13 2:00s 0 - +Rule Austria 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Austria 1945 only - Nov 18 2:00s 0 - +Rule Austria 1946 only - Apr 14 2:00s 1:00 " DST" +Rule Austria 1946 1948 - Oct Sun>=1 2:00s 0 - +Rule Austria 1947 only - Apr 6 2:00s 1:00 " DST" +Rule Austria 1948 only - Apr 18 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vienna 1:05:20 - LMT 1893 Apr + 1:00 M-Eur MET%s 1918 Jun 16 3:00 + 1:00 Austria MET%s 1940 Apr 1 2:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Austria MET%s 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Belarus +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Minsk 1:50:16 - LMT 1880 + 2:31 Russia LST%s 1919 Jul 1 2:00 + 3:00 Russia MS%s 1922 Oct + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): A guess at recent dates: + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 - EET 1992 Jan 19 2:00s + 3:00 Russia MS%s + +# Belgium +# Whitman and Shanks disagree; go with Shanks, usually. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +# From Whitman: +Rule Belgium 1919 only - Mar 1 23:00s 1:00 " DST" +Rule Belgium 1919 only - Oct 4 23:00s 0 - +# Shanks gives 1920 Feb 14 23:00s; go with Whitman. +Rule Belgium 1920 1921 - Mar 14 23:00s 1:00 " DST" +Rule Belgium 1920 only - Oct 23 23:00s 0 - +Rule Belgium 1921 only - Oct 25 23:00s 0 - +Rule Belgium 1922 only - Mar 25 23:00s 1:00 " DST" +# Whitman gives 1927 Oct 1 2:00s and 1928 Oct 7 2:00s; go with Shanks. +Rule Belgium 1922 1928 - Oct Sat>=1 23:00s 0 - +Rule Belgium 1923 only - Apr 21 23:00s 1:00 " DST" +Rule Belgium 1924 only - Mar 29 23:00s 1:00 " DST" +Rule Belgium 1925 only - Apr 4 23:00s 1:00 " DST" +Rule Belgium 1926 only - Apr 17 23:00s 1:00 " DST" +Rule Belgium 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Belgium 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Belgium 1929 only - Apr 21 2:00s 1:00 " DST" +Rule Belgium 1929 1938 - Oct Sun>=2 2:00s 0 - +Rule Belgium 1930 only - Apr 13 2:00s 1:00 " DST" +Rule Belgium 1931 only - Apr 19 2:00s 1:00 " DST" +Rule Belgium 1932 only - Apr 17 2:00s 1:00 " DST" +Rule Belgium 1933 only - Mar 26 2:00s 1:00 " DST" +Rule Belgium 1934 only - Apr 8 2:00s 1:00 " DST" +Rule Belgium 1935 only - Mar 31 2:00s 1:00 " DST" +Rule Belgium 1936 only - Apr 19 2:00s 1:00 " DST" +# Whitman says 1937 Apr 18 2:00s; go with Shanks. +Rule Belgium 1937 only - Apr 4 2:00s 1:00 " DST" +# Whitman says 1938 Apr 10 2:00s; go with Shanks. +Rule Belgium 1938 only - Mar 27 2:00s 1:00 " DST" +Rule Belgium 1939 only - Apr 16 2:00s 1:00 " DST" +Rule Belgium 1939 only - Nov 19 2:00s 0 - +Rule Belgium 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Belgium 1945 only - Sep 16 2:00s 0 - +Rule Belgium 1946 only - May 19 2:00s 1:00 " DST" +Rule Belgium 1946 only - Oct 7 2:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Brussels 0:17:20 - LMT 1880 + 0:17 - BST 1892 May 1 12:00 + 0:00 - WET 1914 Aug 4 + 1:00 M-Eur MET%s 1919 Mar 1 23:00 + 0:00 Belgium WET%s 1940 Feb 24 23:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Belgium MET%s 1977 Apr 3 2:00 + 1:00 M-Eur MET%s + +# Bosnia and Herzegovina +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Sarajevo 1:13:40 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Bulgaria +# Part switched from the Julian to the Gregorian calendar on 1915 Nov 14; +# the rest switched on 1920 Sep 17. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Bulg 1979 only - Mar 31 23:00 1:00 " DST" +Rule Bulg 1979 only - Oct 1 1:00 0 - +Rule Bulg 1980 1982 - Apr Sat<=7 23:00 1:00 " DST" +Rule Bulg 1980 only - Sep 29 1:00 0 - +Rule Bulg 1981 only - Sep 27 2:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Sofia 1:33:16 - LMT 1880 + 1:57 - TST 1894 Nov 30 + 2:00 - EET 1942 Nov 2 3:00 + 1:00 M-Eur MET%s 1945 Apr 2 3:00 + 2:00 - EET 1979 Mar 31 23:00 + 2:00 Bulg EET%s 1982 Sep 26 2:00 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Croatia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Zagreb 1:03:52 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Czech Republic +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Czech 1944 only - Sep 17 2:00s 0 - +Rule Czech 1945 only - Apr 8 2:00s 1:00 " DST" +Rule Czech 1945 only - Nov 18 2:00s 0 - +Rule Czech 1946 only - May 6 2:00s 1:00 " DST" +Rule Czech 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Czech 1947 only - Apr 20 2:00s 1:00 " DST" +Rule Czech 1948 only - Apr 18 2:00s 1:00 " DST" +Rule Czech 1949 only - Apr 9 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Prague 0:57:44 - LMT 1850 + 0:58 - PMT 1891 Oct # Prague Mean Time + 1:00 M-Eur MET%s 1944 Sep 17 2:00s + 1:00 Czech MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s + +# Denmark +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Denmark 1916 only - May 14 23:00 1:00 " DST" +Rule Denmark 1916 only - Sep 30 23:00 0 - +Rule Denmark 1940 only - May 15 0:00 1:00 " DST" +Rule Denmark 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Denmark 1945 only - Aug 15 2:00s 0 - +Rule Denmark 1946 only - May 1 2:00s 1:00 " DST" +Rule Denmark 1946 only - Sep 1 2:00s 0 - +Rule Denmark 1947 only - May 4 2:00s 1:00 " DST" +Rule Denmark 1947 only - Aug 10 2:00s 0 - +Rule Denmark 1948 only - May 9 2:00s 1:00 " DST" +Rule Denmark 1948 only - Aug 8 2:00s 0 - +# Whitman also gives 1949 Apr 9 to 1949 Oct 1, and disagrees in minor ways +# about many of the above dates; go with Shanks. +# +# For 1894, Shanks says Jan, Whitman Apr; go with Whitman. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Copenhagen 0:50:20 - LMT 1890 + 0:50 - CMT 1894 Apr # Copenhagen Mean Time + 1:00 Denmark MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Denmark MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +Zone Atlantic/Faeroe -0:27:04 - LMT 1908 Jan 11 # Torshavn + 0:00 - WET 1981 Mar 29 1:00 + 0:00 W-Eur WET%s +Zone America/Scoresbysund -1:29:00 - LMT 1916 Jul 28 + -2:00 - MGT 1980 Apr 6 2:00 + -2:00 M-Eur MGT%s 1981 Mar 29 + -1:00 M-Eur EGT%s +Zone America/Godthab -3:26:56 - LMT 1916 Jul 28 + -3:00 - WGT 1980 Apr 6 2:00 + -3:00 M-Eur WGT%s +Zone America/Thule -4:35:08 - LMT 1916 Jul 28 + -4:00 - AST + +# Estonia +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# +# From Peter Ilieve <peter@memex.co.uk> (1994-10-15): +# A relative in Tallinn confirms the accuracy of the data for 1989 onwards +# [through 1994] and gives the legal authority for it, +# a regulation of the Government of Estonia, No. 111 of 1989.... +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Tallinn 1:39:00 - LMT 1880 + 1:39 - LST 1918 Feb + 1:00 M-Eur MET%s 1919 Jul + 1:39 - LST 1921 May + 2:00 - EET 1940 Aug 6 + 3:00 - MSK 1941 Sep 15 + 1:00 M-Eur MET%s 1944 Sep 22 + 3:00 Russia MS%s 1989 Mar 26 2:00s + 2:00 1:00 "EET DST" 1989 Sep 24 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Finland +# +# From Hannu Strang <chs@apu.fi> (25 Sep 1994 06:03:37 UTC): +# Well, here in Helsinki we're just changing from summer time to regular one, +# and it's supposed to change at 4am... +# +# From Paul Eggert <eggert@twinsun.com> (25 Sep 1994): +# Shanks says Finland has switched at 02:00 standard time since 1981. +# Go with Strang instead. +# +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Finland 1921 only - May 1 0:00 0 - +Rule Finland 1942 only - Apr 3 0:00 1:00 " DST" +Rule Finland 1942 only - Oct 3 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Helsinki 1:39:52 - LMT 1878 May 31 + 1:40 - HMT 1921 May # Helsinki Mean Time + 2:00 Finland EET%s 1981 Mar 29 2:00 + 2:00 E-Eur EET%s + +# France +# Shanks seems to use `24:00' ambiguously; we resolve it with Whitman. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule France 1911 only - Jan 1 0:00 0 - +Rule France 1916 only - Jun 14 23:00s 1:00 " DST" +Rule France 1916 1919 - Oct Sun>=1 0:00 0 - +Rule France 1917 only - Mar 24 23:00s 1:00 " DST" +Rule France 1918 only - Mar 9 23:00s 1:00 " DST" +Rule France 1919 only - Mar 1 23:00s 1:00 " DST" +Rule France 1920 only - Feb 14 23:00s 1:00 " DST" +Rule France 1920 only - Oct 23 23:00s 0 - +Rule France 1921 only - Mar 14 23:00s 1:00 " DST" +Rule France 1921 only - Oct 25 23:00s 0 - +Rule France 1922 only - Mar 25 23:00s 1:00 " DST" +Rule France 1922 1938 - Oct Sat>=1 23:00s 0 - +Rule France 1923 only - May 26 23:00s 1:00 " DST" +Rule France 1924 only - Mar 29 23:00s 1:00 " DST" +Rule France 1925 only - Apr 4 23:00s 1:00 " DST" +Rule France 1926 only - Apr 17 23:00s 1:00 " DST" +Rule France 1927 only - Apr 9 23:00s 1:00 " DST" +Rule France 1928 only - Apr 14 23:00s 1:00 " DST" +Rule France 1929 only - Apr 20 23:00s 1:00 " DST" +Rule France 1930 only - Apr 12 23:00s 1:00 " DST" +Rule France 1931 only - Apr 18 23:00s 1:00 " DST" +Rule France 1932 only - Apr 2 23:00s 1:00 " DST" +Rule France 1933 only - Mar 25 23:00s 1:00 " DST" +Rule France 1934 only - Apr 7 23:00s 1:00 " DST" +Rule France 1935 only - Mar 30 23:00s 1:00 " DST" +Rule France 1936 only - Apr 18 23:00s 1:00 " DST" +Rule France 1937 only - Apr 3 23:00s 1:00 " DST" +Rule France 1938 only - Mar 26 23:00s 1:00 " DST" +Rule France 1939 only - Apr 15 23:00s 1:00 " DST" +Rule France 1939 only - Nov 18 23:00s 0 - +Rule France 1940 only - Feb 25 2:00 1:00 " DST" +# The French rules for 1941-1944 were not used in Paris, +# but were used in other places (e.g. Monaco). +Rule France 1941 only - May 5 0:00 2:00 " DDST" +Rule France 1941 only - Oct 6 1:00 1:00 " DST" +Rule France 1942 only - Mar 8 0:00 2:00 " DDST" +Rule France 1942 only - Nov 2 3:00 1:00 " DST" +Rule France 1943 only - Mar 29 2:00 2:00 " DDST" +Rule France 1943 only - Nov 4 3:00 1:00 " DST" +Rule France 1944 only - Apr 3 2:00 2:00 " DDST" +Rule France 1944 only - Oct 8 1:00 1:00 " DST" +Rule France 1945 only - Apr 2 2:00 2:00 " DDST" +Rule France 1945 only - Sep 16 3:00 0 - +# From Paul Eggert <eggert@twinsun.com) (November 18, 1993): +# Shanks gives no times for 1975, but according to Cm722, +# France introduced summer time in 1975 from 20 March to 22 September. +Rule France 1975 only - Mar 20 2:00s 1:00 " DST" +Rule France 1975 only - Sep 22 2:00s 0 - +Rule France 1976 only - Mar 28 2:00s 1:00 " DST" +Rule France 1976 only - Sep lastSun 2:00s 0 - +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Paris 0:09:05 - LMT 1891 Mar 15 0:01 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 France WET%s 1940 Jun 14 + 1:00 M-Eur MET%s 1944 Aug 25 + 0:00 France WET%s 1945 Sep 16 3:00 + 1:00 France MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Germany +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Germany 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Germany 1945 only - May 24 2:00 2:00 " DDST" +Rule Germany 1945 only - Sep 24 3:00 1:00 " DST" +Rule Germany 1945 only - Nov 18 2:00s 0 - +Rule Germany 1946 only - Apr 14 2:00s 1:00 " DST" +# Whitman gives 1948 Oct 31; go with Shanks. +Rule Germany 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Germany 1947 only - Apr 6 2:00s 1:00 " DST" +Rule Germany 1947 only - May 11 2:00s 2:00 " DDST" +Rule Germany 1947 only - Jun 29 3:00 1:00 " DST" +Rule Germany 1948 only - Apr 18 2:00s 1:00 " DST" +Rule Germany 1949 only - Apr 10 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Berlin 0:53:28 - LMT 1893 Apr + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Germany MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s + +# Gibraltar +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2 + 0:00 GB-Eire %s 1957 Apr 14 2:00 + 1:00 - MET 1982 Mar 28 2:00 + 1:00 M-Eur MET%s + +# Greece +# They adopted the Julian calendar in 1846. +# Part switched to the Gregorian calendar on 1916 Jul 28. +# The rest switched on 1920 Mar 18. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Greece 1916 only - July 28 0:01 0 - +# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks. +Rule Greece 1932 only - Jul 7 0:00 1:00 " DST" +Rule Greece 1932 only - Sep 1 0:00 0 - +# Whitman gives 1941 Apr 25 - ?; go with Shanks. +Rule Greece 1941 only - Apr 7 0:00 1:00 " DST" +# Whitman gives 1942 Feb 2 - ?; go with Shanks. +Rule Greece 1942 only - Nov 2 3:00 0 - +Rule Greece 1943 only - Mar 30 0:00 1:00 " DST" +Rule Greece 1943 only - Oct 4 0:00 0 - +# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks. +Rule Greece 1952 only - Jul 1 0:00 1:00 " DST" +Rule Greece 1952 only - Nov 2 0:00 0 - +Rule Greece 1975 only - Apr 12 0:00s 1:00 " DST" +Rule Greece 1975 only - Nov 26 0:00s 0 - +Rule Greece 1976 only - Apr 11 2:00s 1:00 " DST" +Rule Greece 1976 only - Oct 10 2:00s 0 - +Rule Greece 1977 1978 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Greece 1977 only - Sep 26 2:00s 0 - +Rule Greece 1978 only - Sep 24 4:00 0 - +Rule Greece 1979 only - Apr 1 9:00 1:00 " DST" +Rule Greece 1979 only - Sep 29 2:00 0 - +Rule Greece 1980 only - Apr 1 0:00 1:00 " DST" +Rule Greece 1980 only - Sep 28 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Athens 1:34:52 - LMT 1895 Sep 14 + 1:35 - AMT 1916 Jul 28 0:01 # Athens MT + 2:00 Greece EET%s 1941 Apr 30 + 1:00 Greece MET%s 1944 Apr 4 + 2:00 Greece EET%s 1981 Mar 29 2:00 +# Greece must change by 1996 for EC compatibility. + 2:00 M-Eur EET%s 1996 # Guess the last minute. + 2:00 E-Eur EET%s + +# Hungary +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Hungary 1918 only - Sep 29 2:00s 0 - +Rule Hungary 1919 only - Apr 15 3:00 1:00 " DST" +Rule Hungary 1919 only - Sep 15 3:00 0 - +Rule Hungary 1920 only - Apr 5 3:00 1:00 " DST" +Rule Hungary 1920 only - Sep 30 3:00 0 - +Rule Hungary 1945 only - May 1 23:00 1:00 " DST" +Rule Hungary 1945 only - Nov 3 0:00 0 - +Rule Hungary 1946 only - Mar 31 2:00s 1:00 " DST" +Rule Hungary 1946 1949 - Oct Sun>=1 2:00s 0 - +Rule Hungary 1947 1949 - Apr Sun>=4 2:00s 1:00 " DST" +Rule Hungary 1950 only - Apr 17 2:00s 1:00 " DST" +Rule Hungary 1950 only - Oct 23 2:00s 0 - +Rule Hungary 1954 1955 - May 23 0:00 1:00 " DST" +Rule Hungary 1954 1955 - Oct 3 0:00 0 - +Rule Hungary 1956 only - Jun Sun>=1 0:00 1:00 " DST" +Rule Hungary 1956 only - Sep lastSun 0:00 0 - +Rule Hungary 1957 only - Jun Sun>=1 1:00 1:00 " DST" +Rule Hungary 1957 only - Sep lastSun 3:00 0 - +Rule Hungary 1980 only - Apr 6 1:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Budapest 1:16:20 - LMT 1890 Oct + 1:00 M-Eur MET%s 1918 Jul + 1:00 Hungary MET%s 1941 Apr 6 2:00 + 1:00 M-Eur MET%s 1945 May 1 23:00 + 1:00 Hungary MET%s 1980 Sep 28 2:00s + 1:00 M-Eur MET%s + +# Iceland +# +# From Adam David <adam@veda.is> (November 6, 1993): +# The name of the timezone in Iceland for system / mail / news purposes is GMT. +# +# (December 5, 1993): +# This material is paraphrased from the 1988 edition of the University of +# Iceland Almanak. +# +# From January 1st, 1908 the whole of Iceland was standardised at 1 hour +# behind GMT. Previously, local mean solar time was used in different parts +# of Iceland, the almanak had been based on Reykjavik mean solar time which +# was 1 hour and 28 minutes behind GMT. +# +# "first day of winter" referred to [below] means the first day of the 26 weeks +# of winter, according to the old icelandic calendar that dates back to the +# time the norsemen first settled Iceland. The first day of winter is always +# Saturday, but is not dependent on the Julian or Gregorian calendars. +# +# (December 10, 1993): +# I have a reference from the Oxford Icelandic-English dictionary for the +# beginning of winter, which ties it to the ecclesiastical calendar (and thus +# to the julian/gregorian calendar) over the period in question. +# the winter begins on the Saturday next before St. Luke's day +# (old style), or on St. Luke's day, if a Saturday. +# St. Luke's day ought to be traceable from ecclesiastical sources. "old style" +# might be a reference to the Julian calendar as opposed to Gregorian, or it +# might mean something else (???). The Gregorian calendar was not introduced +# in Iceland until 1700. +# +# From Paul Eggert <eggert@twinsun.com> (December 9, 1993): +# The Iceland Almanak, Shanks and Whitman disagree on many points. +# We go with the Almanak, except for one claim from Shanks, namely that +# Reykavik was -1:28 from 1837 to 1908, local mean time before that. +# +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Iceland 1908 only - Jan 1 0:00 0 S +Rule Iceland 1917 1918 - Feb 19 23:00 1:00 D +Rule Iceland 1917 only - Oct 21 1:00 0 S +Rule Iceland 1918 only - Nov 16 1:00 0 S +Rule Iceland 1939 only - Apr 29 23:00 1:00 D +Rule Iceland 1939 only - Nov 29 2:00 0 S +Rule Iceland 1940 only - Feb 25 2:00 1:00 D +Rule Iceland 1940 only - Nov 3 2:00 0 S +Rule Iceland 1941 only - Mar 2 1:00s 1:00 D +Rule Iceland 1941 only - Nov 2 1:00s 0 S +Rule Iceland 1942 only - Mar 8 1:00s 1:00 D +Rule Iceland 1942 only - Oct 25 1:00s 0 S +# 1943-1946 - first Sunday in March until first Sunday in winter +Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 D +Rule Iceland 1943 1948 - Oct Sun>=22 1:00s 0 S +# 1947-1967 - first Sunday in April until first Sunday in winter +Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 D +# 1949 Oct transition delayed by 1 week +Rule Iceland 1949 only - Oct 30 1:00s 0 S +Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 S +Rule Iceland 1967 only - Oct 29 1:00s 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Reykjavik -1:27:24 - LMT 1837 + -1:28 - RMT 1908 # Reykjavik Mean Time + -1:00 Iceland I%sT 1968 Apr 7 1:00s + 0:00 - GMT + +# Italy +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Italy 1893 only - Nov 1 0:00s 0 S +# Shanks gives transition times of 1916-1920 as 24:00; go with Whitman. +Rule Italy 1916 only - Jun 3 0:00s 1:00 " DST" +Rule Italy 1916 only - Sep 30 0:00s 0 - +Rule Italy 1917 only - Mar 31 0:00s 1:00 " DST" +Rule Italy 1917 only - Sep 30 0:00s 0 - +Rule Italy 1918 only - Mar 9 0:00s 1:00 " DST" +Rule Italy 1918 1919 - Oct Sun>=1 0:00s 0 - +Rule Italy 1919 only - Mar 1 0:00s 1:00 " DST" +Rule Italy 1920 only - Mar 20 0:00s 1:00 " DST" +# Shanks gives 1920 Sep 18; go with Whitman. +Rule Italy 1920 only - Oct 1 0:00s 0 - +Rule Italy 1940 only - Jun 15 0:00 1:00 " DST" +Rule Italy 1945 only - Apr 2 2:00 1:00 " DST" +Rule Italy 1945 only - Sep 17 0:00 0 - +Rule Italy 1946 only - Mar 17 2:00s 1:00 " DST" +Rule Italy 1946 only - Oct 6 2:00s 0 - +Rule Italy 1947 only - Mar 16 0:00s 1:00 " DST" +Rule Italy 1947 only - Oct 5 0:00s 0 - +Rule Italy 1948 only - Feb 29 2:00s 1:00 " DST" +Rule Italy 1948 only - Oct 3 2:00s 0 - +Rule Italy 1966 1968 - May Sun>=22 0:00 1:00 " DST" +Rule Italy 1966 1969 - Sep Sun>=22 0:00 0 - +Rule Italy 1969 only - Jun 1 0:00 1:00 " DST" +Rule Italy 1970 only - May 31 0:00 1:00 " DST" +Rule Italy 1970 only - Sep lastSun 0:00 0 - +Rule Italy 1971 1972 - May Sun>=22 0:00 1:00 " DST" +Rule Italy 1971 only - Sep lastSun 1:00 0 - +Rule Italy 1972 only - Oct 1 0:00 0 - +Rule Italy 1973 only - Jun 3 0:00 1:00 " DST" +Rule Italy 1973 1974 - Sep lastSun 0:00 0 - +Rule Italy 1974 only - May 26 0:00 1:00 " DST" +Rule Italy 1975 only - Jun 1 0:00s 1:00 " DST" +Rule Italy 1975 1977 - Sep lastSun 0:00s 0 - +Rule Italy 1976 only - May 30 0:00s 1:00 " DST" +Rule Italy 1977 1979 - May Sun>=22 0:00s 1:00 " DST" +Rule Italy 1978 only - Oct 1 0:00s 0 - +Rule Italy 1979 only - Sep 30 0:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Rome 0:49:56 - LMT 1866 Sep 22 + 0:50 - RMT 1893 Nov # Rome Mean Time + 1:00 Italy MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00s + 1:00 Italy MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +# Vatican is identical to Europe/Rome; San Marino is like Europe/Rome. + +# Latvia +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Riga 1:36:24 - LMT 1880 + 1:36 - LST 1918 Apr 15 2:00 + 1:36 M-Eur LST%s 1919 Apr 1 2:00 + 1:36 1:00 "LST DST" 1919 May 22 3:00 + 1:36 - LST 1926 May 11 + 2:00 - EET 1940 Aug 5 + 3:00 - MSK 1941 Jul + 1:00 M-Eur MET%s 1944 Aug 8 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Liechtenstein +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun + 1:00 - MET 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Lithuania +# They switched from the Julian to the Gregorian calendar on 1918 Feb 15. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Vilnius 1:41:16 - LMT 1880 + 1:24 - LST 1917 # Kaunas + 1:36 - LST 1919 Oct 10 + 1:00 - MET 1920 Jul 12 + 2:00 - EET 1920 Oct 9 + 1:00 - MET 1940 Aug 3 + 3:00 - MSK 1941 Jun 24 + 1:00 M-Eur MET%s 1944 Aug + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Luxembourg +# Whitman disagrees with most of these dates in minor ways; go with Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Lux 1904 only - Jun 1 0:00 0 - +Rule Lux 1916 only - May 14 23:00 1:00 " DST" +Rule Lux 1916 only - Oct 1 1:00 0 - +Rule Lux 1917 only - Apr 28 23:00 1:00 " DST" +Rule Lux 1917 only - Sep 17 1:00 0 - +Rule Lux 1918 only - Apr Mon>=15 2:00s 1:00 " DST" +Rule Lux 1918 only - Sep Mon>=15 2:00s 0 - +Rule Lux 1919 only - Mar 1 23:00 1:00 " DST" +Rule Lux 1919 only - Oct 5 3:00 0 - +Rule Lux 1920 only - Feb 14 23:00 1:00 " DST" +Rule Lux 1920 only - Oct 24 2:00 0 - +Rule Lux 1921 only - Mar 14 23:00 1:00 " DST" +Rule Lux 1921 only - Oct 26 2:00 0 - +Rule Lux 1922 only - Mar 25 23:00 1:00 " DST" +Rule Lux 1922 only - Oct Sun>=2 1:00 0 - +Rule Lux 1923 only - Apr 21 23:00 1:00 " DST" +Rule Lux 1923 only - Oct Sun>=2 2:00 0 - +Rule Lux 1924 only - Mar 29 23:00 1:00 " DST" +Rule Lux 1924 1928 - Oct Sun>=2 1:00 0 - +Rule Lux 1925 only - Apr 5 23:00 1:00 " DST" +Rule Lux 1926 only - Apr 17 23:00 1:00 " DST" +Rule Lux 1927 only - Apr 9 23:00 1:00 " DST" +Rule Lux 1928 only - Apr 14 23:00 1:00 " DST" +Rule Lux 1929 only - Apr 20 23:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Luxembourg 0:24:36 - LMT 1904 Jun + 1:00 Lux MET%s 1918 Nov 25 + 0:00 Lux WET%s 1929 Oct 6 2:00s + 0:00 Belgium WET%s 1940 May 14 3:00 + 1:00 M-Eur WET%s 1944 Sep 18 3:00 + 1:00 Belgium MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s + +# Macedonia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Skopje 1:25:44 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Malta +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Malta 1973 only - Mar 31 0:00s 1:00 " DST" +Rule Malta 1973 only - Sep 29 0:00s 0 - +Rule Malta 1974 only - Apr 21 0:00s 1:00 " DST" +Rule Malta 1974 only - Sep 16 0:00s 0 - +Rule Malta 1975 1979 - Apr Sun>=15 2:00 1:00 " DST" +Rule Malta 1975 1980 - Sep Sun>=15 2:00 0 - +Rule Malta 1980 only - Mar 31 2:00 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 # Valletta + 1:00 Italy MET%s 1942 Nov 2 2:00s + 1:00 M-Eur MET%s 1945 Apr 2 2:00s + 1:00 Italy MET%s 1973 Mar 31 + 1:00 Malta MET%s 1981 Mar 29 2:00s + 1:00 M-Eur MET%s + +# Moldova +# They switched from the Julian to the Gregorian calendar on 1919 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Chisinau 1:55:20 - LMT 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Monaco +# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 + 0:09:05 - PMT 1911 Mar 11 # Paris Mean Time + 0:00 France WET%s 1945 Sep 16 3:00 + 1:00 France MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Netherlands +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Neth 1892 only - May 1 0:00 0 AMT +# Shanks gives 1916 May 1 0:00 and 1916 Oct 1 0:00; go with Whitman. +Rule Neth 1916 only - May 1 2:00s 1:00 NST +Rule Neth 1916 only - Oct 2 2:00s 0 AMT +Rule Neth 1917 only - Apr 16 2:00s 1:00 NST +Rule Neth 1917 only - Sep 17 2:00s 0 AMT +# Whitman gives 1918 Apr 14, 1918 Oct 31, and 1921 Sep 28; go with Shanks. +Rule Neth 1918 1921 - Apr Mon>=1 2:00s 1:00 NST +Rule Neth 1918 1921 - Sep Mon>=24 2:00s 0 AMT +Rule Neth 1922 only - Mar 26 2:00s 1:00 NST +# Whitman gives 1939 Oct 1; go with Shanks. +Rule Neth 1922 1939 - Oct Sun>=2 2:00s 0 AMT +Rule Neth 1923 only - Jun 1 2:00s 1:00 NST +Rule Neth 1924 only - Mar 30 2:00s 1:00 NST +# Whitman gives 1925 Apr 5; go with Shanks. +Rule Neth 1925 only - Jun 5 2:00s 1:00 NST +# For 1926 through 1930 Whitman gives Apr 15; go with Shanks. +Rule Neth 1926 1931 - May 15 2:00s 1:00 NST +Rule Neth 1932 only - May 22 2:00s 1:00 NST +Rule Neth 1933 1936 - May 15 2:00s 1:00 NST +Rule Neth 1937 only - May 22 2:00s 1:00 NST +# Whitman gives 1939 Apr 15 and 1940 Apr 19; go with Shanks. +Rule Neth 1938 1939 - May 15 2:00s 1:00 NST +Rule Neth 1945 only - Apr 2 2:00s 1:00 - +Rule Neth 1945 only - May 20 2:00s 0 " DST" +# Before 1937, Shanks says just `0:20'; we use Whitman's more precise figure. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Amsterdam 0:19:28 - LMT 1892 May + 0:19:28 Neth %s 1937 Jul + 0:20 Neth %s 1940 May 16 0:40 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Neth MET%s 1977 Apr Sun>=1 2:00 + 1:00 M-Eur MET%s + +# Norway +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Norway 1892 only - May 1 0:00 0 - +# Whitman gives 1916 May 21 - 1916 Oct 21; go with Shanks. +Rule Norway 1916 only - May 22 1:00 1:00 " DST" +Rule Norway 1916 only - Sep 30 0:00 0 - +# Shanks omits the following transition; go with Whitman. +Rule Norway 1935 only - Aug 11 0:00 1:00 " DST" +# Whitman says DST observed until 1942 Nov 1, then 1943 Mar 29 - Oct 4, +# 1944 Apr 3 - Oct 2, and 1945 Apr 1 - Oct 1; go with Shanks after 1940. +Rule Norway 1945 only - Apr 2 2:00s 1:00 " DST" +Rule Norway 1945 only - Oct 1 2:00s 0 - +Rule Norway 1959 1964 - Mar Sun>=15 2:00s 1:00 " DST" +Rule Norway 1959 1965 - Sep Sun>=15 2:00s 0 - +Rule Norway 1965 only - Apr 25 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Oslo 0:43:00 - LMT 1895 + 1:00 Norway MET%s 1940 Aug 10 23:00 + 1:00 M-Eur MET%s 1945 Apr 2 2:00 + 1:00 Norway MET%s 1980 Apr 6 2:00 + 1:00 M-Eur MET%s +# Svalbard is like Europe/Oslo. +# +# From Whitman: +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Jan_Mayen -1:00 - EGT + +# Poland +# Austrian and German Poland switched from the Julian to the Gregorian calendar +# on 1582 Oct 15. Russian Poland switched on 1918 Jan 14. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Poland 1918 1919 - Sep 16 2:00s 0 - +Rule Poland 1919 only - Apr 15 2:00s 1:00 " DST" +# Whitman gives 1944 Nov 30; go with Shanks. +Rule Poland 1944 only - Oct 4 2:00 0 - +# For 1944-1948 Whitman gives the previous day; go with Shanks. +Rule Poland 1945 only - Apr 29 0:00 1:00 " DST" +Rule Poland 1945 only - Nov 1 0:00 0 - +Rule Poland 1946 only - Apr 14 0:00 1:00 " DST" +Rule Poland 1946 only - Sep 7 0:00 0 - +Rule Poland 1947 only - May 4 0:00 1:00 " DST" +Rule Poland 1947 1948 - Oct Sun>=1 0:00 0 - +Rule Poland 1948 only - Apr 18 0:00 1:00 " DST" +# Whitman also gives 1949 Apr 9 - 1949 Oct 1; go with Shanks. +Rule Poland 1957 only - Jun 2 1:00s 1:00 " DST" +Rule Poland 1957 1958 - Sep lastSun 1:00s 0 - +Rule Poland 1958 only - Mar 30 1:00s 1:00 " DST" +Rule Poland 1959 only - May 31 1:00s 1:00 " DST" +Rule Poland 1959 1961 - Oct Sun>=1 1:00s 0 - +Rule Poland 1960 only - Apr 3 1:00s 1:00 " DST" +Rule Poland 1961 1964 - May Sun>=25 1:00s 1:00 " DST" +Rule Poland 1962 1964 - Sep lastSun 1:00s 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Warsaw 1:24:00 - LMT 1880 + 1:24 - WMT 1915 Aug 5 # Warsaw Mean Time + 1:00 M-Eur MET%s 1918 Sep 16 3:00 + 2:00 Poland EET%s 1922 Jun + 1:00 Poland MET%s 1940 Jun 23 2:00 + 1:00 M-Eur MET%s 1944 Oct + 1:00 Poland MET%s 1977 Apr 3 1:00 + 1:00 W-Eur MET%s +# This may change to `M-Eur' soon, for EC compatibility. + +# Portugal +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Port 1911 only - May 24 0:00 0 - +Rule Port 1916 only - Jun 17 23:00 1:00 " DST" +# Whitman gives 1916 Oct 31; go with Shanks. +Rule Port 1916 only - Nov 1 1:00 0 - +Rule Port 1917 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1917 1921 - Oct 14 23:00s 0 - +Rule Port 1918 only - Mar 1 23:00s 1:00 " DST" +Rule Port 1919 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1920 only - Feb 29 23:00s 1:00 " DST" +Rule Port 1921 only - Feb 28 23:00s 1:00 " DST" +Rule Port 1924 only - Apr 16 23:00s 1:00 " DST" +Rule Port 1924 only - Oct 14 23:00s 0 - +Rule Port 1926 only - Apr 17 23:00s 1:00 " DST" +Rule Port 1926 1929 - Oct Sat>=1 23:00s 0 - +Rule Port 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Port 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Port 1929 only - Apr 20 23:00s 1:00 " DST" +Rule Port 1931 only - Apr 18 23:00s 1:00 " DST" +# Whitman gives 1931 Oct 8; go with Shanks. +Rule Port 1931 1932 - Oct Sat>=1 23:00s 0 - +Rule Port 1932 only - Apr 2 23:00s 1:00 " DST" +# Shanks gives 1934 Apr 4; go with Whitman. +Rule Port 1934 only - Apr 7 23:00s 1:00 " DST" +# Whitman gives 1934 Oct 5; go with Shanks. +Rule Port 1934 1938 - Oct Sat>=1 23:00s 0 - +# Shanks gives 1935 Apr 30; go with Whitman. +Rule Port 1935 only - Mar 30 23:00s 1:00 " DST" +Rule Port 1936 only - Apr 18 23:00s 1:00 " DST" +# Whitman gives 1937 Apr 2; go with Shanks. +Rule Port 1937 only - Apr 3 23:00s 1:00 " DST" +Rule Port 1938 only - Mar 26 23:00s 1:00 " DST" +Rule Port 1939 only - Apr 15 23:00s 1:00 " DST" +# Whitman gives 1939 Oct 7; go with Shanks. +Rule Port 1939 only - Nov 18 23:00s 0 - +Rule Port 1940 only - Feb 24 23:00s 1:00 " DST" +# Shanks gives 1940 Oct 7; go with Whitman. +Rule Port 1940 1941 - Oct 5 23:00s 0 - +Rule Port 1941 only - Apr 5 23:00s 1:00 " DST" +Rule Port 1942 1945 - Mar Sat>=8 23:00s 1:00 " DST" +Rule Port 1942 only - Apr 25 22:00s 2:00 " DDST" +Rule Port 1942 only - Aug 15 22:00s 1:00 " DST" +Rule Port 1942 1945 - Oct Sat>=24 23:00s 0 - +Rule Port 1943 only - Apr 17 22:00s 2:00 " DDST" +Rule Port 1943 1945 - Aug Sat>=25 22:00s 1:00 " DST" +Rule Port 1944 1945 - Apr Sat>=21 22:00s 2:00 " DDST" +Rule Port 1946 only - Apr Sat>=1 23:00s 1:00 " DST" +Rule Port 1946 only - Oct Sat>=1 23:00s 0 - +Rule Port 1947 1949 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Port 1947 1949 - Oct Sun>=1 2:00s 0 - +# Shanks says DST was observed in 1950; go with Whitman. +# Whitman gives Oct lastSun for 1952 on; go with Shanks. +Rule Port 1951 1965 - Apr Sun>=1 2:00s 1:00 " DST" +Rule Port 1951 1965 - Oct Sun>=1 2:00s 0 - +Rule Port 1977 only - Mar 27 0:00s 1:00 " DST" +Rule Port 1977 only - Sep 25 0:00s 0 - +Rule Port 1978 1979 - Apr Sun>=1 0:00s 1:00 " DST" +Rule Port 1978 only - Oct 1 0:00s 0 - +Rule Port 1979 1982 - Sep lastSun 1:00s 0 - +Rule Port 1980 only - Mar lastSun 0:00s 1:00 " DST" +Rule Port 1981 1982 - Mar lastSun 1:00s 1:00 " DST" +Rule Port 1983 only - Mar lastSun 2:00s 1:00 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Lisbon -0:36:32 - LMT 1884 + -0:37 - LMT 1911 May 24 # Lisbon Mean Time + 0:00 Port WET%s 1966 Apr 3 2:00 + 1:00 - MET 1976 Sep 26 1:00 + 0:00 Port WET%s 1983 Sep 25 1:00s + 0:00 W-Eur WET%s 1992 Sep 27 1:00s +# From Rui Pedro Salgueiro <rps@inescca.inescc.pt> (November 12, 1992): +# Portugal has recently (September, 27) changed timezone +# (from WET to MET or CET) to harmonize with EEC. + 1:00 M-Eur MET%s +# We don't know what happened to Madeira or the Azores, +# so we'll just use Shanks for now. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Azores -1:42:40 - LMT 1884 # Ponta Delgada + -1:55 - HMT 1911 May 24 # Horta Mean Time + -2:00 Port ACT%s 1966 Apr 3 2:00 + -1:00 - ACT 1977 Mar 27 + -1:00 - ACT 1983 Sep 25 1:00s + -1:00 W-Eur ACT%s +Zone Atlantic/Madeira -1:07:36 - LMT 1884 # Funchal + -1:08 - FMT 1911 May 24 # Funchal Mean Time + -1:00 Port ACT%s 1966 Apr 3 2:00 + 0:00 - WET 1977 Mar 27 + 0:00 Port WET%s 1983 Sep 25 1:00s + 0:00 W-Eur WET%s + +# Slovakia +Link Europe/Prague Europe/Bratislava + +# Romania +# Catholic Romania switched from the Julian to the Gregorian calendar on +# on 1919 Mar 18. Greek Orthodox Romania switched on 1920 Mar 18. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Romania 1931 only - Jul 24 0:00 0 - +Rule Romania 1932 only - May 21 0:00s 1:00 " DST" +Rule Romania 1932 1939 - Oct Sun>=1 0:00s 0 - +Rule Romania 1933 1939 - Apr Sun>=2 0:00s 1:00 " DST" +Rule Romania 1979 only - May 27 0:00 1:00 " DST" +Rule Romania 1979 only - Sep lastSun 0:00 0 - +Rule Romania 1980 only - Apr 5 23:00 1:00 " DST" +Rule Romania 1980 only - Sep lastSun 1:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct + 1:44 - BMT 1931 Jul 24 # Bucharest MT + 2:00 Romania EET%s 1981 Mar 29 2:00s + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. + +# Russia +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# Moscow and Novosibirsk time zone names, and Moscow rules after 1991, +# are from Andrew A. Chernov <ache@astral.msk.su>. +# I invented the other time zone names, and (unless otherwise specified) +# guessed what happened after 1991; the clocks were chaotic, and we know little. +# The rest is from Shanks. +# +# From Shanks (1991): +# Western Russia switched from the Julian to the Gregorian calendar +# on 1918 Jan 14. Eastern Russia switched on 1920 Mar 18. +# In 1929 the Soviet Union instituted a 5 day week; in 1932 it instituted +# a 6 day week; on 1940 Jun 27 it returned to the Gregorian week. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Moscow 2:30:20 - LMT 1880 + 2:31 Russia LST%s 1919 Jul 1 2:00 + 3:00 Russia MS%s 1922 Oct + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s + 2:00 - EET 1992 Jan 19 2:00s + 3:00 Russia MS%s +Zone Europe/Kuybyshev 3:20:36 - LMT 1924 May 2 + 3:00 - KSK 1957 Mar + 4:00 Russia KS%s 1991 Mar 31 2:00s + 3:00 1:00 KSD 1991 Sep 29 2:00s + 3:00 - KSK 1992 Jan 19 2:00s + 4:00 Russia KS%s +Zone Asia/Yekaterinburg 4:02:34 - LMT 1924 May 2 + 4:00 - SSK 1957 Mar + 5:00 Russia SS%s 1991 Mar 31 2:00s + 4:00 1:00 SSD 1991 Sep 29 2:00s + 4:00 - SSK 1992 Jan 19 2:00s + 5:00 Russia ES%s # name change from Sverdlovsk +Zone Asia/Omsk 4:53:36 - LMT 1924 May 2 + 5:00 - OSK 1957 Mar + 6:00 Russia OS%s 1991 Mar 31 2:00s + 5:00 1:00 OSD 1991 Sep 29 2:00s + 5:00 - OSK 1992 Jan 19 2:00s + 6:00 Russia OS%s +# From Stanislaw A. Kuzikowski <S.A.Kuz@iae.nsk.su> (June 29, 1994): +# But now it is some months since Novosibirsk is 3 hours ahead of Moscow! +# I do not know why they have decided to make this change; +# as far as I remember it was done exactly during winter->summer switching +# so we (Novosibirsk) simply did not switch. +# Tomsk is still 4 hours ahead of Moscow. +Zone Asia/Novosibirsk 5:31:40 - LMT 1924 May 2 + 6:00 - NSK 1957 Mar + 7:00 Russia NS%s 1991 Mar 31 2:00s + 6:00 1:00 NSD 1991 Sep 29 2:00s + 6:00 - NSK 1992 Jan 19 2:00s + 7:00 Russia NS%s 1994 Mar 27 2:00s + 6:00 1:00 NSD 1994 Sep 25 2:00s + 6:00 Russia NS%s +Zone Asia/Tomsk 5:39:52 - LMT 1924 May 2 + 6:00 - TSK 1957 Mar + 7:00 Russia TS%s 1991 Mar 31 2:00s + 6:00 1:00 TSD 1991 Sep 29 2:00s + 6:00 - TSK 1992 Jan 19 2:00s + 7:00 Russia TS%s +Zone Asia/Irkutsk 6:57:20 - LMT 1880 + 6:57 - LST 1924 May 2 + 7:00 - ISK 1957 Mar + 8:00 Russia IS%s 1991 Mar 31 2:00s + 7:00 1:00 ISD 1991 Sep 29 2:00s + 7:00 - ISK 1992 Jan 19 2:00s + 8:00 Russia IS%s +Zone Asia/Yakutsk 8:38:40 - LMT 1924 May 2 + 8:00 - YSK 1957 Mar + 9:00 Russia YS%s 1991 Mar 31 2:00s + 8:00 1:00 YSD 1991 Sep 29 2:00s + 8:00 - YSK 1992 Jan 19 2:00s + 9:00 Russia YS%s +Zone Asia/Vladivostok 8:47:44 - LMT 1880 + 8:48 - LST 1924 May 2 + 9:00 - VSK 1957 Mar + 10:00 Russia VS%s 1991 Mar 31 2:00s + 9:00 1:00 VSD 1991 Sep 29 2:00s + 9:00 - VSK 1992 Jan 19 2:00s + 10:00 Russia VS%s +# MSK is taken; settle for GSK. +Zone Asia/Magadan 10:03:12 - LMT 1924 May 2 + 10:00 - GSK 1957 Mar + 11:00 Russia GS%s 1991 Mar 31 2:00s + 10:00 1:00 GSD 1991 Sep 29 2:00s + 10:00 - GSK 1992 Jan 19 2:00s + 11:00 Russia GS%s +# This name should be Asia/Petropavlovsk-Kamchatski, but that's too long. +Zone Asia/Kamchatka 10:34:36 - LMT 1924 May 2 + 11:00 - PSK 1957 Mar + 12:00 Russia PS%s 1991 Mar 31 2:00s + 11:00 1:00 PSD 1991 Sep 29 2:00s + 11:00 - PSK 1992 Jan 19 2:00s + 12:00 Russia PS%s +Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2 + 12:00 - ASK 1957 Mar + 13:00 Russia AS%s 1991 Mar 31 2:00s + 12:00 1:00 ASD 1991 Sep 29 2:00s + 12:00 - ASK 1992 Jan 19 2:00s + 13:00 Russia AS%s + +# Serbia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Belgrade 1:22:00 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Slovenia +# They switched from the Julian to the Gregorian calendar on 1918 Mar 18. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Ljubljana 0:58:04 - LMT 1884 + 1:00 - MET 1941 Apr 18 23:00 + 1:00 M-Eur MET%s 1945 May 8 2:00s + 1:00 1:00 "MET DST" 1945 Sep 16 2:00s + 1:00 - MET 1983 Mar 27 2:00s + 1:00 M-Eur MET%s + +# Spain +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Spain 1901 only - Jan 1 0:00 0 - +# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1; go with Shanks. +Rule Spain 1917 only - May 5 23:00s 1:00 " DST" +Rule Spain 1917 1919 - Oct 6 23:00s 0 - +Rule Spain 1918 only - Apr 15 23:00s 1:00 " DST" +Rule Spain 1919 only - Apr 5 23:00s 1:00 " DST" +# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks. +Rule Spain 1924 only - Apr 16 23:00s 1:00 " DST" +# Whitman gives 1924 Oct 14; go with Shanks. +Rule Spain 1924 only - Oct 4 23:00s 0 - +Rule Spain 1926 only - Apr 17 23:00s 1:00 " DST" +# Whitman says no DST in 1929; go with Shanks. +Rule Spain 1926 1929 - Oct Sat>=1 23:00s 0 - +Rule Spain 1927 only - Apr 9 23:00s 1:00 " DST" +Rule Spain 1928 only - Apr 14 23:00s 1:00 " DST" +Rule Spain 1929 only - Apr 20 23:00s 1:00 " DST" +# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13; go with Shanks. +Rule Spain 1937 only - May 22 23:00s 1:00 " DST" +Rule Spain 1937 1939 - Oct Sat>=1 23:00s 0 - +Rule Spain 1938 only - Mar 22 23:00s 1:00 " DST" +Rule Spain 1939 only - Apr 15 23:00s 1:00 " DST" +Rule Spain 1940 only - Mar 16 23:00s 1:00 " DST" +# Whitman says no DST 1942-1945; go with Shanks. +Rule Spain 1942 only - May 2 22:00s 2:00 " DDST" +Rule Spain 1942 only - Sep 1 22:00s 1:00 " DST" +Rule Spain 1943 1946 - Apr Sat>=13 22:00s 2:00 " DDST" +Rule Spain 1943 only - Oct 3 22:00s 1:00 " DST" +Rule Spain 1944 only - Oct 10 22:00s 1:00 " DST" +Rule Spain 1945 only - Sep 30 1:00 1:00 " DST" +Rule Spain 1949 only - Apr 30 23:00 1:00 " DST" +Rule Spain 1949 only - Sep 30 1:00 0 - +Rule Spain 1974 1975 - Apr Sat>=13 23:00 1:00 " DST" +Rule Spain 1974 1975 - Oct Sun>=1 1:00 0 - +Rule Spain 1976 only - Mar 27 23:00 1:00 " DST" +Rule Spain 1976 1977 - Sep lastSun 1:00 0 - +Rule Spain 1977 1978 - Apr 2 23:00 1:00 " DST" +Rule Spain 1978 only - Oct 1 1:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Madrid -0:14:44 - LMT 1901 + 0:00 Spain WET%s 1946 Sep 30 + 1:00 Spain MET%s 1979 Apr 1 2:00 + 1:00 M-Eur MET%s +Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C. + -1:00 - ACT 1946 Sep 30 1:00 + 0:00 - WET 1980 Apr 6 0:00s + 0:00 1:00 "WET DST" 1980 Sep 28 0:00s + 0:00 W-Eur WET%s + +# Sweden +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Stockholm 1:12:12 - LMT 1878 May 31 + 1:12 - SMT 1900 Jan 1 1:00 # Stockholm MT + 1:00 - MET 1916 Apr 14 23:00s + 1:00 1:00 "MET DST" 1916 Sep 30 23:00s + 1:00 - MET 1980 Apr 6 2:00 + 1:00 M-Eur MET%s + +# Switzerland +# From Howse (1988), p 82: +# By the end of the 18th century clocks and watches became commonplace +# and their performance improved enormously. Communities began to keep +# mean time in preference to apparent time -- Geneva from 1780 .... +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Swiss 1894 only - Jun 1 0:00 0 - +# From Whitman (who writes ``Midnight?''): +Rule Swiss 1940 only - Nov 2 0:00 1:00 " DST" +Rule Swiss 1940 only - Dec 31 0:00 0 " DST" +# From Shanks (1991): +Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 " DST" +Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 " DST" +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:30 - SST 1894 Jun # Swiss Standard Time + 1:00 Swiss MET%s 1981 Mar 29 2:00 + 1:00 M-Eur MET%s + +# Turkey +# European Turkey switched to the Gregorian calendar in 1908. +# Asian Turkey switched in 1914. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Turkey 1910 only - Oct 1 0:00 0 - +Rule Turkey 1916 only - May 1 0:00 1:00 " DST" +Rule Turkey 1916 only - Oct 1 0:00 0 - +Rule Turkey 1920 only - Mar 28 0:00 1:00 " DST" +Rule Turkey 1920 only - Oct 25 0:00 0 - +Rule Turkey 1921 only - Apr 3 0:00 1:00 " DST" +Rule Turkey 1921 only - Oct 3 0:00 0 - +Rule Turkey 1922 only - Mar 26 0:00 1:00 " DST" +Rule Turkey 1922 only - Oct 8 0:00 0 - +# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925; go with Shanks. +Rule Turkey 1924 only - May 13 0:00 1:00 " DST" +Rule Turkey 1924 1925 - Oct 1 0:00 0 - +Rule Turkey 1925 only - May 1 0:00 1:00 " DST" +# Shanks omits the first two transitions in 1940; go with Whitman. +Rule Turkey 1940 only - Jun 30 0:00 1:00 " DST" +Rule Turkey 1940 only - Oct 5 0:00 0 - +Rule Turkey 1940 only - Dec 1 0:00 1:00 " DST" +Rule Turkey 1941 only - Sep 21 0:00 0 - +Rule Turkey 1942 only - Apr 1 0:00 1:00 " DST" +# Whitman omits the next two transition and gives 1945 Oct 1; go with Shanks. +Rule Turkey 1942 only - Nov 1 0:00 0 - +Rule Turkey 1945 only - Apr 2 0:00 1:00 " DST" +Rule Turkey 1945 only - Oct 8 0:00 0 - +Rule Turkey 1946 only - Jun 1 0:00 1:00 " DST" +Rule Turkey 1946 only - Oct 1 0:00 0 - +Rule Turkey 1947 1948 - Apr Sun>=16 0:00 1:00 " DST" +Rule Turkey 1947 1950 - Oct Sun>=2 0:00 0 - +Rule Turkey 1949 only - Apr 10 0:00 1:00 " DST" +Rule Turkey 1950 only - Apr 19 0:00 1:00 " DST" +Rule Turkey 1951 only - Apr 22 0:00 1:00 " DST" +Rule Turkey 1951 only - Oct 8 0:00 0 - +Rule Turkey 1962 only - Jul 15 0:00 1:00 " DST" +Rule Turkey 1962 only - Oct 8 0:00 0 - +Rule Turkey 1964 only - May 15 0:00 1:00 " DST" +Rule Turkey 1964 only - Oct 1 0:00 0 - +Rule Turkey 1970 1972 - May Sun>=2 0:00 1:00 " DST" +Rule Turkey 1970 1972 - Oct Sun>=2 0:00 0 - +Rule Turkey 1973 only - Jun 3 1:00 1:00 " DST" +Rule Turkey 1973 only - Nov 4 3:00 0 - +Rule Turkey 1974 only - Mar 31 2:00 1:00 " DST" +Rule Turkey 1974 only - Nov 3 5:00 0 - +Rule Turkey 1975 only - Mar 30 0:00 1:00 " DST" +Rule Turkey 1975 1976 - Oct lastSun 0:00 0 - +Rule Turkey 1976 only - Jun 1 0:00 1:00 " DST" +Rule Turkey 1977 1978 - Apr Sun>=1 0:00 1:00 " DST" +Rule Turkey 1977 only - Oct 16 0:00 0 - +Rule Turkey 1979 1980 - Apr Sun>=1 3:00 1:00 " DST" +Rule Turkey 1979 1982 - Oct Mon>=11 0:00 0 - +Rule Turkey 1981 1982 - Mar lastSun 3:00 1:00 " DST" +Rule Turkey 1983 only - Jul 31 0:00 1:00 " DST" +Rule Turkey 1983 only - Oct 2 0:00 0 - +Rule Turkey 1985 only - Apr 20 0:00 1:00 " DST" +Rule Turkey 1985 only - Sep 28 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Istanbul 1:55:52 - LMT 1880 + 1:57 - OMT 1910 Oct # Ottoman Mean Time + 2:00 Turkey EET%s 1978 Oct 15 + 3:00 Turkey TUR%s 1985 Apr 20 + 2:00 Turkey EET%s 1986 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. +Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. + +# Ukraine +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Ukraine 1919 only - Jul 1 2:00 1:00 " DST" +Rule Ukraine 1919 only - Aug 16 0:00 0 - +Rule Ukraine 1921 only - Feb 14 23:00 1:00 " DST" +Rule Ukraine 1921 only - Mar 21 23:00 2:00 " DDST" +Rule Ukraine 1921 only - Sep 1 0:00 1:00 " DST" +Rule Ukraine 1921 only - Oct 1 0:00 0 - +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Europe/Kiev 2:02:04 - LMT 1880 + 2:02 Russia LST%s 1919 Jul 1 2:00 + 2:02 Ukraine LST%s 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1990 Jul 17 + 2:00 M-Eur EET%s +# This may change to `E-Eur' soon, for EC compatibility. +Zone Europe/Simferopol 2:16:24 - LMT 1880 + 2:08 Russia LST%s 1919 Jul 1 2:00 + 2:08 Ukraine LST%s 1924 May 2 + 2:00 - EET 1930 Jun 21 + 3:00 Russia MS%s 1991 Mar 31 2:00s + 2:00 1:00 "EET DST" 1991 Sep 29 2:00s +# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): +# Today's _Economist_ (p 45) reports that Crimea switched +# from Kiev to Moscow time sometime after the January elections. +# For now, we'll guess that there was a 2-hour leap forward on March 27. + 2:00 M-Eur EET%s 1994 Mar 27 2:00s + 3:00 Russia MS%s + +############################################################################### + +# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from +# the last Sunday in March to the last Sunday in September in 1986. +# The source shows Romania changing a day later than everybody else. +# +# According to Bernard Sieloff's source, Poland is in the MET time zone but +# uses the WE DST rules. The Western USSR uses EET+1 and ME DST rules. +# Bernard Sieloff's source claims Romania switches on the same day, but at +# 00:00 standard time (i.e., 01:00 DST). It also claims that Turkey +# switches on the same day, but switches on at 01:00 standard time +# and off at 00:00 standard time (i.e., 01:00 DST) + +# ... +# Date: Wed, 28 Jan 87 16:56:27 -0100 +# From: seismo!mcvax!cgcha!wtho (Tom Hofmann) +# Message-Id: <8701281556.AA22174@cgcha.uucp> +# ... +# +# ...the European time rules are...standardized since 1981, when +# most European coun[tr]ies started DST. Before that year, only +# a few countries (UK, France, Italy) had DST, each according +# to own national rules. In 1981, however, DST started on +# 'Apr firstSun', and not on 'Mar lastSun' as in the following +# years... +# But also since 1981 there are some more national exceptions +# than listed in 'europe': Switzerland, for example, joined DST +# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep +# lastSun' in 1981---I don't know how they handle now. +# +# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the +# Soviet Union (as far as I know). +# +# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG, +# 4002 Basle, Switzerland +# UUCP: ...!mcvax!cernvax!cgcha!wtho + +# ... +# Date: Wed, 4 Feb 87 22:35:22 +0100 +# From: seismo!mcvax!cwi.nl!dik (Dik T. Winter) +# ... +# +# The information from Tom Hofmann is (as far as I know) not entirely correct. +# After a request from chongo at amdahl I tried to retrieve all information +# about DST in Europe. I was able to find all from about 1969. +# +# ...standardization on DST in Europe started in about 1977 with switches on +# first Sunday in April and last Sunday in September... +# In 1981 UK joined Europe insofar that +# the starting day for both shifted to last Sunday in March. And from 1982 +# the whole of Europe used DST, with switch dates April 1 and October 1 in +# the Sov[i]et Union. In 1985 the SU reverted to standard Europe[a]n switch +# dates... +# +# It should also be remembered that time-zones are not constants; e.g. +# Portugal switched in 1976 from MET (or CET) to WET with DST... +# Note also that though there were rules for switch dates not +# all countries abided to these dates, and many individual deviations +# occurred, though not since 1982 I believe. Another note: it is always +# assumed that DST is 1 hour ahead of normal time, this need not be the +# case; at least in the Netherlands there have been times when DST was 2 hours +# in advance of normal time. +# +# ... +# dik t. winter, cwi, amsterdam, nederland +# INTERNET : dik@cwi.nl +# BITNET/EARN: dik@mcvax + +# From Bob Devine (January 28, 1988): +# ... +# Greece: Last Sunday in April to last Sunday in September (iffy on dates). +# Since 1978. Change at midnight. +# ... +# Monaco: has same DST as France. +# ... + +# ... +# Date: Fri, 3 Sep 93 13:43:41 BST +# From: Peter Ilieve <peter@memex.co.uk> +# ... +# Turning to Europe, I now have a copy of the `Sixth Council Directive 92/20/EEC +# of 26 March 1992 on summertime arrangements'. This only covers 1993 and +# 1994, a seventh one is in the works but I doubt that the algorithm will +# change. This says summertime starts at 01:00 GMT on the last Sunday in March +# and ends at 01:00 GMT on the last Sunday in September, except for the UK +# and Eire where it ends at 01:00 GMT on the fourth Sunday in October. +# It says the arrangements for 1995 onwards will be decided by 1 January 1994, +# but as the sixth directive was supposed to appear by 1 Jan 92 and didn't +# arrive til March I wouldn't hold your breath. +# +# The first summertime directive was adopted in 1980, although the UK didn't +# seem to use it until 1981. I suspect it would be safe to move your start +# dates for the -Eur rules back to 1981. diff --git a/time/factory b/time/factory new file mode 100644 index 0000000000..d95df23c1d --- /dev/null +++ b/time/factory @@ -0,0 +1,8 @@ +# @(#)factory 7.1 + +# For companies who don't want to put time zone specification in +# their installation procedures. When users run date, they'll get the message. +# Also useful for the "comp.sources" version. + +# Zone NAME GMTOFF RULES FORMAT +Zone Factory 0 - "Local time zone must be set--see zic manual page" diff --git a/time/gmtime.c b/time/gmtime.c new file mode 100644 index 0000000000..f09baef5f2 --- /dev/null +++ b/time/gmtime.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stddef.h> +#include <time.h> + +/* Return the `struct tm' representation of *T in UTC. */ +struct tm * +DEFUN(gmtime, (t), CONST time_t *t) +{ + struct tm *tp = __offtime (t, 0L); + + tp->tm_gmtoff = 0L; + tp->tm_zone = "GMT"; + + return tp; +} diff --git a/time/ialloc.c b/time/ialloc.c new file mode 100644 index 0000000000..d6a1b22b0e --- /dev/null +++ b/time/ialloc.c @@ -0,0 +1,103 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)ialloc.c 8.24"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/*LINTLIBRARY*/ + +#include "private.h" + +#ifdef MAL +#define NULLMAL(x) ((x) == NULL || (x) == MAL) +#endif /* defined MAL */ +#ifndef MAL +#define NULLMAL(x) ((x) == NULL) +#endif /* !defined MAL */ + +#define nonzero(n) (((n) == 0) ? 1 : (n)) + +char * icalloc P((int nelem, int elsize)); +char * icatalloc P((char * old, const char * new)); +char * icpyalloc P((const char * string)); +char * imalloc P((int n)); +void * irealloc P((void * pointer, int size)); +void ifree P((char * pointer)); + +char * +imalloc(n) +const int n; +{ +#ifdef MAL + register char * result; + + result = malloc((alloc_size_T) nonzero(n)); + return NULLMAL(result) ? NULL : result; +#endif /* defined MAL */ +#ifndef MAL + return malloc((alloc_size_T) nonzero(n)); +#endif /* !defined MAL */ +} + +char * +icalloc(nelem, elsize) +int nelem; +int elsize; +{ + if (nelem == 0 || elsize == 0) + nelem = elsize = 1; + return calloc((alloc_size_T) nelem, (alloc_size_T) elsize); +} + +void * +irealloc(pointer, size) +void * const pointer; +const int size; +{ + if (NULLMAL(pointer)) + return imalloc(size); + return realloc((genericptr_T) pointer, (alloc_size_T) nonzero(size)); +} + +char * +icatalloc(old, new) +char * const old; +const char * const new; +{ + register char * result; + register int oldsize, newsize; + + newsize = NULLMAL(new) ? 0 : strlen(new); + if (NULLMAL(old)) + oldsize = 0; + else if (newsize == 0) + return old; + else oldsize = strlen(old); + if ((result = irealloc(old, oldsize + newsize + 1)) != NULL) + if (!NULLMAL(new)) + (void) strcpy(result + oldsize, new); + return result; +} + +char * +icpyalloc(string) +const char * const string; +{ + return icatalloc((char *) NULL, string); +} + +void +ifree(p) +char * const p; +{ + if (!NULLMAL(p)) + (void) free(p); +} + +void +icfree(p) +char * const p; +{ + if (!NULLMAL(p)) + (void) free(p); +} diff --git a/time/leapseconds b/time/leapseconds new file mode 100644 index 0000000000..d610692f94 --- /dev/null +++ b/time/leapseconds @@ -0,0 +1,41 @@ +# @(#)leapseconds 7.7 + +# Allowance for leapseconds added to each timezone file. + +# The International Earth Rotation Service periodically uses leap seconds +# to keep UTC to within 0.9 s of TAI (atomic time); see +# Terry J Quinn, The BIPM and the accurate measure of time, +# Proc IEEE 79, 7 (July 1991), 894-905. +# There were no leap seconds before 1972, because the official mechanism +# accounting for the discrepancy between atomic time and the earth's rotation +# did not exist until the early 1970s. + +# The correction (+ or -) is made at the given time, so lines +# will typically look like: +# Leap YEAR MON DAY 23:59:60 + R/S +# or +# Leap YEAR MON DAY 23:59:59 - R/S + +# If the leapsecond is Rolling (R) the given time is local time +# If the leapsecond is Stationary (S) the given time is GMT + +# Leap YEAR MONTH DAY HH:MM:SS CORR R/S +Leap 1972 Jun 30 23:59:60 + S +Leap 1972 Dec 31 23:59:60 + S +Leap 1973 Dec 31 23:59:60 + S +Leap 1974 Dec 31 23:59:60 + S +Leap 1975 Dec 31 23:59:60 + S +Leap 1976 Dec 31 23:59:60 + S +Leap 1977 Dec 31 23:59:60 + S +Leap 1978 Dec 31 23:59:60 + S +Leap 1979 Dec 31 23:59:60 + S +Leap 1981 Jun 30 23:59:60 + S +Leap 1982 Jun 30 23:59:60 + S +Leap 1983 Jun 30 23:59:60 + S +Leap 1985 Jun 30 23:59:60 + S +Leap 1987 Dec 31 23:59:60 + S +Leap 1989 Dec 31 23:59:60 + S +Leap 1990 Dec 31 23:59:60 + S +Leap 1992 Jun 30 23:59:60 + S +Leap 1993 Jun 30 23:59:60 + S +Leap 1994 Jun 30 23:59:60 + S diff --git a/time/localtime.c b/time/localtime.c new file mode 100644 index 0000000000..3377b80197 --- /dev/null +++ b/time/localtime.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <stddef.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +#ifndef HAVE_GNU_LD +#define __tzname tzname +#define __daylight daylight +#define __timezone timezone +#endif + +/* Return the `struct tm' representation of *TIMER in the local timezone. */ +struct tm * +DEFUN(localtime, (timer), CONST time_t *timer) +{ + extern int __use_tzfile; + extern int EXFUN(__tz_compute, (time_t timer, struct tm *tp)); + extern int EXFUN(__tzfile_compute, (time_t timer, + long int *leap_correct, int *leap_hit)); + register struct tm *tp; + long int leap_correction; + int leap_extra_secs; + + if (timer == NULL) + { + errno = EINVAL; + return NULL; + } + + { + /* Make sure the database is initialized. */ + extern int __tzset_run; + if (! __tzset_run) + __tzset (); + } + + if (__use_tzfile) + { + if (! __tzfile_compute (*timer, &leap_correction, &leap_extra_secs)) + return NULL; + } + else + { + tp = gmtime (timer); + if (tp == NULL) + return NULL; + + if (! __tz_compute (*timer, tp)) + return NULL; + + leap_correction = 0L; + leap_extra_secs = 0; + } + + tp = __offtime (timer, __timezone - leap_correction); + tp->tm_sec += leap_extra_secs; + tp->tm_isdst = __daylight; + tp->tm_gmtoff = __timezone; + tp->tm_zone = __tzname[__daylight]; + return tp; +} diff --git a/time/mktime.c b/time/mktime.c new file mode 100644 index 0000000000..f86496a941 --- /dev/null +++ b/time/mktime.c @@ -0,0 +1,506 @@ +/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + Contributed by Noel Cragg (noel@cs.oberlin.edu), with fixes by + Michael E. Calwas (calwas@ttd.teradyne.com) and + Wade Hampton (tasi029@tmn.com). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Define this to have a standalone program to test this implementation of + mktime. */ +/* #define DEBUG */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> /* Some systems define `time_t' here. */ +#include <time.h> + + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +/* How many days are in each month. */ +const unsigned short int __mon_lengths[2][12] = + { + /* Normal years. */ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + /* Leap years. */ + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + + +static int times_through_search; /* This library routine should never + hang -- make sure we always return + when we're searching for a value */ + + +#ifdef DEBUG + +#include <stdio.h> +#include <ctype.h> + +int debugging_enabled = 0; + +/* Print the values in a `struct tm'. */ +static void +printtm (it) + struct tm *it; +{ + printf ("%02d/%02d/%04d %02d:%02d:%02d (%s) yday:%03d dst:%d gmtoffset:%ld", + it->tm_mon + 1, + it->tm_mday, + it->tm_year + 1900, + it->tm_hour, + it->tm_min, + it->tm_sec, + it->tm_zone, + it->tm_yday, + it->tm_isdst, + it->tm_gmtoff); +} +#endif + + +static time_t +dist_tm (t1, t2) + struct tm *t1; + struct tm *t2; +{ + time_t distance = 0; + unsigned long int v1, v2; + int diff_flag = 0; + + v1 = v2 = 0; + +#define doit(x, secs) \ + v1 += t1->x * secs; \ + v2 += t2->x * secs; \ + if (!diff_flag) \ + { \ + if (t1->x < t2->x) \ + diff_flag = -1; \ + else if (t1->x > t2->x) \ + diff_flag = 1; \ + } + + doit (tm_year, 31536000); /* Okay, not all years have 365 days. */ + doit (tm_mon, 2592000); /* Okay, not all months have 30 days. */ + doit (tm_mday, 86400); + doit (tm_hour, 3600); + doit (tm_min, 60); + doit (tm_sec, 1); + +#undef doit + + /* We should also make sure that the sign of DISTANCE is correct -- if + DIFF_FLAG is positive, the distance should be positive and vice versa. */ + + distance = (v1 > v2) ? (v1 - v2) : (v2 - v1); + if (diff_flag < 0) + distance = -distance; + + if (times_through_search > 20) /* Arbitrary # of calls, but makes sure we + never hang if there's a problem with + this algorithm. */ + { + distance = diff_flag; + } + + /* We need this DIFF_FLAG business because it is forseeable that the + distance may be zero when, in actuality, the two structures are + different. This is usually the case when the dates are 366 days apart + and one of the years is a leap year. */ + + if (distance == 0 && diff_flag) + distance = 86400 * diff_flag; + + return distance; +} + + +/* MKTIME converts the values in a struct tm to a time_t. The values + in tm_wday and tm_yday are ignored; other values can be put outside + of legal ranges since they will be normalized. This routine takes + care of that normalization. */ + +void +do_normalization (tmptr) + struct tm *tmptr; +{ + +#define normalize(foo,x,y,bar); \ + while (tmptr->foo < x) \ + { \ + tmptr->bar--; \ + tmptr->foo = (y - (x - tmptr->foo) + 1); \ + } \ + while (tmptr->foo > y) \ + { \ + tmptr->foo = (x + (tmptr->foo - y) - 1); \ + tmptr->bar++; \ + } + + normalize (tm_sec, 0, 59, tm_min); + normalize (tm_min, 0, 59, tm_hour); + normalize (tm_hour, 0, 23, tm_mday); + + /* Do the month first, so day range can be found. */ + normalize (tm_mon, 0, 11, tm_year); + + /* Since the day range modifies the month, we should be careful how + we reference the array of month lengths -- it is possible that + the month will go negative, hence the modulo... + + Also, tm_year is the year - 1900, so we have to 1900 to have it + work correctly. */ + + normalize (tm_mday, 1, + __mon_lengths[__isleap (tmptr->tm_year + 1900)] + [((tmptr->tm_mon < 0) + ? (12 + (tmptr->tm_mon % 12)) + : (tmptr->tm_mon % 12)) ], + tm_mon); + + /* Do the month again, because the day may have pushed it out of range. */ + normalize (tm_mon, 0, 11, tm_year); + + /* Do the day again, because the month may have changed the range. */ + normalize (tm_mday, 1, + __mon_lengths[__isleap (tmptr->tm_year + 1900)] + [((tmptr->tm_mon < 0) + ? (12 + (tmptr->tm_mon % 12)) + : (tmptr->tm_mon % 12)) ], + tm_mon); + +#ifdef DEBUG + if (debugging_enabled) + { + printf (" After normalizing:\n "); + printtm (tmptr); + putchar ('\n'); + } +#endif + +} + + +/* Here's where the work gets done. */ + +#define BAD_STRUCT_TM ((time_t) -1) + +time_t +_mktime_internal (timeptr, producer) + struct tm *timeptr; + struct tm *(*producer) __P ((const time_t *)); +{ + struct tm our_tm; /* our working space */ + struct tm *me = &our_tm; /* a pointer to the above */ + time_t result; /* the value we return */ + + *me = *timeptr; /* copy the struct tm that was passed + in by the caller */ + + + /***************************/ + /* Normalize the structure */ + /***************************/ + + /* This routine assumes that the value of TM_ISDST is -1, 0, or 1. + If the user didn't pass it in that way, fix it. */ + + if (me->tm_isdst > 0) + me->tm_isdst = 1; + else if (me->tm_isdst < 0) + me->tm_isdst = -1; + + do_normalization (me); + + /* Get out of here if it's not possible to represent this struct. + If any of the values in the normalized struct tm are negative, + our algorithms won't work. Luckily, we only need to check the + year at this point; normalization guarantees that all values will + be in correct ranges EXCEPT the year. */ + + if (me->tm_year < 0) + return BAD_STRUCT_TM; + + /*************************************************/ + /* Find the appropriate time_t for the structure */ + /*************************************************/ + + /* Modified b-search -- make intelligent guesses as to where the + time might lie along the timeline, assuming that our target time + lies a linear distance (w/o considering time jumps of a + particular region). + + Assume that time does not fluctuate at all along the timeline -- + e.g., assume that a day will always take 86400 seconds, etc. -- + and come up with a hypothetical value for the time_t + representation of the struct tm TARGET, in relation to the guess + variable -- it should be pretty close! + + After testing this, the maximum number of iterations that I had + on any number that I tried was 3! Not bad. + + The reason this is not a subroutine is that we will modify some + fields in the struct tm (yday and mday). I've never felt good + about side-effects when writing structured code... */ + + { + struct tm *guess_tm; + time_t guess = 0; + time_t distance = 0; + time_t last_distance = 0; + + times_through_search = 0; + + do + { + guess += distance; + + times_through_search++; + + guess_tm = (*producer) (&guess); + +#ifdef DEBUG + if (debugging_enabled) + { + printf (" Guessing time_t == %d\n ", (int) guess); + printtm (guess_tm); + putchar ('\n'); + } +#endif + + /* How far is our guess from the desired struct tm? */ + distance = dist_tm (me, guess_tm); + + /* Handle periods of time where a period of time is skipped. + For example, 2:15 3 April 1994 does not exist, because DST + is in effect. The distance function will alternately + return values of 3600 and -3600, because it doesn't know + that the requested time doesn't exist. In these situations + (even if the skip is not exactly an hour) the distances + returned will be the same, but alternating in sign. We + want the later time, so check to see that the distance is + oscillating and we've chosen the correct of the two + possibilities. + + Useful: 3 Apr 94 765356300, 30 Oct 94 783496000 */ + + if ((distance == -last_distance) && (distance < last_distance)) + { + /* If the caller specified that the DST flag was off, it's + not possible to represent this time. */ + if (me->tm_isdst == 0) + { +#ifdef DEBUG + printf (" Distance is oscillating -- dst flag nixes struct!\n"); +#endif + return BAD_STRUCT_TM; + } + +#ifdef DEBUG + printf (" Distance is oscillating -- chose the later time.\n"); +#endif + distance = 0; + } + + if ((distance == 0) && (me->tm_isdst != -1) + && (me->tm_isdst != guess_tm->tm_isdst)) + { + /* If we're in this code, we've got the right time but the + wrong daylight savings flag. We need to move away from + the time that we have and approach the other time from + the other direction. That is, if I've requested the + non-DST version of a time and I get the DST version + instead, I want to put us forward in time and search + backwards to get the other time. I checked all of the + configuration files for the tz package -- no entry + saves more than two hours, so I think we'll be safe by + moving 24 hours in one direction. IF THE AMOUNT OF + TIME SAVED IN THE CONFIGURATION FILES CHANGES, THIS + VALUE MAY NEED TO BE ADJUSTED. Luckily, we can never + have more than one level of overlaps, or this would + never work. */ + +#define SKIP_VALUE 86400 + + if (guess_tm->tm_isdst == 0) + /* we got the later one, but want the earlier one */ + distance = -SKIP_VALUE; + else + distance = SKIP_VALUE; + +#ifdef DEBUG + printf (" Got the right time, wrong DST value -- adjusting\n"); +#endif + } + + last_distance = distance; + + } while (distance != 0); + + /* Check to see that the dst flag matches */ + + if (me->tm_isdst != -1) + { + if (me->tm_isdst != guess_tm->tm_isdst) + { +#ifdef DEBUG + printf (" DST flag doesn't match! FIXME?\n"); +#endif + return BAD_STRUCT_TM; + } + } + + result = guess; /* Success! */ + + /* On successful completion, the values of tm_wday and tm_yday + have to be set appropriately. */ + + /* me->tm_yday = guess_tm->tm_yday; + me->tm_mday = guess_tm->tm_mday; */ + + *me = *guess_tm; + } + + /* Update the caller's version of the structure */ + + *timeptr = *me; + + return result; +} + +time_t +#ifdef DEBUG /* make it work even if the system's + libc has it's own mktime routine */ +my_mktime (timeptr) +#else +mktime (timeptr) +#endif + struct tm *timeptr; +{ + return _mktime_internal (timeptr, localtime); +} + +#ifdef weak_alias +weak_alias (mktime, timelocal) +#endif + +#ifdef DEBUG +void +main (argc, argv) + int argc; + char *argv[]; +{ + int time; + int result_time; + struct tm *tmptr; + + if (argc == 1) + { + long q; + + printf ("starting long test...\n"); + + for (q = 10000000; q < 1000000000; q += 599) + { + struct tm *tm = localtime ((time_t *) &q); + if ((q % 10000) == 0) { printf ("%ld\n", q); fflush (stdout); } + if (q != my_mktime (tm)) + { printf ("failed for %ld\n", q); fflush (stdout); } + } + + printf ("test finished\n"); + + exit (0); + } + + if (argc != 2) + { + printf ("wrong # of args\n"); + exit (0); + } + + debugging_enabled = 1; /* We want to see the info */ + + ++argv; + time = atoi (*argv); + + tmptr = localtime ((time_t *) &time); + printf ("Localtime tells us that a time_t of %d represents\n ", time); + printtm (tmptr); + putchar ('\n'); + + printf (" Given localtime's return val, mktime returns %d which is\n ", + (int) my_mktime (tmptr)); + printtm (tmptr); + putchar ('\n'); + +#if 0 + tmptr->tm_sec -= 20; + tmptr->tm_min -= 20; + tmptr->tm_hour -= 20; + tmptr->tm_mday -= 20; + tmptr->tm_mon -= 20; + tmptr->tm_year -= 20; + tmptr->tm_gmtoff -= 20000; /* This has no effect! */ + tmptr->tm_zone = NULL; /* Nor does this! */ + tmptr->tm_isdst = -1; +#endif + + tmptr->tm_hour += 1; + tmptr->tm_isdst = -1; + + printf ("\n\nchanged ranges: "); + printtm (tmptr); + putchar ('\n'); + + result_time = my_mktime (tmptr); + printf ("\nmktime: %d\n", result_time); + + tmptr->tm_isdst = 0; + + printf ("\n\nchanged ranges: "); + printtm (tmptr); + putchar ('\n'); + + result_time = my_mktime (tmptr); + printf ("\nmktime: %d\n", result_time); +} +#endif /* DEBUG */ + + +/* +Local Variables: +compile-command: "gcc -g mktime.c -o mktime -DDEBUG" +End: +*/ diff --git a/time/northamerica b/time/northamerica new file mode 100644 index 0000000000..40733fddce --- /dev/null +++ b/time/northamerica @@ -0,0 +1,953 @@ +# @(#)northamerica 7.12 +# also includes Central America and the Caribbean + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (August 17, 1994): +# A reliable and entertaining source about time zones is +# Derek Howse, Greenwich time and the discovery of the longitude, +# Oxford University Press (1980). + +############################################################################### + +# United States + +# From Arthur David Olson: +# US Daylight Saving Time ended on the last Sunday of *October* in 1974. +# See, for example, the front page of the Saturday, October 26, 1974 +# and Sunday, October 27, 1974 editions of the Washington Post. + +# From seismo!munnari!kre: +# I recall also being told by someone once that Canada didn't have +# the DST variations in 74/75 that the US did, but I am not nearly +# sure enough of this to add anything. + +# From Arthur David Olson: +# The above has been confirmed by Bob Devine; we'll go with it here. + +# From Arthur David Olson: +# Before the Uniform Time Act of 1966 took effect in 1967, observance of +# Daylight Saving Time in the US was by local option, except during wartime. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule US 1918 1919 - Mar lastSun 2:00 1:00 D +Rule US 1918 1919 - Oct lastSun 2:00 0 S +Rule US 1942 only - Feb 9 2:00 1:00 W # War +Rule US 1945 only - Sep 30 2:00 0 S +Rule US 1967 max - Oct lastSun 2:00 0 S +Rule US 1967 1973 - Apr lastSun 2:00 1:00 D +Rule US 1974 only - Jan 6 2:00 1:00 D +Rule US 1975 only - Feb 23 2:00 1:00 D +Rule US 1976 1986 - Apr lastSun 2:00 1:00 D +Rule US 1987 max - Apr Sun>=1 2:00 1:00 D + +# From Bob Devine (January 28, 1988): +# ...Alaska (and Hawaii) had the timezone names changed in 1967. +# old new +# Pacific Standard Time(PST) -same- +# Yukon Standard Time(YST) -same- +# Central Alaska S.T. (CAT) Alaska-Hawaii St[an]dard Time (AHST) +# Nome Standard Time (NT) Bering Standard Time (BST) +# +# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz. +# The YST zone now covers nearly all of the state, AHST just part +# of the Aleutian islands. No DST. + +# From U. S. Naval Observatory (January 19, 1989): +# USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +# USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +# USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +# USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +# USA MOUNTAIN 7 H BEHIND UTC DENVER +# USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +# USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +# USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +# USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +# USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +# USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +# USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +# USA HAWAII 10 H BEHIND UTC +# USA BERING 11 H BEHIND UTC SAMOA, MIDWAY + +# From Arthur David Olson (January 21, 1989): +# The above dates are for 1988. +# Note the "AKST" and "AKDT" abbreviations, the claim that there's +# no DST in Samoa, and the claim that there is DST in Alaska and the +# Aleutians. + +# From Arthur David Olson (February 13, 1988): +# Legal standard time zone names, from United States Code (1982 Edition and +# Supplement III), Title 15, Chapter 6, Section 260 and forward. First, names +# up to April 1, 1967 (when most provisions of the Uniform Time Act of 1966 +# took effect), as explained in sections 263 and 261: +# (none) +# United States standard eastern time +# United States standard mountain time +# United States standard central time +# United States standard Pacific time +# (none) +# United States standard Alaska time +# (none) +# Next, names from April 1, 1967 until November 30, 1983 (the date for +# public law 98-181): +# Atlantic standard time +# eastern standard time +# central standard time +# mountain standard time +# Pacific standard time +# Yukon standard time +# Alaska-Hawaii standard time +# Bering standard time +# And after November 30, 1983: +# Atlantic standard time +# eastern standard time +# central standard time +# mountain standard time +# Pacific standard time +# Alaska standard time +# Hawaii-Aleutian standard time +# Samoa standard time +# The law doesn't give abbreviations. + +# From Paul Eggert <eggert@twinsun.com> (August 16, 1994): +# Howse writes that Alaska switched from the Julian to the Gregorian calendar, +# and from east-of-GMT to west-of-GMT days, in 1867 when the US purchased it +# from Russia. We don't have this data pinned down yet, though. + +# Easy stuff first--including Alaska, where we ignore history (since we +# can't tell if we should give Yukon time or Alaska-Hawaii time for "old" +# times). + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/New_York -5:00 US E%sT +Zone America/Chicago -6:00 US C%sT +Zone America/Denver -7:00 US M%sT +Zone America/Los_Angeles -8:00 US P%sT +Zone America/Anchorage -9:00 US AK%sT + # AK%sT is the abbreviation per USNO + +# Mainland US areas that are always Standard as of 1986. + +Zone America/Fort_Wayne -5:00 US E%sT 1946 + -5:00 - EST # Always EST as of 1986 +# From Arthur David Olson (October 28, 1991): +# An article on page A3 of the Sunday, October 27, 1991 Washington Post +# notes that Starke County switched from Central time to Eastern time as of +# October 27, 1991. +Zone America/Knox_IN -6:00 US C%sT 1991 Oct 27 2:00 + -5:00 - EST # Always EST as of 1991 +Zone America/Phoenix -7:00 US M%sT 1946 + -7:00 - MST # Always MST as of 1986 + +# From Arthur David Olson (February 13, 1988): +# However. . .a writer from the Inter Tribal Council of Arizona, Inc., +# notes in private correspondence dated 12/28/87 that "Presently, only the +# Navajo Nation participates in the Daylight Saving Time policy, due to its +# large size and location in three states." (The "only" means that other +# tribal nations don't use DST.) + +Link America/Denver Navajo + +# From Bob Devine (January 28, 1988): +# Michigan didn't observe DST from 1968 to 1973. + +Zone America/Detroit -5:00 US E%sT 1968 + -5:00 - EST 1973 + -5:00 US E%sT + +# Samoa just changes names. No DST, per Naval Observatory. +# +# Howse writes that in 1879 the King of Samoa decided to change +# ``the date in his kingdom from the Antipodean to the American system, +# ordaining -- by a masterpiece of diplomatic flattery -- that +# the Fourth of July should be celebrated twice in that year.'' + +Zone Pacific/Samoa 12:37:12 - LMT 1879 Jul 5 + -11:22:48 - LMT 1911 + -11:30 - SST 1950 + -11:00 - NST 1967 Apr # N=Nome + -11:00 - BST 1983 Nov 30 # B=Bering + -11:00 - SST # S=Samoa + +Zone Pacific/Midway -11:49:28 - LMT 1901 + -11:00 - NST 1967 Apr # N=Nome + -11:00 - BST 1983 Nov 30 # B=Bering + -11:00 - SST # S=Samoa + +# Aleutian has a name change. DST, per Naval Observatory. + +Zone America/Atka -10:00 US AH%sT 1983 Nov 30 + -10:00 US HA%sT + +# From Arthur David Olson: +# And then there's Hawaii. +# DST was observed for one day in 1933; +# Standard time was change by half an hour in 1947; +# it's always standard as of 1986. + +Zone Pacific/Honolulu -10:30 US H%sT 1933 Apr 30 2:00 + -10:30 1:00 HDT 1933 May 1 2:00 + -10:30 US H%sT 1947 Jun 8 2:00 + -10:00 - HST + +# Navassa +# no information; probably like US/Eastern + + +# Old names, for S5 users + +# Link LINK-FROM LINK-TO +Link America/New_York EST5EDT +Link America/Chicago CST6CDT +Link America/Denver MST7MDT +Link America/Los_Angeles PST8PDT +Link America/Fort_Wayne EST +Link America/Phoenix MST +Link Pacific/Honolulu HST + +################################################################################ + + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# Another source occasionally used is Edward W. Whitman, World Time Differences, +# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which +# I found in the UCLA library. +# +# I invented the abbreviation SPST for St Pierre Standard Time; SPDT likewise. +# Corrections are welcome! +# +# See the `europe' file for Greenland. +# +# See the `africa' file for Zone naming conventions. + + + +# Canada + +# Canada is reportedly lots easier than the US--leastways since 1951. +# I don't know what they did before then. +# 4.3BSD claims that it's perfectly regular. +# According to a posting in "comp.bugs.misc", "comp.unix.wizards", etc. +# on February 8, 1987, by Dave Sherman of the Law Society of Upper Canada, +# "...Canada (well, Ontario and at least some of the other provinces) are +# adopting the new daylight savings time rules...". We assume all of +# Canada is doing so. + +# From Bob Devine (January 28, 1988): +# All of Canada did have DST from your first rule except Saskatchewan. +# Which parts did not observe DST is hard to pinpoint but most of the +# province follows the rules. +# NOTE: those that didn't have DST for that rule, also +# probably did not have it for several years previous. + +# From U. S. Naval Observatory (January 19, 1989): +# CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +# CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +# CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +# CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +# CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +# CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +# CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +# CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +# CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +# CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +# CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +# CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +# CANADA YUKON SAME AS PACIFIC DAWSON + +# From Arthur David Olson (January 21, 1989): +# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989. Ahem. +# Note claim that there's double DST in Newfoundland and that Yukon should +# be same as Pacific. + +# From W. Jones (jones@skdad.usask.ca) (November 6, 1992): +# The. . .below is based on information I got from our law library, the +# provincial archives, and the provincial Community Services department. +# A precise history would require digging through newspaper archives, and +# since you didn't say what you wanted, I didn't bother. +# +# Saskatchewan is split by a time zone meridian (105W) and over the years +# the boundary became pretty ragged as communities near it reevaluated +# their affiliations in one direction or the other. In 1965 a provincial +# referendum favoured legislating common time practices. +# +# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of +# Saskatchewan 1978) was proclaimed, and established that the eastern +# part of Saskatchewan would use CST year round, that districts in +# northwest Saskatchewan would by default follow CST but could opt to +# follow Mountain Time rules (thus 1 hour difference in the winter and +# zero in the summer), and that districts in southwest Saskatchewan would +# by default follow MT but could opt to follow CST. +# +# It took a few years for the dust to settle (I know one story of a town +# on one time zone having its school in another, such that a mom had to +# serve her family lunch in two shifts), but presently it seems that only +# a few towns on the border with Alberta (e.g. Lloydminster) follow MT +# rules any more; all other districts appear to have used CST year round +# since sometime in the 1960s. +# +# Here's how I would summarize things. Establish a "Saskatchewan" CST +# time zone, and note that it officially exists as of 15 April 1966. Any +# current exceptions can put themselves in the "Mountain" zone, since +# those are the rules they follow. Any past exceptions can be forgotten, +# since that's what those who live here have done. + +# From Arthur David Olson (November 21, 1992): +# East-Saskatchewan kept to avoid problems for folks using that zone by name; +# plain Saskatchewan added. + +# From Alain LaBont<e'> <ALB@immedia.ca> (1994-11-14): +# I post here the time zone abbreviations standardized in Canada +# for both English and French in the CAN/CSA-Z234.4-89 standard.... +# +# UTC Standard time Daylight savings time +# offset French English French English +# -2:30 - - HAT NDT +# -3 - - HAA ADT +# -3:30 HNT NST - - +# -4 HNA AST HAE EDT +# -5 HNE EST HAC CDT +# -6 HNC CST HAR MDT +# -7 HNR MST HAP PDT +# -8 HNP PST HAY YDT +# -9 HNY YST - - +# +# HN: Heure Normale ST: Standard Time +# HA: Heure Avanc<e'>e DT: Daylight saving Time +# +# A: de l'Atlantique Atlantic +# C: du Centre Central +# E: de l'Est Eastern +# M: Mountain +# N: Newfoundland +# P: du Pacifique Pacific +# R: des Rocheuses +# T: de Terre-Neuve +# Y: du Yukon Yukon +# +# From Paul Eggert <eggert@twinsun.com> (1994-11-22): +# Alas, this sort of thing must be handled by localization software. + + + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule StJohns 1884 only - Jan 1 0:00 0 S +Rule StJohns 1917 1918 - Apr Sun>=8 2:00 1:00 D +Rule StJohns 1917 only - Sep 17 2:00 0 S +Rule StJohns 1918 only - Oct 31 2:00 0 S +# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks. +Rule StJohns 1919 only - May 5 23:00 1:00 D +Rule StJohns 1919 only - Aug 12 23:00 0 S +# For 1931-1935 Whitman gives Apr same date; go with Shanks. +Rule StJohns 1920 1935 - May Sun>=1 23:00 1:00 D +Rule StJohns 1920 1935 - Oct lastSun 23:00 0 S +# For 1936-1941 Shanks gives May Mon>=9 and Oct Mon>=2; go with Whitman. +Rule StJohns 1936 1941 - May Sun>=8 0:00 1:00 D +Rule StJohns 1936 1941 - Oct Sun>=1 0:00 0 S +# Shanks gives 1942 May 11 - 1945 Sep 30; go with Whitman. +Rule StJohns 1942 only - Mar 1 0:00 1:00 D +Rule StJohns 1942 only - Dec 31 0:00 0 S +Rule StJohns 1943 only - May 30 0:00 1:00 D +Rule StJohns 1943 only - Sep 5 0:00 0 S +Rule StJohns 1944 only - Jul 10 0:00 1:00 D +Rule StJohns 1944 only - Sep 2 0:00 0 S +Rule StJohns 1945 only - Jan 1 0:00 1:00 D +Rule StJohns 1945 only - Oct 7 2:00 0 S +# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives +# Apr 30 - Sep 24; go with Shanks. +Rule StJohns 1946 1950 - May Sun>=8 2:00 1:00 D +Rule StJohns 1946 1950 - Oct Sun>=2 2:00 0 S +Rule StJohns 1951 1986 - Apr lastSun 2:00 1:00 D +Rule StJohns 1951 1959 - Sep lastSun 2:00 0 S +Rule StJohns 1960 max - Oct lastSun 2:00 0 S +Rule StJohns 1987 only - Apr Sun>=1 2:00 1:00 D +Rule StJohns 1988 only - Apr Sun>=1 2:00 2:00 D +Rule StJohns 1989 max - Apr Sun>=1 2:00 1:00 D +# St John's has an apostrophe, but Posix file names can't have apostrophes. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Johns -3:30:52 - LMT 1884 + -3:31 StJohns N%sT 1935 Mar 30 + -3:30 StJohns N%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Halifax 1902 only - Jun 15 0:00 0 S +Rule Halifax 1916 only - Apr 1 0:00 1:00 D +Rule Halifax 1916 only - Oct 1 0:00 0 S +Rule Halifax 1918 only - Apr 14 2:00 1:00 D +Rule Halifax 1918 only - Oct 31 2:00 0 S +Rule Halifax 1920 only - May 9 0:00 1:00 D +Rule Halifax 1920 only - Aug 29 0:00 0 S +Rule Halifax 1921 only - May 6 0:00 1:00 D +Rule Halifax 1921 1922 - Sep 5 0:00 0 S +Rule Halifax 1922 only - Apr 30 0:00 1:00 D +Rule Halifax 1923 1925 - May Sun>=1 0:00 1:00 D +Rule Halifax 1923 only - Sep 4 0:00 0 S +Rule Halifax 1924 only - Sep 15 0:00 0 S +Rule Halifax 1925 only - Sep 28 0:00 0 S +Rule Halifax 1926 only - May 16 0:00 1:00 D +Rule Halifax 1926 only - Sep 13 0:00 0 S +Rule Halifax 1927 only - May 1 0:00 1:00 D +Rule Halifax 1927 only - Sep 26 0:00 0 S +Rule Halifax 1928 1931 - May Sun>=8 0:00 1:00 D +Rule Halifax 1928 only - Sep 9 0:00 0 S +Rule Halifax 1929 only - Sep 3 0:00 0 S +Rule Halifax 1930 only - Sep 15 0:00 0 S +Rule Halifax 1931 1932 - Sep Mon>=24 0:00 0 S +Rule Halifax 1933 only - Apr 30 0:00 1:00 D +Rule Halifax 1933 only - Oct 2 0:00 0 S +Rule Halifax 1934 only - May 20 0:00 1:00 D +Rule Halifax 1934 only - Sep 16 0:00 0 S +Rule Halifax 1935 only - Jun 2 0:00 1:00 D +Rule Halifax 1935 only - Sep 30 0:00 0 S +Rule Halifax 1936 only - Jun 1 0:00 1:00 D +Rule Halifax 1936 only - Sep 14 0:00 0 S +Rule Halifax 1937 1938 - May Sun>=1 0:00 1:00 D +Rule Halifax 1937 1941 - Sep Mon>=24 0:00 0 S +Rule Halifax 1939 only - May 28 0:00 1:00 D +Rule Halifax 1940 1941 - May Sun>=1 0:00 1:00 D +Rule Halifax 1942 only - Feb 9 2:00 1:00 D +Rule Halifax 1945 1959 - Sep lastSun 2:00 0 S +Rule Halifax 1946 1959 - Apr lastSun 2:00 1:00 D +Rule Halifax 1962 1986 - Apr lastSun 2:00 1:00 D +Rule Halifax 1962 max - Oct lastSun 2:00 0 S +Rule Halifax 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Halifax -4:14:24 - LMT 1902 Jun 15 + -4:00 Halifax A%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mont 1884 only - Jan 1 0:00 0 S +Rule Mont 1917 only - Mar 25 2:00 1:00 D +Rule Mont 1917 only - Apr 24 0:00 0 S +Rule Mont 1918 only - Apr 14 2:00 1:00 D +Rule Mont 1918 only - Oct 31 2:00 0 S +Rule Mont 1919 only - Mar 31 2:30 1:00 D +Rule Mont 1919 only - Oct 25 2:30 0 S +Rule Mont 1920 only - May 2 2:30 1:00 D +Rule Mont 1920 only - Oct 3 2:30 0 S +Rule Mont 1921 only - May 1 2:00 1:00 D +Rule Mont 1921 only - Oct 2 2:30 0 S +Rule Mont 1922 only - Apr 30 2:00 1:00 D +Rule Mont 1922 only - Oct 1 2:30 0 S +Rule Mont 1924 only - May 17 2:00 1:00 D +Rule Mont 1924 1926 - Sep lastSun 2:30 0 S +Rule Mont 1925 1926 - May Sun>=1 2:00 1:00 D +Rule Mont 1927 only - May 1 0:00 1:00 D +Rule Mont 1927 1932 - Sep Sun>=25 0:00 0 S +Rule Mont 1928 1931 - Apr Sun>=25 0:00 1:00 D +Rule Mont 1932 only - May 1 0:00 1:00 D +Rule Mont 1933 1940 - Apr Sun>=24 0:00 1:00 D +Rule Mont 1933 only - Oct 1 0:00 0 S +Rule Mont 1934 1939 - Sep Sun>=24 0:00 0 S +Rule Mont 1945 1948 - Sep lastSun 2:00 0 S +Rule Mont 1946 1986 - Apr lastSun 2:00 1:00 D +Rule Mont 1949 1950 - Oct lastSun 2:00 0 S +Rule Mont 1951 1956 - Sep lastSun 2:00 0 S +Rule Mont 1957 max - Oct lastSun 2:00 0 S +Rule Mont 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montreal -4:54:16 - LMT 1884 + -5:00 Mont E%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Winn 1887 only - Jul 16 0:00 0 S +Rule Winn 1916 only - Apr 23 0:00 1:00 D +Rule Winn 1916 only - Sep 17 0:00 0 S +Rule Winn 1918 only - Apr 14 2:00 1:00 D +Rule Winn 1918 only - Oct 31 2:00 0 S +Rule Winn 1937 only - May 16 2:00 1:00 D +Rule Winn 1937 only - Sep 23 2:00 0 S +Rule Winn 1942 only - Feb 9 2:00 1:00 D +Rule Winn 1945 only - Sep lastSun 2:00 0 S +Rule Winn 1946 only - May 12 2:00 1:00 D +Rule Winn 1946 only - Oct 13 2:00 0 S +Rule Winn 1947 1949 - Apr lastSun 2:00 1:00 D +Rule Winn 1947 1958 - Sep lastSun 2:00 0 S +Rule Winn 1948 only - May 1 2:00 1:00 D +Rule Winn 1948 1960 - Apr lastSun 2:00 1:00 D +Rule Winn 1959 only - Oct lastSun 2:00 0 S +Rule Winn 1960 only - Sep lastSun 2:00 0 S +Rule Winn 1963 only - Apr lastSun 2:00 1:00 D +Rule Winn 1963 only - Sep lastSun 2:00 0 S +Rule Winn 1966 1986 - Apr lastSun 2:00 1:00 D +Rule Winn 1966 max - Sep lastSun 2:00 0 S +Rule Winn 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16 + -6:00 Winn C%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Regina 1905 only - Sep 1 0:00 0 S +Rule Regina 1918 only - Apr 14 2:00 1:00 D +Rule Regina 1918 only - Oct 31 2:00 0 S +Rule Regina 1930 1934 - May Sun>=1 0:00 1:00 D +Rule Regina 1930 1934 - Oct Sun>=1 0:00 0 S +Rule Regina 1937 1941 - Apr Sun>=8 0:00 1:00 D +Rule Regina 1937 only - Oct Sun>=8 0:00 0 S +Rule Regina 1938 only - Oct Sun>=1 0:00 0 S +Rule Regina 1939 1941 - Oct Sun>=8 0:00 0 S +Rule Regina 1942 only - Feb 9 2:00 1:00 D +Rule Regina 1945 only - Sep lastSun 2:00 0 S +Rule Regina 1946 only - Apr 14 2:00 1:00 D +Rule Regina 1946 only - Oct 13 2:00 0 S +Rule Regina 1947 1960 - Apr lastSun 2:00 1:00 D +Rule Regina 1947 1959 - Sep lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Regina -6:58:36 - LMT 1905 Sep + -7:00 Regina M%sT 1966 Apr 15 + -6:00 - CST + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Edm 1906 only - Sep 1 0:00 0 S +Rule Edm 1918 1919 - Apr Sun>=8 2:00 1:00 D +Rule Edm 1918 only - Oct 31 2:00 0 S +Rule Edm 1919 only - May 27 2:00 0 S +Rule Edm 1920 1923 - Apr lastSun 2:00 1:00 D +Rule Edm 1920 only - Oct lastSun 2:00 0 S +Rule Edm 1921 1923 - Sep lastSun 2:00 0 S +Rule Edm 1942 only - Feb 9 2:00 1:00 D +Rule Edm 1945 only - Sep lastSun 2:00 0 S +Rule Edm 1947 only - Apr lastSun 2:00 1:00 D +Rule Edm 1947 only - Sep lastSun 2:00 0 S +Rule Edm 1967 only - Apr lastSun 2:00 1:00 D +Rule Edm 1967 only - Oct lastSun 2:00 0 S +Rule Edm 1969 only - Apr lastSun 2:00 1:00 D +Rule Edm 1969 only - Oct lastSun 2:00 0 S +Rule Edm 1972 1986 - Apr lastSun 2:00 1:00 D +Rule Edm 1972 max - Oct lastSun 2:00 0 S +Rule Edm 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Edmonton -7:33:52 - LMT 1906 Sep + -7:00 Edm M%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Vanc 1884 only - Jan 1 0:00 0 S +Rule Vanc 1918 only - Apr 14 2:00 1:00 D +Rule Vanc 1918 only - Oct 31 2:00 0 S +Rule Vanc 1942 only - Feb 9 2:00 1:00 D +Rule Vanc 1945 only - Sep 30 2:00 0 S +Rule Vanc 1946 1986 - Apr lastSun 2:00 1:00 D +Rule Vanc 1946 only - Oct 13 2:00 0 S +Rule Vanc 1947 1961 - Sep lastSun 2:00 0 S +Rule Vanc 1962 max - Oct lastSun 2:00 0 S +Rule Vanc 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Vancouver -8:12:28 - LMT 1884 + -8:00 Vanc P%sT + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Yukon 1900 only - Jan 1 0:00 0 S +Rule Yukon 1918 only - Apr 14 2:00 1:00 D +Rule Yukon 1918 only - Oct 27 2:00 0 S +Rule Yukon 1919 only - May 25 2:00 1:00 D +Rule Yukon 1919 only - Nov 1 0:00 0 S +Rule Yukon 1942 only - Feb 9 2:00 1:00 D +Rule Yukon 1965 only - Apr 25 0:00 1:00 D +Rule Yukon 1965 only - Oct 31 2:00 0 S +Rule Yukon 1980 1986 - Apr lastSun 2:00 1:00 D +Rule Yukon 1980 max - Oct lastSun 2:00 0 S +Rule Yukon 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Whitehorse -9:00:12 - LMT 1900 Aug 20 + -9:00 Yukon Y%sT 1966 Jul + -8:00 Yukon P%sT +# Parts of Yukon (e.g. Dawson) didn't switch to -8:00 until 1973 Oct 28. + +############################################################################### + +# Mexico + +# From Guy Harris: +# Rules are from the Official Airline Guide, Worldwide Edition, for 1987. +# Rules prior to 1987 are unknown. +# The comments in the OAG say "Only Ensenada, Mexicale, San Felipe and Tijuana +# observe DST." This is presumably Baja California Norte, above 28th parallel, +# as listed there; Mexico/BajaSur is for "Baja California Sur and N. Pacific +# Coast (States of Sinaloa and Sonora)." + +# From Bob Devine (January 28, 1988): +# The Federal District (where Mexico City is) has observed [DST] several +# times but not recently. +# +# I don't where to drawn the line in the North Baja area. 28th latitude +# sounds good -- but it may be higher (how far [d]o radio stations from +# San Diego affect culture?). +# +# The dates of DST probably go back to 1981. The rules are the same as +# US's. This is going to be a headache for US presidential electi[o]n years! + +# From Arthur David Olson (February 13, 1988) +# Since the 1981 starting date is only "probable," we'll keep the 1987 +# starting date below. + +# From U. S. Naval Observatory (January 19, 1989): +# MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +# MEXICO BAJA CAL N N. PACIFIC COAST (STATES +# MEXICO BAJA CAL N OF SINALOA AND SONORA) +# MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +# MEXICO BAJA CAL N - OCT 29 +# MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +# MEXICO BAJA CAL N - 0CT 29 +# MEXICO 6 H BEHIND UTC STATES OF DURANGO, +# MEXICO COAHUILA, NUEVO LEON, +# MEXICO TAMAULIPAS +# MEXICO 5 H BEHIND UTC STATES OF DURANGO, +# MEXICO COAHUILA, NUEVO LEON, +# MEXICO TAMAULIPAS APR 3 - OCT 29 +# MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +# MEXICO CAMPECHE, QUINTANA ROO AND +# MEXICO YUCATAN + +# From Arthur David Olson (January 21, 1989): +# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989. Ahem. +# USNO claims there should be four Mexican zones rather than three: +# a zone that's GMT-8 with DST; a zone that's always GMT-7; +# a zone that's GMT-6 with DST; and a zone that's always GMT-6. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Shanks also says there are four zones, but disagrees about the fourth. +# Instead of GMT-6 with DST, he says there's GMT-8 without DST. + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Mexico 1922 only - Jan 1 0:00 0 S +Rule Mexico 1939 only - Feb 5 0:00 1:00 D +Rule Mexico 1939 only - Jun 25 0:00 0 S +Rule Mexico 1940 only - Dec 9 0:00 1:00 D +Rule Mexico 1941 only - Apr 1 0:00 0 S +Rule Mexico 1943 only - Dec 16 0:00 1:00 D +Rule Mexico 1944 only - May 1 0:00 0 S +Rule Mexico 1950 only - Feb 12 0:00 1:00 D +Rule Mexico 1950 only - Jul 30 0:00 0 S +Rule BajaN 1950 1966 - Apr lastSun 2:00 1:00 D +Rule BajaN 1950 1961 - Sep lastSun 2:00 0 S +Rule BajaN 1961 1966 - Oct lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24 + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 - MST 1931 May 1 23:00 + -6:00 - CST 1931 Oct + -7:00 - MST 1932 Mar 30 23:00 + -6:00 Mexico C%sT +Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20 + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 - MST 1931 May 1 23:00 + -6:00 - CST 1931 Oct + -7:00 - MST 1932 Mar 30 23:00 + -6:00 - CST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 - PST 1970 + -7:00 - MST +Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56 + -8:00 - PST 1927 Jun 10 23:00 + -7:00 - MST 1930 Nov 16 + -8:00 - PST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 BajaN P%sT 1967 Apr lastSun 2:00 + -8:00 US P%sT +Zone America/Ensenada -7:46:28 - LMT 1922 Jan 1 0:13:32 + -8:00 - PST 1927 Jun 10 23:00 + -7:00 - MST 1930 Nov 16 + -8:00 - PST 1942 Apr + -7:00 - MST 1949 Jan 14 + -8:00 - PST +# +# Revillagigedo Is +# no information + +############################################################################### + +# Anguilla +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Anguilla -4:12:16 - LMT 1912 Mar 2 + -4:00 - AST + +# Antigua and Barbuda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Antigua -4:07:12 - LMT 1912 Mar 2 + -5:00 - EST 1951 + -4:00 - AST + +# Bahamas +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Bahamas 1912 only - Mar 2 0:00 0 S +Rule Bahamas 1964 max - Oct lastSun 2:00 0 S +Rule Bahamas 1964 1986 - Apr lastSun 2:00 1:00 D +Rule Bahamas 1987 max - Apr Sun>=1 2:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Nassau -5:09:24 - LMT 1912 Mar 2 + -5:00 Bahamas E%sT + +# Barbados +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Barb 1932 only - Jan 1 0:00 0 S +Rule Barb 1977 only - Jun 12 2:00 1:00 D +Rule Barb 1977 1978 - Oct Sun>=1 2:00 0 S +Rule Barb 1978 1980 - Apr Sun>=15 2:00 1:00 D +Rule Barb 1979 only - Sep 30 2:00 0 S +Rule Barb 1980 only - Sep 25 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Barbados -3:58:28 - LMT 1924 # Bridgetown + -3:58 - BMT 1932 # Bridgetown Mean Time + -4:00 Barb A%sT + +# Belize +# Whitman entirely disagrees with Shanks; go with Shanks. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Belize 1912 only - Apr 1 0:00 0 S +Rule Belize 1918 1942 - Oct Sun>=2 0:00 0:30 HD +Rule Belize 1919 1943 - Feb Sun>=9 0:00 0 S +Rule Belize 1973 only - Dec 5 0:00 1:00 D +Rule Belize 1974 only - Feb 9 0:00 0 S +Rule Belize 1982 only - Dec 18 0:00 1:00 D +Rule Belize 1983 only - Feb 12 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Belize -5:52:48 - LMT 1912 Apr + -6:00 Belize C%sT + +# Bermuda +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Bermuda -4:19:04 - LMT 1930 Jan 1 2:00 # Hamilton + -4:00 - AST 1974 Apr 28 2:00 + -4:00 Bahamas A%sT + +# Cayman Is +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Cayman -5:25:32 - LMT 1890 # Georgetown + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST + +# Clipperton +# no information + +# Costa Rica +# Shanks gives some very odd dates for 1991, and stops there. +# For now, we won't guess further. +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule CR 1921 only - Jan 15 0:00 0 S +Rule CR 1979 1980 - Feb lastSun 0:00 1:00 D +Rule CR 1979 1980 - Jun Sun>=1 0:00 0 S +Rule CR 1991 only - Jan 19 0:00 1:00 D +Rule CR 1991 only - Jul 1 0:00 0 S +# There are too many San Joses elsewhere, so we'll use `Costa Rica'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose + -5:36 - SJMT 1921 Jan 15 # San Jose Mean Time + -6:00 CR C%sT +# Coco +# no information; probably like America/Costa_Rica + +# Cuba + +# From Bob Devine (January 28, 1988): +# . . .DST is from 2nd Sunday in May to 2nd Sunday in October since 1981. +# Change at midnight. In 1979 & 1980, started at 3rd Sunday in March +# (I think). + +# From U. S. Naval Observatory (January 19, 1989): +# CUBA 5 H BEHIND UTC +# CUBA 4 H BEHIND UTC MAR 20 - OCT 8 + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Cuba 1925 only - Jul 19 12:00 0 S +Rule Cuba 1928 only - Jun 10 0:00 1:00 D +Rule Cuba 1928 only - Oct 10 0:00 0 S +Rule Cuba 1940 1942 - Jun Sun>=1 0:00 1:00 D +Rule Cuba 1940 1942 - Sep Sun>=1 0:00 0 S +Rule Cuba 1945 1946 - Jun Sun>=1 0:00 1:00 D +Rule Cuba 1945 1946 - Sep Sun>=1 0:00 0 S +Rule Cuba 1965 only - Jun 1 0:00 1:00 D +Rule Cuba 1965 only - Sep 30 0:00 0 S +Rule Cuba 1966 only - May 29 0:00 1:00 D +Rule Cuba 1966 only - Oct 2 0:00 0 S +Rule Cuba 1967 only - Apr 8 0:00 1:00 D +Rule Cuba 1967 1968 - Sep Sun>=8 0:00 0 S +Rule Cuba 1968 only - Apr 14 0:00 1:00 D +Rule Cuba 1969 1977 - Apr lastSun 0:00 1:00 D +Rule Cuba 1969 1971 - Oct lastSun 0:00 0 S +Rule Cuba 1972 1974 - Oct 8 0:00 0 S +Rule Cuba 1975 1977 - Oct lastSun 0:00 0 S +Rule Cuba 1978 only - May 7 0:00 1:00 D +Rule Cuba 1978 1980 - Oct Sun>=8 0:00 0 S +Rule Cuba 1979 1980 - Mar Sun>=15 0:00 1:00 D +Rule Cuba 1981 1985 - May Sun>=5 0:00 1:00 D +Rule Cuba 1981 max - Oct Sun>=8 0:00 0 S +Rule Cuba 1986 1989 - Mar Sun>=14 0:00 1:00 D +Rule Cuba 1990 only - Apr 1 0:00 1:00 D +Rule Cuba 1991 max - Mar Sun>=14 0:00 1:00 D + +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Havana -5:29:28 - LMT 1890 + -5:30 - HMT 1925 Jul 19 12:00 # Havana MT + -5:00 Cuba C%sT + +# Dominica +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Dominica -4:05:36 - LMT 1911 Jul 1 0:01 # Roseau + -4:00 - AST + +# Dominican Republic +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule DR 1933 only - Apr 1 12:00 0 S +Rule DR 1966 only - Oct 30 0:00 1:00 D +Rule DR 1967 only - Feb 28 0:00 0 S +Rule DR 1969 1973 - Oct lastSun 0:00 0:30 HD +Rule DR 1970 only - Feb 21 0:00 0 S +Rule DR 1971 only - Jan 20 0:00 0 S +Rule DR 1972 1974 - Jan 21 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Santo_Domingo -4:39:36 - LMT 1890 + -4:40 - SDMT 1933 Apr 1 12:00 # S. Dom. MT + -5:00 DR E%sT 1974 Oct 27 + -4:00 - AST + +# El Salvador +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Salv 1921 only - Jan 1 0:00 0 S +Rule Salv 1987 1988 - May Sun>=1 0:00 1:00 D +Rule Salv 1987 1988 - Sep lastSun 0:00 0 S +# There are too many San Salvadors elsewhere, so we'll use `El Salvador'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/El_Salvador -5:56:48 - LMT 1921 # San Salvador + -6:00 Salv C%sT + +# Grenada +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Grenada -4:07:00 - LMT 1911 Jul + -4:00 - AST + +# Guadeloupe +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guadeloupe -4:06:08 - LMT 1911 Jun 8 # Pointe a Pitre + -4:00 - AST + +# Guatemala +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Guat 1918 only - Oct 5 0:00 0 S +Rule Guat 1973 only - Nov 25 0:00 1:00 D +Rule Guat 1974 only - Feb 24 0:00 0 S +Rule Guat 1983 only - May 21 0:00 1:00 D +Rule Guat 1983 only - Sep 22 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5 + -6:00 Guat C%sT + +# Haiti +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Haiti 1917 only - Jan 24 12:00 0 S +Rule Haiti 1983 only - May 8 0:00 1:00 D +Rule Haiti 1984 1987 - Apr lastSun 0:00 1:00 D +Rule Haiti 1983 1987 - Oct lastSun 0:00 0 S +Rule Haiti 1988 max - Apr Sun>=1 2:00 1:00 D +Rule Haiti 1988 max - Oct lastSun 2:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Port-au-Prince -4:49:20 - LMT 1890 + -4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT + -5:00 Haiti E%sT + +# Honduras +# Shanks says 1921 Jan 1; go with Whitman's more precise Apr 1. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Tegucigalpa -5:48:52 - LMT 1921 Apr + -6:00 Salv C%sT + +# Jamaica + +# From Bob Devine (January 28, 1988): +# Follows US rules. + +# From U. S. Naval Observatory (January 19, 1989): +# JAMAICA 5 H BEHIND UTC + +# From Shanks (1991): +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Jamaica -5:07:12 - LMT 1890 # Kingston + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST 1974 Jan 6 2:00 + -5:00 US E%sT + +# Martinique +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Martinique -4:04:20 - LMT 1890 # Fort-de-France + -4:04 - FFMT 1911 May # Fort-de-France MT + -4:00 - AST 1980 Apr 6 + -4:00 1:00 ADT 1980 Sep 28 + -4:00 - AST + +# Montserrat +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montserrat -4:08:52 - LMT 1911 Jul 1 0:01 # Plymouth + -4:00 - AST + +# Nicaragua +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Nic 1975 only - Feb 16 0:00 0 S +Rule Nic 1979 1980 - Mar Sun>=16 0:00 1:00 D +Rule Nic 1979 1980 - Jun Mon>=23 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Managua -5:45:08 - LMT 1890 + -5:45 - MMT 1934 Jun 23 # Managua Mean Time + -6:00 - CST 1973 May + -5:00 - EST 1975 Feb 16 + -6:00 Nic C%sT + +# Panama +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Panama -5:18:08 - LMT 1890 + -5:20 - PMT 1908 Apr 22 # Panama Mean Time + -5:00 - EST + +# Puerto Rico +# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Puerto_Rico -4:24:28 - LMT 1899 Mar 28 12:00 # San Juan + -4:00 - AST 1942 May 3 + -4:00 1:00 ADT 1945 Sep 30 2:00 + -4:00 - AST + +# St Kitts-Nevis +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Kitts -4:10:52 - LMT 1912 Mar 2 # Basseterre + -4:00 - AST + +# St Lucia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Lucia -4:04:00 - LMT 1890 # Castries + -4:04 - CMT 1912 # Castries Mean Time + -4:00 - AST + +# St Pierre and Miquelon +# There are too many St Pierres elsewhere, so we'll use `Miquelon'. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre + -4:00 - AST 1980 May + -3:00 Mont SP%sT + +# St Vincent and the Grenadines +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/St_Vincent -4:04:56 - LMT 1890 # Kingstown + -4:05 - KMT 1912 # Kingstown Mean Time + -4:00 - AST + +# Turks and Caicos +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Grand_Turk -4:44:32 - LMT 1890 + -5:07 - KMT 1912 Feb # Kingston Mean Time + -5:00 - EST 1979 Apr 29 2:00 + -5:00 US E%sT + +# Virgin Is (British and US) +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Virgin -4:19:44 - LMT 1911 Jul # Charlotte Amalie + -4:00 - AST diff --git a/time/offtime.c b/time/offtime.c new file mode 100644 index 0000000000..a392a47e89 --- /dev/null +++ b/time/offtime.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <time.h> + + +/* Defined in mktime.c. */ +extern CONST unsigned short int __mon_lengths[2][12]; + +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (SECS_PER_HOUR * 24) + +/* Returns the `struct tm' representation of *T, + offset OFFSET seconds east of UCT. */ +struct tm * +DEFUN(__offtime, (t, offset), CONST time_t *t AND long int offset) +{ + static struct tm tbuf; + register long int days, rem; + register int y; + register CONST unsigned short int *ip; + + if (t == NULL) + return NULL; + + days = *t / SECS_PER_DAY; + rem = *t % SECS_PER_DAY; + rem += offset; + while (rem < 0) + { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) + { + rem -= SECS_PER_DAY; + ++days; + } + tbuf.tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + tbuf.tm_min = rem / 60; + tbuf.tm_sec = rem % 60; + /* January 1, 1970 was a Thursday. */ + tbuf.tm_wday = (4 + days) % 7; + if (tbuf.tm_wday < 0) + tbuf.tm_wday += 7; + y = 1970; + while (days >= (rem = __isleap(y) ? 366 : 365)) + { + ++y; + days -= rem; + } + while (days < 0) + { + --y; + days += __isleap(y) ? 366 : 365; + } + tbuf.tm_year = y - 1900; + tbuf.tm_yday = days; + ip = __mon_lengths[__isleap(y)]; + for (y = 0; days >= ip[y]; ++y) + days -= ip[y]; + tbuf.tm_mon = y; + tbuf.tm_mday = days + 1; + tbuf.tm_isdst = -1; + + return &tbuf; +} diff --git a/time/pacificnew b/time/pacificnew new file mode 100644 index 0000000000..cd1477cc71 --- /dev/null +++ b/time/pacificnew @@ -0,0 +1,26 @@ +# @(#)pacificnew 7.6 + +# From Arthur David Olson (April 5, 1989): +# On April 5, 1989, the U. S. House of Representatives passed (238-154) a bill +# establishing "Pacific Presidential Election Time"; it was not acted on +# by the Senate or signed into law by the President. +# You might want to change the "PE" (Presidential Election) below to +# "Q" (Quadrennial) to maintain three-character zone abbreviations. +# If you're really conservative, you might want to change it to "D". +# Avoid "L" (Leap Year), which won't be true in 2100. + +# If Presidential Election Time is ever established, replace "XXXX" below +# with the year the law takes effect and uncomment the "##" lines. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +## Rule Twilite XXXX max - Apr Sun>=1 2:00 1:00 D +## Rule Twilite XXXX max uspres Oct lastSun 2:00 1:00 PE +## Rule Twilite XXXX max uspres Nov Sun>=7 2:00 0 S +## Rule Twilite XXXX max nonpres Oct lastSun 2:00 0 S + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +## Zone US/Pacific-PET -8:00 US P%sT XXXX +## -8:00 Twilite P%sT + +# For now... +Link America/Los_Angeles US/Pacific-New ## diff --git a/time/private.h b/time/private.h new file mode 100644 index 0000000000..8852b8337b --- /dev/null +++ b/time/private.h @@ -0,0 +1,210 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +static char privatehid[] = "@(#)private.h 7.10"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** const +*/ + +#ifndef const +#ifndef __STDC__ +#define const +#endif /* !defined __STDC__ */ +#endif /* !defined const */ + +/* +** void +*/ + +#ifndef void +#ifndef __STDC__ +#ifndef vax +#ifndef sun +#define void char +#endif /* !defined sun */ +#endif /* !defined vax */ +#endif /* !defined __STDC__ */ +#endif /* !defined void */ + +/* +** INITIALIZE +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* +** P((args)) +*/ + +#ifndef P +#ifdef __STDC__ +#define P(x) x +#endif /* defined __STDC__ */ +#ifndef __STDC__ +#define P(x) () +#endif /* !defined __STDC__ */ +#endif /* !defined P */ + +/* +** genericptr_T +*/ + +#ifdef __STDC__ +typedef void * genericptr_T; +#endif /* defined __STDC__ */ +#ifndef __STDC__ +typedef char * genericptr_T; +#endif /* !defined __STDC__ */ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "ctype.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT */ +#ifndef _TIME_ +#include "time.h" +#endif /* !defined _TIME_ */ + +#ifndef remove +extern int unlink P((const char * filename)); +#define remove unlink +#endif /* !defined remove */ + +#ifndef FILENAME_MAX + +#ifndef MAXPATHLEN +#ifdef unix +#include "sys/param.h" +#endif /* defined unix */ +#endif /* !defined MAXPATHLEN */ + +#ifdef MAXPATHLEN +#define FILENAME_MAX MAXPATHLEN +#endif /* defined MAXPATHLEN */ +#ifndef MAXPATHLEN +#define FILENAME_MAX 1024 /* Pure guesswork */ +#endif /* !defined MAXPATHLEN */ + +#endif /* !defined FILENAME_MAX */ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* !defined EXIT_SUCCESS */ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* !defined EXIT_FAILURE */ + +#ifdef __STDC__ + +#define alloc_size_T size_t +#define qsort_size_T size_t +#define fwrite_size_T size_t + +#endif /* defined __STDC__ */ +#ifndef __STDC__ + +#ifndef alloc_size_T +#define alloc_size_T unsigned +#endif /* !defined alloc_size_T */ + +#ifndef qsort_size_T +#ifdef USG +#define qsort_size_T unsigned +#endif /* defined USG */ +#ifndef USG +#define qsort_size_T int +#endif /* !defined USG */ +#endif /* !defined qsort_size_T */ + +#ifndef fwrite_size_T +#define fwrite_size_T int +#endif /* !defined fwrite_size_T */ + +#ifndef USG +extern char * sprintf P((char * buf, const char * format, ...)); +#endif /* !defined USG */ + +#endif /* !defined __STDC__ */ + +/* +** Ensure that these are declared--redundantly declaring them shouldn't hurt. +*/ + +extern char * getenv P((const char * name)); +extern genericptr_T malloc P((alloc_size_T size)); +extern genericptr_T calloc P((alloc_size_T nelem, alloc_size_T elsize)); +extern genericptr_T realloc P((genericptr_T oldptr, alloc_size_T newsize)); + +#ifdef USG +extern void exit P((int s)); +extern void qsort P((genericptr_T base, qsort_size_T nelem, + qsort_size_T elsize, int (*comp)())); +extern void perror P((const char * string)); +extern void free P((char * buf)); +#endif /* defined USG */ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit; +** add one for integer division truncation; +** add one more for a minus sign. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +#ifndef LOCALE_HOME +#define LOCALE_HOME "/usr/lib/locale" +#endif /* !defined LOCALE_HOME */ + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +** VAX is a trademark of Digital Equipment Corporation. +*/ + +#endif /* !defined PRIVATE_H */ diff --git a/time/scheck.c b/time/scheck.c new file mode 100644 index 0000000000..404c6b2111 --- /dev/null +++ b/time/scheck.c @@ -0,0 +1,62 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)scheck.c 8.12"; +#endif /* !defined lint */ +#endif /* !defined NOID */ + +/*LINTLIBRARY*/ + +#include "private.h" + +extern char * imalloc P((int n)); +extern void ifree P((char * p)); + +char * +scheck(string, format) +const char * const string; +char * const format; +{ + register char * fbuf; + register const char * fp; + register char * tp; + register int c; + register char * result; + char dummy; + static char nada; + + result = &nada; + if (string == NULL || format == NULL) + return result; + fbuf = imalloc((int) (2 * strlen(format) + 4)); + if (fbuf == NULL) + return result; + fp = format; + tp = fbuf; + while ((*tp++ = c = *fp++) != '\0') { + if (c != '%') + continue; + if (*fp == '%') { + *tp++ = *fp++; + continue; + } + *tp++ = '*'; + if (*fp == '*') + ++fp; + while (isascii(*fp) && isdigit(*fp)) + *tp++ = *fp++; + if (*fp == 'l' || *fp == 'h') + *tp++ = *fp++; + else if (*fp == '[') + do *tp++ = *fp++; + while (*fp != '\0' && *fp != ']'); + if ((*tp++ = *fp++) == '\0') + break; + } + *(tp - 1) = '%'; + *tp++ = 'c'; + *tp = '\0'; + if (sscanf(string, fbuf, &dummy) != 1) + result = (char *) format; + ifree(fbuf); + return result; +} diff --git a/time/solar87 b/time/solar87 new file mode 100644 index 0000000000..a4e2f39df9 --- /dev/null +++ b/time/solar87 @@ -0,0 +1,386 @@ +# @(#)solar87 7.2 + +# So much for footnotes about Saudi Arabia. +# Apparent noon times below are for Riyadh; your mileage will vary. +# Times were computed using formulas in the U.S. Naval Observatory's +# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of +# [plus or minus two] seconds during the current year." +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol87 1987 only - Jan 1 12:03:20s -0:03:20 - +Rule sol87 1987 only - Jan 2 12:03:50s -0:03:50 - +Rule sol87 1987 only - Jan 3 12:04:15s -0:04:15 - +Rule sol87 1987 only - Jan 4 12:04:45s -0:04:45 - +Rule sol87 1987 only - Jan 5 12:05:10s -0:05:10 - +Rule sol87 1987 only - Jan 6 12:05:40s -0:05:40 - +Rule sol87 1987 only - Jan 7 12:06:05s -0:06:05 - +Rule sol87 1987 only - Jan 8 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jan 9 12:06:55s -0:06:55 - +Rule sol87 1987 only - Jan 10 12:07:20s -0:07:20 - +Rule sol87 1987 only - Jan 11 12:07:45s -0:07:45 - +Rule sol87 1987 only - Jan 12 12:08:10s -0:08:10 - +Rule sol87 1987 only - Jan 13 12:08:30s -0:08:30 - +Rule sol87 1987 only - Jan 14 12:08:55s -0:08:55 - +Rule sol87 1987 only - Jan 15 12:09:15s -0:09:15 - +Rule sol87 1987 only - Jan 16 12:09:35s -0:09:35 - +Rule sol87 1987 only - Jan 17 12:09:55s -0:09:55 - +Rule sol87 1987 only - Jan 18 12:10:15s -0:10:15 - +Rule sol87 1987 only - Jan 19 12:10:35s -0:10:35 - +Rule sol87 1987 only - Jan 20 12:10:55s -0:10:55 - +Rule sol87 1987 only - Jan 21 12:11:10s -0:11:10 - +Rule sol87 1987 only - Jan 22 12:11:30s -0:11:30 - +Rule sol87 1987 only - Jan 23 12:11:45s -0:11:45 - +Rule sol87 1987 only - Jan 24 12:12:00s -0:12:00 - +Rule sol87 1987 only - Jan 25 12:12:15s -0:12:15 - +Rule sol87 1987 only - Jan 26 12:12:30s -0:12:30 - +Rule sol87 1987 only - Jan 27 12:12:40s -0:12:40 - +Rule sol87 1987 only - Jan 28 12:12:55s -0:12:55 - +Rule sol87 1987 only - Jan 29 12:13:05s -0:13:05 - +Rule sol87 1987 only - Jan 30 12:13:15s -0:13:15 - +Rule sol87 1987 only - Jan 31 12:13:25s -0:13:25 - +Rule sol87 1987 only - Feb 1 12:13:35s -0:13:35 - +Rule sol87 1987 only - Feb 2 12:13:40s -0:13:40 - +Rule sol87 1987 only - Feb 3 12:13:50s -0:13:50 - +Rule sol87 1987 only - Feb 4 12:13:55s -0:13:55 - +Rule sol87 1987 only - Feb 5 12:14:00s -0:14:00 - +Rule sol87 1987 only - Feb 6 12:14:05s -0:14:05 - +Rule sol87 1987 only - Feb 7 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 8 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 9 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 10 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 11 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 12 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 13 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 14 12:14:15s -0:14:15 - +Rule sol87 1987 only - Feb 15 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 16 12:14:10s -0:14:10 - +Rule sol87 1987 only - Feb 17 12:14:05s -0:14:05 - +Rule sol87 1987 only - Feb 18 12:14:00s -0:14:00 - +Rule sol87 1987 only - Feb 19 12:13:55s -0:13:55 - +Rule sol87 1987 only - Feb 20 12:13:50s -0:13:50 - +Rule sol87 1987 only - Feb 21 12:13:45s -0:13:45 - +Rule sol87 1987 only - Feb 22 12:13:35s -0:13:35 - +Rule sol87 1987 only - Feb 23 12:13:30s -0:13:30 - +Rule sol87 1987 only - Feb 24 12:13:20s -0:13:20 - +Rule sol87 1987 only - Feb 25 12:13:10s -0:13:10 - +Rule sol87 1987 only - Feb 26 12:13:00s -0:13:00 - +Rule sol87 1987 only - Feb 27 12:12:50s -0:12:50 - +Rule sol87 1987 only - Feb 28 12:12:40s -0:12:40 - +Rule sol87 1987 only - Mar 1 12:12:30s -0:12:30 - +Rule sol87 1987 only - Mar 2 12:12:20s -0:12:20 - +Rule sol87 1987 only - Mar 3 12:12:05s -0:12:05 - +Rule sol87 1987 only - Mar 4 12:11:55s -0:11:55 - +Rule sol87 1987 only - Mar 5 12:11:40s -0:11:40 - +Rule sol87 1987 only - Mar 6 12:11:25s -0:11:25 - +Rule sol87 1987 only - Mar 7 12:11:15s -0:11:15 - +Rule sol87 1987 only - Mar 8 12:11:00s -0:11:00 - +Rule sol87 1987 only - Mar 9 12:10:45s -0:10:45 - +Rule sol87 1987 only - Mar 10 12:10:30s -0:10:30 - +Rule sol87 1987 only - Mar 11 12:10:15s -0:10:15 - +Rule sol87 1987 only - Mar 12 12:09:55s -0:09:55 - +Rule sol87 1987 only - Mar 13 12:09:40s -0:09:40 - +Rule sol87 1987 only - Mar 14 12:09:25s -0:09:25 - +Rule sol87 1987 only - Mar 15 12:09:10s -0:09:10 - +Rule sol87 1987 only - Mar 16 12:08:50s -0:08:50 - +Rule sol87 1987 only - Mar 17 12:08:35s -0:08:35 - +Rule sol87 1987 only - Mar 18 12:08:15s -0:08:15 - +Rule sol87 1987 only - Mar 19 12:08:00s -0:08:00 - +Rule sol87 1987 only - Mar 20 12:07:40s -0:07:40 - +Rule sol87 1987 only - Mar 21 12:07:25s -0:07:25 - +Rule sol87 1987 only - Mar 22 12:07:05s -0:07:05 - +Rule sol87 1987 only - Mar 23 12:06:50s -0:06:50 - +Rule sol87 1987 only - Mar 24 12:06:30s -0:06:30 - +Rule sol87 1987 only - Mar 25 12:06:10s -0:06:10 - +Rule sol87 1987 only - Mar 26 12:05:55s -0:05:55 - +Rule sol87 1987 only - Mar 27 12:05:35s -0:05:35 - +Rule sol87 1987 only - Mar 28 12:05:15s -0:05:15 - +Rule sol87 1987 only - Mar 29 12:05:00s -0:05:00 - +Rule sol87 1987 only - Mar 30 12:04:40s -0:04:40 - +Rule sol87 1987 only - Mar 31 12:04:25s -0:04:25 - +Rule sol87 1987 only - Apr 1 12:04:05s -0:04:05 - +Rule sol87 1987 only - Apr 2 12:03:45s -0:03:45 - +Rule sol87 1987 only - Apr 3 12:03:30s -0:03:30 - +Rule sol87 1987 only - Apr 4 12:03:10s -0:03:10 - +Rule sol87 1987 only - Apr 5 12:02:55s -0:02:55 - +Rule sol87 1987 only - Apr 6 12:02:35s -0:02:35 - +Rule sol87 1987 only - Apr 7 12:02:20s -0:02:20 - +Rule sol87 1987 only - Apr 8 12:02:05s -0:02:05 - +Rule sol87 1987 only - Apr 9 12:01:45s -0:01:45 - +Rule sol87 1987 only - Apr 10 12:01:30s -0:01:30 - +Rule sol87 1987 only - Apr 11 12:01:15s -0:01:15 - +Rule sol87 1987 only - Apr 12 12:00:55s -0:00:55 - +Rule sol87 1987 only - Apr 13 12:00:40s -0:00:40 - +Rule sol87 1987 only - Apr 14 12:00:25s -0:00:25 - +Rule sol87 1987 only - Apr 15 12:00:10s -0:00:10 - +Rule sol87 1987 only - Apr 16 11:59:55s 0:00:05 - +Rule sol87 1987 only - Apr 17 11:59:45s 0:00:15 - +Rule sol87 1987 only - Apr 18 11:59:30s 0:00:30 - +Rule sol87 1987 only - Apr 19 11:59:15s 0:00:45 - +Rule sol87 1987 only - Apr 20 11:59:05s 0:00:55 - +Rule sol87 1987 only - Apr 21 11:58:50s 0:01:10 - +Rule sol87 1987 only - Apr 22 11:58:40s 0:01:20 - +Rule sol87 1987 only - Apr 23 11:58:25s 0:01:35 - +Rule sol87 1987 only - Apr 24 11:58:15s 0:01:45 - +Rule sol87 1987 only - Apr 25 11:58:05s 0:01:55 - +Rule sol87 1987 only - Apr 26 11:57:55s 0:02:05 - +Rule sol87 1987 only - Apr 27 11:57:45s 0:02:15 - +Rule sol87 1987 only - Apr 28 11:57:35s 0:02:25 - +Rule sol87 1987 only - Apr 29 11:57:25s 0:02:35 - +Rule sol87 1987 only - Apr 30 11:57:15s 0:02:45 - +Rule sol87 1987 only - May 1 11:57:10s 0:02:50 - +Rule sol87 1987 only - May 2 11:57:00s 0:03:00 - +Rule sol87 1987 only - May 3 11:56:55s 0:03:05 - +Rule sol87 1987 only - May 4 11:56:50s 0:03:10 - +Rule sol87 1987 only - May 5 11:56:45s 0:03:15 - +Rule sol87 1987 only - May 6 11:56:40s 0:03:20 - +Rule sol87 1987 only - May 7 11:56:35s 0:03:25 - +Rule sol87 1987 only - May 8 11:56:30s 0:03:30 - +Rule sol87 1987 only - May 9 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 10 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 11 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 12 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 13 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 14 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 15 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 16 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 17 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 18 11:56:20s 0:03:40 - +Rule sol87 1987 only - May 19 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 20 11:56:25s 0:03:35 - +Rule sol87 1987 only - May 21 11:56:30s 0:03:30 - +Rule sol87 1987 only - May 22 11:56:35s 0:03:25 - +Rule sol87 1987 only - May 23 11:56:40s 0:03:20 - +Rule sol87 1987 only - May 24 11:56:45s 0:03:15 - +Rule sol87 1987 only - May 25 11:56:50s 0:03:10 - +Rule sol87 1987 only - May 26 11:56:55s 0:03:05 - +Rule sol87 1987 only - May 27 11:57:00s 0:03:00 - +Rule sol87 1987 only - May 28 11:57:10s 0:02:50 - +Rule sol87 1987 only - May 29 11:57:15s 0:02:45 - +Rule sol87 1987 only - May 30 11:57:25s 0:02:35 - +Rule sol87 1987 only - May 31 11:57:30s 0:02:30 - +Rule sol87 1987 only - Jun 1 11:57:40s 0:02:20 - +Rule sol87 1987 only - Jun 2 11:57:50s 0:02:10 - +Rule sol87 1987 only - Jun 3 11:58:00s 0:02:00 - +Rule sol87 1987 only - Jun 4 11:58:10s 0:01:50 - +Rule sol87 1987 only - Jun 5 11:58:20s 0:01:40 - +Rule sol87 1987 only - Jun 6 11:58:30s 0:01:30 - +Rule sol87 1987 only - Jun 7 11:58:40s 0:01:20 - +Rule sol87 1987 only - Jun 8 11:58:50s 0:01:10 - +Rule sol87 1987 only - Jun 9 11:59:05s 0:00:55 - +Rule sol87 1987 only - Jun 10 11:59:15s 0:00:45 - +Rule sol87 1987 only - Jun 11 11:59:30s 0:00:30 - +Rule sol87 1987 only - Jun 12 11:59:40s 0:00:20 - +Rule sol87 1987 only - Jun 13 11:59:50s 0:00:10 - +Rule sol87 1987 only - Jun 14 12:00:05s -0:00:05 - +Rule sol87 1987 only - Jun 15 12:00:15s -0:00:15 - +Rule sol87 1987 only - Jun 16 12:00:30s -0:00:30 - +Rule sol87 1987 only - Jun 17 12:00:45s -0:00:45 - +Rule sol87 1987 only - Jun 18 12:00:55s -0:00:55 - +Rule sol87 1987 only - Jun 19 12:01:10s -0:01:10 - +Rule sol87 1987 only - Jun 20 12:01:20s -0:01:20 - +Rule sol87 1987 only - Jun 21 12:01:35s -0:01:35 - +Rule sol87 1987 only - Jun 22 12:01:50s -0:01:50 - +Rule sol87 1987 only - Jun 23 12:02:00s -0:02:00 - +Rule sol87 1987 only - Jun 24 12:02:15s -0:02:15 - +Rule sol87 1987 only - Jun 25 12:02:25s -0:02:25 - +Rule sol87 1987 only - Jun 26 12:02:40s -0:02:40 - +Rule sol87 1987 only - Jun 27 12:02:50s -0:02:50 - +Rule sol87 1987 only - Jun 28 12:03:05s -0:03:05 - +Rule sol87 1987 only - Jun 29 12:03:15s -0:03:15 - +Rule sol87 1987 only - Jun 30 12:03:30s -0:03:30 - +Rule sol87 1987 only - Jul 1 12:03:40s -0:03:40 - +Rule sol87 1987 only - Jul 2 12:03:50s -0:03:50 - +Rule sol87 1987 only - Jul 3 12:04:05s -0:04:05 - +Rule sol87 1987 only - Jul 4 12:04:15s -0:04:15 - +Rule sol87 1987 only - Jul 5 12:04:25s -0:04:25 - +Rule sol87 1987 only - Jul 6 12:04:35s -0:04:35 - +Rule sol87 1987 only - Jul 7 12:04:45s -0:04:45 - +Rule sol87 1987 only - Jul 8 12:04:55s -0:04:55 - +Rule sol87 1987 only - Jul 9 12:05:05s -0:05:05 - +Rule sol87 1987 only - Jul 10 12:05:15s -0:05:15 - +Rule sol87 1987 only - Jul 11 12:05:20s -0:05:20 - +Rule sol87 1987 only - Jul 12 12:05:30s -0:05:30 - +Rule sol87 1987 only - Jul 13 12:05:40s -0:05:40 - +Rule sol87 1987 only - Jul 14 12:05:45s -0:05:45 - +Rule sol87 1987 only - Jul 15 12:05:50s -0:05:50 - +Rule sol87 1987 only - Jul 16 12:06:00s -0:06:00 - +Rule sol87 1987 only - Jul 17 12:06:05s -0:06:05 - +Rule sol87 1987 only - Jul 18 12:06:10s -0:06:10 - +Rule sol87 1987 only - Jul 19 12:06:15s -0:06:15 - +Rule sol87 1987 only - Jul 20 12:06:15s -0:06:15 - +Rule sol87 1987 only - Jul 21 12:06:20s -0:06:20 - +Rule sol87 1987 only - Jul 22 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 23 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 24 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 25 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 26 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 27 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 28 12:06:30s -0:06:30 - +Rule sol87 1987 only - Jul 29 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 30 12:06:25s -0:06:25 - +Rule sol87 1987 only - Jul 31 12:06:25s -0:06:25 - +Rule sol87 1987 only - Aug 1 12:06:20s -0:06:20 - +Rule sol87 1987 only - Aug 2 12:06:15s -0:06:15 - +Rule sol87 1987 only - Aug 3 12:06:10s -0:06:10 - +Rule sol87 1987 only - Aug 4 12:06:05s -0:06:05 - +Rule sol87 1987 only - Aug 5 12:06:00s -0:06:00 - +Rule sol87 1987 only - Aug 6 12:05:55s -0:05:55 - +Rule sol87 1987 only - Aug 7 12:05:50s -0:05:50 - +Rule sol87 1987 only - Aug 8 12:05:40s -0:05:40 - +Rule sol87 1987 only - Aug 9 12:05:35s -0:05:35 - +Rule sol87 1987 only - Aug 10 12:05:25s -0:05:25 - +Rule sol87 1987 only - Aug 11 12:05:15s -0:05:15 - +Rule sol87 1987 only - Aug 12 12:05:05s -0:05:05 - +Rule sol87 1987 only - Aug 13 12:04:55s -0:04:55 - +Rule sol87 1987 only - Aug 14 12:04:45s -0:04:45 - +Rule sol87 1987 only - Aug 15 12:04:35s -0:04:35 - +Rule sol87 1987 only - Aug 16 12:04:25s -0:04:25 - +Rule sol87 1987 only - Aug 17 12:04:10s -0:04:10 - +Rule sol87 1987 only - Aug 18 12:04:00s -0:04:00 - +Rule sol87 1987 only - Aug 19 12:03:45s -0:03:45 - +Rule sol87 1987 only - Aug 20 12:03:30s -0:03:30 - +Rule sol87 1987 only - Aug 21 12:03:15s -0:03:15 - +Rule sol87 1987 only - Aug 22 12:03:00s -0:03:00 - +Rule sol87 1987 only - Aug 23 12:02:45s -0:02:45 - +Rule sol87 1987 only - Aug 24 12:02:30s -0:02:30 - +Rule sol87 1987 only - Aug 25 12:02:15s -0:02:15 - +Rule sol87 1987 only - Aug 26 12:02:00s -0:02:00 - +Rule sol87 1987 only - Aug 27 12:01:40s -0:01:40 - +Rule sol87 1987 only - Aug 28 12:01:25s -0:01:25 - +Rule sol87 1987 only - Aug 29 12:01:05s -0:01:05 - +Rule sol87 1987 only - Aug 30 12:00:50s -0:00:50 - +Rule sol87 1987 only - Aug 31 12:00:30s -0:00:30 - +Rule sol87 1987 only - Sep 1 12:00:10s -0:00:10 - +Rule sol87 1987 only - Sep 2 11:59:50s 0:00:10 - +Rule sol87 1987 only - Sep 3 11:59:35s 0:00:25 - +Rule sol87 1987 only - Sep 4 11:59:15s 0:00:45 - +Rule sol87 1987 only - Sep 5 11:58:55s 0:01:05 - +Rule sol87 1987 only - Sep 6 11:58:35s 0:01:25 - +Rule sol87 1987 only - Sep 7 11:58:15s 0:01:45 - +Rule sol87 1987 only - Sep 8 11:57:55s 0:02:05 - +Rule sol87 1987 only - Sep 9 11:57:30s 0:02:30 - +Rule sol87 1987 only - Sep 10 11:57:10s 0:02:50 - +Rule sol87 1987 only - Sep 11 11:56:50s 0:03:10 - +Rule sol87 1987 only - Sep 12 11:56:30s 0:03:30 - +Rule sol87 1987 only - Sep 13 11:56:10s 0:03:50 - +Rule sol87 1987 only - Sep 14 11:55:45s 0:04:15 - +Rule sol87 1987 only - Sep 15 11:55:25s 0:04:35 - +Rule sol87 1987 only - Sep 16 11:55:05s 0:04:55 - +Rule sol87 1987 only - Sep 17 11:54:45s 0:05:15 - +Rule sol87 1987 only - Sep 18 11:54:20s 0:05:40 - +Rule sol87 1987 only - Sep 19 11:54:00s 0:06:00 - +Rule sol87 1987 only - Sep 20 11:53:40s 0:06:20 - +Rule sol87 1987 only - Sep 21 11:53:15s 0:06:45 - +Rule sol87 1987 only - Sep 22 11:52:55s 0:07:05 - +Rule sol87 1987 only - Sep 23 11:52:35s 0:07:25 - +Rule sol87 1987 only - Sep 24 11:52:15s 0:07:45 - +Rule sol87 1987 only - Sep 25 11:51:55s 0:08:05 - +Rule sol87 1987 only - Sep 26 11:51:35s 0:08:25 - +Rule sol87 1987 only - Sep 27 11:51:10s 0:08:50 - +Rule sol87 1987 only - Sep 28 11:50:50s 0:09:10 - +Rule sol87 1987 only - Sep 29 11:50:30s 0:09:30 - +Rule sol87 1987 only - Sep 30 11:50:10s 0:09:50 - +Rule sol87 1987 only - Oct 1 11:49:50s 0:10:10 - +Rule sol87 1987 only - Oct 2 11:49:35s 0:10:25 - +Rule sol87 1987 only - Oct 3 11:49:15s 0:10:45 - +Rule sol87 1987 only - Oct 4 11:48:55s 0:11:05 - +Rule sol87 1987 only - Oct 5 11:48:35s 0:11:25 - +Rule sol87 1987 only - Oct 6 11:48:20s 0:11:40 - +Rule sol87 1987 only - Oct 7 11:48:00s 0:12:00 - +Rule sol87 1987 only - Oct 8 11:47:45s 0:12:15 - +Rule sol87 1987 only - Oct 9 11:47:25s 0:12:35 - +Rule sol87 1987 only - Oct 10 11:47:10s 0:12:50 - +Rule sol87 1987 only - Oct 11 11:46:55s 0:13:05 - +Rule sol87 1987 only - Oct 12 11:46:40s 0:13:20 - +Rule sol87 1987 only - Oct 13 11:46:25s 0:13:35 - +Rule sol87 1987 only - Oct 14 11:46:10s 0:13:50 - +Rule sol87 1987 only - Oct 15 11:45:55s 0:14:05 - +Rule sol87 1987 only - Oct 16 11:45:45s 0:14:15 - +Rule sol87 1987 only - Oct 17 11:45:30s 0:14:30 - +Rule sol87 1987 only - Oct 18 11:45:20s 0:14:40 - +Rule sol87 1987 only - Oct 19 11:45:05s 0:14:55 - +Rule sol87 1987 only - Oct 20 11:44:55s 0:15:05 - +Rule sol87 1987 only - Oct 21 11:44:45s 0:15:15 - +Rule sol87 1987 only - Oct 22 11:44:35s 0:15:25 - +Rule sol87 1987 only - Oct 23 11:44:25s 0:15:35 - +Rule sol87 1987 only - Oct 24 11:44:20s 0:15:40 - +Rule sol87 1987 only - Oct 25 11:44:10s 0:15:50 - +Rule sol87 1987 only - Oct 26 11:44:05s 0:15:55 - +Rule sol87 1987 only - Oct 27 11:43:55s 0:16:05 - +Rule sol87 1987 only - Oct 28 11:43:50s 0:16:10 - +Rule sol87 1987 only - Oct 29 11:43:45s 0:16:15 - +Rule sol87 1987 only - Oct 30 11:43:45s 0:16:15 - +Rule sol87 1987 only - Oct 31 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 1 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 2 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 3 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 4 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 5 11:43:35s 0:16:25 - +Rule sol87 1987 only - Nov 6 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 7 11:43:40s 0:16:20 - +Rule sol87 1987 only - Nov 8 11:43:45s 0:16:15 - +Rule sol87 1987 only - Nov 9 11:43:50s 0:16:10 - +Rule sol87 1987 only - Nov 10 11:43:55s 0:16:05 - +Rule sol87 1987 only - Nov 11 11:44:00s 0:16:00 - +Rule sol87 1987 only - Nov 12 11:44:05s 0:15:55 - +Rule sol87 1987 only - Nov 13 11:44:15s 0:15:45 - +Rule sol87 1987 only - Nov 14 11:44:20s 0:15:40 - +Rule sol87 1987 only - Nov 15 11:44:30s 0:15:30 - +Rule sol87 1987 only - Nov 16 11:44:40s 0:15:20 - +Rule sol87 1987 only - Nov 17 11:44:50s 0:15:10 - +Rule sol87 1987 only - Nov 18 11:45:05s 0:14:55 - +Rule sol87 1987 only - Nov 19 11:45:15s 0:14:45 - +Rule sol87 1987 only - Nov 20 11:45:30s 0:14:30 - +Rule sol87 1987 only - Nov 21 11:45:45s 0:14:15 - +Rule sol87 1987 only - Nov 22 11:46:00s 0:14:00 - +Rule sol87 1987 only - Nov 23 11:46:15s 0:13:45 - +Rule sol87 1987 only - Nov 24 11:46:30s 0:13:30 - +Rule sol87 1987 only - Nov 25 11:46:50s 0:13:10 - +Rule sol87 1987 only - Nov 26 11:47:10s 0:12:50 - +Rule sol87 1987 only - Nov 27 11:47:25s 0:12:35 - +Rule sol87 1987 only - Nov 28 11:47:45s 0:12:15 - +Rule sol87 1987 only - Nov 29 11:48:05s 0:11:55 - +Rule sol87 1987 only - Nov 30 11:48:30s 0:11:30 - +Rule sol87 1987 only - Dec 1 11:48:50s 0:11:10 - +Rule sol87 1987 only - Dec 2 11:49:10s 0:10:50 - +Rule sol87 1987 only - Dec 3 11:49:35s 0:10:25 - +Rule sol87 1987 only - Dec 4 11:50:00s 0:10:00 - +Rule sol87 1987 only - Dec 5 11:50:25s 0:09:35 - +Rule sol87 1987 only - Dec 6 11:50:50s 0:09:10 - +Rule sol87 1987 only - Dec 7 11:51:15s 0:08:45 - +Rule sol87 1987 only - Dec 8 11:51:40s 0:08:20 - +Rule sol87 1987 only - Dec 9 11:52:05s 0:07:55 - +Rule sol87 1987 only - Dec 10 11:52:30s 0:07:30 - +Rule sol87 1987 only - Dec 11 11:53:00s 0:07:00 - +Rule sol87 1987 only - Dec 12 11:53:25s 0:06:35 - +Rule sol87 1987 only - Dec 13 11:53:55s 0:06:05 - +Rule sol87 1987 only - Dec 14 11:54:25s 0:05:35 - +Rule sol87 1987 only - Dec 15 11:54:50s 0:05:10 - +Rule sol87 1987 only - Dec 16 11:55:20s 0:04:40 - +Rule sol87 1987 only - Dec 17 11:55:50s 0:04:10 - +Rule sol87 1987 only - Dec 18 11:56:20s 0:03:40 - +Rule sol87 1987 only - Dec 19 11:56:50s 0:03:10 - +Rule sol87 1987 only - Dec 20 11:57:20s 0:02:40 - +Rule sol87 1987 only - Dec 21 11:57:50s 0:02:10 - +Rule sol87 1987 only - Dec 22 11:58:20s 0:01:40 - +Rule sol87 1987 only - Dec 23 11:58:50s 0:01:10 - +Rule sol87 1987 only - Dec 24 11:59:20s 0:00:40 - +Rule sol87 1987 only - Dec 25 11:59:50s 0:00:10 - +Rule sol87 1987 only - Dec 26 12:00:20s -0:00:20 - +Rule sol87 1987 only - Dec 27 12:00:45s -0:00:45 - +Rule sol87 1987 only - Dec 28 12:01:15s -0:01:15 - +Rule sol87 1987 only - Dec 29 12:01:45s -0:01:45 - +Rule sol87 1987 only - Dec 30 12:02:15s -0:02:15 - +Rule sol87 1987 only - Dec 31 12:02:45s -0:02:45 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1987, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh87 3:07:04 - ?? 1987 + 3:07:04 sol87 ?? 1988 + 3:07:04 - ?? diff --git a/time/solar88 b/time/solar88 new file mode 100644 index 0000000000..0384b17a07 --- /dev/null +++ b/time/solar88 @@ -0,0 +1,386 @@ +# @(#)solar88 7.2 + +# Apparent noon times below are for Riyadh; they're a bit off for other places. +# Times were computed using formulas in the U.S. Naval Observatory's +# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of +# [plus or minus two] seconds during the current year." +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol88 1988 only - Jan 1 12:03:15s -0:03:15 - +Rule sol88 1988 only - Jan 2 12:03:40s -0:03:40 - +Rule sol88 1988 only - Jan 3 12:04:10s -0:04:10 - +Rule sol88 1988 only - Jan 4 12:04:40s -0:04:40 - +Rule sol88 1988 only - Jan 5 12:05:05s -0:05:05 - +Rule sol88 1988 only - Jan 6 12:05:30s -0:05:30 - +Rule sol88 1988 only - Jan 7 12:06:00s -0:06:00 - +Rule sol88 1988 only - Jan 8 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jan 9 12:06:50s -0:06:50 - +Rule sol88 1988 only - Jan 10 12:07:15s -0:07:15 - +Rule sol88 1988 only - Jan 11 12:07:40s -0:07:40 - +Rule sol88 1988 only - Jan 12 12:08:05s -0:08:05 - +Rule sol88 1988 only - Jan 13 12:08:25s -0:08:25 - +Rule sol88 1988 only - Jan 14 12:08:50s -0:08:50 - +Rule sol88 1988 only - Jan 15 12:09:10s -0:09:10 - +Rule sol88 1988 only - Jan 16 12:09:30s -0:09:30 - +Rule sol88 1988 only - Jan 17 12:09:50s -0:09:50 - +Rule sol88 1988 only - Jan 18 12:10:10s -0:10:10 - +Rule sol88 1988 only - Jan 19 12:10:30s -0:10:30 - +Rule sol88 1988 only - Jan 20 12:10:50s -0:10:50 - +Rule sol88 1988 only - Jan 21 12:11:05s -0:11:05 - +Rule sol88 1988 only - Jan 22 12:11:25s -0:11:25 - +Rule sol88 1988 only - Jan 23 12:11:40s -0:11:40 - +Rule sol88 1988 only - Jan 24 12:11:55s -0:11:55 - +Rule sol88 1988 only - Jan 25 12:12:10s -0:12:10 - +Rule sol88 1988 only - Jan 26 12:12:25s -0:12:25 - +Rule sol88 1988 only - Jan 27 12:12:40s -0:12:40 - +Rule sol88 1988 only - Jan 28 12:12:50s -0:12:50 - +Rule sol88 1988 only - Jan 29 12:13:00s -0:13:00 - +Rule sol88 1988 only - Jan 30 12:13:10s -0:13:10 - +Rule sol88 1988 only - Jan 31 12:13:20s -0:13:20 - +Rule sol88 1988 only - Feb 1 12:13:30s -0:13:30 - +Rule sol88 1988 only - Feb 2 12:13:40s -0:13:40 - +Rule sol88 1988 only - Feb 3 12:13:45s -0:13:45 - +Rule sol88 1988 only - Feb 4 12:13:55s -0:13:55 - +Rule sol88 1988 only - Feb 5 12:14:00s -0:14:00 - +Rule sol88 1988 only - Feb 6 12:14:05s -0:14:05 - +Rule sol88 1988 only - Feb 7 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 8 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 9 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 10 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 11 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 12 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 13 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 14 12:14:15s -0:14:15 - +Rule sol88 1988 only - Feb 15 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 16 12:14:10s -0:14:10 - +Rule sol88 1988 only - Feb 17 12:14:05s -0:14:05 - +Rule sol88 1988 only - Feb 18 12:14:00s -0:14:00 - +Rule sol88 1988 only - Feb 19 12:13:55s -0:13:55 - +Rule sol88 1988 only - Feb 20 12:13:50s -0:13:50 - +Rule sol88 1988 only - Feb 21 12:13:45s -0:13:45 - +Rule sol88 1988 only - Feb 22 12:13:40s -0:13:40 - +Rule sol88 1988 only - Feb 23 12:13:30s -0:13:30 - +Rule sol88 1988 only - Feb 24 12:13:20s -0:13:20 - +Rule sol88 1988 only - Feb 25 12:13:15s -0:13:15 - +Rule sol88 1988 only - Feb 26 12:13:05s -0:13:05 - +Rule sol88 1988 only - Feb 27 12:12:55s -0:12:55 - +Rule sol88 1988 only - Feb 28 12:12:45s -0:12:45 - +Rule sol88 1988 only - Feb 29 12:12:30s -0:12:30 - +Rule sol88 1988 only - Mar 1 12:12:20s -0:12:20 - +Rule sol88 1988 only - Mar 2 12:12:10s -0:12:10 - +Rule sol88 1988 only - Mar 3 12:11:55s -0:11:55 - +Rule sol88 1988 only - Mar 4 12:11:45s -0:11:45 - +Rule sol88 1988 only - Mar 5 12:11:30s -0:11:30 - +Rule sol88 1988 only - Mar 6 12:11:15s -0:11:15 - +Rule sol88 1988 only - Mar 7 12:11:00s -0:11:00 - +Rule sol88 1988 only - Mar 8 12:10:45s -0:10:45 - +Rule sol88 1988 only - Mar 9 12:10:30s -0:10:30 - +Rule sol88 1988 only - Mar 10 12:10:15s -0:10:15 - +Rule sol88 1988 only - Mar 11 12:10:00s -0:10:00 - +Rule sol88 1988 only - Mar 12 12:09:45s -0:09:45 - +Rule sol88 1988 only - Mar 13 12:09:30s -0:09:30 - +Rule sol88 1988 only - Mar 14 12:09:10s -0:09:10 - +Rule sol88 1988 only - Mar 15 12:08:55s -0:08:55 - +Rule sol88 1988 only - Mar 16 12:08:40s -0:08:40 - +Rule sol88 1988 only - Mar 17 12:08:20s -0:08:20 - +Rule sol88 1988 only - Mar 18 12:08:05s -0:08:05 - +Rule sol88 1988 only - Mar 19 12:07:45s -0:07:45 - +Rule sol88 1988 only - Mar 20 12:07:30s -0:07:30 - +Rule sol88 1988 only - Mar 21 12:07:10s -0:07:10 - +Rule sol88 1988 only - Mar 22 12:06:50s -0:06:50 - +Rule sol88 1988 only - Mar 23 12:06:35s -0:06:35 - +Rule sol88 1988 only - Mar 24 12:06:15s -0:06:15 - +Rule sol88 1988 only - Mar 25 12:06:00s -0:06:00 - +Rule sol88 1988 only - Mar 26 12:05:40s -0:05:40 - +Rule sol88 1988 only - Mar 27 12:05:20s -0:05:20 - +Rule sol88 1988 only - Mar 28 12:05:05s -0:05:05 - +Rule sol88 1988 only - Mar 29 12:04:45s -0:04:45 - +Rule sol88 1988 only - Mar 30 12:04:25s -0:04:25 - +Rule sol88 1988 only - Mar 31 12:04:10s -0:04:10 - +Rule sol88 1988 only - Apr 1 12:03:50s -0:03:50 - +Rule sol88 1988 only - Apr 2 12:03:35s -0:03:35 - +Rule sol88 1988 only - Apr 3 12:03:15s -0:03:15 - +Rule sol88 1988 only - Apr 4 12:03:00s -0:03:00 - +Rule sol88 1988 only - Apr 5 12:02:40s -0:02:40 - +Rule sol88 1988 only - Apr 6 12:02:25s -0:02:25 - +Rule sol88 1988 only - Apr 7 12:02:05s -0:02:05 - +Rule sol88 1988 only - Apr 8 12:01:50s -0:01:50 - +Rule sol88 1988 only - Apr 9 12:01:35s -0:01:35 - +Rule sol88 1988 only - Apr 10 12:01:15s -0:01:15 - +Rule sol88 1988 only - Apr 11 12:01:00s -0:01:00 - +Rule sol88 1988 only - Apr 12 12:00:45s -0:00:45 - +Rule sol88 1988 only - Apr 13 12:00:30s -0:00:30 - +Rule sol88 1988 only - Apr 14 12:00:15s -0:00:15 - +Rule sol88 1988 only - Apr 15 12:00:00s 0:00:00 - +Rule sol88 1988 only - Apr 16 11:59:45s 0:00:15 - +Rule sol88 1988 only - Apr 17 11:59:30s 0:00:30 - +Rule sol88 1988 only - Apr 18 11:59:20s 0:00:40 - +Rule sol88 1988 only - Apr 19 11:59:05s 0:00:55 - +Rule sol88 1988 only - Apr 20 11:58:55s 0:01:05 - +Rule sol88 1988 only - Apr 21 11:58:40s 0:01:20 - +Rule sol88 1988 only - Apr 22 11:58:30s 0:01:30 - +Rule sol88 1988 only - Apr 23 11:58:15s 0:01:45 - +Rule sol88 1988 only - Apr 24 11:58:05s 0:01:55 - +Rule sol88 1988 only - Apr 25 11:57:55s 0:02:05 - +Rule sol88 1988 only - Apr 26 11:57:45s 0:02:15 - +Rule sol88 1988 only - Apr 27 11:57:35s 0:02:25 - +Rule sol88 1988 only - Apr 28 11:57:30s 0:02:30 - +Rule sol88 1988 only - Apr 29 11:57:20s 0:02:40 - +Rule sol88 1988 only - Apr 30 11:57:10s 0:02:50 - +Rule sol88 1988 only - May 1 11:57:05s 0:02:55 - +Rule sol88 1988 only - May 2 11:56:55s 0:03:05 - +Rule sol88 1988 only - May 3 11:56:50s 0:03:10 - +Rule sol88 1988 only - May 4 11:56:45s 0:03:15 - +Rule sol88 1988 only - May 5 11:56:40s 0:03:20 - +Rule sol88 1988 only - May 6 11:56:35s 0:03:25 - +Rule sol88 1988 only - May 7 11:56:30s 0:03:30 - +Rule sol88 1988 only - May 8 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 9 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 10 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 11 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 12 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 13 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 14 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 15 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 16 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 17 11:56:20s 0:03:40 - +Rule sol88 1988 only - May 18 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 19 11:56:25s 0:03:35 - +Rule sol88 1988 only - May 20 11:56:30s 0:03:30 - +Rule sol88 1988 only - May 21 11:56:35s 0:03:25 - +Rule sol88 1988 only - May 22 11:56:40s 0:03:20 - +Rule sol88 1988 only - May 23 11:56:45s 0:03:15 - +Rule sol88 1988 only - May 24 11:56:50s 0:03:10 - +Rule sol88 1988 only - May 25 11:56:55s 0:03:05 - +Rule sol88 1988 only - May 26 11:57:00s 0:03:00 - +Rule sol88 1988 only - May 27 11:57:05s 0:02:55 - +Rule sol88 1988 only - May 28 11:57:15s 0:02:45 - +Rule sol88 1988 only - May 29 11:57:20s 0:02:40 - +Rule sol88 1988 only - May 30 11:57:30s 0:02:30 - +Rule sol88 1988 only - May 31 11:57:40s 0:02:20 - +Rule sol88 1988 only - Jun 1 11:57:50s 0:02:10 - +Rule sol88 1988 only - Jun 2 11:57:55s 0:02:05 - +Rule sol88 1988 only - Jun 3 11:58:05s 0:01:55 - +Rule sol88 1988 only - Jun 4 11:58:15s 0:01:45 - +Rule sol88 1988 only - Jun 5 11:58:30s 0:01:30 - +Rule sol88 1988 only - Jun 6 11:58:40s 0:01:20 - +Rule sol88 1988 only - Jun 7 11:58:50s 0:01:10 - +Rule sol88 1988 only - Jun 8 11:59:00s 0:01:00 - +Rule sol88 1988 only - Jun 9 11:59:15s 0:00:45 - +Rule sol88 1988 only - Jun 10 11:59:25s 0:00:35 - +Rule sol88 1988 only - Jun 11 11:59:35s 0:00:25 - +Rule sol88 1988 only - Jun 12 11:59:50s 0:00:10 - +Rule sol88 1988 only - Jun 13 12:00:00s 0:00:00 - +Rule sol88 1988 only - Jun 14 12:00:15s -0:00:15 - +Rule sol88 1988 only - Jun 15 12:00:25s -0:00:25 - +Rule sol88 1988 only - Jun 16 12:00:40s -0:00:40 - +Rule sol88 1988 only - Jun 17 12:00:55s -0:00:55 - +Rule sol88 1988 only - Jun 18 12:01:05s -0:01:05 - +Rule sol88 1988 only - Jun 19 12:01:20s -0:01:20 - +Rule sol88 1988 only - Jun 20 12:01:30s -0:01:30 - +Rule sol88 1988 only - Jun 21 12:01:45s -0:01:45 - +Rule sol88 1988 only - Jun 22 12:02:00s -0:02:00 - +Rule sol88 1988 only - Jun 23 12:02:10s -0:02:10 - +Rule sol88 1988 only - Jun 24 12:02:25s -0:02:25 - +Rule sol88 1988 only - Jun 25 12:02:35s -0:02:35 - +Rule sol88 1988 only - Jun 26 12:02:50s -0:02:50 - +Rule sol88 1988 only - Jun 27 12:03:00s -0:03:00 - +Rule sol88 1988 only - Jun 28 12:03:15s -0:03:15 - +Rule sol88 1988 only - Jun 29 12:03:25s -0:03:25 - +Rule sol88 1988 only - Jun 30 12:03:40s -0:03:40 - +Rule sol88 1988 only - Jul 1 12:03:50s -0:03:50 - +Rule sol88 1988 only - Jul 2 12:04:00s -0:04:00 - +Rule sol88 1988 only - Jul 3 12:04:10s -0:04:10 - +Rule sol88 1988 only - Jul 4 12:04:25s -0:04:25 - +Rule sol88 1988 only - Jul 5 12:04:35s -0:04:35 - +Rule sol88 1988 only - Jul 6 12:04:45s -0:04:45 - +Rule sol88 1988 only - Jul 7 12:04:55s -0:04:55 - +Rule sol88 1988 only - Jul 8 12:05:05s -0:05:05 - +Rule sol88 1988 only - Jul 9 12:05:10s -0:05:10 - +Rule sol88 1988 only - Jul 10 12:05:20s -0:05:20 - +Rule sol88 1988 only - Jul 11 12:05:30s -0:05:30 - +Rule sol88 1988 only - Jul 12 12:05:35s -0:05:35 - +Rule sol88 1988 only - Jul 13 12:05:45s -0:05:45 - +Rule sol88 1988 only - Jul 14 12:05:50s -0:05:50 - +Rule sol88 1988 only - Jul 15 12:05:55s -0:05:55 - +Rule sol88 1988 only - Jul 16 12:06:00s -0:06:00 - +Rule sol88 1988 only - Jul 17 12:06:05s -0:06:05 - +Rule sol88 1988 only - Jul 18 12:06:10s -0:06:10 - +Rule sol88 1988 only - Jul 19 12:06:15s -0:06:15 - +Rule sol88 1988 only - Jul 20 12:06:20s -0:06:20 - +Rule sol88 1988 only - Jul 21 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 22 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 23 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 24 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 25 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 26 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 27 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 28 12:06:30s -0:06:30 - +Rule sol88 1988 only - Jul 29 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 30 12:06:25s -0:06:25 - +Rule sol88 1988 only - Jul 31 12:06:20s -0:06:20 - +Rule sol88 1988 only - Aug 1 12:06:15s -0:06:15 - +Rule sol88 1988 only - Aug 2 12:06:15s -0:06:15 - +Rule sol88 1988 only - Aug 3 12:06:10s -0:06:10 - +Rule sol88 1988 only - Aug 4 12:06:05s -0:06:05 - +Rule sol88 1988 only - Aug 5 12:05:55s -0:05:55 - +Rule sol88 1988 only - Aug 6 12:05:50s -0:05:50 - +Rule sol88 1988 only - Aug 7 12:05:45s -0:05:45 - +Rule sol88 1988 only - Aug 8 12:05:35s -0:05:35 - +Rule sol88 1988 only - Aug 9 12:05:25s -0:05:25 - +Rule sol88 1988 only - Aug 10 12:05:20s -0:05:20 - +Rule sol88 1988 only - Aug 11 12:05:10s -0:05:10 - +Rule sol88 1988 only - Aug 12 12:05:00s -0:05:00 - +Rule sol88 1988 only - Aug 13 12:04:50s -0:04:50 - +Rule sol88 1988 only - Aug 14 12:04:35s -0:04:35 - +Rule sol88 1988 only - Aug 15 12:04:25s -0:04:25 - +Rule sol88 1988 only - Aug 16 12:04:15s -0:04:15 - +Rule sol88 1988 only - Aug 17 12:04:00s -0:04:00 - +Rule sol88 1988 only - Aug 18 12:03:50s -0:03:50 - +Rule sol88 1988 only - Aug 19 12:03:35s -0:03:35 - +Rule sol88 1988 only - Aug 20 12:03:20s -0:03:20 - +Rule sol88 1988 only - Aug 21 12:03:05s -0:03:05 - +Rule sol88 1988 only - Aug 22 12:02:50s -0:02:50 - +Rule sol88 1988 only - Aug 23 12:02:35s -0:02:35 - +Rule sol88 1988 only - Aug 24 12:02:20s -0:02:20 - +Rule sol88 1988 only - Aug 25 12:02:00s -0:02:00 - +Rule sol88 1988 only - Aug 26 12:01:45s -0:01:45 - +Rule sol88 1988 only - Aug 27 12:01:30s -0:01:30 - +Rule sol88 1988 only - Aug 28 12:01:10s -0:01:10 - +Rule sol88 1988 only - Aug 29 12:00:50s -0:00:50 - +Rule sol88 1988 only - Aug 30 12:00:35s -0:00:35 - +Rule sol88 1988 only - Aug 31 12:00:15s -0:00:15 - +Rule sol88 1988 only - Sep 1 11:59:55s 0:00:05 - +Rule sol88 1988 only - Sep 2 11:59:35s 0:00:25 - +Rule sol88 1988 only - Sep 3 11:59:20s 0:00:40 - +Rule sol88 1988 only - Sep 4 11:59:00s 0:01:00 - +Rule sol88 1988 only - Sep 5 11:58:40s 0:01:20 - +Rule sol88 1988 only - Sep 6 11:58:20s 0:01:40 - +Rule sol88 1988 only - Sep 7 11:58:00s 0:02:00 - +Rule sol88 1988 only - Sep 8 11:57:35s 0:02:25 - +Rule sol88 1988 only - Sep 9 11:57:15s 0:02:45 - +Rule sol88 1988 only - Sep 10 11:56:55s 0:03:05 - +Rule sol88 1988 only - Sep 11 11:56:35s 0:03:25 - +Rule sol88 1988 only - Sep 12 11:56:15s 0:03:45 - +Rule sol88 1988 only - Sep 13 11:55:50s 0:04:10 - +Rule sol88 1988 only - Sep 14 11:55:30s 0:04:30 - +Rule sol88 1988 only - Sep 15 11:55:10s 0:04:50 - +Rule sol88 1988 only - Sep 16 11:54:50s 0:05:10 - +Rule sol88 1988 only - Sep 17 11:54:25s 0:05:35 - +Rule sol88 1988 only - Sep 18 11:54:05s 0:05:55 - +Rule sol88 1988 only - Sep 19 11:53:45s 0:06:15 - +Rule sol88 1988 only - Sep 20 11:53:25s 0:06:35 - +Rule sol88 1988 only - Sep 21 11:53:00s 0:07:00 - +Rule sol88 1988 only - Sep 22 11:52:40s 0:07:20 - +Rule sol88 1988 only - Sep 23 11:52:20s 0:07:40 - +Rule sol88 1988 only - Sep 24 11:52:00s 0:08:00 - +Rule sol88 1988 only - Sep 25 11:51:40s 0:08:20 - +Rule sol88 1988 only - Sep 26 11:51:15s 0:08:45 - +Rule sol88 1988 only - Sep 27 11:50:55s 0:09:05 - +Rule sol88 1988 only - Sep 28 11:50:35s 0:09:25 - +Rule sol88 1988 only - Sep 29 11:50:15s 0:09:45 - +Rule sol88 1988 only - Sep 30 11:49:55s 0:10:05 - +Rule sol88 1988 only - Oct 1 11:49:35s 0:10:25 - +Rule sol88 1988 only - Oct 2 11:49:20s 0:10:40 - +Rule sol88 1988 only - Oct 3 11:49:00s 0:11:00 - +Rule sol88 1988 only - Oct 4 11:48:40s 0:11:20 - +Rule sol88 1988 only - Oct 5 11:48:25s 0:11:35 - +Rule sol88 1988 only - Oct 6 11:48:05s 0:11:55 - +Rule sol88 1988 only - Oct 7 11:47:50s 0:12:10 - +Rule sol88 1988 only - Oct 8 11:47:30s 0:12:30 - +Rule sol88 1988 only - Oct 9 11:47:15s 0:12:45 - +Rule sol88 1988 only - Oct 10 11:47:00s 0:13:00 - +Rule sol88 1988 only - Oct 11 11:46:45s 0:13:15 - +Rule sol88 1988 only - Oct 12 11:46:30s 0:13:30 - +Rule sol88 1988 only - Oct 13 11:46:15s 0:13:45 - +Rule sol88 1988 only - Oct 14 11:46:00s 0:14:00 - +Rule sol88 1988 only - Oct 15 11:45:45s 0:14:15 - +Rule sol88 1988 only - Oct 16 11:45:35s 0:14:25 - +Rule sol88 1988 only - Oct 17 11:45:20s 0:14:40 - +Rule sol88 1988 only - Oct 18 11:45:10s 0:14:50 - +Rule sol88 1988 only - Oct 19 11:45:00s 0:15:00 - +Rule sol88 1988 only - Oct 20 11:44:45s 0:15:15 - +Rule sol88 1988 only - Oct 21 11:44:40s 0:15:20 - +Rule sol88 1988 only - Oct 22 11:44:30s 0:15:30 - +Rule sol88 1988 only - Oct 23 11:44:20s 0:15:40 - +Rule sol88 1988 only - Oct 24 11:44:10s 0:15:50 - +Rule sol88 1988 only - Oct 25 11:44:05s 0:15:55 - +Rule sol88 1988 only - Oct 26 11:44:00s 0:16:00 - +Rule sol88 1988 only - Oct 27 11:43:55s 0:16:05 - +Rule sol88 1988 only - Oct 28 11:43:50s 0:16:10 - +Rule sol88 1988 only - Oct 29 11:43:45s 0:16:15 - +Rule sol88 1988 only - Oct 30 11:43:40s 0:16:20 - +Rule sol88 1988 only - Oct 31 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 1 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 2 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 3 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 4 11:43:35s 0:16:25 - +Rule sol88 1988 only - Nov 5 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 6 11:43:40s 0:16:20 - +Rule sol88 1988 only - Nov 7 11:43:45s 0:16:15 - +Rule sol88 1988 only - Nov 8 11:43:45s 0:16:15 - +Rule sol88 1988 only - Nov 9 11:43:50s 0:16:10 - +Rule sol88 1988 only - Nov 10 11:44:00s 0:16:00 - +Rule sol88 1988 only - Nov 11 11:44:05s 0:15:55 - +Rule sol88 1988 only - Nov 12 11:44:10s 0:15:50 - +Rule sol88 1988 only - Nov 13 11:44:20s 0:15:40 - +Rule sol88 1988 only - Nov 14 11:44:30s 0:15:30 - +Rule sol88 1988 only - Nov 15 11:44:40s 0:15:20 - +Rule sol88 1988 only - Nov 16 11:44:50s 0:15:10 - +Rule sol88 1988 only - Nov 17 11:45:00s 0:15:00 - +Rule sol88 1988 only - Nov 18 11:45:15s 0:14:45 - +Rule sol88 1988 only - Nov 19 11:45:25s 0:14:35 - +Rule sol88 1988 only - Nov 20 11:45:40s 0:14:20 - +Rule sol88 1988 only - Nov 21 11:45:55s 0:14:05 - +Rule sol88 1988 only - Nov 22 11:46:10s 0:13:50 - +Rule sol88 1988 only - Nov 23 11:46:30s 0:13:30 - +Rule sol88 1988 only - Nov 24 11:46:45s 0:13:15 - +Rule sol88 1988 only - Nov 25 11:47:05s 0:12:55 - +Rule sol88 1988 only - Nov 26 11:47:20s 0:12:40 - +Rule sol88 1988 only - Nov 27 11:47:40s 0:12:20 - +Rule sol88 1988 only - Nov 28 11:48:00s 0:12:00 - +Rule sol88 1988 only - Nov 29 11:48:25s 0:11:35 - +Rule sol88 1988 only - Nov 30 11:48:45s 0:11:15 - +Rule sol88 1988 only - Dec 1 11:49:05s 0:10:55 - +Rule sol88 1988 only - Dec 2 11:49:30s 0:10:30 - +Rule sol88 1988 only - Dec 3 11:49:55s 0:10:05 - +Rule sol88 1988 only - Dec 4 11:50:15s 0:09:45 - +Rule sol88 1988 only - Dec 5 11:50:40s 0:09:20 - +Rule sol88 1988 only - Dec 6 11:51:05s 0:08:55 - +Rule sol88 1988 only - Dec 7 11:51:35s 0:08:25 - +Rule sol88 1988 only - Dec 8 11:52:00s 0:08:00 - +Rule sol88 1988 only - Dec 9 11:52:25s 0:07:35 - +Rule sol88 1988 only - Dec 10 11:52:55s 0:07:05 - +Rule sol88 1988 only - Dec 11 11:53:20s 0:06:40 - +Rule sol88 1988 only - Dec 12 11:53:50s 0:06:10 - +Rule sol88 1988 only - Dec 13 11:54:15s 0:05:45 - +Rule sol88 1988 only - Dec 14 11:54:45s 0:05:15 - +Rule sol88 1988 only - Dec 15 11:55:15s 0:04:45 - +Rule sol88 1988 only - Dec 16 11:55:45s 0:04:15 - +Rule sol88 1988 only - Dec 17 11:56:15s 0:03:45 - +Rule sol88 1988 only - Dec 18 11:56:40s 0:03:20 - +Rule sol88 1988 only - Dec 19 11:57:10s 0:02:50 - +Rule sol88 1988 only - Dec 20 11:57:40s 0:02:20 - +Rule sol88 1988 only - Dec 21 11:58:10s 0:01:50 - +Rule sol88 1988 only - Dec 22 11:58:40s 0:01:20 - +Rule sol88 1988 only - Dec 23 11:59:10s 0:00:50 - +Rule sol88 1988 only - Dec 24 11:59:40s 0:00:20 - +Rule sol88 1988 only - Dec 25 12:00:10s -0:00:10 - +Rule sol88 1988 only - Dec 26 12:00:40s -0:00:40 - +Rule sol88 1988 only - Dec 27 12:01:10s -0:01:10 - +Rule sol88 1988 only - Dec 28 12:01:40s -0:01:40 - +Rule sol88 1988 only - Dec 29 12:02:10s -0:02:10 - +Rule sol88 1988 only - Dec 30 12:02:35s -0:02:35 - +Rule sol88 1988 only - Dec 31 12:03:05s -0:03:05 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1988, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh88 3:07:04 - ?? 1988 + 3:07:04 sol88 ?? 1989 + 3:07:04 - ?? diff --git a/time/solar89 b/time/solar89 new file mode 100644 index 0000000000..3221f976c3 --- /dev/null +++ b/time/solar89 @@ -0,0 +1,391 @@ +# @(#)solar89 7.2 + +# Apparent noon times below are for Riyadh; they're a bit off for other places. +# Times were computed using a formula provided by the U. S. Naval Observatory: +# eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l) +# -12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l) +# + 19.3 * cos(3 * l); +# where l is the "mean longitude of the Sun" given by +# l = 279.642 degrees + 0.985647 * d +# and d is the interval in days from January 0, 0 hours Universal Time +# (equaling the day of the year plus the fraction of a day from zero hours). +# The accuracy of the formula is plus or minus three seconds. +# +# Rounding to the nearest five seconds results in fewer than +# 256 different "time types"--a limit that's faced because time types are +# stored on disk as unsigned chars. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule sol89 1989 only - Jan 1 12:03:35s -0:03:35 - +Rule sol89 1989 only - Jan 2 12:04:05s -0:04:05 - +Rule sol89 1989 only - Jan 3 12:04:30s -0:04:30 - +Rule sol89 1989 only - Jan 4 12:05:00s -0:05:00 - +Rule sol89 1989 only - Jan 5 12:05:25s -0:05:25 - +Rule sol89 1989 only - Jan 6 12:05:50s -0:05:50 - +Rule sol89 1989 only - Jan 7 12:06:15s -0:06:15 - +Rule sol89 1989 only - Jan 8 12:06:45s -0:06:45 - +Rule sol89 1989 only - Jan 9 12:07:10s -0:07:10 - +Rule sol89 1989 only - Jan 10 12:07:35s -0:07:35 - +Rule sol89 1989 only - Jan 11 12:07:55s -0:07:55 - +Rule sol89 1989 only - Jan 12 12:08:20s -0:08:20 - +Rule sol89 1989 only - Jan 13 12:08:45s -0:08:45 - +Rule sol89 1989 only - Jan 14 12:09:05s -0:09:05 - +Rule sol89 1989 only - Jan 15 12:09:25s -0:09:25 - +Rule sol89 1989 only - Jan 16 12:09:45s -0:09:45 - +Rule sol89 1989 only - Jan 17 12:10:05s -0:10:05 - +Rule sol89 1989 only - Jan 18 12:10:25s -0:10:25 - +Rule sol89 1989 only - Jan 19 12:10:45s -0:10:45 - +Rule sol89 1989 only - Jan 20 12:11:05s -0:11:05 - +Rule sol89 1989 only - Jan 21 12:11:20s -0:11:20 - +Rule sol89 1989 only - Jan 22 12:11:35s -0:11:35 - +Rule sol89 1989 only - Jan 23 12:11:55s -0:11:55 - +Rule sol89 1989 only - Jan 24 12:12:10s -0:12:10 - +Rule sol89 1989 only - Jan 25 12:12:20s -0:12:20 - +Rule sol89 1989 only - Jan 26 12:12:35s -0:12:35 - +Rule sol89 1989 only - Jan 27 12:12:50s -0:12:50 - +Rule sol89 1989 only - Jan 28 12:13:00s -0:13:00 - +Rule sol89 1989 only - Jan 29 12:13:10s -0:13:10 - +Rule sol89 1989 only - Jan 30 12:13:20s -0:13:20 - +Rule sol89 1989 only - Jan 31 12:13:30s -0:13:30 - +Rule sol89 1989 only - Feb 1 12:13:40s -0:13:40 - +Rule sol89 1989 only - Feb 2 12:13:45s -0:13:45 - +Rule sol89 1989 only - Feb 3 12:13:55s -0:13:55 - +Rule sol89 1989 only - Feb 4 12:14:00s -0:14:00 - +Rule sol89 1989 only - Feb 5 12:14:05s -0:14:05 - +Rule sol89 1989 only - Feb 6 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 7 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 8 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 9 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 10 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 11 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 12 12:14:20s -0:14:20 - +Rule sol89 1989 only - Feb 13 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 14 12:14:15s -0:14:15 - +Rule sol89 1989 only - Feb 15 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 16 12:14:10s -0:14:10 - +Rule sol89 1989 only - Feb 17 12:14:05s -0:14:05 - +Rule sol89 1989 only - Feb 18 12:14:00s -0:14:00 - +Rule sol89 1989 only - Feb 19 12:13:55s -0:13:55 - +Rule sol89 1989 only - Feb 20 12:13:50s -0:13:50 - +Rule sol89 1989 only - Feb 21 12:13:40s -0:13:40 - +Rule sol89 1989 only - Feb 22 12:13:35s -0:13:35 - +Rule sol89 1989 only - Feb 23 12:13:25s -0:13:25 - +Rule sol89 1989 only - Feb 24 12:13:15s -0:13:15 - +Rule sol89 1989 only - Feb 25 12:13:05s -0:13:05 - +Rule sol89 1989 only - Feb 26 12:12:55s -0:12:55 - +Rule sol89 1989 only - Feb 27 12:12:45s -0:12:45 - +Rule sol89 1989 only - Feb 28 12:12:35s -0:12:35 - +Rule sol89 1989 only - Mar 1 12:12:25s -0:12:25 - +Rule sol89 1989 only - Mar 2 12:12:10s -0:12:10 - +Rule sol89 1989 only - Mar 3 12:12:00s -0:12:00 - +Rule sol89 1989 only - Mar 4 12:11:45s -0:11:45 - +Rule sol89 1989 only - Mar 5 12:11:35s -0:11:35 - +Rule sol89 1989 only - Mar 6 12:11:20s -0:11:20 - +Rule sol89 1989 only - Mar 7 12:11:05s -0:11:05 - +Rule sol89 1989 only - Mar 8 12:10:50s -0:10:50 - +Rule sol89 1989 only - Mar 9 12:10:35s -0:10:35 - +Rule sol89 1989 only - Mar 10 12:10:20s -0:10:20 - +Rule sol89 1989 only - Mar 11 12:10:05s -0:10:05 - +Rule sol89 1989 only - Mar 12 12:09:50s -0:09:50 - +Rule sol89 1989 only - Mar 13 12:09:30s -0:09:30 - +Rule sol89 1989 only - Mar 14 12:09:15s -0:09:15 - +Rule sol89 1989 only - Mar 15 12:09:00s -0:09:00 - +Rule sol89 1989 only - Mar 16 12:08:40s -0:08:40 - +Rule sol89 1989 only - Mar 17 12:08:25s -0:08:25 - +Rule sol89 1989 only - Mar 18 12:08:05s -0:08:05 - +Rule sol89 1989 only - Mar 19 12:07:50s -0:07:50 - +Rule sol89 1989 only - Mar 20 12:07:30s -0:07:30 - +Rule sol89 1989 only - Mar 21 12:07:15s -0:07:15 - +Rule sol89 1989 only - Mar 22 12:06:55s -0:06:55 - +Rule sol89 1989 only - Mar 23 12:06:35s -0:06:35 - +Rule sol89 1989 only - Mar 24 12:06:20s -0:06:20 - +Rule sol89 1989 only - Mar 25 12:06:00s -0:06:00 - +Rule sol89 1989 only - Mar 26 12:05:40s -0:05:40 - +Rule sol89 1989 only - Mar 27 12:05:25s -0:05:25 - +Rule sol89 1989 only - Mar 28 12:05:05s -0:05:05 - +Rule sol89 1989 only - Mar 29 12:04:50s -0:04:50 - +Rule sol89 1989 only - Mar 30 12:04:30s -0:04:30 - +Rule sol89 1989 only - Mar 31 12:04:10s -0:04:10 - +Rule sol89 1989 only - Apr 1 12:03:55s -0:03:55 - +Rule sol89 1989 only - Apr 2 12:03:35s -0:03:35 - +Rule sol89 1989 only - Apr 3 12:03:20s -0:03:20 - +Rule sol89 1989 only - Apr 4 12:03:00s -0:03:00 - +Rule sol89 1989 only - Apr 5 12:02:45s -0:02:45 - +Rule sol89 1989 only - Apr 6 12:02:25s -0:02:25 - +Rule sol89 1989 only - Apr 7 12:02:10s -0:02:10 - +Rule sol89 1989 only - Apr 8 12:01:50s -0:01:50 - +Rule sol89 1989 only - Apr 9 12:01:35s -0:01:35 - +Rule sol89 1989 only - Apr 10 12:01:20s -0:01:20 - +Rule sol89 1989 only - Apr 11 12:01:05s -0:01:05 - +Rule sol89 1989 only - Apr 12 12:00:50s -0:00:50 - +Rule sol89 1989 only - Apr 13 12:00:35s -0:00:35 - +Rule sol89 1989 only - Apr 14 12:00:20s -0:00:20 - +Rule sol89 1989 only - Apr 15 12:00:05s -0:00:05 - +Rule sol89 1989 only - Apr 16 11:59:50s 0:00:10 - +Rule sol89 1989 only - Apr 17 11:59:35s 0:00:25 - +Rule sol89 1989 only - Apr 18 11:59:20s 0:00:40 - +Rule sol89 1989 only - Apr 19 11:59:10s 0:00:50 - +Rule sol89 1989 only - Apr 20 11:58:55s 0:01:05 - +Rule sol89 1989 only - Apr 21 11:58:45s 0:01:15 - +Rule sol89 1989 only - Apr 22 11:58:30s 0:01:30 - +Rule sol89 1989 only - Apr 23 11:58:20s 0:01:40 - +Rule sol89 1989 only - Apr 24 11:58:10s 0:01:50 - +Rule sol89 1989 only - Apr 25 11:58:00s 0:02:00 - +Rule sol89 1989 only - Apr 26 11:57:50s 0:02:10 - +Rule sol89 1989 only - Apr 27 11:57:40s 0:02:20 - +Rule sol89 1989 only - Apr 28 11:57:30s 0:02:30 - +Rule sol89 1989 only - Apr 29 11:57:20s 0:02:40 - +Rule sol89 1989 only - Apr 30 11:57:15s 0:02:45 - +Rule sol89 1989 only - May 1 11:57:05s 0:02:55 - +Rule sol89 1989 only - May 2 11:57:00s 0:03:00 - +Rule sol89 1989 only - May 3 11:56:50s 0:03:10 - +Rule sol89 1989 only - May 4 11:56:45s 0:03:15 - +Rule sol89 1989 only - May 5 11:56:40s 0:03:20 - +Rule sol89 1989 only - May 6 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 7 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 8 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 9 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 10 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 11 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 12 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 13 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 14 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 15 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 16 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 17 11:56:20s 0:03:40 - +Rule sol89 1989 only - May 18 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 19 11:56:25s 0:03:35 - +Rule sol89 1989 only - May 20 11:56:30s 0:03:30 - +Rule sol89 1989 only - May 21 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 22 11:56:35s 0:03:25 - +Rule sol89 1989 only - May 23 11:56:40s 0:03:20 - +Rule sol89 1989 only - May 24 11:56:45s 0:03:15 - +Rule sol89 1989 only - May 25 11:56:55s 0:03:05 - +Rule sol89 1989 only - May 26 11:57:00s 0:03:00 - +Rule sol89 1989 only - May 27 11:57:05s 0:02:55 - +Rule sol89 1989 only - May 28 11:57:15s 0:02:45 - +Rule sol89 1989 only - May 29 11:57:20s 0:02:40 - +Rule sol89 1989 only - May 30 11:57:30s 0:02:30 - +Rule sol89 1989 only - May 31 11:57:35s 0:02:25 - +Rule sol89 1989 only - Jun 1 11:57:45s 0:02:15 - +Rule sol89 1989 only - Jun 2 11:57:55s 0:02:05 - +Rule sol89 1989 only - Jun 3 11:58:05s 0:01:55 - +Rule sol89 1989 only - Jun 4 11:58:15s 0:01:45 - +Rule sol89 1989 only - Jun 5 11:58:25s 0:01:35 - +Rule sol89 1989 only - Jun 6 11:58:35s 0:01:25 - +Rule sol89 1989 only - Jun 7 11:58:45s 0:01:15 - +Rule sol89 1989 only - Jun 8 11:59:00s 0:01:00 - +Rule sol89 1989 only - Jun 9 11:59:10s 0:00:50 - +Rule sol89 1989 only - Jun 10 11:59:20s 0:00:40 - +Rule sol89 1989 only - Jun 11 11:59:35s 0:00:25 - +Rule sol89 1989 only - Jun 12 11:59:45s 0:00:15 - +Rule sol89 1989 only - Jun 13 12:00:00s 0:00:00 - +Rule sol89 1989 only - Jun 14 12:00:10s -0:00:10 - +Rule sol89 1989 only - Jun 15 12:00:25s -0:00:25 - +Rule sol89 1989 only - Jun 16 12:00:35s -0:00:35 - +Rule sol89 1989 only - Jun 17 12:00:50s -0:00:50 - +Rule sol89 1989 only - Jun 18 12:01:05s -0:01:05 - +Rule sol89 1989 only - Jun 19 12:01:15s -0:01:15 - +Rule sol89 1989 only - Jun 20 12:01:30s -0:01:30 - +Rule sol89 1989 only - Jun 21 12:01:40s -0:01:40 - +Rule sol89 1989 only - Jun 22 12:01:55s -0:01:55 - +Rule sol89 1989 only - Jun 23 12:02:10s -0:02:10 - +Rule sol89 1989 only - Jun 24 12:02:20s -0:02:20 - +Rule sol89 1989 only - Jun 25 12:02:35s -0:02:35 - +Rule sol89 1989 only - Jun 26 12:02:45s -0:02:45 - +Rule sol89 1989 only - Jun 27 12:03:00s -0:03:00 - +Rule sol89 1989 only - Jun 28 12:03:10s -0:03:10 - +Rule sol89 1989 only - Jun 29 12:03:25s -0:03:25 - +Rule sol89 1989 only - Jun 30 12:03:35s -0:03:35 - +Rule sol89 1989 only - Jul 1 12:03:45s -0:03:45 - +Rule sol89 1989 only - Jul 2 12:04:00s -0:04:00 - +Rule sol89 1989 only - Jul 3 12:04:10s -0:04:10 - +Rule sol89 1989 only - Jul 4 12:04:20s -0:04:20 - +Rule sol89 1989 only - Jul 5 12:04:30s -0:04:30 - +Rule sol89 1989 only - Jul 6 12:04:40s -0:04:40 - +Rule sol89 1989 only - Jul 7 12:04:50s -0:04:50 - +Rule sol89 1989 only - Jul 8 12:05:00s -0:05:00 - +Rule sol89 1989 only - Jul 9 12:05:10s -0:05:10 - +Rule sol89 1989 only - Jul 10 12:05:20s -0:05:20 - +Rule sol89 1989 only - Jul 11 12:05:25s -0:05:25 - +Rule sol89 1989 only - Jul 12 12:05:35s -0:05:35 - +Rule sol89 1989 only - Jul 13 12:05:40s -0:05:40 - +Rule sol89 1989 only - Jul 14 12:05:50s -0:05:50 - +Rule sol89 1989 only - Jul 15 12:05:55s -0:05:55 - +Rule sol89 1989 only - Jul 16 12:06:00s -0:06:00 - +Rule sol89 1989 only - Jul 17 12:06:05s -0:06:05 - +Rule sol89 1989 only - Jul 18 12:06:10s -0:06:10 - +Rule sol89 1989 only - Jul 19 12:06:15s -0:06:15 - +Rule sol89 1989 only - Jul 20 12:06:20s -0:06:20 - +Rule sol89 1989 only - Jul 21 12:06:20s -0:06:20 - +Rule sol89 1989 only - Jul 22 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 23 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 24 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 25 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 26 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 27 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 28 12:06:30s -0:06:30 - +Rule sol89 1989 only - Jul 29 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 30 12:06:25s -0:06:25 - +Rule sol89 1989 only - Jul 31 12:06:20s -0:06:20 - +Rule sol89 1989 only - Aug 1 12:06:20s -0:06:20 - +Rule sol89 1989 only - Aug 2 12:06:15s -0:06:15 - +Rule sol89 1989 only - Aug 3 12:06:10s -0:06:10 - +Rule sol89 1989 only - Aug 4 12:06:05s -0:06:05 - +Rule sol89 1989 only - Aug 5 12:06:00s -0:06:00 - +Rule sol89 1989 only - Aug 6 12:05:50s -0:05:50 - +Rule sol89 1989 only - Aug 7 12:05:45s -0:05:45 - +Rule sol89 1989 only - Aug 8 12:05:35s -0:05:35 - +Rule sol89 1989 only - Aug 9 12:05:30s -0:05:30 - +Rule sol89 1989 only - Aug 10 12:05:20s -0:05:20 - +Rule sol89 1989 only - Aug 11 12:05:10s -0:05:10 - +Rule sol89 1989 only - Aug 12 12:05:00s -0:05:00 - +Rule sol89 1989 only - Aug 13 12:04:50s -0:04:50 - +Rule sol89 1989 only - Aug 14 12:04:40s -0:04:40 - +Rule sol89 1989 only - Aug 15 12:04:30s -0:04:30 - +Rule sol89 1989 only - Aug 16 12:04:15s -0:04:15 - +Rule sol89 1989 only - Aug 17 12:04:05s -0:04:05 - +Rule sol89 1989 only - Aug 18 12:03:50s -0:03:50 - +Rule sol89 1989 only - Aug 19 12:03:35s -0:03:35 - +Rule sol89 1989 only - Aug 20 12:03:25s -0:03:25 - +Rule sol89 1989 only - Aug 21 12:03:10s -0:03:10 - +Rule sol89 1989 only - Aug 22 12:02:55s -0:02:55 - +Rule sol89 1989 only - Aug 23 12:02:40s -0:02:40 - +Rule sol89 1989 only - Aug 24 12:02:20s -0:02:20 - +Rule sol89 1989 only - Aug 25 12:02:05s -0:02:05 - +Rule sol89 1989 only - Aug 26 12:01:50s -0:01:50 - +Rule sol89 1989 only - Aug 27 12:01:30s -0:01:30 - +Rule sol89 1989 only - Aug 28 12:01:15s -0:01:15 - +Rule sol89 1989 only - Aug 29 12:00:55s -0:00:55 - +Rule sol89 1989 only - Aug 30 12:00:40s -0:00:40 - +Rule sol89 1989 only - Aug 31 12:00:20s -0:00:20 - +Rule sol89 1989 only - Sep 1 12:00:00s 0:00:00 - +Rule sol89 1989 only - Sep 2 11:59:45s 0:00:15 - +Rule sol89 1989 only - Sep 3 11:59:25s 0:00:35 - +Rule sol89 1989 only - Sep 4 11:59:05s 0:00:55 - +Rule sol89 1989 only - Sep 5 11:58:45s 0:01:15 - +Rule sol89 1989 only - Sep 6 11:58:25s 0:01:35 - +Rule sol89 1989 only - Sep 7 11:58:05s 0:01:55 - +Rule sol89 1989 only - Sep 8 11:57:45s 0:02:15 - +Rule sol89 1989 only - Sep 9 11:57:20s 0:02:40 - +Rule sol89 1989 only - Sep 10 11:57:00s 0:03:00 - +Rule sol89 1989 only - Sep 11 11:56:40s 0:03:20 - +Rule sol89 1989 only - Sep 12 11:56:20s 0:03:40 - +Rule sol89 1989 only - Sep 13 11:56:00s 0:04:00 - +Rule sol89 1989 only - Sep 14 11:55:35s 0:04:25 - +Rule sol89 1989 only - Sep 15 11:55:15s 0:04:45 - +Rule sol89 1989 only - Sep 16 11:54:55s 0:05:05 - +Rule sol89 1989 only - Sep 17 11:54:35s 0:05:25 - +Rule sol89 1989 only - Sep 18 11:54:10s 0:05:50 - +Rule sol89 1989 only - Sep 19 11:53:50s 0:06:10 - +Rule sol89 1989 only - Sep 20 11:53:30s 0:06:30 - +Rule sol89 1989 only - Sep 21 11:53:10s 0:06:50 - +Rule sol89 1989 only - Sep 22 11:52:45s 0:07:15 - +Rule sol89 1989 only - Sep 23 11:52:25s 0:07:35 - +Rule sol89 1989 only - Sep 24 11:52:05s 0:07:55 - +Rule sol89 1989 only - Sep 25 11:51:45s 0:08:15 - +Rule sol89 1989 only - Sep 26 11:51:25s 0:08:35 - +Rule sol89 1989 only - Sep 27 11:51:05s 0:08:55 - +Rule sol89 1989 only - Sep 28 11:50:40s 0:09:20 - +Rule sol89 1989 only - Sep 29 11:50:20s 0:09:40 - +Rule sol89 1989 only - Sep 30 11:50:00s 0:10:00 - +Rule sol89 1989 only - Oct 1 11:49:45s 0:10:15 - +Rule sol89 1989 only - Oct 2 11:49:25s 0:10:35 - +Rule sol89 1989 only - Oct 3 11:49:05s 0:10:55 - +Rule sol89 1989 only - Oct 4 11:48:45s 0:11:15 - +Rule sol89 1989 only - Oct 5 11:48:30s 0:11:30 - +Rule sol89 1989 only - Oct 6 11:48:10s 0:11:50 - +Rule sol89 1989 only - Oct 7 11:47:50s 0:12:10 - +Rule sol89 1989 only - Oct 8 11:47:35s 0:12:25 - +Rule sol89 1989 only - Oct 9 11:47:20s 0:12:40 - +Rule sol89 1989 only - Oct 10 11:47:00s 0:13:00 - +Rule sol89 1989 only - Oct 11 11:46:45s 0:13:15 - +Rule sol89 1989 only - Oct 12 11:46:30s 0:13:30 - +Rule sol89 1989 only - Oct 13 11:46:15s 0:13:45 - +Rule sol89 1989 only - Oct 14 11:46:00s 0:14:00 - +Rule sol89 1989 only - Oct 15 11:45:50s 0:14:10 - +Rule sol89 1989 only - Oct 16 11:45:35s 0:14:25 - +Rule sol89 1989 only - Oct 17 11:45:20s 0:14:40 - +Rule sol89 1989 only - Oct 18 11:45:10s 0:14:50 - +Rule sol89 1989 only - Oct 19 11:45:00s 0:15:00 - +Rule sol89 1989 only - Oct 20 11:44:50s 0:15:10 - +Rule sol89 1989 only - Oct 21 11:44:40s 0:15:20 - +Rule sol89 1989 only - Oct 22 11:44:30s 0:15:30 - +Rule sol89 1989 only - Oct 23 11:44:20s 0:15:40 - +Rule sol89 1989 only - Oct 24 11:44:10s 0:15:50 - +Rule sol89 1989 only - Oct 25 11:44:05s 0:15:55 - +Rule sol89 1989 only - Oct 26 11:44:00s 0:16:00 - +Rule sol89 1989 only - Oct 27 11:43:50s 0:16:10 - +Rule sol89 1989 only - Oct 28 11:43:45s 0:16:15 - +Rule sol89 1989 only - Oct 29 11:43:40s 0:16:20 - +Rule sol89 1989 only - Oct 30 11:43:40s 0:16:20 - +Rule sol89 1989 only - Oct 31 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 1 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 2 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 3 11:43:30s 0:16:30 - +Rule sol89 1989 only - Nov 4 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 5 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 6 11:43:35s 0:16:25 - +Rule sol89 1989 only - Nov 7 11:43:40s 0:16:20 - +Rule sol89 1989 only - Nov 8 11:43:45s 0:16:15 - +Rule sol89 1989 only - Nov 9 11:43:50s 0:16:10 - +Rule sol89 1989 only - Nov 10 11:43:55s 0:16:05 - +Rule sol89 1989 only - Nov 11 11:44:00s 0:16:00 - +Rule sol89 1989 only - Nov 12 11:44:05s 0:15:55 - +Rule sol89 1989 only - Nov 13 11:44:15s 0:15:45 - +Rule sol89 1989 only - Nov 14 11:44:25s 0:15:35 - +Rule sol89 1989 only - Nov 15 11:44:35s 0:15:25 - +Rule sol89 1989 only - Nov 16 11:44:45s 0:15:15 - +Rule sol89 1989 only - Nov 17 11:44:55s 0:15:05 - +Rule sol89 1989 only - Nov 18 11:45:10s 0:14:50 - +Rule sol89 1989 only - Nov 19 11:45:20s 0:14:40 - +Rule sol89 1989 only - Nov 20 11:45:35s 0:14:25 - +Rule sol89 1989 only - Nov 21 11:45:50s 0:14:10 - +Rule sol89 1989 only - Nov 22 11:46:05s 0:13:55 - +Rule sol89 1989 only - Nov 23 11:46:25s 0:13:35 - +Rule sol89 1989 only - Nov 24 11:46:40s 0:13:20 - +Rule sol89 1989 only - Nov 25 11:47:00s 0:13:00 - +Rule sol89 1989 only - Nov 26 11:47:20s 0:12:40 - +Rule sol89 1989 only - Nov 27 11:47:35s 0:12:25 - +Rule sol89 1989 only - Nov 28 11:47:55s 0:12:05 - +Rule sol89 1989 only - Nov 29 11:48:20s 0:11:40 - +Rule sol89 1989 only - Nov 30 11:48:40s 0:11:20 - +Rule sol89 1989 only - Dec 1 11:49:00s 0:11:00 - +Rule sol89 1989 only - Dec 2 11:49:25s 0:10:35 - +Rule sol89 1989 only - Dec 3 11:49:50s 0:10:10 - +Rule sol89 1989 only - Dec 4 11:50:15s 0:09:45 - +Rule sol89 1989 only - Dec 5 11:50:35s 0:09:25 - +Rule sol89 1989 only - Dec 6 11:51:00s 0:09:00 - +Rule sol89 1989 only - Dec 7 11:51:30s 0:08:30 - +Rule sol89 1989 only - Dec 8 11:51:55s 0:08:05 - +Rule sol89 1989 only - Dec 9 11:52:20s 0:07:40 - +Rule sol89 1989 only - Dec 10 11:52:50s 0:07:10 - +Rule sol89 1989 only - Dec 11 11:53:15s 0:06:45 - +Rule sol89 1989 only - Dec 12 11:53:45s 0:06:15 - +Rule sol89 1989 only - Dec 13 11:54:10s 0:05:50 - +Rule sol89 1989 only - Dec 14 11:54:40s 0:05:20 - +Rule sol89 1989 only - Dec 15 11:55:10s 0:04:50 - +Rule sol89 1989 only - Dec 16 11:55:40s 0:04:20 - +Rule sol89 1989 only - Dec 17 11:56:05s 0:03:55 - +Rule sol89 1989 only - Dec 18 11:56:35s 0:03:25 - +Rule sol89 1989 only - Dec 19 11:57:05s 0:02:55 - +Rule sol89 1989 only - Dec 20 11:57:35s 0:02:25 - +Rule sol89 1989 only - Dec 21 11:58:05s 0:01:55 - +Rule sol89 1989 only - Dec 22 11:58:35s 0:01:25 - +Rule sol89 1989 only - Dec 23 11:59:05s 0:00:55 - +Rule sol89 1989 only - Dec 24 11:59:35s 0:00:25 - +Rule sol89 1989 only - Dec 25 12:00:05s -0:00:05 - +Rule sol89 1989 only - Dec 26 12:00:35s -0:00:35 - +Rule sol89 1989 only - Dec 27 12:01:05s -0:01:05 - +Rule sol89 1989 only - Dec 28 12:01:35s -0:01:35 - +Rule sol89 1989 only - Dec 29 12:02:00s -0:02:00 - +Rule sol89 1989 only - Dec 30 12:02:30s -0:02:30 - +Rule sol89 1989 only - Dec 31 12:03:00s -0:03:00 - + +# Riyadh is at about 46 degrees 46 minutes East: 3 hrs, 7 mins, 4 secs +# Before and after 1989, we'll operate on local mean solar time. + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone Mideast/Riyadh89 3:07:04 - ?? 1989 + 3:07:04 sol89 ?? 1990 + 3:07:04 - ?? diff --git a/time/southamerica b/time/southamerica new file mode 100644 index 0000000000..b40ce559a3 --- /dev/null +++ b/time/southamerica @@ -0,0 +1,397 @@ +# @(#)southamerica 7.6 + +# This data is by no means authoritative; if you think you know better, +# go ahead and edit the file (and please send any changes to +# tz@elsie.nci.nih.gov for general use in the future). + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# A good source for time zone historical data outside the U.S. is +# Thomas G. Shanks, The International Atlas (3rd edition), +# San Diego: ACS Publications, Inc. (1991). +# Except where otherwise noted, it is the source for the data below. +# +# I invented the abbreviations marked `*' in the following table; +# the rest are from earlier versions of this file, or from other sources. +# Some of these are just plausible excuses for common English abbreviations. +# Corrections are welcome! +# std dst +# LMT Local Mean Time +# -2:00 FST FDT Fernando de Noronha +# -3:00 EST EDT Eastern South America (conflicts with -5:00) +# -4:00 AST ADT Andes*, Antilles*, Asuncion*, Atlantic +# -4:00 CST CDT Chile (conflicts with -6:00) +# -4:00 WST WDT Western Brazil +# -5:00 AST ADT Acre (conflicts with -4:00) +# -5:00 EST EDT Eastern, Ecuador* +# -6:00 CST CDT Archipelago of Columbus*, Central +# -7:00 MST MDT Mataveri*, Mountain +# +# See the `africa' file for Zone naming conventions. + +# From Guy Harris: +# From Official Airline Guide - Worldwide Edition (1987). Countries not +# listed here do not observe DST, according to the OAG. Time zone names +# are pure inventions, and none are supplied for countries not observing +# DST; updates from natives would be appreciated. The times that DST +# starts and ends are based on the assumption that they switch a 2AM just +# as everybody else does. + +############################################################################### + +############################################################################### + +# Argentina + +# From Bob Devine (January 28, 1988): +# Argentina: first Sunday in October to first Sunday in April since 1976. +# Double Summer time from 1969 to 1974. Switches at midnight. + +# From U. S. Naval Observatory (January 19, 19889): +# ARGENTINA 3 H BEHIND UTC + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Arg 1930 only - Dec 1 0:00 1:00 D +Rule Arg 1931 only - Apr 1 0:00 0 S +Rule Arg 1931 only - Oct 15 0:00 1:00 D +Rule Arg 1932 1940 - Mar 1 0:00 0 S +Rule Arg 1932 1939 - Nov 1 0:00 1:00 D +Rule Arg 1940 only - Jul 1 0:00 1:00 D +Rule Arg 1941 only - Jun 15 0:00 0 S +Rule Arg 1941 only - Oct 15 0:00 1:00 D +Rule Arg 1943 only - Aug 1 0:00 0 S +Rule Arg 1943 only - Oct 15 0:00 1:00 D +Rule Arg 1946 only - Mar 1 0:00 0 S +Rule Arg 1946 only - Oct 1 0:00 1:00 D +Rule Arg 1963 only - Oct 1 0:00 0 S +Rule Arg 1963 only - Dec 15 0:00 1:00 D +Rule Arg 1964 1966 - Mar 1 0:00 0 S +Rule Arg 1964 1966 - Oct 15 0:00 1:00 D +Rule Arg 1967 only - Apr 1 0:00 0 S +Rule Arg 1967 1968 - Oct Sun<=7 0:00 1:00 D +Rule Arg 1968 1969 - Apr Sun<=7 0:00 0 S +Rule Arg 1974 only - Jan 23 0:00 1:00 D +Rule Arg 1974 only - May 1 0:00 0 S +Rule Arg 1974 1976 - Oct Sun<=7 0:00 1:00 D +Rule Arg 1975 1977 - Apr Sun<=7 0:00 0 S +Rule Arg 1985 only - Nov 2 0:00 1:00 D +Rule Arg 1986 only - Mar 14 0:00 0 S +Rule Arg 1986 1987 - Oct 25 0:00 1:00 D +Rule Arg 1987 only - Feb 13 0:00 0 S +Rule Arg 1988 only - Feb 7 0:00 0 S +Rule Arg 1988 only - Dec 1 0:00 1:00 D +Rule Arg 1989 only - Mar 16 0:00 0 S +Rule Arg 1989 only - Oct 15 0:00 1:00 D +Rule Arg 1990 only - Mar 4 0:00 0 S +# _The Economist_ (8 Jan 1994, p 42) reports that Argentina +# had DST in 1991-2 and 1992-3, but not in 1990-1 or in 1993-4. +# It has something to do with electricity companies meeting demand in summer. +# We don't know the 1991-3 transition times, unfortunately. +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Buenos_Aires -3:53:48 - LMT 1894 Nov + -4:17 - CMT 1920 May # Cordoba Mean Time + -4:00 - AST 1930 Dec + -4:00 Arg A%sT 1969 Oct 5 + -3:00 Arg E%sT + +# Bolivia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/La_Paz -4:32:36 - LMT 1890 + -4:33 - LPMT 1931 Oct 15 # La Paz Mean Time + -4:33 1:00 LPDT 1932 Mar 21 + -4:00 - AST + +# Brazil + +# From Guy Harris: +# The OAG lists October 25, 1987 and February 12, 1988 as the starting and +# ending dates, giving them as "estimated date(s) based on previous year". We +# infer a rule here from one example, always a dangerous practice.... Yes, +# they really do switch on Saturday, according to the OAG. +# "Brazil/Acre" is for the Territory of Acre; "Brazil/DeNoronha" is for +# Fernando De Noronha. + +# From Bob Devine (January 28, 1988): +# The only information I found is that there was no DST up to 1985. +# But there was some before 1952! + +# From U. S. Naval Observatory (January 16, 1989): +# BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +# BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +# BRAZIL '89 (ESTIMATED) +# BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +# BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +# BRAZIL CENTRAL '89 (ESTIMATED) +# BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +# BRAZIL EAST PAULO, BRASILIA +# BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +# BRAZIL PAULO, BRASILIA OCT 23, +# BRAZIL '88-FEB 11, '89 +# BRAZIL (ESTIMATED) +# BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +# BRAZIL DE NORONHA +# BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +# BRAZIL (ESTIMATED) +# BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. + +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# The mayor of Rio recently attempted to change the time zone rules +# just in his city, in order to leave more summer time for the tourist trade. +# The rule change lasted only part of the day; +# the federal government refused to follow the city's rules, and business +# was in a chaos, so the mayor backed down that afternoon. +# Shanks claims Acre stopped observing DST after 1988 Feb 7, but it +# could just be that his table ran out of room. We're extrapolating +# about time zone changes after 1990 Feb 11. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Brazil 1914 only - Jan 1 0:00 0 S +Rule Brazil 1931 only - Oct 3 11:00 1 D +Rule Brazil 1932 1933 - Apr 1 0:00 0 S +Rule Brazil 1932 only - Oct 3 0:00 1 D +Rule Brazil 1949 1952 - Dec 1 0:00 1 D +Rule Brazil 1950 only - Apr 16 0:00 0 S +Rule Brazil 1951 1953 - Apr 1 0:00 0 S +Rule Brazil 1963 only - Dec 9 0:00 1 D +Rule Brazil 1964 only - Mar 1 0:00 0 S +Rule Brazil 1965 only - Jan 31 0:00 1 D +Rule Brazil 1965 only - Apr 1 0:00 0 S +Rule Brazil 1965 only - Dec 1 0:00 1 D +Rule Brazil 1966 1968 - Mar 1 0:00 0 S +Rule Brazil 1966 1967 - Nov 1 0:00 1 D +Rule Brazil 1985 only - Nov 2 0:00 1 D +Rule Brazil 1986 only - Mar 15 0:00 0 S +Rule Brazil 1986 1987 - Oct Sat<=28 0:00 1 D +Rule Brazil 1987 only - Feb 14 0:00 0 S +Rule Brazil 1988 only - Feb 7 0:00 0 S +Rule Brazil 1989 only - Jan 22 0:00 0 S +Rule Brazil 1988 max - Oct Sun>=15 0:00 1 D +Rule Brazil 1990 max - Feb Sun>=8 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Noronha -2:09:40 - LMT 1914 + -2:00 - FST 1963 Dec 9 + -2:00 Brazil F%sT +Zone America/Sao_Paulo -3:06:28 - LMT 1914 + -3:00 Brazil E%sT +Zone America/Manaus -4:00:04 - LMT 1914 + -4:00 - WST 1963 Dec 9 + -4:00 Brazil W%sT +# Rio_Branco is too ambiguous, since there's a Rio Branco in Uruguay too. +Zone America/Porto_Acre -4:31:12 - LMT 1914 + -5:00 - AST 1963 Dec 9 + -5:00 Brazil A%sT +# +# Martin Vaz and Trinidade are like America/Noronha. + + +# Chile + +# From Guy Harris: +# The OAG lists October 11, 1987 and March 12, 1988 as the starting and +# ending dates, giving them as "estimated date(s) based on previous year." + +# From Bob Devine (January 28, 1988): +# Chile has had 2nd Sunday in October to 2nd Sunday in March DST since 1977. +# Switch is at midnight. OAG is right. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Chile 1918 only - Sep 1 0:00 1:00 D +Rule Chile 1919 only - Jul 2 0:00 0 S +Rule Chile 1927 1931 - Sep 1 0:00 1:00 D +Rule Chile 1928 1932 - Apr 1 0:00 0 S +Rule Chile 1969 max - Oct Sun>=8 0:00 1:00 D +Rule Chile 1970 max - Mar Sun>=8 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Santiago -4:42:40 - LMT 1890 + -4:43 - SMT 1910 # Santiago Mean Time + -5:00 Chile C%sT 1932 Sep + -4:00 Chile C%sT +Zone Pacific/Easter -7:17:28 - LMT 1890 # Mataveri + -7:17 - MMT 1932 Sep # Mataveri Mean Time + -7:00 Chile M%sT 1982 Mar 14 + -6:00 Chile C%sT +# +# Whitman says Juan Fernandez Is are like America/Santiago. +# San Ambrosio, San Felix +# no information; probably like America/Santiago + + +# Colombia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Bogota -4:56:20 - LMT 1884 Mar 13 + -4:56 - BMT 1914 Nov 23 # Bogota Mean Time + -5:00 - EST +# Malpelo, Providencia, San Andres +# no information; probably like America/Bogota + +# Curacao +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Curacao -4:35:44 - LMT 1912 Feb 12 # Willemstad + -4:30 - NAST 1965 # Netherlands Antilles + -4:00 - AST + +# Ecuador +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guayaquil -5:19:20 - LMT 1890 + -5:14 - QMT 1931 # Quito Mean Time + -5:00 - EST +Zone Pacific/Galapagos -5:58:24 - LMT 1931 # Puerto Baquerizo Moreno + -5:00 - EST 1986 + -6:00 - CST + +# Falklands +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Falk 1912 only - Mar 12 0:00 0 S +Rule Falk 1937 1938 - Sep lastSun 0:00 1:00 D +Rule Falk 1938 1942 - Mar Sun>=19 0:00 0 S +Rule Falk 1939 only - Oct 1 0:00 1:00 D +Rule Falk 1940 1942 - Sep lastSun 0:00 1:00 D +Rule Falk 1943 only - Jan 1 0:00 0 S +Rule Falk 1983 only - Sep lastSun 0:00 1:00 D +Rule Falk 1984 1985 - Apr lastSun 0:00 0 S +Rule Falk 1984 only - Sep 16 0:00 1:00 D +Rule Falk 1985 max - Sep Sun>=9 0:00 1:00 D +Rule Falk 1986 max - Apr Sun>=16 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/Stanley -3:51:24 - LMT 1890 + -3:51 - SMT 1912 Mar 12 # Stanley Mean Time + -4:00 Falk A%sT 1983 May + -3:00 Falk E%sT 1985 Sep 15 + -4:00 Falk A%sT + +# French Guiana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Cayenne -3:29:20 - LMT 1911 Jul + -4:00 - AST 1967 Oct + -3:00 - EST + +# Guyana +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Guyana -3:52:40 - LMT 1915 Mar # Georgetown + -3:45 - BGST 1975 Jul 31 # British Guiana ST + -3:00 - EST + + +# Paraguay + +# From Bob Devine (January 28, 1988): +# Paraguay: First day in October to last in March. Midnight switch?? +# Since 1980. + +# From U. S. Naval Observatory (January 19, 1989): +# PARAGUAY 4 H BEHIND UTC +# PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 + +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Para 1974 only - Apr 1 0:00 0 S +Rule Para 1975 1978 - Oct 1 0:00 1:00 D +Rule Para 1975 1978 - Mar 1 0:00 0 S +# Shanks says 1979 was all DST. +Rule Para 1980 max - Apr 1 0:00 0 S +Rule Para 1980 1988 - Oct 1 0:00 1:00 D +Rule Para 1989 only - Oct 22 0:00 1:00 D +Rule Para 1990 max - Oct 1 0:00 1:00 D +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Asuncion -3:50:40 - LMT 1890 + -3:51 - AMT 1931 Oct 10 # Asuncion Mean Time + -4:00 - AST 1972 Oct + -3:00 - EST 1974 Apr + -4:00 Para A%sT + +# Peru +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Peru 1908 only - Jul 28 0:00 0 S +Rule Peru 1938 only - Jan 1 0:00 1:00 D +Rule Peru 1938 only - Apr 1 0:00 0 S +Rule Peru 1938 1939 - Sep lastSun 0:00 1:00 D +Rule Peru 1939 1940 - Mar Sun>=24 0:00 0 S +Rule Peru 1987 only - Jan 1 0:00 1:00 D +Rule Peru 1987 only - Apr 1 0:00 0 S +Rule Peru 1990 only - Jan 1 0:00 1:00 D +Rule Peru 1990 only - Apr 1 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Lima -5:08:12 - LMT 1890 + -5:09 - LMT 1908 Jul 28 + -5:00 Peru E%sT + +# South Georgia +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Atlantic/South_Georgia -2:26:08 - LMT 1890 # Grytviken + -2:00 - FST + +# South Sandwich Is +# no information + +# Suriname +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Paramaribo -3:40:40 - LMT 1911 + -3:40:52 - PMT 1935 # Paramaribo Mean Time + -3:40:36 - PMT 1945 Oct # The capital moved? + -3:30 - DGST 1984 Oct # Dutch Guiana Std Time + -3:00 - EST + +# Trinidad and Tobago +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Port_of_Spain -4:06:04 - LMT 1912 Mar 2 + -4:00 - AST + +# Uruguay +# From Paul Eggert <eggert@twinsun.com> (November 18, 1993): +# Uruguay wins the prize for the strangest peacetime manipulation of the rules. +# Your guess is as good as mine for what happened after 1989. +# From Shanks (1991): +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Uruguay 1920 only - May 1 0:00 0 S +# Whitman gives 1923 Oct 1; go with Shanks. +Rule Uruguay 1923 only - Oct 2 0:00 0:30 HD +Rule Uruguay 1924 1926 - Apr 1 0:00 0 S +Rule Uruguay 1924 1925 - Oct 1 0:00 0:30 HD +Rule Uruguay 1933 1935 - Oct lastSun 0:00 0:30 HD +# Shanks gives 1935 Apr 1 0:00 and 1936 Mar 30 0:00; go with Whitman. +Rule Uruguay 1934 1936 - Mar Sat>=25 23:30s 0 S +Rule Uruguay 1936 only - Nov 1 0:00 0:30 HD +Rule Uruguay 1937 1941 - Mar lastSun 0:00 0 S +# Whitman gives 1937 Oct 3; go with Shanks. +Rule Uruguay 1937 1940 - Oct lastSun 0:00 0:30 HD +# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13, +# and 1943 Apr 13 ``to present time''; go with Shanks. +Rule Uruguay 1941 only - Aug 1 0:00 0 S +Rule Uruguay 1942 only - Jan 1 0:00 0:30 HD +Rule Uruguay 1942 only - Dec 14 0:00 1:00 D +Rule Uruguay 1943 only - Mar 14 0:00 0 S +Rule Uruguay 1959 only - May 24 0:00 1:00 D +Rule Uruguay 1959 only - Nov 15 0:00 0 S +Rule Uruguay 1960 only - Jan 17 0:00 1:00 D +Rule Uruguay 1960 only - Mar 6 0:00 0 S +Rule Uruguay 1965 1967 - Apr Sun>=1 0:00 1:00 D +Rule Uruguay 1965 only - Sep 26 0:00 0 S +Rule Uruguay 1966 1967 - Oct 31 0:00 0 S +Rule Uruguay 1968 1970 - May 27 0:00 0:30 HD +Rule Uruguay 1968 1970 - Dec 2 0:00 0 S +Rule Uruguay 1972 only - Apr 24 0:00 1:00 D +Rule Uruguay 1972 only - Aug 15 0:00 0 S +Rule Uruguay 1974 only - Mar 10 0:00 0:30 HD +Rule Uruguay 1974 only - Dec 22 0:00 1:00 D +Rule Uruguay 1976 only - Oct 1 0:00 0 S +Rule Uruguay 1977 only - Dec 4 0:00 1:00 D +Rule Uruguay 1978 only - Apr 1 0:00 0 S +Rule Uruguay 1979 only - Oct 1 0:00 1:00 D +Rule Uruguay 1980 only - May 1 0:00 0 S +Rule Uruguay 1987 only - Dec 14 0:00 1:00 D +Rule Uruguay 1988 only - Mar 14 0:00 0 S +Rule Uruguay 1988 only - Dec 11 0:00 1:00 D +Rule Uruguay 1989 only - Mar 12 0:00 0 S +Rule Uruguay 1989 only - Oct 29 0:00 1:00 D +Rule Uruguay 1990 only - Mar 4 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28 + -3:45 - MMT 1920 May 1 # Montevideo MT + -3:30 Uruguay U%sT 1942 Dec 14 # Uruguay ST + -3:00 Uruguay E%sT + +# Venezuela +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone America/Caracas -4:27:44 - LMT 1890 + -4:28 - CMT 1912 Feb 12 # Caracas Mean Time + -4:30 - VZT 1965 # Venezuela Time + -4:00 - AST diff --git a/time/strftime.c b/time/strftime.c new file mode 100644 index 0000000000..ccc19c72b0 --- /dev/null +++ b/time/strftime.c @@ -0,0 +1,296 @@ +/* Extensions for GNU date that are still missing here: + - + _ +*/ + +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <ctype.h> +#include <limits.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#ifndef HAVE_GNU_LD +#define __tzname tzname +#define __daylight daylight +#define __timezone timezone +#endif + + +#define add(n, f) \ + do \ + { \ + i += (n); \ + if (i >= maxsize) \ + return 0; \ + else \ + if (p != NULL) \ + { \ + f; \ + p += (n); \ + } \ + } while (0) +#define cpy(n, s) add((n), memcpy((PTR) p, (PTR) (s), (n))) +#define fmt(n, args) add((n), if (sprintf args != (n)) return 0) + +/* Return the week in the year specified by TP, + with weeks starting on STARTING_DAY. */ +#ifdef __GNUC__ +inline +#endif +static unsigned int +DEFUN(week, (tp, starting_day), + CONST struct tm *CONST tp AND int starting_day) +{ + int wday, dl; + + wday = tp->tm_wday - starting_day; + if (wday < 0) + wday += 7; + + /* Set DL to the day in the year of the last day of the week previous to the + one containing the day specified in TP. If DL is negative or zero, the + day specified in TP is in the first week of the year. Otherwise, + calculate the number of complete weeks before our week (DL / 7) and + add any partial week at the start of the year (DL % 7). */ + dl = tp->tm_yday - wday; + return dl <= 0 ? 0 : ((dl / 7) + ((dl % 7) == 0 ? 0 : 1)); +} + + +/* Write information from TP into S according to the format + string FORMAT, writing no more that MAXSIZE characters + (including the terminating '\0') and returning number of + characters written. If S is NULL, nothing will be written + anywhere, so to determine how many characters would be + written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ +size_t +DEFUN(strftime, (s, maxsize, format, tp), + char *s AND size_t maxsize AND + CONST char *format AND register CONST struct tm *tp) +{ + CONST char *CONST a_wkday = _time_info->abbrev_wkday[tp->tm_wday]; + CONST char *CONST f_wkday = _time_info->full_wkday[tp->tm_wday]; + CONST char *CONST a_month = _time_info->abbrev_month[tp->tm_mon]; + CONST char *CONST f_month = _time_info->full_month[tp->tm_mon]; + size_t aw_len = strlen(a_wkday); + size_t am_len = strlen(a_month); + size_t wkday_len = strlen(f_wkday); + size_t month_len = strlen(f_month); + int hour12 = tp->tm_hour; + CONST char *CONST ampm = _time_info->ampm[hour12 >= 12]; + size_t ap_len = strlen(ampm); + CONST unsigned int y_week0 = week(tp, 0); + CONST unsigned int y_week1 = week(tp, 1); + CONST char *zone; + size_t zonelen; + register size_t i = 0; + register char *p = s; + register CONST char *f; + + if (tp->tm_isdst < 0) + { + zone = ""; + zonelen = 0; + } + else + { + zone = __tzname[tp->tm_isdst]; + zonelen = strlen(zone); + } + + if (hour12 > 12) + hour12 -= 12; + else + if (hour12 == 0) hour12 = 12; + + for (f = format; *f != '\0'; ++f) + { + CONST char *subfmt; + + if (!isascii(*f)) + { + /* Non-ASCII, may be a multibyte. */ + int len = mblen(f, strlen(f)); + if (len > 0) + { + cpy(len, f); + continue; + } + } + + if (*f != '%') + { + add(1, *p = *f); + continue; + } + + ++f; + switch (*f) + { + case '\0': + case '%': + add(1, *p = *f); + break; + + case 'a': + cpy(aw_len, a_wkday); + break; + + case 'A': + cpy(wkday_len, f_wkday); + break; + + case 'b': + case 'h': /* GNU extension. */ + cpy(am_len, a_month); + break; + + case 'B': + cpy(month_len, f_month); + break; + + case 'c': + subfmt = _time_info->date_time; + subformat: + { + size_t len = strftime (p, maxsize - i, subfmt, tp); + add(len, ); + } + break; + + case 'C': + fmt (2, (p, "%.2d", (1900 + tp->tm_year) / 100)); + break; + + case 'D': /* GNU extension. */ + subfmt = "%m/%d/%y"; + goto subformat; + + case 'd': + fmt(2, (p, "%.2d", tp->tm_mday)); + break; + + case 'e': /* GNU extension: %d, but blank-padded. */ + fmt(2, (p, "%2d", tp->tm_mday)); + break; + + case 'H': + fmt(2, (p, "%.2d", tp->tm_hour)); + break; + + case 'I': + fmt(2, (p, "%.2d", hour12)); + break; + + case 'k': /* GNU extension. */ + fmt(2, (p, "%2d", tp->tm_hour)); + break; + + case 'l': /* GNU extension. */ + fmt(2, (p, "%2d", hour12)); + break; + + case 'j': + fmt(3, (p, "%.3d", 1 + tp->tm_yday)); + break; + + case 'M': + fmt(2, (p, "%.2d", tp->tm_min)); + break; + + case 'm': + fmt(2, (p, "%.2d", tp->tm_mon + 1)); + break; + + case 'n': /* GNU extension. */ + add (1, *p = '\n'); + break; + + case 'p': + cpy(ap_len, ampm); + break; + + case 'R': /* GNU extension. */ + subfmt = "%H:%M"; + goto subformat; + + case 'r': /* GNU extension. */ + subfmt = "%I:%M:%S %p"; + goto subformat; + + case 'S': + fmt(2, (p, "%.2d", tp->tm_sec)); + break; + + case 'T': /* GNU extenstion. */ + subfmt = "%H:%M:%S"; + goto subformat; + + case 't': /* GNU extenstion. */ + add (1, *p = '\t'); + break; + + case 'U': + fmt(2, (p, "%.2u", y_week0)); + break; + + case 'W': + fmt(2, (p, "%.2u", y_week1)); + break; + + case 'w': + fmt(2, (p, "%.2d", tp->tm_wday)); + break; + + case 'X': + subfmt = _time_info->time; + goto subformat; + + case 'x': + subfmt = _time_info->date; + goto subformat; + + case 'Y': + fmt(4, (p, "%.4d", 1900 + tp->tm_year)); + break; + + case 'y': + fmt(2, (p, "%.2d", tp->tm_year)); + break; + + case 'Z': + cpy(zonelen, zone); + break; + + default: + /* Bad format. */ + break; + } + } + + if (p != NULL) + *p = '\0'; + return i; +} diff --git a/time/sys/time.h b/time/sys/time.h new file mode 100644 index 0000000000..7275561541 --- /dev/null +++ b/time/sys/time.h @@ -0,0 +1,147 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_TIME_H + +#define _SYS_TIME_H 1 +#include <features.h> + +#include <time.h> + +__BEGIN_DECLS + +/* A time value that is accurate to the nearest + microsecond but also has a range of years. */ +struct timeval + { + int tv_sec; /* Seconds. */ + int tv_usec; /* Microseconds. */ + }; + +/* POSIX.4 structure for a time value. This is like a `struct timeval' but + has nanoseconds instead of microseconds. */ +struct timespec + { + long int ts_sec; /* Seconds. */ + long int ts_nsec; /* Nanoseconds. */ + }; + +/* Macros for converting between `struct timeval' and `struct timespec'. */ +#define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->ts_sec = (tv)->tv_sec; \ + (ts)->ts_nsec = (tv)->tv_usec * 1000; \ +} +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (ts)->ts_sec; \ + (tv)->tv_usec = (ts)->ts_nsec / 1000; \ +} + + +/* Structure crudely representing a timezone. + This is obsolete and should never be used. */ +struct timezone + { + int tz_minuteswest; /* Minutes west of GMT. */ + int tz_dsttime; /* Nonzero if DST is ever in effect. */ + }; + +/* Get the current time of day and timezone information, + putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. + Returns 0 on success, -1 on errors. + NOTE: This form of timezone information is obsolete. + Use the functions and variables declared in <time.h> instead. */ +extern int __gettimeofday __P ((struct timeval *__tv, + struct timezone *__tz)); +extern int gettimeofday __P ((struct timeval *__tv, + struct timezone *__tz)); + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +extern int __settimeofday __P ((__const struct timeval *__tv, + __const struct timezone *__tz)); +extern int settimeofday __P ((__const struct timeval *__tv, + __const struct timezone *__tz)); + +/* Adjust the current time of day by the amount in DELTA. + If OLDDELTA is not NULL, it is filled in with the amount + of time adjustment remaining to be done from the last `adjtime' call. + This call is restricted to the super-user. */ +extern int __adjtime __P ((__const struct timeval *__delta, + struct timeval *__olddelta)); +extern int adjtime __P ((__const struct timeval *__delta, + struct timeval *__olddelta)); + + +/* Values for the first argument to `getitimer' and `setitimer'. */ +enum __itimer_which + { + /* Timers run in real time. */ + ITIMER_REAL = 0, + /* Timers run only when the process is executing. */ + ITIMER_VIRTUAL = 1, + /* Timers run when the process is executing and when + the system is executing on behalf of the process. */ + ITIMER_PROF = 2 + }; + +/* Type of the second argument to `getitimer' and + the second and third arguments `setitimer'. */ +struct itimerval + { + /* Value to put into `it_value' when the timer expires. */ + struct timeval it_interval; + /* Time to the next timer expiration. */ + struct timeval it_value; + }; + +/* Set *VALUE to the current setting of timer WHICH. + Return 0 on success, -1 on errors. */ +extern int __getitimer __P ((enum __itimer_which __which, + struct itimerval *__value)); +extern int getitimer __P ((enum __itimer_which __which, + struct itimerval *__value)); + +/* Set the timer WHICH to *NEW. If OLD is not NULL, + set *OLD to the old value of timer WHICH. + Returns 0 on success, -1 on errors. */ +extern int __setitimer __P ((enum __itimer_which __which, + struct itimerval *__new, + struct itimerval *__old)); +extern int setitimer __P ((enum __itimer_which __which, + struct itimerval *__new, + struct itimerval *__old)); + +/* Change the access time of FILE to TVP[0] and + the modification time of FILE to TVP[1]. */ +extern int __utimes __P ((__const char *__file, struct timeval __tvp[2])); +extern int utimes __P ((__const char *__file, struct timeval __tvp[2])); + + +/* Convenience macros for operations on timevals. + NOTE: `timercmp' does not work for >= or <=. */ +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, CMP) \ + ((tvp)->tv_sec CMP (uvp)->tv_sec || \ + (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec CMP (uvp)->tv_usec) +#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) + + + +__END_DECLS + +#endif /* sys/time.h */ diff --git a/time/sys/timeb.h b/time/sys/timeb.h new file mode 100644 index 0000000000..965cb3deba --- /dev/null +++ b/time/sys/timeb.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_TIMEB_H + +#define _SYS_TIMEB_H 1 +#include <features.h> + +#define __need_time_t +#include <time.h> + + +/* Structure returned by the `ftime' function. */ + +struct timeb + { + time_t time; /* Seconds since epoch, as from `time'. */ + unsigned short int millitm; /* Additional milliseconds. */ + short int timezone; /* Minutes west of GMT. */ + short int dstflag; /* Nonzero if Daylight Savings Time used. */ + }; + +/* Fill in TIMEBUF with information about the current time. */ + +extern int ftime __P ((struct timeb *__timebuf)); + + +#endif /* sys/timeb.h */ diff --git a/time/systemv b/time/systemv new file mode 100644 index 0000000000..a6f79d231a --- /dev/null +++ b/time/systemv @@ -0,0 +1,35 @@ +# @(#)systemv 7.2 + +# Old rules, should the need arise. +# No attempt is made to handle Newfoundland, since it cannot be expressed +# using the System V "TZ" scheme (half-hour offset), or anything outside +# North America (no support for non-standard DST start/end dates), nor +# the change in the DST rules in the US in 1987 (can't split between +# Canada, with no changes, and the US) +# +# Be sure to compile this *without* leap second correction for true conformance. + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule SystemV min 1973 - Apr lastSun 2:00 1:00 D +Rule SystemV min 1973 - Oct lastSun 2:00 0 S +Rule SystemV 1974 only - Jan 6 2:00 1:00 D +Rule SystemV 1974 only - Nov lastSun 2:00 0 S +Rule SystemV 1975 only - Feb 23 2:00 1:00 D +Rule SystemV 1975 only - Oct lastSun 2:00 0 S +Rule SystemV 1976 max - Apr lastSun 2:00 1:00 D +Rule SystemV 1976 max - Oct lastSun 2:00 0 S + +# Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone SystemV/AST4ADT -4:00 SystemV A%sT +Zone SystemV/EST5EDT -5:00 SystemV E%sT +Zone SystemV/CST6CDT -6:00 SystemV C%sT +Zone SystemV/MST7MDT -7:00 SystemV M%sT +Zone SystemV/PST8PDT -8:00 SystemV P%sT +Zone SystemV/YST9YDT -9:00 SystemV Y%sT +Zone SystemV/AST4 -4:00 - AST +Zone SystemV/EST5 -5:00 - EST +Zone SystemV/CST6 -6:00 - CST +Zone SystemV/MST7 -7:00 - MST +Zone SystemV/PST8 -8:00 - PST +Zone SystemV/YST9 -9:00 - YST +Zone SystemV/HST10 -10:00 - HST diff --git a/time/test_time.args b/time/test_time.args new file mode 100644 index 0000000000..d84cd1c066 --- /dev/null +++ b/time/test_time.args @@ -0,0 +1,2 @@ +EST5EDT +CST diff --git a/time/test_time.c b/time/test_time.c new file mode 100644 index 0000000000..a090d93db4 --- /dev/null +++ b/time/test_time.c @@ -0,0 +1,117 @@ +/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + + +int +DEFUN(main, (argc, argv), int argc AND char **argv) +{ + time_t t; + register struct tm *tp; + struct tm tbuf; + int lose = 0; + + --argc; + ++argv; + + do + { + char buf[BUFSIZ]; + if (argc > 0) + { + static char buf[BUFSIZ]; + sprintf(buf, "TZ=%s", *argv); + if (putenv(buf)) + { + puts("putenv failed."); + lose = 1; + } + else + puts (buf); + } + tzset(); + tbuf.tm_year = 72; + tbuf.tm_mon = 0; + tbuf.tm_mday = 31; + tbuf.tm_hour = 6; + tbuf.tm_min = 14; + tbuf.tm_sec = 50; + tbuf.tm_isdst = -1; + doit:; + t = mktime(&tbuf); + if (t == (time_t) -1) + { + puts("mktime() failed?"); + lose = 1; + } + tp = localtime(&t); + if (tp == NULL) + { + puts("localtime() failed."); + lose = 1; + } + else if (strftime(buf, sizeof(buf), "%a %b %d %X %Z %Y", tp) == 0) + { + puts("strftime() failed."); + lose = 1; + } + else + puts(buf); + if (tbuf.tm_year == 101) + { + tbuf.tm_year = 97; + tbuf.tm_mon = 0; + goto doit; + } + ++argv; + } while (--argc > 0); + + { +#define SIZE 256 + char buffer[SIZE]; + time_t curtime; + struct tm *loctime; + + curtime = time (NULL); + + loctime = localtime (&curtime); + + fputs (asctime (loctime), stdout); + + strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime); + fputs (buffer, stdout); + strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime); + fputs (buffer, stdout); + + loctime->tm_year = 72; + loctime->tm_mon = 8; + loctime->tm_mday = 12; + loctime->tm_hour = 20; + loctime->tm_min = 49; + loctime->tm_sec = 05; + curtime = mktime (loctime); + strftime (buffer, SIZE, "%D %T was %w the %jth.\n", loctime); + fputs (buffer, stdout); + } + + return (lose ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/time/time.h b/time/time.h new file mode 100644 index 0000000000..7070881949 --- /dev/null +++ b/time/time.h @@ -0,0 +1,204 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.12 DATE and TIME <time.h> + */ + +#ifndef _TIME_H + +#if !defined(__need_time_t) && !defined(__need_clock_t) +#define _TIME_H 1 +#include <features.h> + +__BEGIN_DECLS + +#endif + +#ifdef _TIME_H +/* Get size_t and NULL from <stddef.h>. */ +#define __need_size_t +#define __need_NULL +#include <stddef.h> +#endif /* <time.h> included. */ + + + +#ifdef _TIME_H +/* Processor clock ticks per second. */ +#define CLOCKS_PER_SEC 1 /* ??? */ + +#ifdef __USE_POSIX +#define CLK_TCK 60 /* ??? */ +#endif + +#endif /* <time.h> included. */ + + +#if !defined(__clock_t_defined) && \ + (defined(_TIME_H) || defined(__need_clock_t)) +#define __clock_t_defined 1 + +/* Returned by `clock'. */ +typedef long int clock_t; + +#endif /* clock_t not defined and <time.h> or need clock_t. */ +#undef __need_clock_t + +#if !defined(__time_t_defined) && \ + (defined(_TIME_H) || defined(__need_time_t)) +#define __time_t_defined 1 + +#include <gnu/types.h> + +/* Returned by `time'. */ +typedef __time_t time_t; + +#endif /* time_t not defined and <time.h> or need time_t. */ +#undef __need_time_t + + +#ifdef _TIME_H +/* Used by other time functions. */ +struct tm +{ + int tm_sec; /* Seconds. [0-61] (2 leap seconds) */ + int tm_min; /* Minutes. [0-59] */ + int tm_hour; /* Hours. [0-23] */ + int tm_mday; /* Day. [1-31] */ + int tm_mon; /* Month. [0-11] */ + int tm_year; /* Year - 1900. */ + int tm_wday; /* Day of week. [0-6] */ + int tm_yday; /* Days in year.[0-365] */ + int tm_isdst; /* DST. [-1/0/1]*/ + long int tm_gmtoff; /* Seconds west of UTC. */ + __const char *tm_zone; /* Timezone abbreviation. */ +}; + +#endif /* <time.h> included. */ + + +#ifdef _TIME_H +/* Time used by the program so far (user time + system time). + The result / CLOCKS_PER_SECOND is program time in seconds. */ +extern clock_t clock __P ((void)); + +/* Return the current time and put it in *TIMER if TIMER is not NULL. */ +extern time_t time __P ((time_t *__timer)); + +/* Return the difference between TIME1 and TIME0. */ +extern double difftime __P ((time_t __time1, time_t __time0)) + __attribute__ ((__const__)); + +/* Return the `time_t' representation of TP and normalize TP. */ +extern time_t mktime __P ((struct tm *__tp)); + +/* Subroutine of `mktime'. Return the `time_t' representation of TP and + normalize TP, given that a `struct tm *' maps to a `time_t' as performed + by FUNC. */ +extern time_t _mktime_internal __P ((struct tm *__tp, + struct tm *(*__func) (const time_t *))); + + +/* Format TP into S according to FORMAT. + Write no more than MAXSIZE characters and return the number + of characters written, or 0 if it would exceed MAXSIZE. */ +extern size_t strftime __P ((char *__s, size_t __maxsize, + __const char *__format, __const struct tm *__tp)); + + +/* Return the `struct tm' representation of *TIMER + in Universal Coordinated Time (aka Greenwich Mean Time). */ +extern struct tm *gmtime __P ((__const time_t *__timer)); + +/* Return the `struct tm' representation + of *TIMER in the local timezone. */ +extern struct tm *localtime __P ((__const time_t *__timer)); + +/* Return the `struct tm' representation of *TIMER, + offset OFFSET seconds east of Universal Coordinated Time. */ +extern struct tm *__offtime __P ((__const time_t *__timer, + long int __offset)); + +/* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n" + that is the representation of TP in this format. */ +extern char *asctime __P ((__const struct tm *__tp)); + +/* Equivalent to `asctime(localtime(timer))'. */ +extern char *ctime __P ((__const time_t *__timer)); + + +/* Defined in localtime.c. */ +extern char *__tzname[2]; /* Current timezone names. */ +extern int __daylight; /* If it is daylight savings time. */ +extern long int __timezone; /* Seconds west of UTC. */ + +/* Set time conversion information from the TZ environment variable. + If TZ is not defined, a locale-dependent default is used. */ +extern void __tzset __P ((void)); + +#ifdef __USE_POSIX +/* Same as above. */ +extern char *tzname[2]; + +/* Return the maximum length of a timezone name. + This is what `sysconf (_SC_TZNAME_MAX)' does. */ +extern long int __tzname_max __P ((void)); + +extern void tzset __P ((void)); +#ifdef __OPTIMIZE__ +#define tzset() __tzset() +#endif /* Optimizing. */ +#endif + +#ifdef __USE_SVID +extern int daylight; +extern long int timezone; + +/* Set the system time to *WHEN. + This call is restricted to the superuser. */ +extern int stime __P ((__const time_t *__when)); +#endif + + +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + + +#ifdef __USE_MISC +/* Miscellaneous functions many Unices inherited from the public domain + localtime package. These are included only for compatibility. */ + +/* Like `mktime', but for TP represents Universal Time, not local time. */ +extern time_t timegm __P ((struct tm *__tp)); + +/* Another name for `mktime'. */ +extern time_t timelocal __P ((struct tm *__tp)); + +/* Return the number of days in YEAR. */ +extern int dysize __P ((int __year)); +#endif + + +__END_DECLS + +#endif /* <time.h> included. */ + +#endif /* <time.h> not already included. */ diff --git a/time/timegm.c b/time/timegm.c new file mode 100644 index 0000000000..dc80f78683 --- /dev/null +++ b/time/timegm.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <time.h> + +time_t +timegm (tmp) + struct tm *const tmp; +{ + tmp->tm_isdst = 0; + return _mktime_internal (tmp, gmtime); +} diff --git a/time/tzfile.c b/time/tzfile.c new file mode 100644 index 0000000000..841f598c87 --- /dev/null +++ b/time/tzfile.c @@ -0,0 +1,332 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <string.h> +#include <limits.h> + +#define NOID +#include <tzfile.h> + +#ifndef HAVE_GNU_LD +#define __tzname tzname +#define __daylight daylight +#define __timezone timezone +#endif + +int __use_tzfile = 0; + +struct ttinfo + { + long int offset; /* Seconds east of GMT. */ + unsigned char isdst; /* Used to set tm_isdst. */ + unsigned char idx; /* Index into `zone_names'. */ + unsigned char isstd; /* Transition times are standard time. */ + }; + +struct leap + { + time_t transition; /* Time the transition takes effect. */ + long int change; /* Seconds of correction to apply. */ + }; + +static void compute_tzname_max __P ((size_t)); + +static size_t num_transitions; +static time_t *transitions = NULL; +static unsigned char *type_idxs = NULL; +static size_t num_types; +static struct ttinfo *types = NULL; +static char *zone_names = NULL; +static size_t num_leaps; +static struct leap *leaps = NULL; + +#define uc2ul(x) _uc2ul((unsigned char *) (x)) +#define _uc2ul(x) \ + ((x)[3] + ((x)[2] << CHAR_BIT) + ((x)[1] << (2 * CHAR_BIT)) + \ + ((x)[0] << (3 * CHAR_BIT))) + +void +DEFUN(__tzfile_read, (file), CONST char *file) +{ + size_t num_isstd; + register FILE *f; + struct tzhead tzhead; + size_t chars; + register size_t i; + + __use_tzfile = 0; + + if (transitions != NULL) + free((PTR) transitions); + transitions = NULL; + if (type_idxs != NULL) + free((PTR) type_idxs); + type_idxs = NULL; + if (types != NULL) + free((PTR) types); + types = NULL; + if (zone_names != NULL) + free((PTR) zone_names); + zone_names = NULL; + if (leaps != NULL) + free((PTR) leaps); + leaps = NULL; + + if (file == NULL || *file == '\0') + file = TZDEFAULT; + + if (*file != '/') + { + static CONST char tzdir[] = TZDIR; + register CONST unsigned int len = strlen(file) + 1; + char *new = (char *) __alloca(sizeof(tzdir) + len); + memcpy(new, tzdir, sizeof(tzdir) - 1); + new[sizeof(tzdir) - 1] = '/'; + memcpy(&new[sizeof(tzdir)], file, len); + file = new; + } + + f = fopen(file, "r"); + if (f == NULL) + return; + + if (fread((PTR) &tzhead, sizeof(tzhead), 1, f) != 1) + goto lose; + + num_transitions = (size_t) uc2ul(tzhead.tzh_timecnt); + num_types = (size_t) uc2ul(tzhead.tzh_typecnt); + chars = (size_t) uc2ul(tzhead.tzh_charcnt); + num_leaps = (size_t) uc2ul(tzhead.tzh_leapcnt); + num_isstd = (size_t) uc2ul(tzhead.tzh_ttisstdcnt); + + if (num_transitions > 0) + { + transitions = (time_t *) malloc (num_transitions * sizeof(time_t)); + if (transitions == NULL) + goto lose; + type_idxs = (unsigned char *) malloc (num_transitions); + if (type_idxs == NULL) + goto lose; + } + if (num_types > 0) + { + types = (struct ttinfo *) malloc (num_types * sizeof (struct ttinfo)); + if (types == NULL) + goto lose; + } + if (chars > 0) + { + zone_names = (char *) malloc (chars); + if (zone_names == NULL) + goto lose; + } + if (num_leaps > 0) + { + leaps = (struct leap *) malloc (num_leaps * sizeof (struct leap)); + if (leaps == NULL) + goto lose; + } + + if (fread((PTR) transitions, sizeof(time_t), + num_transitions, f) != num_transitions || + fread((PTR) type_idxs, 1, num_transitions, f) != num_transitions) + goto lose; + + for (i = 0; i < num_transitions; ++i) + transitions[i] = uc2ul (&transitions[i]); + + for (i = 0; i < num_types; ++i) + { + unsigned char x[4]; + if (fread((PTR) x, 1, 4, f) != 4 || + fread((PTR) &types[i].isdst, 1, 1, f) != 1 || + fread((PTR) &types[i].idx, 1, 1, f) != 1) + goto lose; + types[i].offset = (long int) uc2ul(x); + } + + if (fread((PTR) zone_names, 1, chars, f) != chars) + goto lose; + + for (i = 0; i < num_leaps; ++i) + { + unsigned char x[4]; + if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x)) + goto lose; + leaps[i].transition = (time_t) uc2ul(x); + if (fread((PTR) x, 1, sizeof(x), f) != sizeof(x)) + goto lose; + leaps[i].change = (long int) uc2ul(x); + } + + for (i = 0; i < num_isstd; ++i) + { + char c = getc(f); + if (c == EOF) + goto lose; + types[i].isstd = c != 0; + } + while (i < num_types) + types[i++].isstd = 0; + + (void) fclose(f); + + compute_tzname_max (chars); + + __use_tzfile = 1; + return; + + lose:; + (void) fclose(f); +} + +void +DEFUN(__tzfile_default, (std, dst, stdoff, dstoff), + char *std AND char *dst AND + long int stdoff AND long int dstoff) +{ + size_t stdlen, dstlen, i; + + __tzfile_read (TZDEFRULES); + if (!__use_tzfile) + return; + + if (num_types < 2) + { + __use_tzfile = 0; + return; + } + + free (zone_names); + + stdlen = strlen (std) + 1; + dstlen = strlen (dst) + 1; + zone_names = malloc (stdlen + dstlen); + if (zone_names == NULL) + { + __use_tzfile = 0; + return; + } + memcpy (zone_names, std, stdlen); + memcpy (&zone_names[stdlen], dst, dstlen); + + for (i = 0; i < num_types; ++i) + if (types[i].isdst) + { + types[i].idx = stdlen; + if (dst[0] != '\0') + types[i].offset = dstoff; + } + else + { + types[i].idx = 0; + if (dst[0] != '\0') + types[i].offset = stdoff; + } + + compute_tzname_max (stdlen + dstlen); +} + +int +DEFUN(__tzfile_compute, (timer, leap_correct, leap_hit), + time_t timer AND long int *leap_correct AND int *leap_hit) +{ + struct ttinfo *info; + register size_t i; + + if (num_transitions == 0 || timer < transitions[0]) + { + /* TIMER is before any transition (or there are no transitions). + Choose the first non-DST type + (or the first if they're all DST types). */ + i = 0; + while (i < num_types && types[i].isdst) + ++i; + if (i == num_types) + i = 0; + } + else + { + /* Find the first transition after TIMER, and + then pick the type of the transition before it. */ + for (i = 1; i < num_transitions; ++i) + if (timer < transitions[i]) + break; + i = type_idxs[i - 1]; + } + + info = &types[i]; + __daylight = info->isdst; + __timezone = info->offset; + for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]); + ++i) + __tzname[types[i].isdst] = &zone_names[types[i].idx]; + if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0])) + __tzname[info->isdst] = &zone_names[info->idx]; + + *leap_correct = 0L; + *leap_hit = 0; + + /* Find the last leap second correction transition time before TIMER. */ + i = num_leaps; + do + if (i-- == 0) + return 1; + while (timer < leaps[i].transition); + + /* Apply its correction. */ + *leap_correct = leaps[i].change; + + if (timer == leaps[i].transition && /* Exactly at the transition time. */ + ((i == 0 && leaps[i].change > 0) || + leaps[i].change > leaps[i - 1].change)) + { + *leap_hit = 1; + while (i > 0 && + leaps[i].transition == leaps[i - 1].transition + 1 && + leaps[i].change == leaps[i - 1].change + 1) + { + ++*leap_hit; + --i; + } + } + + return 1; +} + +void +DEFUN(compute_tzname_max, (chars), size_t chars) +{ + extern long int __tzname_cur_max; /* Defined in __tzset.c. */ + + const char *p; + + p = zone_names; + do + { + const char *start = p; + while (*p != '\0') + ++p; + if (p - start > __tzname_cur_max) + __tzname_cur_max = p - start; + } while (++p < &zone_names[chars]); +} diff --git a/time/tzfile.h b/time/tzfile.h new file mode 100644 index 0000000000..45b4d7d606 --- /dev/null +++ b/time/tzfile.h @@ -0,0 +1,170 @@ +#ifndef TZFILE_H + +#define TZFILE_H + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +static char tzfilehid[] = "@(#)tzfile.h 7.4"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ + +#ifndef TZDEFAULT +#define TZDEFAULT "localtime" +#endif /* !defined TZDEFAULT */ + +#ifndef TZDEFRULES +#define TZDEFRULES "posixrules" +#endif /* !defined TZDEFRULES */ + +/* +** Each file begins with. . . +*/ + +struct tzhead { + char tzh_reserved[24]; /* reserved for future use */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +/* +** . . .followed by. . . +** +** tzh_timecnt (char [4])s coded transition times a la time(2) +** tzh_timecnt (unsigned char)s types of local time starting at above +** tzh_typecnt repetitions of +** one (char [4]) coded GMT offset in seconds +** one (unsigned char) used to set tm_isdst +** one (unsigned char) that's an abbreviation list index +** tzh_charcnt (char)s '\0'-terminated zone abbreviations +** tzh_leapcnt repetitions of +** one (char [4]) coded leap second transition times +** one (char [4]) total correction after above +** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition +** time is standard time, if FALSE, +** transition time is wall clock time +** if absent, transition times are +** assumed to be wall clock time +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +/* +** The TZ_MAX_TIMES value below is enough to handle a bit more than a +** year's worth of solar time (corrected daily to the nearest second) or +** 138 years of Pacific Presidential Election time +** (where there are three time zone transitions every fourth year). +*/ +#define TZ_MAX_TIMES 370 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +#ifndef NOSOLAR +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined NOSOLAR */ +#ifdef NOSOLAR +#define TZ_MAX_TYPES 10 /* Maximum number of local time types */ +#endif /* !defined NOSOLAR */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +/* +** Accurate only for the past couple of centuries; +** that will probably do. +*/ + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +#ifndef USG + +/* +** Use of the underscored variants may cause problems if you move your code to +** certain System-V-based systems; for maximum portability, use the +** underscore-free variants. The underscored variants are provided for +** backward compatibility only; they may disappear from future versions of +** this file. +*/ + +#define SECS_PER_MIN SECSPERMIN +#define MINS_PER_HOUR MINSPERHOUR +#define HOURS_PER_DAY HOURSPERDAY +#define DAYS_PER_WEEK DAYSPERWEEK +#define DAYS_PER_NYEAR DAYSPERNYEAR +#define DAYS_PER_LYEAR DAYSPERLYEAR +#define SECS_PER_HOUR SECSPERHOUR +#define SECS_PER_DAY SECSPERDAY +#define MONS_PER_YEAR MONSPERYEAR + +#endif /* !defined USG */ + +#endif /* !defined TZFILE_H */ diff --git a/time/tzset.c b/time/tzset.c new file mode 100644 index 0000000000..e4d5209e88 --- /dev/null +++ b/time/tzset.c @@ -0,0 +1,487 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <localeinfo.h> +#include <ctype.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +/* Defined in mktime.c. */ +extern CONST unsigned short int __mon_lengths[2][12]; + +#define NOID +#include "tzfile.h" + +extern int __use_tzfile; +extern void EXFUN(__tzfile_read, (CONST char *file)); +extern void EXFUN(__tzfile_default, (char *std AND char *dst AND + long int stdoff AND long int dstoff)); +extern int EXFUN(__tzfile_compute, (time_t, struct tm)); + +#ifndef HAVE_WEAK_SYMBOLS +#define __tzname tzname +#define __daylight daylight +#define __timezone timezone +#else +weak_alias (__tzname, tzname) +weak_alias (__daylight, daylight) +weak_alias (__timezone, timezone) +#endif + +char *__tzname[2] = { (char *) "GMT", (char *) "GMT" }; +int __daylight = 0; +long int __timezone = 0L; + + +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define sign(x) ((x) < 0 ? -1 : 1) + + +/* This structure contains all the information about a + timezone given in the POSIX standard TZ envariable. */ +typedef struct + { + char *name; + + /* When to change. */ + enum { J0, J1, M } type; /* Interpretation of: */ + unsigned short int m, n, d; /* Month, week, day. */ + unsigned int secs; /* Time of day. */ + + long int offset; /* Seconds east of GMT (west if < 0). */ + + /* We cache the computed time of change for a + given year so we don't have to recompute it. */ + time_t change; /* When to change to this zone. */ + int computed_for; /* Year above is computed for. */ + } tz_rule; + +/* tz_rules[0] is standard, tz_rules[1] is daylight. */ +static tz_rule tz_rules[2]; + +int __tzset_run = 0; + +/* Interpret the TZ envariable. */ +void +DEFUN_VOID(__tzset) +{ + register CONST char *tz; + register size_t l; + unsigned short int hh, mm, ss; + unsigned short int whichrule; + + /* Free old storage. */ + if (tz_rules[0].name != NULL && *tz_rules[0].name != '\0') + free((PTR) tz_rules[0].name); + if (tz_rules[1].name != NULL && *tz_rules[1].name != '\0' && + tz_rules[1].name != tz_rules[0].name) + free((PTR) tz_rules[1].name); + + tz = getenv("TZ"); + + if (tz != NULL && *tz == ':') + { + __tzfile_read(tz + 1); + if (__use_tzfile) + { + __tzset_run = 1; + return; + } + else + tz = NULL; + } + + if (tz == NULL || *tz == '\0') + tz = _time_info->tz; + if (tz == NULL || *tz == '\0') + { + __tzfile_read((char *) NULL); + if (!__use_tzfile) + { + size_t len = strlen(_time_info->ut0) + 1; + tz_rules[0].name = (char *) malloc(len); + if (tz_rules[0].name == NULL) + return; + tz_rules[1].name = (char *) malloc(len); + if (tz_rules[1].name == NULL) + return; + memcpy((PTR) tz_rules[0].name, _time_info->ut0, len); + memcpy((PTR) tz_rules[1].name, _time_info->ut0, len); + tz_rules[0].type = tz_rules[1].type = J0; + tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0; + tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0; + tz_rules[0].secs = tz_rules[1].secs = 0; + tz_rules[0].offset = tz_rules[1].offset = 0L; + tz_rules[0].change = tz_rules[1].change = (time_t) -1; + tz_rules[0].computed_for = tz_rules[1].computed_for = 0; + } + __tzset_run = 1; + return; + } + + /* Clear out old state and reset to unnamed GMT. */ + memset (tz_rules, 0, sizeof tz_rules); + tz_rules[0].name = tz_rules[1].name = (char *) ""; + + /* Get the standard timezone name. */ + tz_rules[0].name = (char *) malloc (strlen (tz) + 1); + if (tz_rules[0].name == NULL) + /* Don't set __tzset_run so we will try again. */ + return; + + if (sscanf(tz, "%[^0-9,+-]", tz_rules[0].name) != 1 || + (l = strlen(tz_rules[0].name)) < 3) + { + free (tz_rules[0].name); + tz_rules[0].name = (char *) ""; + return; + } + + { + char *n = realloc ((PTR) tz_rules[0].name, l + 1); + if (n != NULL) + tz_rules[0].name = n; + } + + tz += l; + + /* Figure out the standard offset from GMT. */ + if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit(*tz))) + return; + + if (*tz == '-' || *tz == '+') + tz_rules[0].offset = *tz++ == '-' ? 1L : -1L; + else + tz_rules[0].offset = -1L; + switch (sscanf (tz, "%hu:%hu:%hu", &hh, &mm, &ss)) + { + default: + return; + case 1: + mm = 0; + case 2: + ss = 0; + case 3: + break; + } + tz_rules[0].offset *= (min(ss, 59) + (min(mm, 59) * 60) + + (min(hh, 12) * 60 * 60)); + + for (l = 0; l < 3; ++l) + { + while (isdigit(*tz)) + ++tz; + if (l < 2 && *tz == ':') + ++tz; + } + + /* Get the DST timezone name (if any). */ + if (*tz != '\0') + { + char *n = malloc (strlen(tz) + 1); + if (n != NULL) + { + tz_rules[1].name = n; + if (sscanf(tz, "%[^0-9,+-]", tz_rules[1].name) != 1 || + (l = strlen(tz_rules[1].name)) < 3) + { + free (n); + tz_rules[1].name = (char *) ""; + goto done_names; /* Punt on name, set up the offsets. */ + } + n = realloc ((PTR) tz_rules[1].name, l + 1); + if (n != NULL) + tz_rules[1].name = n; + } + } + + tz += l; + + /* Figure out the DST offset from GMT. */ + if (*tz == '-' || *tz == '+') + tz_rules[1].offset = *tz++ == '-' ? 1L : -1L; + else + tz_rules[1].offset = -1L; + + switch (sscanf (tz, "%hu:%hu:%hu", &hh, &mm, &ss)) + { + default: + /* Default to one hour later than standard time. */ + tz_rules[1].offset = tz_rules[0].offset + (60 * 60); + break; + + case 1: + mm = 0; + case 2: + ss = 0; + case 3: + tz_rules[1].offset *= (min(ss, 59) + (min(mm, 59) * 60) + + (min(hh, 12) * (60 * 60))); + break; + } + for (l = 0; l < 3; ++l) + { + while (isdigit (*tz)) + ++tz; + if (l < 2 && *tz == ':') + ++tz; + } + + done_names: + + if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) + { + /* There is no rule. See if there is a default rule file. */ + __tzfile_default (tz_rules[0].name, tz_rules[1].name, + tz_rules[0].offset, tz_rules[1].offset); + if (__use_tzfile) + { + __tzset_run = 1; + return; + } + } + + /* Figure out the standard <-> DST rules. */ + for (whichrule = 0; whichrule < 2; ++whichrule) + { + register tz_rule *tzr = &tz_rules[whichrule]; + + if (*tz == ',') + { + ++tz; + if (*tz == '\0') + return; + } + + /* Get the date of the change. */ + if (*tz == 'J' || isdigit (*tz)) + { + char *end; + tzr->type = *tz == 'J' ? J1 : J0; + if (tzr->type == J1 && !isdigit (*++tz)) + return; + tzr->d = (unsigned short int) strtoul (tz, &end, 10); + if (end == tz || tzr->d > 365) + return; + else if (tzr->type == J1 && tzr->d == 0) + return; + tz = end; + } + else if (*tz == 'M') + { + int n; + tzr->type = M; + if (sscanf (tz, "M%hu.%hu.%hu%n", + &tzr->m, &tzr->n, &tzr->d, &n) != 3 || + tzr->m < 1 || tzr->m > 12 || + tzr->n < 1 || tzr->n > 5 || tzr->d > 6) + return; + tz += n; + } + else if (*tz == '\0') + { + /* United States Federal Law, the equivalent of "M4.1.0,M10.5.0". */ + tzr->type = M; + if (tzr == &tz_rules[0]) + { + tzr->m = 4; + tzr->n = 1; + tzr->d = 0; + } + else + { + tzr->m = 10; + tzr->n = 5; + tzr->d = 0; + } + } + else + return; + + if (*tz != '\0' && *tz != '/' && *tz != ',') + return; + else if (*tz == '/') + { + /* Get the time of day of the change. */ + ++tz; + if (*tz == '\0') + return; + switch (sscanf (tz, "%hu:%hu:%hu", &hh, &mm, &ss)) + { + default: + hh = 2; /* Default to 2:00 AM. */ + case 1: + mm = 0; + case 2: + ss = 0; + case 3: + break; + } + for (l = 0; l < 3; ++l) + { + while (isdigit(*tz)) + ++tz; + if (l < 2 && *tz == ':') + ++tz; + } + tzr->secs = (hh * 60 * 60) + (mm * 60) + ss; + } + else + /* Default to 2:00 AM. */ + tzr->secs = 2 * 60 * 60; + + tzr->computed_for = -1; + } + + __tzset_run = 1; +} + +/* Maximum length of a timezone name. __tz_compute keeps this up to date + (never decreasing it) when ! __use_tzfile. + tzfile.c keeps it up to date when __use_tzfile. */ +long int __tzname_cur_max; + +long int +DEFUN_VOID(__tzname_max) +{ + if (! __tzset_run) + __tzset (); + + return __tzname_cur_max; +} + +/* Figure out the exact time (as a time_t) in YEAR + when the change described by RULE will occur and + put it in RULE->change, saving YEAR in RULE->computed_for. + Return nonzero if successful, zero on failure. */ +static int +DEFUN(compute_change, (rule, year), tz_rule *rule AND int year) +{ + register time_t t; + int y; + + if (year != -1 && rule->computed_for == year) + /* Operations on times in 1969 will be slower. Oh well. */ + return 1; + + /* First set T to January 1st, 0:00:00 GMT in YEAR. */ + t = 0; + for (y = 1970; y < year; ++y) + t += SECSPERDAY * (__isleap (y) ? 366 : 365); + + switch (rule->type) + { + case J1: + /* 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. */ + t += (rule->d - 1) * SECSPERDAY; + if (rule->d >= 60 && __isleap (year)) + t += SECSPERDAY; + break; + + case J0: + /* n - Day of year. + Just add SECSPERDAY times the day number to the time of Jan 1st. */ + t += rule->d * SECSPERDAY; + break; + + case M: + /* Mm.n.d - Nth "Dth day" of month M. */ + { + register int i, d, m1, yy0, yy1, yy2, dow; + + /* First add SECSPERDAY for each day in months before M. */ + for (i = 0; i < rule->m - 1; ++i) + t += __mon_lengths[__isleap (year)][i] * SECSPERDAY; + + /* Use Zeller's Congruence to get day-of-week of first day of month. */ + m1 = (rule->m + 9) % 12 + 1; + yy0 = (rule->m <= 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 += 7; + + /* 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 = rule->d - dow; + if (d < 0) + d += 7; + for (i = 1; i < rule->n; ++i) + { + if (d + 7 >= __mon_lengths[__isleap (year)][rule->m - 1]) + break; + d += 7; + } + + /* D is the day-of-month (zero-origin) of the day we want. */ + t += d * SECSPERDAY; + } + break; + } + + /* T is now the Epoch-relative time of 0:00:00 GMT on the day we want. + Just add the time of day and local offset from GMT, and we're done. */ + + rule->change = t + rule->offset + rule->secs; + rule->computed_for = year; + return 1; +} + + +/* Figure out the correct timezone for *TIMER and TM (which must be the same) + and set `__tzname', `__timezone', and `__daylight' accordingly. + Return nonzero on success, zero on failure. */ +int +DEFUN(__tz_compute, (timer, tm), + time_t timer AND const struct tm *tm) +{ + if (! __tzset_run) + __tzset (); + + if (! compute_change (&tz_rules[0], 1900 + tm->tm_year) || + ! compute_change (&tz_rules[1], 1900 + tm->tm_year)) + return 0; + + __daylight = timer >= tz_rules[0].change && timer < tz_rules[1].change; + __timezone = tz_rules[__daylight ? 1 : 0].offset; + __tzname[0] = (char *) tz_rules[0].name; + __tzname[1] = (char *) tz_rules[1].name; + + { + /* Keep __tzname_cur_max up to date. */ + size_t len0 = strlen (__tzname[0]); + size_t len1 = strlen (__tzname[1]); + if (len0 > __tzname_cur_max) + __tzname_cur_max = len0; + if (len1 > __tzname_cur_max) + __tzname_cur_max = len1; + } + + return 1; +} + +weak_alias (__tzset, tzset) diff --git a/time/yearistype b/time/yearistype new file mode 100755 index 0000000000..c7a886c25b --- /dev/null +++ b/time/yearistype @@ -0,0 +1,26 @@ +#! /bin/sh + +: '@(#)yearistype.sh 7.3' + +case $#-$2 in + 2-even) case $1 in + *[24680]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-nonpres) case $1 in + *[02468][048]|*[13567][26]) exit 1 ;; + *) exit 0 ;; + esac ;; + 2-odd) case $1 in + *[13579]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-uspres) case $1 in + *[02468][048]|*[13567][26]) exit 0 ;; + *) exit 1 ;; + esac ;; + 2-*) echo "$0: wild type - $2" >&2 + exit 1 ;; + *) echo "$0: usage is $0 year type" >&2 + exit 1 ;; +esac diff --git a/time/zdump.c b/time/zdump.c new file mode 100644 index 0000000000..d35df33073 --- /dev/null +++ b/time/zdump.c @@ -0,0 +1,331 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)zdump.c 7.12"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** This code has been made independent of the rest of the time +** conversion package to increase confidence in the verification it provides. +** You can use this code to help in verifying other implementations. +*/ + +#include "stdio.h" /* for stdout, stderr */ +#include "string.h" /* for strcpy */ +#include "sys/types.h" /* for time_t */ +#include "time.h" /* for struct tm */ + +#ifndef MAX_STRING_LENGTH +#define MAX_STRING_LENGTH 1024 +#endif /* !defined MAX_STRING_LENGTH */ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* !defined EXIT_SUCCESS */ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* !defined EXIT_FAILURE */ + +#ifndef SECSPERMIN +#define SECSPERMIN 60 +#endif /* !defined SECSPERMIN */ + +#ifndef MINSPERHOUR +#define MINSPERHOUR 60 +#endif /* !defined MINSPERHOUR */ + +#ifndef SECSPERHOUR +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#endif /* !defined SECSPERHOUR */ + +#ifndef HOURSPERDAY +#define HOURSPERDAY 24 +#endif /* !defined HOURSPERDAY */ + +#ifndef EPOCH_YEAR +#define EPOCH_YEAR 1970 +#endif /* !defined EPOCH_YEAR */ + +#ifndef TM_YEAR_BASE +#define TM_YEAR_BASE 1900 +#endif /* !defined TM_YEAR_BASE */ + +#ifndef DAYSPERNYEAR +#define DAYSPERNYEAR 365 +#endif /* !defined DAYSPERNYEAR */ + +#ifndef isleap +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) +#endif /* !defined isleap */ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +extern char ** environ; +extern int getopt(); +extern char * optarg; +extern int optind; +extern time_t time(); +extern char * tzname[2]; + +#ifdef USG +extern void exit(); +extern void perror(); +#endif /* defined USG */ + +static char * abbr(); +static long delta(); +static time_t hunt(); +static int longest; +static char * progname; +static void show(); + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i, c; + register int vflag; + register char * cutoff; + register int cutyear; + register long cuttime; + char ** fakeenv; + time_t now; + time_t t, newt; + time_t hibit; + struct tm tm, newtm; + + INITIALIZE(cuttime); + progname = argv[0]; + vflag = 0; + cutoff = NULL; + while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') + if (c == 'v') + vflag = 1; + else cutoff = optarg; + if (c != EOF || + (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { + (void) fprintf(stderr, +"%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n", + argv[0], argv[0]); + (void) exit(EXIT_FAILURE); + } + if (cutoff != NULL) { + int y; + + cutyear = atoi(cutoff); + cuttime = 0; + for (y = EPOCH_YEAR; y < cutyear; ++y) + cuttime += DAYSPERNYEAR + isleap(y); + cuttime *= SECSPERHOUR * HOURSPERDAY; + } + (void) time(&now); + longest = 0; + for (i = optind; i < argc; ++i) + if (strlen(argv[i]) > longest) + longest = strlen(argv[i]); + for (hibit = 1; (hibit << 1) != 0; hibit <<= 1) + continue; + { + register int from, to; + + for (i = 0; environ[i] != NULL; ++i) + continue; + fakeenv = (char **) malloc((i + 2) * sizeof *fakeenv); + if (fakeenv == NULL || + (fakeenv[0] = (char *) malloc(longest + 4)) == NULL) { + (void) perror(progname); + (void) exit(EXIT_FAILURE); + } + to = 0; + (void) strcpy(fakeenv[to++], "TZ="); + for (from = 0; environ[from] != NULL; ++from) + if (strncmp(environ[from], "TZ=", 3) != 0) + fakeenv[to++] = environ[from]; + fakeenv[to] = NULL; + environ = fakeenv; + } + for (i = optind; i < argc; ++i) { + static char buf[MAX_STRING_LENGTH]; + + (void) strcpy(&fakeenv[0][3], argv[i]); + show(argv[i], now, FALSE); + if (!vflag) + continue; + /* + ** Get lowest value of t. + */ + t = hibit; + if (t > 0) /* time_t is unsigned */ + t = 0; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + tm = *localtime(&t); + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + for ( ; ; ) { + if (cutoff != NULL && t >= cuttime) + break; + newt = t + SECSPERHOUR * 12; + if (cutoff != NULL && newt >= cuttime) + break; + if (newt <= t) + break; + newtm = *localtime(&newt); + if (delta(&newtm, &tm) != (newt - t) || + newtm.tm_isdst != tm.tm_isdst || + strcmp(abbr(&newtm), buf) != 0) { + newt = hunt(argv[i], t, newt); + newtm = *localtime(&newt); + (void) strncpy(buf, abbr(&newtm), + (sizeof buf) - 1); + } + t = newt; + tm = newtm; + } + /* + ** Get highest value of t. + */ + t = ~((time_t) 0); + if (t < 0) /* time_t is signed */ + t &= ~hibit; + t -= SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + } + if (fflush(stdout) || ferror(stdout)) { + (void) fprintf(stderr, "%s: Error writing standard output ", + argv[0]); + (void) perror("standard output"); + (void) exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); + + /* gcc -Wall pacifier */ + for ( ; ; ) + continue; +} + +static time_t +hunt(name, lot, hit) +char * name; +time_t lot; +time_t hit; +{ + time_t t; + struct tm lotm; + struct tm tm; + static char loab[MAX_STRING_LENGTH]; + + lotm = *localtime(&lot); + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + while ((hit - lot) >= 2) { + t = lot / 2 + hit / 2; + if (t <= lot) + ++t; + else if (t >= hit) + --t; + tm = *localtime(&t); + if (delta(&tm, &lotm) == (t - lot) && + tm.tm_isdst == lotm.tm_isdst && + strcmp(abbr(&tm), loab) == 0) { + lot = t; + lotm = tm; + } else hit = t; + } + show(name, lot, TRUE); + show(name, hit, TRUE); + return hit; +} + +/* +** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta. +*/ + +static long +delta(newp, oldp) +struct tm * newp; +struct tm * oldp; +{ + long result; + int tmy; + + if (newp->tm_year < oldp->tm_year) + return -delta(oldp, newp); + result = 0; + for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy) + result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE); + result += newp->tm_yday - oldp->tm_yday; + result *= HOURSPERDAY; + result += newp->tm_hour - oldp->tm_hour; + result *= MINSPERHOUR; + result += newp->tm_min - oldp->tm_min; + result *= SECSPERMIN; + result += newp->tm_sec - oldp->tm_sec; + return result; +} + +extern struct tm * localtime(); + +static void +show(zone, t, v) +char * zone; +time_t t; +int v; +{ + struct tm * tmp; + + (void) printf("%-*s ", longest, zone); + if (v) + (void) printf("%.24s GMT = ", asctime(gmtime(&t))); + tmp = localtime(&t); + (void) printf("%.24s", asctime(tmp)); + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); +#ifdef TM_GMTOFF + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); +#endif /* defined TM_GMTOFF */ + } + (void) printf("\n"); +} + +static char * +abbr(tmp) +struct tm * tmp; +{ + register char * result; + static char nada; + + if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1) + return &nada; + result = tzname[tmp->tm_isdst]; + return (result == NULL) ? &nada : result; +} diff --git a/time/zic.c b/time/zic.c new file mode 100644 index 0000000000..73ea46821e --- /dev/null +++ b/time/zic.c @@ -0,0 +1,1956 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)zic.c 7.28"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#include "private.h" +#include "tzfile.h" + +struct rule { + const char * r_filename; + int r_linenum; + const char * r_name; + + int r_loyear; /* for example, 1986 */ + int r_hiyear; /* for example, 1986 */ + const char * r_yrtype; + + int r_month; /* 0..11 */ + + int r_dycode; /* see below */ + int r_dayofmonth; + int r_wday; + + long r_tod; /* time from midnight */ + int r_todisstd; /* above is standard time if TRUE */ + /* or wall clock time if FALSE */ + int r_todisuniv; /* above is universal time if TRUE */ + /* or local time if FALSE */ + long r_stdoff; /* offset from standard time */ + const char * r_abbrvar; /* variable part of abbreviation */ + + int r_todo; /* a rule to do (used in outzone) */ + time_t r_temp; /* used in outzone */ +}; + +/* +** r_dycode r_dayofmonth r_wday +*/ + +#define DC_DOM 0 /* 1..31 */ /* unused */ +#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */ +#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */ + +struct zone { + const char * z_filename; + int z_linenum; + + const char * z_name; + long z_gmtoff; + const char * z_rule; + const char * z_format; + + long z_stdoff; + + struct rule * z_rules; + int z_nrules; + + struct rule z_untilrule; + time_t z_untiltime; +}; + +extern int emkdir P((const char * name, int mode)); +extern int getopt P((int argc, char * argv[], const char * options)); +extern char * icatalloc P((char * old, const char * new)); +extern char * icpyalloc P((const char * string)); +extern void ifree P((char * p)); +extern char * imalloc P((int n)); +extern void * irealloc P((void * old, int n)); +extern int link P((const char * fromname, const char * toname)); +extern char * optarg; +extern int optind; +extern char * scheck P((const char * string, const char * format)); + +static void addtt P((time_t starttime, int type)); +static int addtype P((long gmtoff, const char * abbr, int isdst, + int ttisstd)); +static void leapadd P((time_t t, int positive, int rolling, int count)); +static void adjleap P((void)); +static void associate P((void)); +static int ciequal P((const char * ap, const char * bp)); +static void convert P((long val, char * buf)); +static void dolink P((const char * fromfile, const char * tofile)); +static void eat P((const char * name, int num)); +static void eats P((const char * name, int num, + const char * rname, int rnum)); +static long eitol P((int i)); +static void error P((const char * message)); +static char ** getfields P((char * buf)); +static long gethms P((const char * string, const char * errstrng, + int signable)); +static void infile P((const char * filename)); +static void inleap P((char ** fields, int nfields)); +static void inlink P((char ** fields, int nfields)); +static void inrule P((char ** fields, int nfields)); +static int inzcont P((char ** fields, int nfields)); +static int inzone P((char ** fields, int nfields)); +static int inzsub P((char ** fields, int nfields, int iscont)); +static int itsabbr P((const char * abbr, const char * word)); +static int itsdir P((const char * name)); +static int lowerit P((int c)); +static char * memcheck P((char * tocheck)); +static int mkdirs P((char * filename)); +static void newabbr P((const char * abbr)); +static long oadd P((long t1, long t2)); +static void outzone P((const struct zone * zp, int ntzones)); +static void puttzcode P((long code, FILE * fp)); +static int rcomp P((const genericptr_T leftp, const genericptr_T rightp)); +static time_t rpytime P((const struct rule * rp, int wantedy)); +static void rulesub P((struct rule * rp, + const char * loyearp, const char * hiyearp, + const char * typep, const char * monthp, + const char * dayp, const char * timep)); +static void setboundaries P((void)); +static time_t tadd P((time_t t1, long t2)); +static void usage P((void)); +static void writezone P((const char * name)); +static int yearistype P((int year, const char * type)); + +static int charcnt; +static int errors; +static const char * filename; +static int leapcnt; +static int linenum; +static int max_int; +static time_t max_time; +static int max_year; +static int min_int; +static time_t min_time; +static int min_year; +static int noise; +static const char * rfilename; +static int rlinenum; +static const char * progname; +static int timecnt; +static int typecnt; +static int tt_signed; + +/* +** Line codes. +*/ + +#define LC_RULE 0 +#define LC_ZONE 1 +#define LC_LINK 2 +#define LC_LEAP 3 + +/* +** Which fields are which on a Zone line. +*/ + +#define ZF_NAME 1 +#define ZF_GMTOFF 2 +#define ZF_RULE 3 +#define ZF_FORMAT 4 +#define ZF_TILYEAR 5 +#define ZF_TILMONTH 6 +#define ZF_TILDAY 7 +#define ZF_TILTIME 8 +#define ZONE_MINFIELDS 5 +#define ZONE_MAXFIELDS 9 + +/* +** Which fields are which on a Zone continuation line. +*/ + +#define ZFC_GMTOFF 0 +#define ZFC_RULE 1 +#define ZFC_FORMAT 2 +#define ZFC_TILYEAR 3 +#define ZFC_TILMONTH 4 +#define ZFC_TILDAY 5 +#define ZFC_TILTIME 6 +#define ZONEC_MINFIELDS 3 +#define ZONEC_MAXFIELDS 7 + +/* +** Which files are which on a Rule line. +*/ + +#define RF_NAME 1 +#define RF_LOYEAR 2 +#define RF_HIYEAR 3 +#define RF_COMMAND 4 +#define RF_MONTH 5 +#define RF_DAY 6 +#define RF_TOD 7 +#define RF_STDOFF 8 +#define RF_ABBRVAR 9 +#define RULE_FIELDS 10 + +/* +** Which fields are which on a Link line. +*/ + +#define LF_FROM 1 +#define LF_TO 2 +#define LINK_FIELDS 3 + +/* +** Which fields are which on a Leap line. +*/ + +#define LP_YEAR 1 +#define LP_MONTH 2 +#define LP_DAY 3 +#define LP_TIME 4 +#define LP_CORR 5 +#define LP_ROLL 6 +#define LEAP_FIELDS 7 + +/* +** Year synonyms. +*/ + +#define YR_MINIMUM 0 +#define YR_MAXIMUM 1 +#define YR_ONLY 2 + +static struct rule * rules; +static int nrules; /* number of rules */ + +static struct zone * zones; +static int nzones; /* number of zones */ + +struct link { + const char * l_filename; + int l_linenum; + const char * l_from; + const char * l_to; +}; + +static struct link * links; +static int nlinks; + +struct lookup { + const char * l_word; + const int l_value; +}; + +static struct lookup const * byword P((const char * string, + const struct lookup * lp)); + +static struct lookup const line_codes[] = { + { "Rule", LC_RULE }, + { "Zone", LC_ZONE }, + { "Link", LC_LINK }, + { "Leap", LC_LEAP }, + { NULL, 0} +}; + +static struct lookup const mon_names[] = { + { "January", TM_JANUARY }, + { "February", TM_FEBRUARY }, + { "March", TM_MARCH }, + { "April", TM_APRIL }, + { "May", TM_MAY }, + { "June", TM_JUNE }, + { "July", TM_JULY }, + { "August", TM_AUGUST }, + { "September", TM_SEPTEMBER }, + { "October", TM_OCTOBER }, + { "November", TM_NOVEMBER }, + { "December", TM_DECEMBER }, + { NULL, 0 } +}; + +static struct lookup const wday_names[] = { + { "Sunday", TM_SUNDAY }, + { "Monday", TM_MONDAY }, + { "Tuesday", TM_TUESDAY }, + { "Wednesday", TM_WEDNESDAY }, + { "Thursday", TM_THURSDAY }, + { "Friday", TM_FRIDAY }, + { "Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const lasts[] = { + { "last-Sunday", TM_SUNDAY }, + { "last-Monday", TM_MONDAY }, + { "last-Tuesday", TM_TUESDAY }, + { "last-Wednesday", TM_WEDNESDAY }, + { "last-Thursday", TM_THURSDAY }, + { "last-Friday", TM_FRIDAY }, + { "last-Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const begin_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { NULL, 0 } +}; + +static struct lookup const end_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { "only", YR_ONLY }, + { NULL, 0 } +}; + +static struct lookup const leap_types[] = { + { "Rolling", TRUE }, + { "Stationary", FALSE }, + { NULL, 0 } +}; + +static const int len_months[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 len_years[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +static time_t ats[TZ_MAX_TIMES]; +static unsigned char types[TZ_MAX_TIMES]; +static long gmtoffs[TZ_MAX_TYPES]; +static char isdsts[TZ_MAX_TYPES]; +static unsigned char abbrinds[TZ_MAX_TYPES]; +static char ttisstds[TZ_MAX_TYPES]; +static char chars[TZ_MAX_CHARS]; +static time_t trans[TZ_MAX_LEAPS]; +static long corr[TZ_MAX_LEAPS]; +static char roll[TZ_MAX_LEAPS]; + +/* +** Memory allocation. +*/ + +static char * +memcheck(ptr) +char * const ptr; +{ + if (ptr == NULL) { + (void) perror(progname); + (void) exit(EXIT_FAILURE); + } + return ptr; +} + +#define emalloc(size) memcheck(imalloc(size)) +#define erealloc(ptr, size) memcheck(irealloc((ptr), (size))) +#define ecpyalloc(ptr) memcheck(icpyalloc(ptr)) +#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp))) + +/* +** Error handling. +*/ + +static void +eats(name, num, rname, rnum) +const char * const name; +const int num; +const char * const rname; +const int rnum; +{ + filename = name; + linenum = num; + rfilename = rname; + rlinenum = rnum; +} + +static void +eat(name, num) +const char * const name; +const int num; +{ + eats(name, num, (char *) NULL, -1); +} + +static void +error(string) +const char * const string; +{ + /* + ** Match the format of "cc" to allow sh users to + ** zic ... 2>&1 | error -t "*" -v + ** on BSD systems. + */ + (void) fprintf(stderr, "\"%s\", line %d: %s", + filename, linenum, string); + if (rfilename != NULL) + (void) fprintf(stderr, " (rule from \"%s\", line %d)", + rfilename, rlinenum); + (void) fprintf(stderr, "\n"); + ++errors; +} + +static void +usage P((void)) +{ + (void) fprintf(stderr, +"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ] \n\ +\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n", + progname, progname); + (void) exit(EXIT_FAILURE); +} + +static const char * psxrules; +static const char * lcltime; +static const char * directory; +static const char * leapsec; +static const char * yitcommand; +static int sflag = FALSE; + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i, j; + register int c; + +#ifdef unix + (void) umask(umask(022) | 022); +#endif /* defined unix */ + progname = argv[0]; + while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF) + switch (c) { + default: + usage(); + case 'd': + if (directory == NULL) + directory = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -d option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'l': + if (lcltime == NULL) + lcltime = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -l option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'p': + if (psxrules == NULL) + psxrules = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -p option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'y': + if (yitcommand == NULL) + yitcommand = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -y option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'L': + if (leapsec == NULL) + leapsec = optarg; + else { + (void) fprintf(stderr, +"%s: More than one -L option specified\n", + progname); + (void) exit(EXIT_FAILURE); + } + break; + case 'v': + noise = TRUE; + break; + case 's': + sflag = TRUE; + break; + } + if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) + usage(); /* usage message by request */ + if (directory == NULL) + directory = TZDIR; + if (yitcommand == NULL) + yitcommand = "yearistype"; + + setboundaries(); + + if (optind < argc && leapsec != NULL) { + infile(leapsec); + adjleap(); + } + + for (i = optind; i < argc; ++i) + infile(argv[i]); + if (errors) + (void) exit(EXIT_FAILURE); + associate(); + for (i = 0; i < nzones; i = j) { + /* + ** Find the next non-continuation zone entry. + */ + for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j) + continue; + outzone(&zones[i], j - i); + } + /* + ** Make links. + */ + for (i = 0; i < nlinks; ++i) + dolink(links[i].l_from, links[i].l_to); + if (lcltime != NULL) + dolink(lcltime, TZDEFAULT); + if (psxrules != NULL) + dolink(psxrules, TZDEFRULES); + return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +static void +dolink(fromfile, tofile) +const char * const fromfile; +const char * const tofile; +{ + register char * fromname; + register char * toname; + + if (fromfile[0] == '/') + fromname = ecpyalloc(fromfile); + else { + fromname = ecpyalloc(directory); + fromname = ecatalloc(fromname, "/"); + fromname = ecatalloc(fromname, fromfile); + } + if (tofile[0] == '/') + toname = ecpyalloc(tofile); + else { + toname = ecpyalloc(directory); + toname = ecatalloc(toname, "/"); + toname = ecatalloc(toname, tofile); + } + /* + ** We get to be careful here since + ** there's a fair chance of root running us. + */ + if (!itsdir(toname)) + (void) remove(toname); + if (link(fromname, toname) != 0) { + if (mkdirs(toname) != 0) + (void) exit(EXIT_FAILURE); + if (link(fromname, toname) != 0) { + (void) fprintf(stderr, "%s: Can't link from %s to ", + progname, fromname); + (void) perror(toname); + (void) exit(EXIT_FAILURE); + } + } + ifree(fromname); + ifree(toname); +} + +static void +setboundaries P((void)) +{ + register time_t bit; + register int bii; + + for (bit = 1; bit > 0; bit <<= 1) + continue; + if (bit == 0) { /* time_t is an unsigned type */ + tt_signed = FALSE; + min_time = 0; + max_time = ~(time_t) 0; + if (sflag) + max_time >>= 1; + } else { + tt_signed = TRUE; + min_time = bit; + max_time = bit; + ++max_time; + max_time = -max_time; + if (sflag) + min_time = 0; + } + min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; + max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; + + for (bii = 1; bii > 0; bii <<= 1) + continue; + min_int = bii; + max_int = -1 - bii; +} + +static int +itsdir(name) +const char * const name; +{ + register char * myname; + register int accres; + + myname = ecpyalloc(name); + myname = ecatalloc(myname, "/."); + accres = access(myname, 0); + ifree(myname); + return accres == 0; +} + +/* +** Associate sets of rules with zones. +*/ + +/* +** Sort by rule name. +*/ + +static int +rcomp(cp1, cp2) +const genericptr_T cp1; +const genericptr_T cp2; +{ + return strcmp(((struct rule *) cp1)->r_name, + ((struct rule *) cp2)->r_name); +} + +static void +associate P((void)) +{ + register struct zone * zp; + register struct rule * rp; + register int base, out; + register int i; + + if (nrules != 0) + (void) qsort((genericptr_T) rules, + (qsort_size_T) nrules, + (qsort_size_T) sizeof *rules, rcomp); + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + zp->z_rules = NULL; + zp->z_nrules = 0; + } + for (base = 0; base < nrules; base = out) { + rp = &rules[base]; + for (out = base + 1; out < nrules; ++out) + if (strcmp(rp->r_name, rules[out].r_name) != 0) + break; + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (strcmp(zp->z_rule, rp->r_name) != 0) + continue; + zp->z_rules = rp; + zp->z_nrules = out - base; + } + } + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (zp->z_nrules == 0) { + /* + ** Maybe we have a local standard time offset. + */ + eat(zp->z_filename, zp->z_linenum); + zp->z_stdoff = gethms(zp->z_rule, "unruly zone", TRUE); + /* + ** Note, though, that if there's no rule, + ** a '%s' in the format is a bad thing. + */ + if (strchr(zp->z_format, '%') != 0) + error("%s in ruleless zone"); + } + } + if (errors) + (void) exit(EXIT_FAILURE); +} + +static void +infile(name) +const char * name; +{ + register FILE * fp; + register char ** fields; + register char * cp; + register const struct lookup * lp; + register int nfields; + register int wantcont; + register int num; + char buf[BUFSIZ]; + + if (strcmp(name, "-") == 0) { + name = "standard input"; + fp = stdin; + } else if ((fp = fopen(name, "r")) == NULL) { + (void) fprintf(stderr, "%s: Can't open ", progname); + (void) perror(name); + (void) exit(EXIT_FAILURE); + } + wantcont = FALSE; + for (num = 1; ; ++num) { + eat(name, num); + if (fgets(buf, (int) sizeof buf, fp) != buf) + break; + cp = strchr(buf, '\n'); + if (cp == NULL) { + error("line too long"); + (void) exit(EXIT_FAILURE); + } + *cp = '\0'; + fields = getfields(buf); + nfields = 0; + while (fields[nfields] != NULL) { + static char nada; + + if (ciequal(fields[nfields], "-")) + fields[nfields] = &nada; + ++nfields; + } + if (nfields == 0) { + /* nothing to do */ + } else if (wantcont) { + wantcont = inzcont(fields, nfields); + } else { + lp = byword(fields[0], line_codes); + if (lp == NULL) + error("input line of unknown type"); + else switch ((int) (lp->l_value)) { + case LC_RULE: + inrule(fields, nfields); + wantcont = FALSE; + break; + case LC_ZONE: + wantcont = inzone(fields, nfields); + break; + case LC_LINK: + inlink(fields, nfields); + wantcont = FALSE; + break; + case LC_LEAP: + if (name != leapsec) + (void) fprintf(stderr, +"%s: Leap line in non leap seconds file %s\n", + progname, name); + else inleap(fields, nfields); + wantcont = FALSE; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, +"%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } + } + ifree((char *) fields); + } + if (ferror(fp)) { + (void) fprintf(stderr, "%s: Error reading ", progname); + (void) perror(filename); + (void) exit(EXIT_FAILURE); + } + if (fp != stdin && fclose(fp)) { + (void) fprintf(stderr, "%s: Error closing ", progname); + (void) perror(filename); + (void) exit(EXIT_FAILURE); + } + if (wantcont) + error("expected continuation line not found"); +} + +/* +** Convert a string of one of the forms +** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss +** into a number of seconds. +** A null string maps to zero. +** Call error with errstring and return zero on errors. +*/ + +static long +gethms(string, errstring, signable) +const char * string; +const char * const errstring; +const int signable; +{ + int hh, mm, ss, sign; + + if (string == NULL || *string == '\0') + return 0; + if (!signable) + sign = 1; + else if (*string == '-') { + sign = -1; + ++string; + } else sign = 1; + if (sscanf(string, scheck(string, "%d"), &hh) == 1) + mm = ss = 0; + else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2) + ss = 0; + else if (sscanf(string, scheck(string, "%d:%d:%d"), + &hh, &mm, &ss) != 3) { + error(errstring); + return 0; + } + if (hh < 0 || hh >= HOURSPERDAY || + mm < 0 || mm >= MINSPERHOUR || + ss < 0 || ss > SECSPERMIN) { + error(errstring); + return 0; + } + return eitol(sign) * + (eitol(hh * MINSPERHOUR + mm) * + eitol(SECSPERMIN) + eitol(ss)); +} + +static void +inrule(fields, nfields) +register char ** const fields; +const int nfields; +{ + static struct rule r; + + if (nfields != RULE_FIELDS) { + error("wrong number of fields on Rule line"); + return; + } + if (*fields[RF_NAME] == '\0') { + error("nameless rule"); + return; + } + r.r_filename = filename; + r.r_linenum = linenum; + r.r_stdoff = gethms(fields[RF_STDOFF], "invalid saved time", TRUE); + rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], + fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); + r.r_name = ecpyalloc(fields[RF_NAME]); + r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); + rules = (struct rule *) (void *) erealloc((char *) rules, + (int) ((nrules + 1) * sizeof *rules)); + rules[nrules++] = r; +} + +static int +inzone(fields, nfields) +register char ** const fields; +const int nfields; +{ + register int i; + static char * buf; + + if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { + error("wrong number of fields on Zone line"); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); + (void) sprintf(buf, +"\"Zone %s\" line and -l option are mutually exclusive", + TZDEFAULT); + error(buf); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); + (void) sprintf(buf, +"\"Zone %s\" line and -p option are mutually exclusive", + TZDEFRULES); + error(buf); + return FALSE; + } + for (i = 0; i < nzones; ++i) + if (zones[i].z_name != NULL && + strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { + buf = erealloc(buf, (int) (132 + + strlen(fields[ZF_NAME]) + + strlen(zones[i].z_filename))); + (void) sprintf(buf, +"duplicate zone name %s (file \"%s\", line %d)", + fields[ZF_NAME], + zones[i].z_filename, + zones[i].z_linenum); + error(buf); + return FALSE; + } + return inzsub(fields, nfields, FALSE); +} + +static int +inzcont(fields, nfields) +register char ** const fields; +const int nfields; +{ + if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { + error("wrong number of fields on Zone continuation line"); + return FALSE; + } + return inzsub(fields, nfields, TRUE); +} + +static int +inzsub(fields, nfields, iscont) +register char ** const fields; +const int nfields; +const int iscont; +{ + register char * cp; + static struct zone z; + register int i_gmtoff, i_rule, i_format; + register int i_untilyear, i_untilmonth; + register int i_untilday, i_untiltime; + register int hasuntil; + + if (iscont) { + i_gmtoff = ZFC_GMTOFF; + i_rule = ZFC_RULE; + i_format = ZFC_FORMAT; + i_untilyear = ZFC_TILYEAR; + i_untilmonth = ZFC_TILMONTH; + i_untilday = ZFC_TILDAY; + i_untiltime = ZFC_TILTIME; + z.z_name = NULL; + } else { + i_gmtoff = ZF_GMTOFF; + i_rule = ZF_RULE; + i_format = ZF_FORMAT; + i_untilyear = ZF_TILYEAR; + i_untilmonth = ZF_TILMONTH; + i_untilday = ZF_TILDAY; + i_untiltime = ZF_TILTIME; + z.z_name = ecpyalloc(fields[ZF_NAME]); + } + z.z_filename = filename; + z.z_linenum = linenum; + z.z_gmtoff = gethms(fields[i_gmtoff], "invalid GMT offset", TRUE); + if ((cp = strchr(fields[i_format], '%')) != 0) { + if (*++cp != 's' || strchr(cp, '%') != 0) { + error("invalid abbreviation format"); + return FALSE; + } + } + z.z_rule = ecpyalloc(fields[i_rule]); + z.z_format = ecpyalloc(fields[i_format]); + hasuntil = nfields > i_untilyear; + if (hasuntil) { + z.z_untilrule.r_filename = filename; + z.z_untilrule.r_linenum = linenum; + rulesub(&z.z_untilrule, + fields[i_untilyear], + "only", + "", + (nfields > i_untilmonth) ? + fields[i_untilmonth] : "Jan", + (nfields > i_untilday) ? fields[i_untilday] : "1", + (nfields > i_untiltime) ? fields[i_untiltime] : "0"); + z.z_untiltime = rpytime(&z.z_untilrule, + z.z_untilrule.r_loyear); + if (iscont && nzones > 0 && + z.z_untiltime > min_time && + z.z_untiltime < max_time && + zones[nzones - 1].z_untiltime > min_time && + zones[nzones - 1].z_untiltime < max_time && + zones[nzones - 1].z_untiltime >= z.z_untiltime) { +error("Zone continuation line end time is not after end time of previous line"); + return FALSE; + } + } + zones = (struct zone *) (void *) erealloc((char *) zones, + (int) ((nzones + 1) * sizeof *zones)); + zones[nzones++] = z; + /* + ** If there was an UNTIL field on this line, + ** there's more information about the zone on the next line. + */ + return hasuntil; +} + +static void +inleap(fields, nfields) +register char ** const fields; +const int nfields; +{ + register const char * cp; + register const struct lookup * lp; + register int i, j; + int year, month, day; + long dayoff, tod; + time_t t; + + if (nfields != LEAP_FIELDS) { + error("wrong number of fields on Leap line"); + return; + } + dayoff = 0; + cp = fields[LP_YEAR]; + if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { + /* + * Leapin' Lizards! + */ + error("invalid leaping year"); + return; + } + j = EPOCH_YEAR; + while (j != year) { + if (year > j) { + i = len_years[isleap(j)]; + ++j; + } else { + --j; + i = -len_years[isleap(j)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { + error("invalid month name"); + return; + } + month = lp->l_value; + j = TM_JANUARY; + while (j != month) { + i = len_months[isleap(year)][j]; + dayoff = oadd(dayoff, eitol(i)); + ++j; + } + cp = fields[LP_DAY]; + if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || + day <= 0 || day > len_months[isleap(year)][month]) { + error("invalid day of month"); + return; + } + dayoff = oadd(dayoff, eitol(day - 1)); + if (dayoff < 0 && !tt_signed) { + error("time before zero"); + return; + } + t = (time_t) dayoff * SECSPERDAY; + /* + ** Cheap overflow check. + */ + if (t / SECSPERDAY != dayoff) { + error("time overflow"); + return; + } + tod = gethms(fields[LP_TIME], "invalid time of day", FALSE); + cp = fields[LP_CORR]; + { + register int positive; + int count; + + if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */ + positive = FALSE; + count = 1; + } else if (strcmp(cp, "--") == 0) { + positive = FALSE; + count = 2; + } else if (strcmp(cp, "+") == 0) { + positive = TRUE; + count = 1; + } else if (strcmp(cp, "++") == 0) { + positive = TRUE; + count = 2; + } else { + error("illegal CORRECTION field on Leap line"); + return; + } + if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { + error("illegal Rolling/Stationary field on Leap line"); + return; + } + leapadd(tadd(t, tod), positive, lp->l_value, count); + } +} + +static void +inlink(fields, nfields) +register char ** const fields; +const int nfields; +{ + struct link l; + + if (nfields != LINK_FIELDS) { + error("wrong number of fields on Link line"); + return; + } + if (*fields[LF_FROM] == '\0') { + error("blank FROM field on Link line"); + return; + } + if (*fields[LF_TO] == '\0') { + error("blank TO field on Link line"); + return; + } + l.l_filename = filename; + l.l_linenum = linenum; + l.l_from = ecpyalloc(fields[LF_FROM]); + l.l_to = ecpyalloc(fields[LF_TO]); + links = (struct link *) (void *) erealloc((char *) links, + (int) ((nlinks + 1) * sizeof *links)); + links[nlinks++] = l; +} + +static void +rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep) +register struct rule * const rp; +const char * const loyearp; +const char * const hiyearp; +const char * const typep; +const char * const monthp; +const char * const dayp; +const char * const timep; +{ + register const struct lookup * lp; + register const char * cp; + register char * dp; + register char * ep; + + if ((lp = byword(monthp, mon_names)) == NULL) { + error("invalid month name"); + return; + } + rp->r_month = lp->l_value; + rp->r_todisstd = FALSE; + rp->r_todisuniv = FALSE; + dp = ecpyalloc(timep); + if (*dp != '\0') { + ep = dp + strlen(dp) - 1; + switch (lowerit(*ep)) { + case 's': /* Standard */ + rp->r_todisstd = TRUE; + rp->r_todisuniv = FALSE; + *ep = '\0'; + break; + case 'w': /* Wall */ + rp->r_todisstd = FALSE; + rp->r_todisuniv = FALSE; + *ep = '\0'; + case 'g': /* Greenwich */ + case 'u': /* Universal */ + case 'z': /* Zulu */ + rp->r_todisstd = TRUE; + rp->r_todisuniv = TRUE; + *ep = '\0'; + break; + } + } + rp->r_tod = gethms(dp, "invalid time of day", FALSE); + ifree(dp); + /* + ** Year work. + */ + cp = loyearp; + if ((lp = byword(cp, begin_years)) != NULL) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_loyear = min_int; + break; + case YR_MAXIMUM: + rp->r_loyear = max_int; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, + "%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { + error("invalid starting year"); + return; + } + cp = hiyearp; + if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_hiyear = min_int; + break; + case YR_MAXIMUM: + rp->r_hiyear = max_int; + break; + case YR_ONLY: + rp->r_hiyear = rp->r_loyear; + break; + default: /* "cannot happen" */ + (void) fprintf(stderr, + "%s: panic: Invalid l_value %d\n", + progname, lp->l_value); + (void) exit(EXIT_FAILURE); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { + error("invalid ending year"); + return; + } + if (rp->r_loyear > rp->r_hiyear) { + error("starting year greater than ending year"); + return; + } + if (*typep == '\0') + rp->r_yrtype = NULL; + else { + if (rp->r_loyear == rp->r_hiyear) { + error("typed single year"); + return; + } + rp->r_yrtype = ecpyalloc(typep); + } + /* + ** Day work. + ** Accept things such as: + ** 1 + ** last-Sunday + ** Sun<=20 + ** Sun>=7 + */ + dp = ecpyalloc(dayp); + if ((lp = byword(dp, lasts)) != NULL) { + rp->r_dycode = DC_DOWLEQ; + rp->r_wday = lp->l_value; + rp->r_dayofmonth = len_months[1][rp->r_month]; + } else { + if ((ep = strchr(dp, '<')) != 0) + rp->r_dycode = DC_DOWLEQ; + else if ((ep = strchr(dp, '>')) != 0) + rp->r_dycode = DC_DOWGEQ; + else { + ep = dp; + rp->r_dycode = DC_DOM; + } + if (rp->r_dycode != DC_DOM) { + *ep++ = 0; + if (*ep++ != '=') { + error("invalid day of month"); + ifree(dp); + return; + } + if ((lp = byword(dp, wday_names)) == NULL) { + error("invalid weekday name"); + ifree(dp); + return; + } + rp->r_wday = lp->l_value; + } + if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || + rp->r_dayofmonth <= 0 || + (rp->r_dayofmonth > len_months[1][rp->r_month])) { + error("invalid day of month"); + ifree(dp); + return; + } + } + ifree(dp); +} + +static void +convert(val, buf) +const long val; +char * const buf; +{ + register int i; + register long shift; + + for (i = 0, shift = 24; i < 4; ++i, shift -= 8) + buf[i] = val >> shift; +} + +static void +puttzcode(val, fp) +const long val; +FILE * const fp; +{ + char buf[4]; + + convert(val, buf); + (void) fwrite((genericptr_T) buf, + (fwrite_size_T) sizeof buf, + (fwrite_size_T) 1, fp); +} + +static void +writezone(name) +const char * const name; +{ + register FILE * fp; + register int i, j; + static char * fullname; + static struct tzhead tzh; + + fullname = erealloc(fullname, + (int) (strlen(directory) + 1 + strlen(name) + 1)); + (void) sprintf(fullname, "%s/%s", directory, name); + if ((fp = fopen(fullname, "wb")) == NULL) { + if (mkdirs(fullname) != 0) + (void) exit(EXIT_FAILURE); + if ((fp = fopen(fullname, "wb")) == NULL) { + (void) fprintf(stderr, "%s: Can't create ", progname); + (void) perror(fullname); + (void) exit(EXIT_FAILURE); + } + } + convert(eitol(typecnt), tzh.tzh_ttisstdcnt); + convert(eitol(leapcnt), tzh.tzh_leapcnt); + convert(eitol(timecnt), tzh.tzh_timecnt); + convert(eitol(typecnt), tzh.tzh_typecnt); + convert(eitol(charcnt), tzh.tzh_charcnt); + (void) fwrite((genericptr_T) &tzh, + (fwrite_size_T) sizeof tzh, + (fwrite_size_T) 1, fp); + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] >= trans[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; + } + puttzcode((long) ats[i], fp); + } + if (timecnt > 0) + (void) fwrite((genericptr_T) types, + (fwrite_size_T) sizeof types[0], + (fwrite_size_T) timecnt, fp); + for (i = 0; i < typecnt; ++i) { + puttzcode((long) gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc(abbrinds[i], fp); + } + if (charcnt != 0) + (void) fwrite((genericptr_T) chars, + (fwrite_size_T) sizeof chars[0], + (fwrite_size_T) charcnt, fp); + for (i = 0; i < leapcnt; ++i) { + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp); + } else puttzcode((long) trans[i], fp); + puttzcode((long) corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + (void) putc(ttisstds[i], fp); + if (ferror(fp) || fclose(fp)) { + (void) fprintf(stderr, "%s: Write error on ", progname); + (void) perror(fullname); + (void) exit(EXIT_FAILURE); + } +} + +static void +outzone(zpfirst, zonecount) +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register int i, j; + register int usestart, useuntil; + register time_t starttime, untiltime; + register long gmtoff; + register long stdoff; + register int year; + register long startoff; + register int startisdst; + register int startttisstd; + register int type; + char startbuf[BUFSIZ]; + + INITIALIZE(untiltime); + INITIALIZE(starttime); + INITIALIZE(startoff); + /* + ** Now. . .finally. . .generate some useful data! + */ + timecnt = 0; + typecnt = 0; + charcnt = 0; + /* + ** A guess that may well be corrected later. + */ + stdoff = 0; + /* + ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au) + ** for noting the need to unconditionally initialize startttisstd. + */ + startttisstd = FALSE; +#ifdef lint + starttime = 0; +#endif /* defined lint */ + for (i = 0; i < zonecount; ++i) { + zp = &zpfirst[i]; + usestart = i > 0 && (zp - 1)->z_untiltime > min_time; + useuntil = i < (zonecount - 1); + if (useuntil && zp->z_untiltime <= min_time) + continue; + gmtoff = zp->z_gmtoff; + eat(zp->z_filename, zp->z_linenum); + startisdst = -1; + if (zp->z_nrules == 0) { + stdoff = zp->z_stdoff; + (void) strcpy(startbuf, zp->z_format); + type = addtype(oadd(zp->z_gmtoff, stdoff), + startbuf, stdoff != 0, startttisstd); + if (usestart) + addtt(starttime, type); + else if (stdoff != 0) + addtt(min_time, type); + } else for (year = min_year; year <= max_year; ++year) { + if (useuntil && year > zp->z_untilrule.r_hiyear) + break; + /* + ** Mark which rules to do in the current year. + ** For those to do, calculate rpytime(rp, year); + */ + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + rp->r_todo = year >= rp->r_loyear && + year <= rp->r_hiyear && + yearistype(year, rp->r_yrtype); + if (rp->r_todo) + rp->r_temp = rpytime(rp, year); + } + for ( ; ; ) { + register int k; + register time_t jtime, ktime; + register long offset; + char buf[BUFSIZ]; + + INITIALIZE(ktime); + if (useuntil) { + /* + ** Turn untiltime into GMT + ** assuming the current gmtoff and + ** stdoff values. + */ + untiltime = zp->z_untiltime; + if (!zp->z_untilrule.r_todisuniv) + untiltime = tadd(untiltime, + -gmtoff); + if (!zp->z_untilrule.r_todisstd) + untiltime = tadd(untiltime, + -stdoff); + } + /* + ** Find the rule (of those to do, if any) + ** that takes effect earliest in the year. + */ + k = -1; +#ifdef lint + ktime = 0; +#endif /* defined lint */ + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (!rp->r_todo) + continue; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + offset = rp->r_todisuniv ? 0 : gmtoff; + if (!rp->r_todisstd) + offset = oadd(offset, stdoff); + jtime = rp->r_temp; + if (jtime == min_time || + jtime == max_time) + continue; + jtime = tadd(jtime, -offset); + if (k < 0 || jtime < ktime) { + k = j; + ktime = jtime; + } + } + if (k < 0) + break; /* go on to next year */ + rp = &zp->z_rules[k]; + rp->r_todo = FALSE; + if (useuntil && ktime >= untiltime) + break; + if (usestart) { + if (ktime < starttime) { + stdoff = rp->r_stdoff; + startoff = oadd(zp->z_gmtoff, + rp->r_stdoff); + (void) sprintf(startbuf, zp->z_format, + rp->r_abbrvar); + startisdst = rp->r_stdoff != 0; + continue; + } + usestart = FALSE; + if (ktime != starttime) { + if (startisdst < 0 && + zp->z_gmtoff != + (zp - 1)->z_gmtoff) { + type = (timecnt == 0) ? 0 : + types[timecnt - 1]; + startoff = oadd(gmtoffs[type], + -(zp - 1)->z_gmtoff); + startisdst = startoff != 0; + startoff = oadd(startoff, + zp->z_gmtoff); + (void) strcpy(startbuf, + &chars[abbrinds[type]]); + } + if (startisdst >= 0) +addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd)); + } + } + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + (void) sprintf(buf, zp->z_format, + rp->r_abbrvar); + offset = oadd(zp->z_gmtoff, rp->r_stdoff); + type = addtype(offset, buf, rp->r_stdoff != 0, + rp->r_todisstd); + addtt(ktime, type); + stdoff = rp->r_stdoff; + } + } + /* + ** Now we may get to set starttime for the next zone line. + */ + if (useuntil) { + starttime = tadd(zp->z_untiltime, -gmtoff); + startttisstd = zp->z_untilrule.r_todisstd; + if (!startttisstd) + starttime = tadd(starttime, -stdoff); + } + } + writezone(zpfirst->z_name); +} + +static void +addtt(starttime, type) +const time_t starttime; +const int type; +{ + if (timecnt != 0 && type == types[timecnt - 1]) + return; /* easy enough! */ + if (timecnt == 0 && type == 0 && isdsts[0] == 0) + return; /* handled by default rule */ + if (timecnt >= TZ_MAX_TIMES) { + error("too many transitions?!"); + (void) exit(EXIT_FAILURE); + } + ats[timecnt] = starttime; + types[timecnt] = type; + ++timecnt; +} + +static int +addtype(gmtoff, abbr, isdst, ttisstd) +const long gmtoff; +const char * const abbr; +const int isdst; +const int ttisstd; +{ + register int i, j; + + /* + ** See if there's already an entry for this zone type. + ** If so, just return its index. + */ + for (i = 0; i < typecnt; ++i) { + if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && + strcmp(abbr, &chars[abbrinds[i]]) == 0 && + ttisstd == ttisstds[i]) + return i; + } + /* + ** There isn't one; add a new one, unless there are already too + ** many. + */ + if (typecnt >= TZ_MAX_TYPES) { + error("too many local time types"); + (void) exit(EXIT_FAILURE); + } + gmtoffs[i] = gmtoff; + isdsts[i] = isdst; + ttisstds[i] = ttisstd; + + for (j = 0; j < charcnt; ++j) + if (strcmp(&chars[j], abbr) == 0) + break; + if (j == charcnt) + newabbr(abbr); + abbrinds[i] = j; + ++typecnt; + return i; +} + +static void +leapadd(t, positive, rolling, count) +const time_t t; +const int positive; +const int rolling; +int count; +{ + register int i, j; + + if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { + error("too many leap seconds"); + (void) exit(EXIT_FAILURE); + } + for (i = 0; i < leapcnt; ++i) + if (t <= trans[i]) { + if (t == trans[i]) { + error("repeated leap second moment"); + (void) exit(EXIT_FAILURE); + } + break; + } + do { + for (j = leapcnt; j > i; --j) { + trans[j] = trans[j - 1]; + corr[j] = corr[j - 1]; + roll[j] = roll[j - 1]; + } + trans[i] = t; + corr[i] = positive ? 1L : eitol(-count); + roll[i] = rolling; + ++leapcnt; + } while (positive && --count != 0); +} + +static void +adjleap P((void)) +{ + register int i; + register long last = 0; + + /* + ** propagate leap seconds forward + */ + for (i = 0; i < leapcnt; ++i) { + trans[i] = tadd(trans[i], last); + last = corr[i] += last; + } +} + +static int +yearistype(year, type) +const int year; +const char * const type; +{ + static char * buf; + int result; + + if (type == NULL || *type == '\0') + return TRUE; + buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type))); + (void) sprintf(buf, "%s %d %s", yitcommand, year, type); + result = system(buf); + if (result == 0) + return TRUE; + if (result == (1 << 8)) + return FALSE; + error("Wild result from command execution"); + (void) fprintf(stderr, "%s: command was '%s', result was %d\n", + progname, buf, result); + for ( ; ; ) + (void) exit(EXIT_FAILURE); +} + +static int +lowerit(a) +const int a; +{ + return (isascii(a) && isupper(a)) ? tolower(a) : a; +} + +static int +ciequal(ap, bp) /* case-insensitive equality */ +register const char * ap; +register const char * bp; +{ + while (lowerit(*ap) == lowerit(*bp++)) + if (*ap++ == '\0') + return TRUE; + return FALSE; +} + +static int +itsabbr(abbr, word) +register const char * abbr; +register const char * word; +{ + if (lowerit(*abbr) != lowerit(*word)) + return FALSE; + ++word; + while (*++abbr != '\0') + do if (*word == '\0') + return FALSE; + while (lowerit(*word++) != lowerit(*abbr)); + return TRUE; +} + +static const struct lookup * +byword(word, table) +register const char * const word; +register const struct lookup * const table; +{ + register const struct lookup * foundlp; + register const struct lookup * lp; + + if (word == NULL || table == NULL) + return NULL; + /* + ** Look for exact match. + */ + for (lp = table; lp->l_word != NULL; ++lp) + if (ciequal(word, lp->l_word)) + return lp; + /* + ** Look for inexact match. + */ + foundlp = NULL; + for (lp = table; lp->l_word != NULL; ++lp) + if (itsabbr(word, lp->l_word)) + if (foundlp == NULL) + foundlp = lp; + else return NULL; /* multiple inexact matches */ + return foundlp; +} + +static char ** +getfields(cp) +register char * cp; +{ + register char * dp; + register char ** array; + register int nsubs; + + if (cp == NULL) + return NULL; + array = (char **) (void *) + emalloc((int) ((strlen(cp) + 1) * sizeof *array)); + nsubs = 0; + for ( ; ; ) { + while (isascii(*cp) && isspace(*cp)) + ++cp; + if (*cp == '\0' || *cp == '#') + break; + array[nsubs++] = dp = cp; + do { + if ((*dp = *cp++) != '"') + ++dp; + else while ((*dp = *cp++) != '"') + if (*dp != '\0') + ++dp; + else error("Odd number of quotation marks"); + } while (*cp != '\0' && *cp != '#' && + (!isascii(*cp) || !isspace(*cp))); + if (isascii(*cp) && isspace(*cp)) + ++cp; + *dp = '\0'; + } + array[nsubs] = NULL; + return array; +} + +static long +oadd(t1, t2) +const long t1; +const long t2; +{ + register long t; + + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error("time overflow"); + (void) exit(EXIT_FAILURE); + } + return t; +} + +static time_t +tadd(t1, t2) +const time_t t1; +const long t2; +{ + register time_t t; + + if (t1 == max_time && t2 > 0) + return max_time; + if (t1 == min_time && t2 < 0) + return min_time; + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error("time overflow"); + (void) exit(EXIT_FAILURE); + } + return t; +} + +/* +** Given a rule, and a year, compute the date - in seconds since January 1, +** 1970, 00:00 LOCAL time - in that year that the rule refers to. +*/ + +static time_t +rpytime(rp, wantedy) +register const struct rule * const rp; +register const int wantedy; +{ + register int y, m, i; + register long dayoff; /* with a nod to Margaret O. */ + register time_t t; + + if (wantedy == min_int) + return min_time; + if (wantedy == max_int) + return max_time; + dayoff = 0; + m = TM_JANUARY; + y = EPOCH_YEAR; + while (wantedy != y) { + if (wantedy > y) { + i = len_years[isleap(y)]; + ++y; + } else { + --y; + i = -len_years[isleap(y)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + while (m != rp->r_month) { + i = len_months[isleap(y)][m]; + dayoff = oadd(dayoff, eitol(i)); + ++m; + } + i = rp->r_dayofmonth; + if (m == TM_FEBRUARY && i == 29 && !isleap(y)) { + if (rp->r_dycode == DC_DOWLEQ) + --i; + else { + error("use of 2/29 in non leap-year"); + (void) exit(EXIT_FAILURE); + } + } + --i; + dayoff = oadd(dayoff, eitol(i)); + if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { + register long wday; + +#define LDAYSPERWEEK ((long) DAYSPERWEEK) + wday = eitol(EPOCH_WDAY); + /* + ** Don't trust mod of negative numbers. + */ + if (dayoff >= 0) + wday = (wday + dayoff) % LDAYSPERWEEK; + else { + wday -= ((-dayoff) % LDAYSPERWEEK); + if (wday < 0) + wday += LDAYSPERWEEK; + } + while (wday != eitol(rp->r_wday)) + if (rp->r_dycode == DC_DOWGEQ) { + dayoff = oadd(dayoff, (long) 1); + if (++wday >= LDAYSPERWEEK) + wday = 0; + ++i; + } else { + dayoff = oadd(dayoff, (long) -1); + if (--wday < 0) + wday = LDAYSPERWEEK - 1; + --i; + } + if (i < 0 || i >= len_months[isleap(y)][m]) { + error("no day in month matches rule"); + (void) exit(EXIT_FAILURE); + } + } + if (dayoff < 0 && !tt_signed) + return min_time; + t = (time_t) dayoff * SECSPERDAY; + /* + ** Cheap overflow check. + */ + if (t / SECSPERDAY != dayoff) + return (dayoff > 0) ? max_time : min_time; + return tadd(t, rp->r_tod); +} + +static void +newabbr(string) +const char * const string; +{ + register int i; + + i = strlen(string) + 1; + if (charcnt + i > TZ_MAX_CHARS) { + error("too many, or too long, time zone abbreviations"); + (void) exit(EXIT_FAILURE); + } + (void) strcpy(&chars[charcnt], string); + charcnt += eitol(i); +} + +static int +mkdirs(argname) +char * const argname; +{ + register char * name; + register char * cp; + + if (argname == NULL || *argname == '\0') + return 0; + cp = name = ecpyalloc(argname); + while ((cp = strchr(cp + 1, '/')) != 0) { + *cp = '\0'; +#ifndef unix + /* + ** MS-DOS drive specifier? + */ + if (strlen(name) == 2 && isascii(name[0]) && + isalpha(name[0]) && name[1] == ':') { + *cp = '/'; + continue; + } +#endif /* !defined unix */ + if (!itsdir(name)) { + /* + ** It doesn't seem to exist, so we try to create it. + */ + if (emkdir(name, 0755) != 0) { + (void) fprintf(stderr, + "%s: Can't create directory ", + progname); + (void) perror(name); + ifree(name); + return -1; + } + } + *cp = '/'; + } + ifree(name); + return 0; +} + +static long +eitol(i) +const int i; +{ + long l; + + l = i; + if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) { + (void) fprintf(stderr, + "%s: %d did not sign extend correctly\n", + progname, i); + (void) exit(EXIT_FAILURE); + } + return l; +} + +/* +** UNIX was a registered trademark of UNIX System Laboratories in 1993. +*/ diff --git a/ttyent.h b/ttyent.h new file mode 100644 index 0000000000..ba790e3542 --- /dev/null +++ b/ttyent.h @@ -0,0 +1 @@ +#include <misc/ttyent.h> diff --git a/unistd.h b/unistd.h new file mode 100644 index 0000000000..77901d9846 --- /dev/null +++ b/unistd.h @@ -0,0 +1 @@ +#include <posix/unistd.h> diff --git a/utime.h b/utime.h new file mode 100644 index 0000000000..e9dfbeaaa2 --- /dev/null +++ b/utime.h @@ -0,0 +1 @@ +#include <posix/utime.h> diff --git a/version.c b/version.c new file mode 100644 index 0000000000..73dfe6f0a7 --- /dev/null +++ b/version.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <stdio.h> + +CONST char __libc_release[] = "alpha"; +CONST char __libc_version[] = "1.09.5"; + +void +DEFUN_VOID(__libc_print_version) +{ + printf ("GNU C Library %s release version %s, by Roland McGrath.", + __libc_release, __libc_version); +#ifdef __VERSION__ + printf ("Compiled by GNU CC version %s.\n", __VERSION__); +#endif + puts ("\ +Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ +PARTICULAR PURPOSE."); +} + +/* + Local Variables: + version-control: never + End: +*/ diff --git a/wordexp.h b/wordexp.h new file mode 100644 index 0000000000..64e036e062 --- /dev/null +++ b/wordexp.h @@ -0,0 +1 @@ +#include <posix/wordexp.h> |