mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
478b92f03a
1997-06-23 23:39 Ulrich Drepper <drepper@cygnus.com> * string/Makefile (headers): Change bytesex.h to bits/endian.h. * sysdeps/generic/Makefile: Don't try to generate bytesex.h, but bits/endian.h. * math/libm-test.c (lgamma_test): Make sure the test of the ilogb function will not fail because of exceptions. * math/math.h: Add warning about use of M_* constants. Pretty print. 1997-06-23 11:36 Andreas Jaeger <aj@arthur.rhein-neckar.de> * hurd/path-lookup.c: Change GPL to LGPL, update and reformat copyright, remove trailing white spaces and send through unexpand. * inet/netinet/icmp6.h: Likewise. * inet/netinet/in.h: Likewise. * inet/netinet/ip6.h: Likewise. * locale/programs/xmalloc.c: Likewise. * locale/programs/xstrdup.c: Likewise. * sysdeps/generic/make_siglist.c: Likewise. * sysdeps/generic/morecore.c: Likewise. * sysdeps/generic/sbrk.c: Likewise. * sysdeps/generic/signame.c: Likewise. * sysdeps/generic/signame.h: Likewise. * sysdeps/generic/netinet/inbits.h: Likewise. * sysdeps/posix/getpagesize.c: Likewise. * sysdeps/unix/errnos-tmpl.c: Likewise. * sysdeps/unix/getpagesize.c: Likewise. * sysdeps/unix/make_errlist.c: Likewise. * sysdeps/unix/mkfifo.c: Likewise. * sysdeps/unix/nlist.c: Likewise. * sysdeps/unix/start.c: Likewise. * sysdeps/unix/sysv/linux/netinet/inbits.h: Likewise. * munch-tmpl.c: Update and reformat copyright, remove trailing white spaces and send through unexpand. * libio/clearerr_u.c: Likewise. * libio/memstream.c: Likewise. * libio/putc_u.c: Likewise. * libio/putchar_u.c: Likewise. * stdio-common/scanf.c: Likewise. * stdlib/longlong.h: Likewise. * sysdeps/alpha/__longjmp.c: Likewise. * sysdeps/alpha/divrem.h: Likewise. * sysdeps/alpha/machine-gmon.h: Likewise. * sysdeps/alpha/setjmp_aux.c: Likewise. * sysdeps/alpha/bits/setjmp.h: Likewise. * sysdeps/arm/fpu_control.h: Likewise. * sysdeps/generic/_strerror.c: Likewise. * sysdeps/generic/det_endian.c: Likewise. * sysdeps/generic/fdatasync.c: Likewise. * sysdeps/generic/fpu_control.c: Likewise. * sysdeps/generic/ftime.c: Likewise. * sysdeps/generic/getdomain.c: Likewise. * sysdeps/generic/group_member.c: Likewise. * sysdeps/generic/ldiv.c: Likewise. * sysdeps/generic/lldiv.c: Likewise. * sysdeps/generic/lxstat.c: Likewise. * sysdeps/generic/memcmp.c: Likewise. * sysdeps/generic/memmem.c: Likewise. * sysdeps/generic/mig-reply.c: Likewise. * sysdeps/generic/pagecopy.h: Likewise. * sysdeps/generic/profil-counter.h: Likewise. * sysdeps/generic/pselect.c: Likewise. * sysdeps/generic/setfpucw.c: Likewise. * sysdeps/generic/stpcpy.c: Likewise. * sysdeps/generic/uname.c: Likewise. * sysdeps/generic/varargs.h: Likewise. * sysdeps/generic/vlimit.c: Likewise. * sysdeps/generic/bits/sigaction.h: Likewise. * sysdeps/generic/bits/ustat.h: Likewise. * sysdeps/generic/netinet/if_ether.h: Likewise. * sysdeps/generic/sys/swap.h: Likewise. * sysdeps/generic/sys/sysinfo.h: Likewise. * sysdeps/i386/init-first.c: Likewise. * sysdeps/i386/ldbl2mpn.c: Likewise. * sysdeps/i386/memcopy.h: Likewise. * sysdeps/i386/i586/memcopy.h: Likewise. * sysdeps/i860/memcopy.h: Likewise. * sysdeps/m68k/__longjmp.c: Likewise. * sysdeps/m68k/fpu_control.h: Likewise. * sysdeps/m68k/memcopy.h: Likewise. * sysdeps/m68k/s_isinfl.c: Likewise. * sysdeps/m68k/s_isnanl.c: Likewise. * sysdeps/m68k/setjmp.c: Likewise. * sysdeps/mach/_strerror.c: Likewise. * sysdeps/mach/getsysstats.c: Likewise. * sysdeps/mach/mprotect.c: Likewise. * sysdeps/mach/munmap.c: Likewise. * sysdeps/mach/pagecopy.h: Likewise. * sysdeps/mach/start.c: Likewise. * sysdeps/mach/sysdep.h: Likewise. * sysdeps/mach/alpha/machine-lock.h: Likewise. * sysdeps/mach/alpha/machine-sp.h: Likewise. * sysdeps/mach/alpha/sysdep.h: Likewise. * sysdeps/mach/alpha/thread_state.h: Likewise. * sysdeps/mach/hppa/machine-lock.h: Likewise. * sysdeps/mach/hurd/access.c: Likewise. * sysdeps/mach/hurd/closedir.c: Likewise. * sysdeps/mach/hurd/dirstream.h: Likewise. * sysdeps/mach/hurd/dl-cache.c: Likewise. * sysdeps/mach/hurd/euidaccess.c: Likewise. * sysdeps/mach/hurd/fdatasync.c: Likewise. * sysdeps/mach/hurd/fexecve.c: Likewise. * sysdeps/mach/hurd/fork.c: Likewise. * sysdeps/mach/hurd/fpathconf.c: Likewise. * sysdeps/mach/hurd/fstatfs.c: Likewise. * sysdeps/mach/hurd/fxstat.c: Likewise. * sysdeps/mach/hurd/getcwd.c: Likewise. * sysdeps/mach/hurd/getpriority.c: Likewise. * sysdeps/mach/hurd/getrlimit.c: Likewise. * sysdeps/mach/hurd/getsid.c: Likewise. * sysdeps/mach/hurd/group_member.c: Likewise. * sysdeps/mach/hurd/kill.c: Likewise. * sysdeps/mach/hurd/lchown.c: Likewise. * sysdeps/mach/hurd/lxstat.c: Likewise. * sysdeps/mach/hurd/mig-reply.c: Likewise. * sysdeps/mach/hurd/mmap.c: Likewise. * sysdeps/mach/hurd/opendir.c: Likewise. * sysdeps/mach/hurd/pathconf.c: Likewise. * sysdeps/mach/hurd/profil.c: Likewise. * sysdeps/mach/hurd/ptrace.c: Likewise. * sysdeps/mach/hurd/readdir.c: Likewise. * sysdeps/mach/hurd/readdir_r.c: Likewise. * sysdeps/mach/hurd/send.c: Likewise. * sysdeps/mach/hurd/sendto.c: Likewise. * sysdeps/mach/hurd/setpriority.c: Likewise. * sysdeps/mach/hurd/statfs.c: Likewise. * sysdeps/mach/hurd/ttyname.c: Likewise. * sysdeps/mach/hurd/uname.c: Likewise. * sysdeps/mach/hurd/xstat.c: Likewise. * sysdeps/mach/hurd/alpha/exc2signal.c: Likewise. * sysdeps/mach/hurd/alpha/longjmp-ts.c: Likewise. * sysdeps/mach/hurd/alpha/sigreturn.c: Likewise. * sysdeps/mach/hurd/alpha/trampoline.c: Likewise. * sysdeps/mach/hurd/alpha/bits/sigcontext.h: Likewise. * sysdeps/mach/hurd/hppa/trampoline.c: Likewise. * sysdeps/mach/hurd/hppa/bits/sigcontext.h: Likewise. * sysdeps/mach/hurd/i386/exc2signal.c: Likewise. * sysdeps/mach/hurd/i386/intr-msg.h: Likewise. * sysdeps/mach/hurd/i386/longjmp-ts.c: Likewise. * sysdeps/mach/hurd/i386/sigreturn.c: Likewise. * sysdeps/mach/hurd/i386/trampoline.c: Likewise. * sysdeps/mach/hurd/i386/bits/sigcontext.h: Likewise. * sysdeps/mach/hurd/mips/bits/sigcontext.h: Likewise. * sysdeps/mach/hurd/sys/param.h: Likewise. * sysdeps/mach/i386/machine-lock.h: Likewise. * sysdeps/mach/i386/machine-sp.h: Likewise. * sysdeps/mach/i386/sysdep.h: Likewise. * sysdeps/mach/i386/thread_state.h: Likewise. * sysdeps/posix/dup2.c: Likewise. * sysdeps/posix/flock.c: Likewise. * sysdeps/posix/getdtsz.c: Likewise. * sysdeps/posix/gettimeofday.c: Likewise. * sysdeps/posix/isatty.c: Likewise. * sysdeps/posix/killpg.c: Likewise. * sysdeps/posix/mk-stdiolim.c: Likewise. * sysdeps/posix/profil.c: Likewise. * sysdeps/posix/remove.c: Likewise. * sysdeps/posix/rename.c: Likewise. * sysdeps/posix/sigsuspend.c: Likewise. * sysdeps/posix/tempname.c: Likewise. * sysdeps/posix/truncate.c: Likewise. * sysdeps/posix/utimes.c: Likewise. * sysdeps/posix/wait.c: Likewise. * sysdeps/posix/wait3.c: Likewise. * sysdeps/rs6000/memcopy.h: Likewise. * sysdeps/sparc/memcopy.h: Likewise. * sysdeps/standalone/close.c: Likewise. * sysdeps/standalone/dirstream.h: Likewise. * sysdeps/standalone/filedesc.h: Likewise. * sysdeps/standalone/open.c: Likewise. * sysdeps/standalone/read.c: Likewise. * sysdeps/standalone/standalone.h: Likewise. * sysdeps/standalone/write.c: Likewise. * sysdeps/standalone/bits/stdio_lim.h: Likewise. * sysdeps/standalone/i386/i386.h: Likewise. * sysdeps/standalone/m68k/m68020/m68020.h: Likewise. * sysdeps/stub/__longjmp.c: Likewise. * sysdeps/stub/accept.c: Likewise. * sysdeps/stub/access.c: Likewise. * sysdeps/stub/acct.c: Likewise. * sysdeps/stub/adjtime.c: Likewise. * sysdeps/stub/alarm.c: Likewise. * sysdeps/stub/bind.c: Likewise. * sysdeps/stub/brk.c: Likewise. * sysdeps/stub/bsd-_setjmp.c: Likewise. * sysdeps/stub/bsd-setjmp.c: Likewise. * sysdeps/stub/chdir.c: Likewise. * sysdeps/stub/chflags.c: Likewise. * sysdeps/stub/chmod.c: Likewise. * sysdeps/stub/chown.c: Likewise. * sysdeps/stub/chroot.c: Likewise. * sysdeps/stub/clock.c: Likewise. * sysdeps/stub/close.c: Likewise. * sysdeps/stub/closedir.c: Likewise. * sysdeps/stub/connect.c: Likewise. * sysdeps/stub/ctermid.c: Likewise. * sysdeps/stub/cuserid.c: Likewise. * sysdeps/stub/dbl2mpn.c: Likewise. * sysdeps/stub/dirstream.h: Likewise. * sysdeps/stub/dup.c: Likewise. * sysdeps/stub/dup2.c: Likewise. * sysdeps/stub/exc2signal.c: Likewise. * sysdeps/stub/execve.c: Likewise. * sysdeps/stub/fchflags.c: Likewise. * sysdeps/stub/fchown.c: Likewise. * sysdeps/stub/fcntl.c: Likewise. * sysdeps/stub/fdopen.c: Likewise. * sysdeps/stub/fexecve.c: Likewise. * sysdeps/stub/flock.c: Likewise. * sysdeps/stub/fork.c: Likewise. * sysdeps/stub/fpathconf.c: Likewise. * sysdeps/stub/fpu_control.h: Likewise. * sysdeps/stub/fstatfs.c: Likewise. * sysdeps/stub/fsync.c: Likewise. * sysdeps/stub/ftruncate.c: Likewise. * sysdeps/stub/fxstat.c: Likewise. * sysdeps/stub/getcwd.c: Likewise. * sysdeps/stub/getdomain.c: Likewise. * sysdeps/stub/getdtsz.c: Likewise. * sysdeps/stub/getegid.c: Likewise. * sysdeps/stub/geteuid.c: Likewise. * sysdeps/stub/getgid.c: Likewise. * sysdeps/stub/getgroups.c: Likewise. * sysdeps/stub/gethostid.c: Likewise. * sysdeps/stub/gethostname.c: Likewise. * sysdeps/stub/getitimer.c: Likewise. * sysdeps/stub/getpeername.c: Likewise. * sysdeps/stub/getpgid.c: Likewise. * sysdeps/stub/getpid.c: Likewise. * sysdeps/stub/getppid.c: Likewise. * sysdeps/stub/getpriority.c: Likewise. * sysdeps/stub/getrlimit.c: Likewise. * sysdeps/stub/getrusage.c: Likewise. * sysdeps/stub/getsid.c: Likewise. * sysdeps/stub/getsockname.c: Likewise. * sysdeps/stub/getsockopt.c: Likewise. * sysdeps/stub/getsysstats.c: Likewise. * sysdeps/stub/gettimeofday.c: Likewise. * sysdeps/stub/getuid.c: Likewise. * sysdeps/stub/gtty.c: Likewise. * sysdeps/stub/if_index.c: Likewise. * sysdeps/stub/init-posix.c: Likewise. * sysdeps/stub/ioctl.c: Likewise. * sysdeps/stub/isatty.c: Likewise. * sysdeps/stub/isfdtype.c: Likewise. * sysdeps/stub/jmp-unwind.c: Likewise. * sysdeps/stub/kill.c: Likewise. * sysdeps/stub/killpg.c: Likewise. * sysdeps/stub/ldbl2mpn.c: Likewise. * sysdeps/stub/link.c: Likewise. * sysdeps/stub/listen.c: Likewise. * sysdeps/stub/lockfile.c: Likewise. * sysdeps/stub/longjmp-ts.c: Likewise. * sysdeps/stub/lseek.c: Likewise. * sysdeps/stub/lxstat.c: Likewise. * sysdeps/stub/machine-lock.h: Likewise. * sysdeps/stub/machine-sp.h: Likewise. * sysdeps/stub/madvise.c: Likewise. * sysdeps/stub/mkdir.c: Likewise. * sysdeps/stub/mkfifo.c: Likewise. * sysdeps/stub/mmap.c: Likewise. * sysdeps/stub/morecore.c: Likewise. * sysdeps/stub/mpn2dbl.c: Likewise. * sysdeps/stub/mpn2flt.c: Likewise. * sysdeps/stub/mpn2ldbl.c: Likewise. * sysdeps/stub/mprotect.c: Likewise. * sysdeps/stub/msgctl.c: Likewise. * sysdeps/stub/msgget.c: Likewise. * sysdeps/stub/msgrcv.c: Likewise. * sysdeps/stub/msgsnd.c: Likewise. * sysdeps/stub/munmap.c: Likewise. * sysdeps/stub/nanosleep.c: Likewise. * sysdeps/stub/nice.c: Likewise. * sysdeps/stub/nlist.c: Likewise. * sysdeps/stub/open.c: Likewise. * sysdeps/stub/opendir.c: Likewise. * sysdeps/stub/pathconf.c: Likewise. * sysdeps/stub/pause.c: Likewise. * sysdeps/stub/pipestream.c: Likewise. * sysdeps/stub/poll.c: Likewise. * sysdeps/stub/profil.c: Likewise. * sysdeps/stub/ptrace.c: Likewise. * sysdeps/stub/putenv.c: Likewise. * sysdeps/stub/read.c: Likewise. * sysdeps/stub/readdir.c: Likewise. * sysdeps/stub/readdir_r.c: Likewise. * sysdeps/stub/readlink.c: Likewise. * sysdeps/stub/reboot.c: Likewise. * sysdeps/stub/recv.c: Likewise. * sysdeps/stub/recvfrom.c: Likewise. * sysdeps/stub/recvmsg.c: Likewise. * sysdeps/stub/remove.c: Likewise. * sysdeps/stub/rename.c: Likewise. * sysdeps/stub/revoke.c: Likewise. * sysdeps/stub/rewinddir.c: Likewise. * sysdeps/stub/rmdir.c: Likewise. * sysdeps/stub/sbrk.c: Likewise. * sysdeps/stub/sched_getp.c: Likewise. * sysdeps/stub/sched_gets.c: Likewise. * sysdeps/stub/sched_primax.c: Likewise. * sysdeps/stub/sched_primin.c: Likewise. * sysdeps/stub/sched_rr_gi.c: Likewise. * sysdeps/stub/sched_setp.c: Likewise. * sysdeps/stub/sched_sets.c: Likewise. * sysdeps/stub/sched_yield.c: Likewise. * sysdeps/stub/seekdir.c: Likewise. * sysdeps/stub/select.c: Likewise. * sysdeps/stub/semctl.c: Likewise. * sysdeps/stub/semget.c: Likewise. * sysdeps/stub/semop.c: Likewise. * sysdeps/stub/send.c: Likewise. * sysdeps/stub/sendmsg.c: Likewise. * sysdeps/stub/sendto.c: Likewise. * sysdeps/stub/setdomain.c: Likewise. * sysdeps/stub/setegid.c: Likewise. * sysdeps/stub/setenv.c: Likewise. * sysdeps/stub/seteuid.c: Likewise. * sysdeps/stub/setgid.c: Likewise. * sysdeps/stub/setgroups.c: Likewise. * sysdeps/stub/sethostid.c: Likewise. * sysdeps/stub/sethostname.c: Likewise. * sysdeps/stub/setjmp.c: Likewise. * sysdeps/stub/setlogin.c: Likewise. * sysdeps/stub/setpgid.c: Likewise. * sysdeps/stub/setpriority.c: Likewise. * sysdeps/stub/setregid.c: Likewise. * sysdeps/stub/setreuid.c: Likewise. * sysdeps/stub/setrlimit.c: Likewise. * sysdeps/stub/setsid.c: Likewise. * sysdeps/stub/setsockopt.c: Likewise. * sysdeps/stub/settimeofday.c: Likewise. * sysdeps/stub/setuid.c: Likewise. * sysdeps/stub/shmctl.c: Likewise. * sysdeps/stub/shmget.c: Likewise. * sysdeps/stub/shutdown.c: Likewise. * sysdeps/stub/sigaction.c: Likewise. * sysdeps/stub/sigaltstack.c: Likewise. * sysdeps/stub/sigblock.c: Likewise. * sysdeps/stub/sigintr.c: Likewise. * sysdeps/stub/sigpending.c: Likewise. * sysdeps/stub/sigprocmask.c: Likewise. * sysdeps/stub/sigreturn.c: Likewise. * sysdeps/stub/sigsetmask.c: Likewise. * sysdeps/stub/sigstack.c: Likewise. * sysdeps/stub/sigsuspend.c: Likewise. * sysdeps/stub/sigvec.c: Likewise. * sysdeps/stub/socket.c: Likewise. * sysdeps/stub/socketpair.c: Likewise. * sysdeps/stub/sstk.c: Likewise. * sysdeps/stub/statfs.c: Likewise. * sysdeps/stub/stdio_init.c: Likewise. * sysdeps/stub/stime.c: Likewise. * sysdeps/stub/stty.c: Likewise. * sysdeps/stub/swapoff.c: Likewise. * sysdeps/stub/swapon.c: Likewise. * sysdeps/stub/symlink.c: Likewise. * sysdeps/stub/sync.c: Likewise. * sysdeps/stub/syscall.c: Likewise. * sysdeps/stub/sysd-stdio.c: Likewise. * sysdeps/stub/system.c: Likewise. * sysdeps/stub/tcdrain.c: Likewise. * sysdeps/stub/tcflow.c: Likewise. * sysdeps/stub/tcflush.c: Likewise. * sysdeps/stub/tcgetattr.c: Likewise. * sysdeps/stub/tcgetpgrp.c: Likewise. * sysdeps/stub/tcsendbrk.c: Likewise. * sysdeps/stub/tcsetpgrp.c: Likewise. * sysdeps/stub/telldir.c: Likewise. * sysdeps/stub/thread_state.h: Likewise. * sysdeps/stub/time.c: Likewise. * sysdeps/stub/times.c: Likewise. * sysdeps/stub/trampoline.c: Likewise. * sysdeps/stub/truncate.c: Likewise. * sysdeps/stub/ttyname.c: Likewise. * sysdeps/stub/ttyname_r.c: Likewise. * sysdeps/stub/ualarm.c: Likewise. * sysdeps/stub/ulimit.c: Likewise. * sysdeps/stub/umask.c: Likewise. * sysdeps/stub/unlink.c: Likewise. * sysdeps/stub/usleep.c: Likewise. * sysdeps/stub/ustat.c: Likewise. * sysdeps/stub/utime.c: Likewise. * sysdeps/stub/utimes.c: Likewise. * sysdeps/stub/vdprintf.c: Likewise. * sysdeps/stub/vhangup.c: Likewise. * sysdeps/stub/wait.c: Likewise. * sysdeps/stub/wait3.c: Likewise. * sysdeps/stub/wait4.c: Likewise. * sysdeps/stub/waitpid.c: Likewise. * sysdeps/stub/write.c: Likewise. * sysdeps/stub/xmknod.c: Likewise. * sysdeps/stub/xstat.c: Likewise. * sysdeps/stub/bits/errno.h: Likewise. * sysdeps/stub/bits/sigcontext.h: Likewise. * sysdeps/unix/fxstat.c: Likewise. * sysdeps/unix/mk-local_lim.c: Likewise. * sysdeps/unix/mkdir.c: Likewise. * sysdeps/unix/nice.c: Likewise. * sysdeps/unix/rmdir.c: Likewise. * sysdeps/unix/stime.c: Likewise. * sysdeps/unix/telldir.c: Likewise. * sysdeps/unix/xstat.c: Likewise. * sysdeps/unix/arm/sysdep.h: Likewise. * sysdeps/unix/bsd/ftime.c: Likewise. * sysdeps/unix/bsd/isatty.c: Likewise. * sysdeps/unix/bsd/setegid.c: Likewise. * sysdeps/unix/bsd/seteuid.c: Likewise. * sysdeps/unix/bsd/setsid.c: Likewise. * sysdeps/unix/bsd/sigaction.c: Likewise. * sysdeps/unix/bsd/sigprocmask.c: Likewise. * sysdeps/unix/bsd/tcgetattr.c: Likewise. * sysdeps/unix/bsd/tcsetattr.c: Likewise. * sysdeps/unix/bsd/times.c: Likewise. * sysdeps/unix/bsd/ulimit.c: Likewise. * sysdeps/unix/bsd/bits/dirent.h: Likewise. * sysdeps/unix/bsd/bsd4.4/tcdrain.c: Likewise. * sysdeps/unix/bsd/bsd4.4/wait.c: Likewise. * sysdeps/unix/bsd/bsd4.4/waitpid.c: Likewise. * sysdeps/unix/bsd/hp/m68k/sysdep.h: Likewise. * sysdeps/unix/bsd/osf/alpha/sysdep.h: Likewise. * sysdeps/unix/bsd/sequent/i386/sysdep.h: Likewise. * sysdeps/unix/bsd/sony/newsos/m68k/sysdep.h: Likewise. * sysdeps/unix/bsd/sun/m68k/sigtramp.c: Likewise. * sysdeps/unix/bsd/sun/m68k/sysdep.h: Likewise. * sysdeps/unix/bsd/sun/m68k/bits/sigcontext.h: Likewise. * sysdeps/unix/bsd/sun/sparc/sigtramp.c: Likewise. * sysdeps/unix/bsd/sun/sparc/bits/sigcontext.h: Likewise. * sysdeps/unix/bsd/sun/sunos4/mmap.c: Likewise. * sysdeps/unix/bsd/sun/sunos4/speed.c: Likewise. * sysdeps/unix/bsd/ultrix4/sysconf.c: Likewise. * sysdeps/unix/bsd/ultrix4/bits/posix_opt.h: Likewise. * sysdeps/unix/bsd/ultrix4/mips/bits/sigcontext.h: Likewise. * sysdeps/unix/bsd/vax/sysdep.h: Likewise. * sysdeps/unix/common/lxstat.c: Likewise. * sysdeps/unix/common/tcsendbrk.c: Likewise. * sysdeps/unix/common/bits/dirent.h: Likewise. * sysdeps/unix/i386/sysdep.h: Likewise. * sysdeps/unix/mips/sysdep.h: Likewise. * sysdeps/unix/sysv/setrlimit.c: Likewise. * sysdeps/unix/sysv/settimeofday.c: Likewise. * sysdeps/unix/sysv/sigaction.c: Likewise. * sysdeps/unix/sysv/sysv_termio.h: Likewise. * sysdeps/unix/sysv/tcdrain.c: Likewise. * sysdeps/unix/sysv/tcflow.c: Likewise. * sysdeps/unix/sysv/tcflush.c: Likewise. * sysdeps/unix/sysv/tcgetattr.c: Likewise. * sysdeps/unix/sysv/tcsendbrk.c: Likewise. * sysdeps/unix/sysv/tcsetattr.c: Likewise. * sysdeps/unix/sysv/bits/dirent.h: Likewise. * sysdeps/unix/sysv/irix4/getpriority.c: Likewise. * sysdeps/unix/sysv/irix4/setpriority.c: Likewise. * sysdeps/unix/sysv/irix4/bits/confname.h: Likewise. * sysdeps/unix/sysv/linux/adjtime.c: Likewise. * sysdeps/unix/sysv/linux/dl-sysdep.c: Likewise. * sysdeps/unix/sysv/linux/gethostname.c: Likewise. * sysdeps/unix/sysv/linux/if_index.c: Likewise. * sysdeps/unix/sysv/linux/ptrace.c: Likewise. * sysdeps/unix/sysv/linux/reboot.c: Likewise. * sysdeps/unix/sysv/linux/speed.c: Likewise. * sysdeps/unix/sysv/linux/sysctl.c: Likewise. * sysdeps/unix/sysv/linux/tcdrain.c: Likewise. * sysdeps/unix/sysv/linux/ulimit.c: Likewise. * sysdeps/unix/sysv/linux/waitpid.c: Likewise. * sysdeps/unix/sysv/linux/alpha/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/alpha/bits/sigaction.h: Likewise. * sysdeps/unix/sysv/linux/alpha/bits/signum.h: Likewise. * sysdeps/unix/sysv/linux/i386/profil-counter.h: Likewise. * sysdeps/unix/sysv/linux/m68k/sysdep.h: Likewise. * sysdeps/unix/sysv/minix/bits/sigaction.h: Likewise. * sysdeps/unix/sysv/sco3.2.4/bits/confname.h: Likewise. * sysdeps/unix/sysv/sco3.2.4/bits/sigaction.h: Likewise. * sysdeps/unix/sysv/sysv4/sigaction.c: Likewise. * sysdeps/unix/sysv/sysv4/siginfo.h: Likewise. * sysdeps/unix/sysv/sysv4/sysconf.c: Likewise. * sysdeps/unix/sysv/sysv4/sysconfig.h: Likewise. * sysdeps/unix/sysv/sysv4/waitpid.c: Likewise. * sysdeps/unix/sysv/sysv4/bits/sigaction.h: Likewise. * sysdeps/unix/sysv/sysv4/i386/sysdep.h: Likewise. * sysdeps/unix/sysv/sysv4/solaris2/sparc/sysdep.h: Likewise. * sysdeps/vax/fl.h: Likewise. * sysdeps/vax/setjmp.c: Likewise. 1997-06-21 16:58 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * stdlib/strtod.c (INTERNAL (STRTOF)): Fix recognition of Infinity and NaN strings. 1997-06-20 21:52 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/bits/mathinline.h (__scalbn): Fix type of second argument. (__ilogb): Remove special case for zero, add stupid special case for NaN. (__ieee754_scalb): Remove definition. * sysdeps/m68k/fpu/mathbits.h (FP_ILOGB0, FP_ILOGBNAN): Define. * sysdeps/m68k/fpu/s_scalbn.c: Fix type of second argument. * sysdeps/m68k/fpu/e_scalb.c: Rewritten. * sysdeps/m68k/fpu/e_scalbf.c: Adapted. * sysdeps/m68k/fpu/e_scalbl.c: Adapted. * sysdeps/libm-ieee754/e_scalb.c: Raise no exceptions when returning NaN. Handle zero specially. * sysdeps/libm-ieee754/e_scalbf.c: Likewise. * sysdeps/libm-ieee754/e_scalbl.c: Likewise. * math/libm-test.c (ilogb_test): Don't require exceptions for zero and NaN. (gamma_test): Use different argument when checking whether function is implemented. (scalb_test): Remove duplicate tests. 1997-06-03 15:59 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makerules (+depfiles): Add dependencies for $(test-srcs). (distinfo-vars): Add test-srcs.
647 lines
21 KiB
C
647 lines
21 KiB
C
/* Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, 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 */
|
|
|
|
|
|
/* Things that want to be locked while forking. */
|
|
symbol_set_declare (_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;
|
|
struct hurd_sigstate *volatile ss;
|
|
|
|
ss = _hurd_self_sigstate ();
|
|
__spin_lock (&ss->critical_section_lock);
|
|
|
|
#undef LOSE
|
|
#define LOSE assert_perror (err) /* XXX */
|
|
|
|
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, stopped = 0;
|
|
|
|
void resume_threads (void)
|
|
{
|
|
if (! stopped)
|
|
return;
|
|
|
|
assert (threads);
|
|
|
|
for (i = 0; i < nthreads; ++i)
|
|
if (threads[i] != ss->thread)
|
|
__thread_resume (threads[i]);
|
|
stopped = 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. */
|
|
{
|
|
void *const *p;
|
|
for (p = symbol_set_first_element (_hurd_fork_locks);
|
|
! symbol_set_end_p (_hurd_fork_locks, p);
|
|
++p)
|
|
__mutex_lock (*p);
|
|
}
|
|
__mutex_lock (&_hurd_siglock);
|
|
|
|
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;
|
|
|
|
|
|
/* Stop all other threads while copying the address space,
|
|
so nothing changes. */
|
|
err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
|
|
if (!err)
|
|
{
|
|
stopped = 1;
|
|
|
|
#define XXX_KERNEL_PAGE_FAULT_BUG /* XXX work around page fault bug in mk */
|
|
|
|
#ifdef XXX_KERNEL_PAGE_FAULT_BUG
|
|
/* Gag me with a pitchfork.
|
|
The bug scenario is this:
|
|
|
|
- The page containing __mach_task_self_ is paged out.
|
|
- The signal thread was faulting on that page when we
|
|
suspended it via proc_dostop. It holds some lock, or set
|
|
some busy bit, or somesuch.
|
|
- Now this thread faults on that same page.
|
|
- GRATUIOUS DEADLOCK
|
|
|
|
We can break the deadlock by aborting the thread that faulted
|
|
first, which if the bug happened was the signal thread because
|
|
it is the only other thread and we just suspended it.
|
|
*/
|
|
__thread_abort (_hurd_msgport_thread);
|
|
#endif
|
|
/* Create the child task. It will inherit a copy of our memory. */
|
|
err = __task_create (__mach_task_self (), 1, &newtask);
|
|
}
|
|
|
|
/* Unlock the global signal state lock, so we do not
|
|
block the signal thread any longer than necessary. */
|
|
__mutex_unlock (&_hurd_siglock);
|
|
|
|
if (err)
|
|
LOSE;
|
|
|
|
/* Fetch the names of all ports used in this task. */
|
|
if (err = __mach_port_names (__mach_task_self (),
|
|
&portnames, &nportnames,
|
|
&porttypes, &nporttypes))
|
|
LOSE;
|
|
if (nportnames != nporttypes)
|
|
{
|
|
err = EGRATUITOUS;
|
|
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))
|
|
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))
|
|
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)
|
|
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))
|
|
LOSE;
|
|
if (err = __mach_port_extract_right (newtask,
|
|
portnames[i],
|
|
MACH_MSG_TYPE_MAKE_SEND,
|
|
&port, &poly))
|
|
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))
|
|
LOSE;
|
|
if (old != MACH_PORT_NULL)
|
|
/* XXX what to do here? */
|
|
__mach_port_deallocate (__mach_task_self (), old);
|
|
/* The new task will receive its own exceptions
|
|
on its message port. */
|
|
if (err = __task_set_special_port (newtask,
|
|
TASK_EXCEPTION_PORT,
|
|
port))
|
|
LOSE;
|
|
}
|
|
if (err = __mach_port_insert_right (newtask,
|
|
portnames[i],
|
|
port,
|
|
MACH_MSG_TYPE_MOVE_SEND))
|
|
LOSE;
|
|
if (refs > 1 &&
|
|
(err = __mach_port_mod_refs (newtask,
|
|
portnames[i],
|
|
MACH_PORT_RIGHT_SEND,
|
|
refs - 1)))
|
|
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))
|
|
LOSE;
|
|
if (err = __mach_port_insert_right
|
|
(newtask,
|
|
portnames[i], port,
|
|
MACH_MSG_TYPE_MOVE_SEND_ONCE))
|
|
LOSE;
|
|
}
|
|
}
|
|
else if (porttypes[i] &
|
|
(MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
|
|
{
|
|
/* 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;
|
|
mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
|
|
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))
|
|
LOSE;
|
|
insert_type = MACH_MSG_TYPE_MOVE_SEND;
|
|
}
|
|
else if (portnames[i] == ss->thread)
|
|
{
|
|
/* 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]))
|
|
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]))
|
|
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;
|
|
|
|
/* Copy our own send right. */
|
|
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))
|
|
LOSE;
|
|
if (insert == MACH_PORT_NULL)
|
|
continue;
|
|
if (insert == portnames[i] &&
|
|
(porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
|
|
/* This is a dead name; allocate another dead name
|
|
with the same name in the child. */
|
|
allocate_dead_name:
|
|
err = __mach_port_allocate_name (newtask,
|
|
MACH_PORT_RIGHT_DEAD_NAME,
|
|
portnames[i]);
|
|
else
|
|
/* Insert the chosen send right into the child. */
|
|
err = __mach_port_insert_right (newtask,
|
|
portnames[i],
|
|
insert,
|
|
MACH_MSG_TYPE_COPY_SEND);
|
|
switch (err)
|
|
{
|
|
case 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);
|
|
break;
|
|
}
|
|
|
|
case KERN_INVALID_CAPABILITY:
|
|
/* The port just died. It was a send right,
|
|
and now it's a dead name. */
|
|
goto allocate_dead_name;
|
|
|
|
default:
|
|
LOSE;
|
|
break;
|
|
|
|
case KERN_SUCCESS:
|
|
/* 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)))
|
|
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;
|
|
|
|
/* All state has now been copied from the parent. It is safe to
|
|
resume other parent threads. */
|
|
resume_threads ();
|
|
|
|
/* Create the child main user thread and signal thread. */
|
|
if ((err = __thread_create (newtask, &thread)) ||
|
|
(err = __thread_create (newtask, &sigthread)))
|
|
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, ss->thread)) ||
|
|
(err = __mach_port_insert_right (newtask, ss->thread,
|
|
thread, MACH_MSG_TYPE_COPY_SEND)))
|
|
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, ss->thread,
|
|
MACH_PORT_RIGHT_SEND,
|
|
thread_refs)))
|
|
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))))
|
|
LOSE;
|
|
if (sigthread_refs > 1 &&
|
|
(err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
|
|
MACH_PORT_RIGHT_SEND,
|
|
sigthread_refs - 1)))
|
|
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)
|
|
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))
|
|
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))
|
|
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))
|
|
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)))
|
|
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)))
|
|
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);
|
|
|
|
resume_threads ();
|
|
|
|
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 (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 = ss->thread;
|
|
|
|
/* 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;
|
|
__mutex_unlock (&_hurd_siglock);
|
|
|
|
/* 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));
|
|
|
|
/* Forking clears the trace flag. */
|
|
__sigemptyset (&_hurdsig_traced);
|
|
|
|
/* 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. */
|
|
{
|
|
void *const *p;
|
|
for (p = symbol_set_first_element (_hurd_fork_locks);
|
|
! symbol_set_end_p (_hurd_fork_locks, p);
|
|
++p)
|
|
__mutex_unlock (*p);
|
|
}
|
|
|
|
_hurd_critical_section_unlock (ss);
|
|
|
|
return err ? __hurd_fail (err) : pid;
|
|
}
|
|
|
|
weak_alias (__fork, fork)
|