aboutsummaryrefslogtreecommitdiff
path: root/REORG.TODO/sysdeps/mach
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/sysdeps/mach')
-rw-r--r--REORG.TODO/sysdeps/mach/Makefile53
-rw-r--r--REORG.TODO/sysdeps/mach/Subdirs9
-rw-r--r--REORG.TODO/sysdeps/mach/_strerror.c120
-rw-r--r--REORG.TODO/sysdeps/mach/adjtime.c42
-rw-r--r--REORG.TODO/sysdeps/mach/configure564
-rw-r--r--REORG.TODO/sysdeps/mach/configure.ac135
-rw-r--r--REORG.TODO/sysdeps/mach/getloadavg.c53
-rw-r--r--REORG.TODO/sysdeps/mach/getpagesize.c28
-rw-r--r--REORG.TODO/sysdeps/mach/getsysstats.c105
-rw-r--r--REORG.TODO/sysdeps/mach/gettimeofday.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/Implies5
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/Makeconfig7
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/Makefile206
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/Subdirs9
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/Versions37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/_exit.c55
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/accept.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/accept4.c98
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/access.c173
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/adjtime.c52
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bind.c118
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/errno.h329
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/fcntl.h221
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/ioctls.h432
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/local_lim.h34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/param.h85
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/posix_opt.h182
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/socket.h362
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/stat.h258
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/statfs.h86
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/statvfs.h95
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/bits/typesizes.h68
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/brk.c166
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/chdir.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/check_fds.c107
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/chflags.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/chmod.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/chown.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/chroot.c65
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/clock.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/close.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/closedir.c60
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/configure49
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/configure.ac32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/connect.c77
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/cthreads.c59
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/device-nrs.h27
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dirfd.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dirstream.h41
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-execstack.c51
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-fcntl.h22
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-mman.h23
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-sysdep.c661
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-sysdep.h31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dl-unistd.h28
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dup2.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/dup3.c139
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/eloop-threshold.h37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/enbl-secure.c23
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/err_hurd.sub12
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/errlist.c28
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/errno-loc.c28
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/errno.c1
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/errnos.awk165
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/euidaccess.c57
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/execve.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/faccessat.c65
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchdir.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchflags.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchmod.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchmodat.c39
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchown.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fchownat.c40
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fcntl.c212
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fdatasync.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fdopendir.c57
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fexecve.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fgetxattr.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/flistxattr.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/flock.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fork.c733
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fpathconf.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fremovexattr.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fsetxattr.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fstatfs.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fstatfs64.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fstatvfs.c28
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fstatvfs64.c27
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fsync.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ftruncate.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ftruncate64.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/futimes.c50
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fxstat.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fxstat64.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fxstatat.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/fxstatat64.c46
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getclktck.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getcwd.c320
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getdents.c1
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getdomain.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getdtsz.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getegid.c56
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/geteuid.c56
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getgid.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getgroups.c69
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/gethostid.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/gethostname.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getitimer.c101
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getlogin.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getlogin_r.c48
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getpeername.c69
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getpgid.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getpid.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getppid.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getpriority.c85
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getresgid.c61
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getresuid.c61
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getrlimit.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getrusage.c91
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getsid.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getsockname.c59
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getsockopt.c55
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getuid.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/getxattr.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/group_member.c54
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/Makefile8
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/Versions10
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/____longjmp_chk.S114
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/bits/sigcontext.h121
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/c++-types.data67
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/dl-machine.h7
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/exc2signal.c165
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/init-first.c410
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/intr-msg.h112
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/ioperm.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/longjmp-ts.c39
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/sigcontextinfo.h24
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/signal-defines.sym10
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/sigreturn.c139
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/static-start.S27
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/sys/io.h177
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/tls.h169
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/i386/trampoline.c265
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/if_index.c196
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ifreq.c64
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ifreq.h44
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/init-posix.c2
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ioctl.c326
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/isatty.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/jmp-unwind.c79
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/kernel-features.h21
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/kill.c149
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lchmod.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lchown.c40
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lgetxattr.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/libc-ldscript6
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/libc-lock.h216
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/libc-tsd.h34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/libc_p-ldscript6
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/link.c58
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/linkat.c62
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/listen.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/listxattr.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/llistxattr.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lremovexattr.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lseek.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lseek64.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lsetxattr.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lutimes.c57
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lxstat.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/lxstat64.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/malloc-machine.h36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mig-reply.c87
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mkdir.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mkdirat.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mlock.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mmap.c188
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/mmap64.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/munlock.c46
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/net/ethernet.h75
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/net/if_arp.h144
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/net/if_ether.h84
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/net/if_ppp.h172
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/net/route.h140
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/open.c60
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/open64.c1
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/openat.c59
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/openat64.c1
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/opendir.c130
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pathconf.c40
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pipe.c50
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/poll.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ppoll.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pread.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pread64.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/prof-freq.c2
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/profil.c285
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pselect.c39
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ptrace.c385
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ptsname.c64
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pwrite.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/pwrite64.c39
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/read.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readdir.c66
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readdir64.c101
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readdir64_r.c111
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readdir_r.c64
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readlink.c61
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/readlinkat.c59
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/reboot.c49
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/recv.c64
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/recvfrom.c103
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/recvmsg.c146
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/removexattr.c34
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/rename.c45
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/renameat.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/revoke.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/rewinddir.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/rmdir.c39
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sbrk.c41
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/seekdir.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/select.c45
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/send.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sendfile.c36
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sendfile64.c59
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sendmsg.c165
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sendto.c100
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setdomain.c29
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setegid.c67
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/seteuid.c67
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setgid.c94
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setgroups.c62
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sethostid.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sethostname.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setitimer.c372
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setlogin.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setpgid.c54
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setpriority.c98
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setregid.c95
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setresgid.c123
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setresuid.c124
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setreuid.c95
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setrlimit.c56
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setsid.c73
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setsockopt.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/settimeofday.c52
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setuid.c99
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/setxattr.c35
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/shlib-versions12
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/shutdown.c38
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigaction.c91
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigaltstack.c60
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/siglist.h22
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigpending.c45
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigprocmask.c83
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigstack.c43
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigsuspend.c83
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sigwait.c133
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/socket.c65
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/socketpair.c94
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/spawni.c758
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/statfs.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/statfs64.c37
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/statfsconv.c48
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/statvfs.c28
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/statvfs64.c27
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/symlink.c69
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/symlinkat.c72
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sync.c30
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/syncfs.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/sysconf.c26
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/telldir.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/times.c74
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/tls.h57
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/tmpfile.c68
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/tmpfile64.c1
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/truncate.c41
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/truncate64.c42
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ttyname.c41
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/ttyname_r.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/umask.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/uname.c47
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/unlink.c44
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/unlinkat.c51
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/utimes.c55
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/wait4.c53
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/write.c32
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/xmknod.c33
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/xmknodat.c119
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/xstat.c31
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/xstat64.c46
-rw-r--r--REORG.TODO/sysdeps/mach/hurd/xstatconv.c64
-rw-r--r--REORG.TODO/sysdeps/mach/i386/machine-lock.h67
-rw-r--r--REORG.TODO/sysdeps/mach/i386/machine-sp.h30
-rw-r--r--REORG.TODO/sysdeps/mach/i386/syscall.S29
-rw-r--r--REORG.TODO/sysdeps/mach/i386/sysdep.h69
-rw-r--r--REORG.TODO/sysdeps/mach/i386/thread_state.h42
-rw-r--r--REORG.TODO/sysdeps/mach/libc-lock.h145
-rw-r--r--REORG.TODO/sysdeps/mach/mprotect.c50
-rw-r--r--REORG.TODO/sysdeps/mach/msync.c56
-rw-r--r--REORG.TODO/sysdeps/mach/munmap.c46
-rw-r--r--REORG.TODO/sysdeps/mach/nanosleep.c70
-rw-r--r--REORG.TODO/sysdeps/mach/pagecopy.h32
-rw-r--r--REORG.TODO/sysdeps/mach/readonly-area.c56
-rw-r--r--REORG.TODO/sysdeps/mach/sched_yield.c31
-rw-r--r--REORG.TODO/sysdeps/mach/sleep.c44
-rw-r--r--REORG.TODO/sysdeps/mach/strerror_l.c101
-rw-r--r--REORG.TODO/sysdeps/mach/sys/reboot.h171
-rw-r--r--REORG.TODO/sysdeps/mach/sys/syscall.h1
-rw-r--r--REORG.TODO/sysdeps/mach/sysdep.h86
-rw-r--r--REORG.TODO/sysdeps/mach/thread_state.h86
-rw-r--r--REORG.TODO/sysdeps/mach/usleep.c41
-rw-r--r--REORG.TODO/sysdeps/mach/xpg-strerror.c72
313 files changed, 23963 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/mach/Makefile b/REORG.TODO/sysdeps/mach/Makefile
new file mode 100644
index 0000000000..1ae25b2d74
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/Makefile
@@ -0,0 +1,53 @@
+# Copyright (C) 1993-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+ifdef in-Makerules
+
+# Look for header files in mach/ under the top-level library source directory.
+# Look for generated header files where they get created.
+includes += -I$(..)mach -I$(common-objpfx)mach/
+
+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.
+
+mach-objpfx = $(common-objpfx)mach/
+else
+mach-objpfx = $(objpfx)
+endif
+
+# These are all the generated files that <mach.h> includes.
+# Actually, it's only some of them. We omit mach_interface.h
+# because it's different in Darwin and the conditional crap is
+# too much trouble. This should suffice for getting the mach/Makefile
+# rules invoked when they need to be.
+mach-before-compile := $(mach-objpfx)mach-shortcuts.h \
+ $(patsubst %,$(mach-objpfx)mach/mach_%.h,\
+ port host)
+
+ifneq (mach,$(subdir))
+# 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)): mach-before-compile # Run only if doesn't exist.
+.PHONY: mach-before-compile
+mach-before-compile:
+ $(MAKE) -C $(..)mach subdir=mach mach-before-compile no_deps=t generating=t
+
+before-compile += $(mach-before-compile)
+endif
+
+endif # in-Makerules
diff --git a/REORG.TODO/sysdeps/mach/Subdirs b/REORG.TODO/sysdeps/mach/Subdirs
new file mode 100644
index 0000000000..24fa4a3c98
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/Subdirs
@@ -0,0 +1,9 @@
+# This file says that the mach subdirectory should appear before all others.
+# The mach and hurd subdirectories have many generated header files which
+# much of the 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.
+
+first mach
diff --git a/REORG.TODO/sysdeps/mach/_strerror.c b/REORG.TODO/sysdeps/mach/_strerror.c
new file mode 100644
index 0000000000..8b4b602eaa
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/_strerror.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libintl.h>
+#include <stdio.h>
+#include <string.h>
+#include <mach/error.h>
+#include <errorlib.h>
+#include <sys/param.h>
+#include <_itoa.h>
+
+/* It is critical here that we always use the `dcgettext' function for
+ the message translation. Since <libintl.h> only defines the macro
+ `dgettext' to use `dcgettext' for optimizing programs this is not
+ always guaranteed. */
+#ifndef dgettext
+# include <locale.h> /* We need LC_MESSAGES. */
+# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
+#endif
+
+/* Return a string describing the errno code in ERRNUM. */
+char *
+__strerror_r (int errnum, char *buf, size_t buflen)
+{
+ 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 || ! __mach_error_systems[system].bad_sub)
+ {
+ /* Buffer we use to print the number in. For a maximum size for
+ `int' of 8 bytes we never need more than 20 digits. */
+ char numbuf[21];
+ const char *unk = _("Error in unknown error system: ");
+ const size_t unklen = strlen (unk);
+ char *p, *q;
+
+ numbuf[20] = '\0';
+ p = _itoa_word (errnum, &numbuf[20], 16, 1);
+
+ /* Now construct the result while taking care for the destination
+ buffer size. */
+ q = __mempcpy (buf, unk, MIN (unklen, buflen));
+ if (unklen < buflen)
+ memcpy (q, p, MIN (&numbuf[21] - p, buflen - unklen));
+
+ /* Terminate the string in any case. */
+ if (buflen > 0)
+ buf[buflen - 1] = '\0';
+
+ return buf;
+ }
+
+ es = &__mach_error_systems[system];
+
+ if (sub >= es->max_sub)
+ return (char *) es->bad_sub;
+
+ if (code >= es->subsystem[sub].max_code)
+ {
+ /* Buffer we use to print the number in. For a maximum size for
+ `int' of 8 bytes we never need more than 20 digits. */
+ char numbuf[21];
+ const char *unk = _("Unknown error ");
+ const size_t unklen = strlen (unk);
+ char *p, *q;
+ size_t len = strlen (es->subsystem[sub].subsys_name);
+
+ numbuf[20] = '\0';
+ p = _itoa_word (errnum, &numbuf[20], 10, 0);
+
+ /* Now construct the result while taking care for the destination
+ buffer size. */
+ q = __mempcpy (buf, unk, MIN (unklen, buflen));
+ if (unklen < buflen)
+ {
+ q = __mempcpy (q, es->subsystem[sub].subsys_name,
+ MIN (len, buflen - unklen));
+ if (unklen + len < buflen)
+ {
+ *q++ = ' ';
+ if (unklen + len + 1 < buflen)
+ memcpy (q, p,
+ MIN (&numbuf[21] - p, buflen - unklen - len - 1));
+ }
+ }
+
+ /* Terminate the string in any case. */
+ if (buflen > 0)
+ buf[buflen - 1] = '\0';
+
+ return buf;
+ }
+
+ return (char *) _(es->subsystem[sub].codes[code]);
+}
+libc_hidden_def (__strerror_r)
+weak_alias (__strerror_r, strerror_r)
diff --git a/REORG.TODO/sysdeps/mach/adjtime.c b/REORG.TODO/sysdeps/mach/adjtime.c
new file mode 100644
index 0000000000..f68b0013ff
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/adjtime.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__adjtime (const struct timeval *delta, 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/REORG.TODO/sysdeps/mach/configure b/REORG.TODO/sysdeps/mach/configure
new file mode 100644
index 0000000000..632a9c9fa4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/configure
@@ -0,0 +1,564 @@
+
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_preproc LINENO HEADER VAR
+# ----------------------------------------------
+# Tests whether HEADER is present, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_preproc ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_preproc
+# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mig", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mig; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MIG"; then
+ ac_cv_prog_MIG="$MIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MIG="${ac_tool_prefix}mig"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MIG=$ac_cv_prog_MIG
+if test -n "$MIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MIG" >&5
+$as_echo "$MIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MIG"; then
+ ac_ct_MIG=$MIG
+ # Extract the first word of "mig", so it can be a program name with args.
+set dummy mig; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MIG"; then
+ ac_cv_prog_ac_ct_MIG="$ac_ct_MIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MIG="mig"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MIG=$ac_cv_prog_ac_ct_MIG
+if test -n "$ac_ct_MIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MIG" >&5
+$as_echo "$ac_ct_MIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MIG" = x; then
+ MIG="MISSING"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MIG=$ac_ct_MIG
+ fi
+else
+ MIG="$ac_cv_prog_MIG"
+fi
+
+if test "x$MIG" = xMISSING; then
+ as_fn_error $? "cannot find required build tool mig" "$LINENO" 5
+fi
+config_vars="$config_vars
+MIG = $MIG"
+
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+
+### Sanity checks for Mach header installation
+
+
+ac_fn_c_check_header_preproc "$LINENO" "mach/mach_types.h" "ac_cv_header_mach_mach_types_h"
+if test "x$ac_cv_header_mach_mach_types_h" = xyes; then :
+
+else
+ as_fn_error $? "cannot find Mach headers" "$LINENO" 5
+fi
+
+
+ac_fn_c_check_header_preproc "$LINENO" "mach/mach_types.defs" "ac_cv_header_mach_mach_types_defs"
+if test "x$ac_cv_header_mach_mach_types_defs" = xyes; then :
+
+else
+ as_fn_error $? "cannot find Mach .defs files" "$LINENO" 5
+fi
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for task_t in mach/mach_types.h" >&5
+$as_echo_n "checking for task_t in mach/mach_types.h... " >&6; }
+if ${libc_cv_mach_task_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/mach_types.h>
+int
+main ()
+{
+extern task_t foo;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libc_cv_mach_task_t=task_t
+else
+ libc_cv_mach_task_t=task_port_t
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_task_t" >&5
+$as_echo "$libc_cv_mach_task_t" >&6; }
+if test $libc_cv_mach_task_t != task_t; then
+ DEFINES="$DEFINES -Dtask_t=task_port_t"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for thread_t in mach/mach_types.h" >&5
+$as_echo_n "checking for thread_t in mach/mach_types.h... " >&6; }
+if ${libc_cv_mach_thread_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/mach_types.h>
+int
+main ()
+{
+extern thread_t foo;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libc_cv_mach_thread_t=thread_t
+else
+ libc_cv_mach_thread_t=thread_port_t
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_thread_t" >&5
+$as_echo "$libc_cv_mach_thread_t" >&6; }
+if test $libc_cv_mach_thread_t != thread_t; then
+ DEFINES="$DEFINES -Dthread_t=thread_port_t"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for creation_time in task_basic_info" >&5
+$as_echo_n "checking for creation_time in task_basic_info... " >&6; }
+if ${libc_cv_mach_task_creation_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/task_info.h>
+int
+main ()
+{
+
+extern struct task_basic_info *i;
+long s = i->creation_time.seconds;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libc_cv_mach_task_creation_time=yes
+else
+ libc_cv_mach_task_creation_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_task_creation_time" >&5
+$as_echo "$libc_cv_mach_task_creation_time" >&6; }
+if test $libc_cv_mach_task_creation_time = no; then
+ as_fn_error $? "you need Mach headers supporting task_info.creation_time" "$LINENO" 5
+fi
+
+mach_interface_list=
+for ifc in mach mach4 \
+ clock clock_priv host_priv host_security ledger lock_set \
+ processor processor_set task task_notify thread_act vm_map \
+ memory_object memory_object_default default_pager \
+ i386/mach_i386 \
+ ; do
+ as_ac_Header=`$as_echo "ac_cv_header_mach/${ifc}.defs" | $as_tr_sh`
+ac_fn_c_check_header_preproc "$LINENO" "mach/${ifc}.defs" "$as_ac_Header"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ mach_interface_list="$mach_interface_list $ifc"
+fi
+
+
+done
+if test "x$mach_interface_list" = x; then
+ as_fn_error $? "what manner of Mach is this?" "$LINENO" 5
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for host_page_size in mach_host.defs" >&5
+$as_echo_n "checking for host_page_size in mach_host.defs... " >&6; }
+if ${libc_cv_mach_host_page_size+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/mach_host.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "host_page_size" >/dev/null 2>&1; then :
+ libc_cv_mach_host_page_size=yes
+else
+ libc_cv_mach_host_page_size=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_host_page_size" >&5
+$as_echo "$libc_cv_mach_host_page_size" >&6; }
+if test $libc_cv_mach_host_page_size = yes; then
+ $as_echo "#define HAVE_HOST_PAGE_SIZE 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_header_preproc "$LINENO" "mach/machine/ndr_def.h" "ac_cv_header_mach_machine_ndr_def_h"
+if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes; then :
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"
+else
+ ac_fn_c_check_header_preproc "$LINENO" "machine/ndr_def.h" "ac_cv_header_machine_ndr_def_h"
+if test "x$ac_cv_header_machine_ndr_def_h" = xyes; then :
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<machine/ndr_def.h>'"
+fi
+
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for i386_io_perm_modify in mach_i386.defs" >&5
+$as_echo_n "checking for i386_io_perm_modify in mach_i386.defs... " >&6; }
+if ${libc_cv_mach_i386_ioports+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/i386/mach_i386.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "i386_io_perm_modify" >/dev/null 2>&1; then :
+ libc_cv_mach_i386_ioports=yes
+else
+ libc_cv_mach_i386_ioports=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_i386_ioports" >&5
+$as_echo "$libc_cv_mach_i386_ioports" >&6; }
+if test $libc_cv_mach_i386_ioports = yes; then
+ $as_echo "#define HAVE_I386_IO_PERM_MODIFY 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for i386_set_gdt in mach_i386.defs" >&5
+$as_echo_n "checking for i386_set_gdt in mach_i386.defs... " >&6; }
+if ${libc_cv_mach_i386_gdt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/i386/mach_i386.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "i386_set_gdt" >/dev/null 2>&1; then :
+ libc_cv_mach_i386_gdt=yes
+else
+ libc_cv_mach_i386_gdt=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_i386_gdt" >&5
+$as_echo "$libc_cv_mach_i386_gdt" >&6; }
+if test $libc_cv_mach_i386_gdt = yes; then
+ $as_echo "#define HAVE_I386_SET_GDT 1" >>confdefs.h
+
+fi
+
+
+
+# See if mig groks `retcode'.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $MIG supports the retcode keyword" >&5
+$as_echo_n "checking whether $MIG supports the retcode keyword... " >&6; }
+if ${hurd_cv_mig_retcode+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.defs <<\EOF
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+subsystem foobar 1000;
+type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
+ ctype: mach_port_t;
+simpleroutine foobar_reply (
+ reply_port: reply_port_t;
+ err: kern_return_t, RetCode);
+EOF
+if { ac_try='CC="${CC}" ${MIG-false} -n conftest.defs 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ hurd_cv_mig_retcode=yes
+else
+ hurd_cv_mig_retcode=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_mig_retcode" >&5
+$as_echo "$hurd_cv_mig_retcode" >&6; }
+if test $hurd_cv_mig_retcode = yes; then
+ $as_echo "#define HAVE_MIG_RETCODE 1" >>confdefs.h
+
+fi
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
diff --git a/REORG.TODO/sysdeps/mach/configure.ac b/REORG.TODO/sysdeps/mach/configure.ac
new file mode 100644
index 0000000000..3033fec946
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/configure.ac
@@ -0,0 +1,135 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+AC_CHECK_TOOL(MIG, mig, MISSING)
+if test "x$MIG" = xMISSING; then
+ AC_MSG_ERROR([cannot find required build tool mig])
+fi
+LIBC_CONFIG_VAR([MIG], [$MIG])
+
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+
+### Sanity checks for Mach header installation
+AC_CHECK_HEADER(mach/mach_types.h,,
+ [AC_MSG_ERROR([cannot find Mach headers])], -)
+AC_CHECK_HEADER(mach/mach_types.defs,, [dnl
+AC_MSG_ERROR([cannot find Mach .defs files])], -)
+
+dnl
+dnl mach_TYPE_CHECK(foo_t, bar_t)
+dnl
+dnl Check if foo_t is defined by <mach/mach_types.h>.
+dnl If not, compile with -Dfoo_t=bar_t.
+dnl
+AC_DEFUN([mach_TYPE_CHECK], [dnl
+AC_CACHE_CHECK(for $1 in mach/mach_types.h, libc_cv_mach_$1,
+AC_TRY_COMPILE([#include <mach/mach_types.h>], [extern $1 foo;],
+libc_cv_mach_$1=$1, libc_cv_mach_$1=$2))
+if test [$]libc_cv_mach_$1 != $1; then
+ DEFINES="$DEFINES -D$1=$2"
+fi])
+
+dnl
+dnl OSF Mach has renamed these typedefs for some reason.
+dnl
+mach_TYPE_CHECK(task_t, task_port_t)
+mach_TYPE_CHECK(thread_t, thread_port_t)
+
+dnl
+dnl The creation_time field is a GNU Mach addition the other variants lack.
+dnl
+AC_CACHE_CHECK(for creation_time in task_basic_info,
+ libc_cv_mach_task_creation_time, [dnl
+AC_TRY_COMPILE([#include <mach/task_info.h>], [
+extern struct task_basic_info *i;
+long s = i->creation_time.seconds;
+], libc_cv_mach_task_creation_time=yes, libc_cv_mach_task_creation_time=no)])
+if test $libc_cv_mach_task_creation_time = no; then
+ AC_MSG_ERROR([you need Mach headers supporting task_info.creation_time])
+fi
+
+dnl
+dnl The Darwin variant no longer has <mach/mach.defs>
+dnl but instead has several constituent .defs files.
+dnl In this scenario we will presume there is a <mach/mach_interface.h>
+dnl that contains an #include for each constituent header file,
+dnl but we don't do a check for that here because in a bare
+dnl environment the compile against those headers will fail.
+dnl
+mach_interface_list=
+for ifc in mach mach4 \
+ clock clock_priv host_priv host_security ledger lock_set \
+ processor processor_set task task_notify thread_act vm_map \
+ memory_object memory_object_default default_pager \
+ i386/mach_i386 \
+ ; do
+ AC_CHECK_HEADER(mach/${ifc}.defs, [dnl
+ mach_interface_list="$mach_interface_list $ifc"],, -)
+done
+if test "x$mach_interface_list" = x; then
+ AC_MSG_ERROR([what manner of Mach is this?])
+fi
+
+AC_CACHE_CHECK(for host_page_size in mach_host.defs,
+ libc_cv_mach_host_page_size, [dnl
+AC_EGREP_HEADER(host_page_size, mach/mach_host.defs,
+ libc_cv_mach_host_page_size=yes,
+ libc_cv_mach_host_page_size=no)])
+if test $libc_cv_mach_host_page_size = yes; then
+ AC_DEFINE([HAVE_HOST_PAGE_SIZE])
+fi
+
+AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl
+AC_CHECK_HEADER(machine/ndr_def.h, [dnl
+ DEFINES="$DEFINES -DNDR_DEF_HEADER='<machine/ndr_def.h>'"],, -)], -)
+
+AC_CACHE_CHECK(for i386_io_perm_modify in mach_i386.defs,
+ libc_cv_mach_i386_ioports, [dnl
+AC_EGREP_HEADER(i386_io_perm_modify, mach/i386/mach_i386.defs,
+ libc_cv_mach_i386_ioports=yes,
+ libc_cv_mach_i386_ioports=no)])
+if test $libc_cv_mach_i386_ioports = yes; then
+ AC_DEFINE([HAVE_I386_IO_PERM_MODIFY])
+fi
+
+AC_CACHE_CHECK(for i386_set_gdt in mach_i386.defs,
+ libc_cv_mach_i386_gdt, [dnl
+AC_EGREP_HEADER(i386_set_gdt, mach/i386/mach_i386.defs,
+ libc_cv_mach_i386_gdt=yes,
+ libc_cv_mach_i386_gdt=no)])
+if test $libc_cv_mach_i386_gdt = yes; then
+ AC_DEFINE([HAVE_I386_SET_GDT])
+fi
+
+dnl Swiped from hurd/aclocal.m4
+AC_DEFUN([hurd_MIG_RETCODE], [dnl
+# See if mig groks `retcode'.
+AC_CACHE_CHECK(whether $MIG supports the retcode keyword, hurd_cv_mig_retcode,
+[cat > conftest.defs <<\EOF
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+subsystem foobar 1000;
+type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
+ ctype: mach_port_t;
+simpleroutine foobar_reply (
+ reply_port: reply_port_t;
+ err: kern_return_t, RetCode);
+EOF
+if AC_TRY_COMMAND([CC="${CC}" ${MIG-false} -n conftest.defs 1>&AS_MESSAGE_LOG_FD]); then
+ hurd_cv_mig_retcode=yes
+else
+ hurd_cv_mig_retcode=no
+fi
+rm -f conftest*])
+if test $hurd_cv_mig_retcode = yes; then
+ AC_DEFINE(HAVE_MIG_RETCODE)
+fi])
+
+hurd_MIG_RETCODE
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
diff --git a/REORG.TODO/sysdeps/mach/getloadavg.c b/REORG.TODO/sysdeps/mach/getloadavg.c
new file mode 100644
index 0000000000..c54b772a15
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/getloadavg.c
@@ -0,0 +1,53 @@
+/* Get system load averages. Mach version.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <mach.h>
+#include <mach/host_info.h>
+#include <hurd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+/* Put the 1 minute, 5 minute and 15 minute load averages
+ into the first NELEM elements of LOADAVG.
+ Return the number written (never more than 3, but may be less than NELEM),
+ or -1 if an error occurred. */
+
+int
+getloadavg (double loadavg[], int nelem)
+{
+ host_load_info_data_t info;
+ mach_msg_type_number_t size = HOST_LOAD_INFO_COUNT;
+ error_t err;
+ int i;
+
+ err = __host_info (__mach_host_self (), HOST_LOAD_INFO,
+ (host_info_t) &info, &size);
+ if (err)
+ return __hurd_fail (err);
+ if (size < HOST_LOAD_INFO_COUNT)
+ return __hurd_fail (EGRATUITOUS);
+
+ if (nelem > 3)
+ nelem = 3;
+ for (i = 0; i < nelem; ++i)
+ loadavg[i] = (double) info.avenrun[i] / (double) LOAD_SCALE;
+
+ return i;
+}
diff --git a/REORG.TODO/sysdeps/mach/getpagesize.c b/REORG.TODO/sysdeps/mach/getpagesize.c
new file mode 100644
index 0000000000..e1ab8168c2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/getpagesize.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <mach.h>
+
+/* Return the system page size. */
+int
+__getpagesize (void)
+{
+ return __vm_page_size;
+}
+libc_hidden_def (__getpagesize)
+weak_alias (__getpagesize, getpagesize)
diff --git a/REORG.TODO/sysdeps/mach/getsysstats.c b/REORG.TODO/sysdeps/mach/getsysstats.c
new file mode 100644
index 0000000000..0dacab0300
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/getsysstats.c
@@ -0,0 +1,105 @@
+/* System dependent pieces of sysconf; Mach version
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <mach.h>
+#include <hurd.h>
+#include <sys/sysinfo.h>
+
+
+/* Return the number of processors configured on the system. */
+int
+__get_nprocs_conf (void)
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.max_cpus;
+}
+weak_alias (__get_nprocs_conf, get_nprocs_conf)
+
+/* Return the number of processors currently available on the system. */
+int
+__get_nprocs (void)
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.avail_cpus;
+}
+weak_alias (__get_nprocs, get_nprocs)
+
+/* Return the number of physical pages on the system. */
+long int
+__get_phys_pages (void)
+{
+ struct host_basic_info hbi;
+ kern_return_t err;
+ mach_msg_type_number_t cnt = HOST_BASIC_INFO_COUNT;
+
+ err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
+ (host_info_t) &hbi, &cnt);
+ if (err)
+ return __hurd_fail (err);
+ else if (cnt != HOST_BASIC_INFO_COUNT)
+ return __hurd_fail (EIEIO);
+
+ return hbi.memory_size / __vm_page_size;
+}
+weak_alias (__get_phys_pages, get_phys_pages)
+
+/* Return the number of available physical pages */
+long int
+__get_avphys_pages (void)
+{
+ vm_statistics_data_t vs;
+ kern_return_t err;
+
+#ifdef HOST_VM_INFO
+ {
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ err = __host_info (__mach_host_self (), HOST_VM_INFO,
+ (host_info_t) &vs, &count);
+ if (!err && count < HOST_VM_INFO_COUNT)
+ err = EGRATUITOUS;
+ }
+#else
+ err = __vm_statistics (__mach_task_self (), &vs);
+#endif
+ if (err)
+ return __hurd_fail (err);
+
+ return vs.free_count;
+}
+weak_alias (__get_avphys_pages, get_avphys_pages)
diff --git a/REORG.TODO/sysdeps/mach/gettimeofday.c b/REORG.TODO/sysdeps/mach/gettimeofday.c
new file mode 100644
index 0000000000..ca0252e7af
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/gettimeofday.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.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
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ kern_return_t err;
+
+ if (tz != NULL)
+ *tz = (struct timezone){0, 0}; /* XXX */
+
+ if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+libc_hidden_def (__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/REORG.TODO/sysdeps/mach/hurd/Implies b/REORG.TODO/sysdeps/mach/hurd/Implies
new file mode 100644
index 0000000000..d2d5234c1f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/Implies
@@ -0,0 +1,5 @@
+# The gnu subdirectory exists for things common to both Linux-based and
+# Hurd-based GNU systems.
+gnu
+# The Hurd provides a rough superset of the functionality of 4.4 BSD.
+unix/bsd
diff --git a/REORG.TODO/sysdeps/mach/hurd/Makeconfig b/REORG.TODO/sysdeps/mach/hurd/Makeconfig
new file mode 100644
index 0000000000..fe3b7c553e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/Makeconfig
@@ -0,0 +1,7 @@
+# We need special startup code for statically linked binaries.
+# See Makefile in this directory for the rule that builds this.
+# We must define this variable earlier than sysdeps Makefiles are included.
+static-start-installed-name = crt0.o
+
+# GNU libc on the Hurd is always reentrant.
+libc-reentrant = yes
diff --git a/REORG.TODO/sysdeps/mach/hurd/Makefile b/REORG.TODO/sysdeps/mach/hurd/Makefile
new file mode 100644
index 0000000000..13bdf5c7c9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/Makefile
@@ -0,0 +1,206 @@
+# Copyright (C) 1993-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+ifdef in-Makerules
+
+# Look for header files in hurd/ under the top-level library source directory.
+# Look for generated header files where they get created.
+includes += -I$(..)hurd -I$(common-objpfx)hurd/
+
+# We use the style `if (err = call(...))' a lot in the Hurd code,
+# where we have a lot of functions that return zero or an errno code.
++cflags += -Wno-parentheses
+
+# 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.*
+inhibit-unix-syscalls = yes
+
+# 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/.)
+
+hurd-objpfx = $(common-objpfx)hurd/
+
+# These are all the generated headers that <hurd.h> includes.
+before-compile += $(patsubst %,$(hurd-objpfx)hurd/%.h,auth io fs process)
+$(patsubst %,$(hurd-objpfx)hurd/%.h,auth io fs process): hurd-before-compile
+.PHONY: hurd-before-compile
+hurd-before-compile: $(common-objpfx)mach/mach-shortcuts.h
+ $(MAKE) -C $(..)hurd subdir=hurd before-compile no_deps=t
+endif
+
+# Hurd profil.c includes this file, so give a rule to make it.
+ifeq ($(subdir),gmon)
+$(common-objpfx)hurd/../mach/RPC_task_get_sampled_pcs.c:
+ $(MAKE) -C $(..)mach subdir=mach before-compile no_deps=t
+endif
+
+
+# Generate bits/errno.h from the section of the manual that lists all the errno
+# codes.
+
+errno.texinfo = $(..)manual/errno.texi
+
+hurd = $(..)sysdeps/mach/hurd
+
+define mach-errno-h
+($(foreach h,mach/message.h \
+ mach/kern_return.h \
+ mach/mig_errors.h \
+ device/device_types.h,\
+ echo '#include <$h>';\
+ ))
+endef
+
+# We use the compiler to generate a list of absolute file names for
+# the headers we want to search for Mach error codes, listed above (and
+# incidentally, all other headers those include).
+-include $(common-objpfx)errnos.d
+$(common-objpfx)errnos.d: $(mach-errnos-deps)
+ $(mach-errno-h) | \
+ $(CC) $(CFLAGS) \
+ $(subst -include $(common-objpfx)libc-modules.h,,$(CPPFLAGS)) \
+ -M -x c - | \
+ sed $(sed-remove-objpfx) -e 's,- *:,mach-errnos-deps :=,' \
+ -e 's, \.\./, $(..),g' > $@t
+ mv -f $@t $@
+
+$(hurd)/bits/errno.h: $(common-objpfx)stamp-errnos ;
+$(common-objpfx)stamp-errnos: $(hurd)/errnos.awk $(errno.texinfo) \
+ $(mach-errnos-deps) $(common-objpfx)errnos.d
+ $(AWK) -f $^ > $(hurd)/bits/errno.h-tmp
+# Make it unwritable so noone will edit it by mistake.
+ -chmod a-w $(hurd)/bits/errno.h-tmp
+ $(move-if-change) $(hurd)/bits/errno.h-tmp $(hurd)/bits/errno.h
+ touch $@
+
+common-generated += errnos.d stamp-errnos
+
+# 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 += $(inst_libdir)/libc.a
+$(inst_libdir)/libc.a: $(hurd)/libc-ldscript $(+force); $(do-install)
+ifeq (yes,$(build-profile))
+install-others += $(inst_libdir)/libc_p.a
+$(inst_libdir)/libc_p.a: $(hurd)/libc_p-ldscript $(+force); $(do-install)
+endif
+endif
+
+# Make sure these are used to build the libc.so shared object too. There
+# is a circular dependency between each of these shared objects and libc
+# (many high-level libc functions call stubs, stubs call low-level libc
+# functions like memcpy and mach_msg). This works out fine at run time
+# (all the objects are loaded before resolving their symbols, so these
+# interdependencies are fine). But to create the shared objects we must
+# link them one at a time; since each needs one or both of the others to
+# produce its DT_NEEDED entries and to assign its undefined symbols the
+# right symbol versions, we can't do any of them before the others! To
+# get around this, we link each lib*user.so shared object twice. First,
+# we link an object without reference to libc.so (since we haven't linked
+# libc.so yet), so it lacks a DT_NEEDED record for the libc soname it
+# depends on, and its undefined symbol references lack the symbol version
+# assignments they should have. We will use this shared object solely to
+# link libc.so against it; that gives libc.so the proper DT_NEEDED record,
+# and symbol versions assignments (if the lib*user.so object is using them).
+# Finally we link a second version of the same lib*user.so shared object,
+# this time linked normally against libc so it gets a proper DT_NEEDED
+# record and symbol version set; this one can be installed for run-time use.
+rpcuserlibs := $(common-objpfx)mach/libmachuser.so \
+ $(common-objpfx)hurd/libhurduser.so
+link-rpcuserlibs := $(rpcuserlibs:%user.so=%user-link.so)
+$(common-objpfx)libc.so: $(link-rpcuserlibs)
+$(common-objpfx)linkobj/libc.so: $(link-rpcuserlibs)
+rpath-dirs += mach hurd
+
+# Make sure the `lib' pass builds the dummy shared objects so
+# we can link libc against them.
+ifeq (mach,$(subdir))
+lib-noranlib: $(common-objpfx)mach/libmachuser-link.so
+endif
+ifeq (hurd,$(subdir))
+lib-noranlib: $(common-objpfx)hurd/libhurduser-link.so
+endif
+
+$(link-rpcuserlibs): %-link.so: %_pic.a
+# These shared objects are just for the purpose of linking libc,
+# so they don't need abi-note.o linked into them.
+ $(build-shlib-helper) \
+ -nostdlib -o $@ \
+ -Wl,-soname=$(*F).so$($(*F).so-version) \
+ $(build-shlib-objlist)
+libmachuser-link.so-no-z-defs = yes
+libhurduser-link.so-no-z-defs = yes
+
+# And get them into the libc.so ldscript.
+$(inst_libdir)/libc.so: $(rpcuserlibs)
+
+# The RPC stubs from these libraries are needed in building the dynamic
+# linker, too. It must be self-contained, so we link the needed PIC
+# objects directly into the shared object.
+ifeq (elf,$(subdir))
+$(objpfx)librtld.map: $(rpcuserlibs:.so=_pic.a)
+
+CFLAGS-dl-load.c = -DEXTERNAL_MAP_FROM_FD
+endif
+
+# Override the generic Makeconfig values so we link against the RPC libs.
+link-libc-static := -Wl,--start-group \
+ $(patsubst %,$(common-objpfx)%.a,\
+ libc mach/libmachuser hurd/libhurduser) \
+ $(static-gnulib) -Wl,--end-group
+link-libc-static-tests := -Wl,--start-group \
+ $(patsubst %,$(common-objpfx)%.a,\
+ libc mach/libmachuser hurd/libhurduser) \
+ $(static-gnulib-tests) -Wl,--end-group
+
+ifeq ($(subdir),csu)
+
+extra-objs += static-start.o
+
+# We need special startup code for statically linked binaries.
+$(objpfx)crt0.o: $(objpfx)static-start.o $(objpfx)abi-note.o $(objpfx)init.o
+ $(link-relocatable)
+
+endif
+
+ifeq (hurd, $(subdir))
+sysdep_routines += cthreads
+endif
+
+ifeq ($(subdir),sunrpc)
+sysdep_headers += nfs/nfs.h
+endif
+
+ifeq ($(subdir),socket)
+sysdep_headers += net/ethernet.h net/if_arp.h net/if_ether.h net/if_ppp.h \
+ net/route.h
+endif
+
+endif # in-Makerules
diff --git a/REORG.TODO/sysdeps/mach/hurd/Subdirs b/REORG.TODO/sysdeps/mach/hurd/Subdirs
new file mode 100644
index 0000000000..7a7757582a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/Subdirs
@@ -0,0 +1,9 @@
+# This file says that the hurd subdirectory should appear before all others.
+# The mach and hurd subdirectories have many generated header files which
+# much of the 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.
+
+first hurd
diff --git a/REORG.TODO/sysdeps/mach/hurd/Versions b/REORG.TODO/sysdeps/mach/hurd/Versions
new file mode 100644
index 0000000000..89e19061af
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/Versions
@@ -0,0 +1,37 @@
+libc {
+ GLIBC_2.0 {
+ # functions with a weak definition in the dynamic linker
+ __getcwd; __mmap;
+ }
+ GLIBC_PRIVATE {
+ # Functions shared with the dynamic linker
+ __libc_read; __libc_write; __libc_lseek64;
+
+ _dl_init_first;
+ }
+}
+
+ld {
+ GLIBC_2.0 {
+ # variables that must be shared with libc
+ __hurd_sigthread_stack_base; __hurd_sigthread_stack_end;
+ __hurd_sigthread_variables;
+ __hurd_threadvar_stack_mask; __hurd_threadvar_stack_offset;
+
+ # functions that must be shared with libc
+ __close; __getcwd; __getpid;
+ __mmap; __open; __xstat64; __fxstat64;
+ _exit; _hurd_intr_rpc_mach_msg;
+ abort;
+ }
+ GLIBC_2.2.6 {
+ # this also must be shared with libc.
+ __errno_location;
+ }
+ GLIBC_PRIVATE {
+ _dl_init_first;
+
+ # functions that must be shared with libc
+ __libc_read; __libc_write; __libc_lseek64;
+ }
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/_exit.c b/REORG.TODO/sysdeps/mach/hurd/_exit.c
new file mode 100644
index 0000000000..ae3b7984a8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/_exit.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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, 0));
+
+ /* 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
+_exit (int status)
+{
+ _hurd_exit (W_EXITCODE (status, 0));
+}
+libc_hidden_def (_exit)
+rtld_hidden_def (_exit)
+weak_alias (_exit, _Exit)
diff --git a/REORG.TODO/sysdeps/mach/hurd/accept.c b/REORG.TODO/sysdeps/mach/hurd/accept.c
new file mode 100644
index 0000000000..5c6d5256bf
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/accept.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/socket.h>
+
+/* Await a connection on socket FD.
+ When a connection arrives, open a new socket to communicate with it,
+ set *ADDRARG (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
+accept (int fd, __SOCKADDR_ARG addrarg, socklen_t *addr_len)
+{
+ return __libc_accept4 (fd, addrarg, addr_len, 0);
+}
+libc_hidden_def (accept)
diff --git a/REORG.TODO/sysdeps/mach/hurd/accept4.c b/REORG.TODO/sysdeps/mach/hurd/accept4.c
new file mode 100644
index 0000000000..4b3f62a5a5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/accept4.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <fcntl-internal.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Await a connection on socket FD.
+ When a connection arrives, open a new socket to communicate with it,
+ set *ADDRARG (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. The operation can be influenced
+ by the FLAGS parameter. */
+int
+__libc_accept4 (int fd, __SOCKADDR_ARG addrarg, socklen_t *addr_len, int flags)
+{
+ error_t err;
+ socket_t new;
+ addr_port_t aport;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ char *buf = (char *) addr;
+ mach_msg_type_number_t buflen;
+ int type;
+
+ flags = sock_to_o_flags (flags);
+
+ if (flags & ~(O_CLOEXEC | O_NONBLOCK))
+ return __hurd_fail (EINVAL);
+
+ if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport)))
+ return __hurd_dfail (fd, err);
+
+ if (addr != NULL)
+ {
+ buflen = *addr_len;
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = (char *)addr;
+ buflen = 0;
+ err = 0;
+ }
+ }
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (! err)
+ {
+ if (flags & O_NONBLOCK)
+ err = __io_set_some_openmodes (new, O_NONBLOCK);
+ /* TODO: do we need special ERR massaging after the previous call? */
+ }
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), new);
+ return __hurd_dfail (fd, err);
+ }
+
+ if (addr != NULL)
+ {
+ if (*addr_len > buflen)
+ *addr_len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *addr_len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ addr->sa_family = type;
+ }
+
+ return _hurd_intern_fd (new, O_IGNORE_CTTY | flags, 1);
+}
+weak_alias (__libc_accept4, accept4)
diff --git a/REORG.TODO/sysdeps/mach/hurd/access.c b/REORG.TODO/sysdeps/mach/hurd/access.c
new file mode 100644
index 0000000000..185e000c9d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/access.c
@@ -0,0 +1,173 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/id.h>
+#include <hurd/lookup.h>
+#include <fcntl.h>
+
+static int
+hurd_fail_seterrno (error_t err)
+{
+ return __hurd_fail (err);
+}
+
+static int
+hurd_fail_noerrno (error_t err)
+{
+ return -1;
+}
+
+static int
+access_common (const char *file, int type, int (*errfunc) (error_t))
+{
+ error_t err;
+ file_t rcrdir, rcwdir, io;
+ int flags, allowed;
+
+ error_t reauthenticate (int which, file_t *result)
+ {
+ /* Get a port to our root directory, authenticated with the real IDs. */
+ error_t err;
+ mach_port_t ref;
+ ref = __mach_reply_port ();
+ err = HURD_PORT_USE
+ (&_hurd_ports[which],
+ ({
+ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (_hurd_id.rid_auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ result);
+ err;
+ }));
+ __mach_port_destroy (__mach_task_self (), ref);
+ return err;
+ }
+
+ error_t init_port (int which, error_t (*operate) (mach_port_t))
+ {
+ switch (which)
+ {
+ case INIT_PORT_AUTH:
+ return (*operate) (_hurd_id.rid_auth);
+ case INIT_PORT_CRDIR:
+ return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
+ (*operate) (rcrdir));
+ case INIT_PORT_CWDIR:
+ return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
+ (*operate) (rcwdir));
+ default:
+ return _hurd_ports_use (which, operate);
+ }
+ }
+
+ rcrdir = rcwdir = MACH_PORT_NULL;
+
+ 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.uids,
+ _hurd_id.aux.nuids,
+ _hurd_id.aux.gids, 1,
+ _hurd_id.aux.gids,
+ _hurd_id.aux.ngids,
+ &_hurd_id.rid_auth)))
+ goto lose;
+ }
+
+ if (!err)
+ /* Look up the file name using the modified init ports. */
+ err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
+ file, 0, 0, &io);
+
+ /* We are done with _hurd_id.rid_auth now. */
+ lose:
+ __mutex_unlock (&_hurd_id.lock);
+
+ HURD_CRITICAL_END;
+
+ if (rcrdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcrdir);
+ if (rcwdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcwdir);
+ if (err)
+ return errfunc (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 errfunc (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 errfunc (EACCES);
+
+ return 0;
+}
+
+/* Test for access to FILE by our real user and group IDs without setting
+ errno. This may be unsafe to run during initialization of tunables
+ since access_common calls __hurd_file_name_lookup, which calls
+ __hurd_file_name_lookup_retry, which can set errno. */
+int
+__access_noerrno (const char *file, int type)
+{
+ return access_common (file, type, hurd_fail_noerrno);
+}
+
+/* Test for access to FILE by our real user and group IDs. */
+int
+__access (const char *file, int type)
+{
+ return access_common (file, type, hurd_fail_seterrno);
+}
+weak_alias (__access, access)
diff --git a/REORG.TODO/sysdeps/mach/hurd/adjtime.c b/REORG.TODO/sysdeps/mach/hurd/adjtime.c
new file mode 100644
index 0000000000..3175e47ff0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/adjtime.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__adjtime (const struct timeval *delta, struct timeval *olddelta)
+{
+ error_t err;
+ mach_port_t hostpriv;
+ struct timeval dummy;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ if (olddelta == NULL)
+ olddelta = &dummy;
+
+ 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/REORG.TODO/sysdeps/mach/hurd/bind.c b/REORG.TODO/sysdeps/mach/hurd/bind.c
new file mode 100644
index 0000000000..a0dbea6551
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bind.c
@@ -0,0 +1,118 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 "hurd/hurdsocket.h"
+
+/* Give the socket FD the local address ADDR (which is LEN bytes long). */
+int
+__bind (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len)
+{
+ addr_port_t aport;
+ error_t err;
+ const struct sockaddr_un *addr = addrarg.__sockaddr_un__;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ char *name = _hurd_sun_path_dupa (addr, len);
+ /* For the local domain, we must create a node in the filesystem
+ using the ifsock translator and then fetch the address from it. */
+ file_t dir, node, ifsock;
+ char *n;
+
+ 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)
+ {
+ /* 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)
+ {
+ enum retry_type doretry;
+ char retryname[1024];
+ /* Get a port to the ifsock translator. */
+ err = __dir_lookup (node, "", 0, 0, &doretry, retryname, &ifsock);
+ if (! err && (doretry != FS_RETRY_NORMAL || retryname[0] != '\0'))
+ err = EADDRINUSE;
+ }
+ if (! err)
+ {
+ /* Get the address port. */
+ err = __ifsock_getsockaddr (ifsock, &aport);
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ err = EGRATUITOUS;
+ if (! err)
+ {
+ /* Link the node, now a socket with proper mode, into the
+ target directory. */
+ err = __dir_link (dir, node, n, 1);
+ if (err == EEXIST)
+ err = EADDRINUSE;
+ if (err)
+ __mach_port_deallocate (__mach_task_self (), aport);
+ }
+ __mach_port_deallocate (__mach_task_self (), ifsock);
+ }
+ __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->sun_family,
+ (char *) addr, len,
+ &aport);
+ if (! err)
+ {
+ err = __socket_bind (port, aport);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+
+weak_alias (__bind, bind)
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/errno.h b/REORG.TODO/sysdeps/mach/hurd/bits/errno.h
new file mode 100644
index 0000000000..d20ffe654a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/errno.h
@@ -0,0 +1,329 @@
+/* This file generated by errnos.awk. */
+
+/* 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
+{
+ /* The value zero always means success and it is perfectly fine for
+ code to use 0 explicitly (or implicitly, e.g. via Boolean coercion).
+ Having an enum entry for zero both makes the debugger print the name
+ for error_t-typed zero values, and prevents the compiler from
+ issuing warnings about 'case 0:' in a switch on an error_t-typed
+ value. */
+ ESUCCESS = 0,
+
+#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) /* No such device or address */
+ 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 or resource 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)/* No such 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 (24),
+#define EMFILE _HURD_ERRNO (24)/* Too many open files */
+ ENFILE = _HURD_ERRNO (23),
+#define ENFILE _HURD_ERRNO (23)/* 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 */
+ 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 */
+ EADDRINUSE = _HURD_ERRNO (48),
+#define EADDRINUSE _HURD_ERRNO (48)/* Address already in use */
+ EADDRNOTAVAIL = _HURD_ERRNO (49),
+#define EADDRNOTAVAIL _HURD_ERRNO (49)/* Cannot 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)/* Transport endpoint is already connected */
+ ENOTCONN = _HURD_ERRNO (57),
+#define ENOTCONN _HURD_ERRNO (57)/* Transport endpoint is not connected */
+ EDESTADDRREQ = _HURD_ERRNO (39),
+#define EDESTADDRREQ _HURD_ERRNO (39)/* Destination address required */
+ ESHUTDOWN = _HURD_ERRNO (58),
+#define ESHUTDOWN _HURD_ERRNO (58)/* Cannot send after transport endpoint shutdown */
+ ETOOMANYREFS = _HURD_ERRNO (59),
+#define ETOOMANYREFS _HURD_ERRNO (59)/* Too many references: cannot splice */
+ ETIMEDOUT = _HURD_ERRNO (60),
+#define ETIMEDOUT _HURD_ERRNO (60)/* Connection timed out */
+ ECONNREFUSED = _HURD_ERRNO (61),
+#define ECONNREFUSED _HURD_ERRNO (61)/* Connection refused */
+ ELOOP = _HURD_ERRNO (62),
+#define ELOOP _HURD_ERRNO (62)/* Too many levels of symbolic links */
+ ENAMETOOLONG = _HURD_ERRNO (63),
+#define ENAMETOOLONG _HURD_ERRNO (63)/* File name too long */
+ EHOSTDOWN = _HURD_ERRNO (64),
+#define EHOSTDOWN _HURD_ERRNO (64)/* Host is down */
+ EHOSTUNREACH = _HURD_ERRNO (65),
+#define EHOSTUNREACH _HURD_ERRNO (65)/* No route to host */
+ ENOTEMPTY = _HURD_ERRNO (66),
+#define ENOTEMPTY _HURD_ERRNO (66)/* Directory not empty */
+ EPROCLIM = _HURD_ERRNO (67),
+#define EPROCLIM _HURD_ERRNO (67)/* Too many processes */
+ EUSERS = _HURD_ERRNO (68),
+#define EUSERS _HURD_ERRNO (68)/* Too many users */
+ EDQUOT = _HURD_ERRNO (69),
+#define EDQUOT _HURD_ERRNO (69)/* Disk quota exceeded */
+ ESTALE = _HURD_ERRNO (70),
+#define ESTALE _HURD_ERRNO (70)/* Stale file handle */
+ EREMOTE = _HURD_ERRNO (71),
+#define EREMOTE _HURD_ERRNO (71)/* Object is remote */
+ EBADRPC = _HURD_ERRNO (72),
+#define EBADRPC _HURD_ERRNO (72)/* RPC struct is bad */
+ ERPCMISMATCH = _HURD_ERRNO (73),
+#define ERPCMISMATCH _HURD_ERRNO (73)/* RPC version wrong */
+ EPROGUNAVAIL = _HURD_ERRNO (74),
+#define EPROGUNAVAIL _HURD_ERRNO (74)/* RPC program not available */
+ EPROGMISMATCH = _HURD_ERRNO (75),
+#define EPROGMISMATCH _HURD_ERRNO (75)/* RPC program version wrong */
+ EPROCUNAVAIL = _HURD_ERRNO (76),
+#define EPROCUNAVAIL _HURD_ERRNO (76)/* RPC bad procedure for program */
+ ENOLCK = _HURD_ERRNO (77),
+#define ENOLCK _HURD_ERRNO (77)/* No locks available */
+ EFTYPE = _HURD_ERRNO (79),
+#define EFTYPE _HURD_ERRNO (79)/* Inappropriate file type or format */
+ EAUTH = _HURD_ERRNO (80),
+#define EAUTH _HURD_ERRNO (80)/* Authentication error */
+ ENEEDAUTH = _HURD_ERRNO (81),
+#define ENEEDAUTH _HURD_ERRNO (81)/* Need authenticator */
+ ENOSYS = _HURD_ERRNO (78),
+#define ENOSYS _HURD_ERRNO (78)/* Function not implemented */
+ ENOTSUP = _HURD_ERRNO (118),
+#define ENOTSUP _HURD_ERRNO (118)/* Not supported */
+ EILSEQ = _HURD_ERRNO (106),
+#define EILSEQ _HURD_ERRNO (106)/* Invalid or incomplete multibyte or wide character */
+ EBACKGROUND = _HURD_ERRNO (100),
+#define EBACKGROUND _HURD_ERRNO (100)/* Inappropriate operation for background process */
+ EDIED = _HURD_ERRNO (101),
+#define EDIED _HURD_ERRNO (101)/* Translator died */
+ ED = _HURD_ERRNO (102),
+#define ED _HURD_ERRNO (102)/* ? */
+ EGREGIOUS = _HURD_ERRNO (103),
+#define EGREGIOUS _HURD_ERRNO (103)/* You really blew it this time */
+ EIEIO = _HURD_ERRNO (104),
+#define EIEIO _HURD_ERRNO (104)/* Computer bought the farm */
+ EGRATUITOUS = _HURD_ERRNO (105),
+#define EGRATUITOUS _HURD_ERRNO (105)/* Gratuitous error */
+ EBADMSG = _HURD_ERRNO (107),
+#define EBADMSG _HURD_ERRNO (107)/* Bad message */
+ EIDRM = _HURD_ERRNO (108),
+#define EIDRM _HURD_ERRNO (108)/* Identifier removed */
+ EMULTIHOP = _HURD_ERRNO (109),
+#define EMULTIHOP _HURD_ERRNO (109)/* Multihop attempted */
+ ENODATA = _HURD_ERRNO (110),
+#define ENODATA _HURD_ERRNO (110)/* No data available */
+ ENOLINK = _HURD_ERRNO (111),
+#define ENOLINK _HURD_ERRNO (111)/* Link has been severed */
+ ENOMSG = _HURD_ERRNO (112),
+#define ENOMSG _HURD_ERRNO (112)/* No message of desired type */
+ ENOSR = _HURD_ERRNO (113),
+#define ENOSR _HURD_ERRNO (113)/* Out of streams resources */
+ ENOSTR = _HURD_ERRNO (114),
+#define ENOSTR _HURD_ERRNO (114)/* Device not a stream */
+ EOVERFLOW = _HURD_ERRNO (115),
+#define EOVERFLOW _HURD_ERRNO (115)/* Value too large for defined data type */
+ EPROTO = _HURD_ERRNO (116),
+#define EPROTO _HURD_ERRNO (116)/* Protocol error */
+ ETIME = _HURD_ERRNO (117),
+#define ETIME _HURD_ERRNO (117)/* Timer expired */
+ ECANCELED = _HURD_ERRNO (119),
+#define ECANCELED _HURD_ERRNO (119)/* Operation canceled */
+
+ /* 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,
+ EKERN_WRITE_PROTECTION_FAILURE = 24,
+ EKERN_TERMINATED = 26,
+
+ /* 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 120
+
+/* 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;
+#define __error_t_defined 1
+#endif
+
+/* Return the current thread's location for `errno'.
+ The syntax of this function allows redeclarations like `int errno'. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+#define errno (*__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/REORG.TODO/sysdeps/mach/hurd/bits/fcntl.h b/REORG.TODO/sysdeps/mach/hurd/bits/fcntl.h
new file mode 100644
index 0000000000..915c7c6abb
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/fcntl.h
@@ -0,0 +1,221 @@
+/* O_*, F_*, FD_* bit values for GNU.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#include <sys/types.h>
+
+/* 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. */
+# define O_NORW 0 /* Open without R/W access. */
+#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. */
+
+#define O_LARGEFILE 0
+
+
+/* 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
+
+#ifdef __USE_XOPEN2K8
+# define O_NOFOLLOW 0x00100000 /* Produce ENOENT if file is a symlink. */
+# define O_DIRECTORY 0x00200000 /* Produce ENOTDIR if not a directory. */
+#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. */
+#define O_ASYNC 0x0200 /* Send SIGIO to owner when data is ready. */
+#define O_FSYNC 0x0400 /* Synchronous writes. */
+#define O_SYNC O_FSYNC
+#ifdef __USE_GNU
+# define O_NOATIME 0x0800 /* Don't set access time on read (owner). */
+#endif
+#ifdef __USE_MISC
+# define O_SHLOCK 0x00020000 /* Open with shared file lock. */
+# define O_EXLOCK 0x00040000 /* Open with exclusive file lock. */
+#endif
+
+/* These are lesser flavors of partial synchronization that are
+ implied by our one flag (O_FSYNC). */
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+# define O_DSYNC O_SYNC /* Synchronize data. */
+# define O_RSYNC O_SYNC /* Synchronize read operations. */
+#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_MISC
+# define O_NDELAY O_NONBLOCK /* Deprecated. */
+#endif
+
+
+#ifdef __USE_GNU
+/* Mask of bits which are understood by io servers. */
+# define O_HURD (0xffff | O_EXLOCK | O_SHLOCK)
+#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_XOPEN2K8
+# define O_CLOEXEC 0x00400000 /* Set FD_CLOEXEC. */
+#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_MISC
+/* 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. */
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+# 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_XOPEN2K8
+# define F_DUPFD_CLOEXEC 1030 /* Duplicate, set FD_CLOEXEC on new one. */
+#endif
+
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+
+#include <bits/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'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the 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. */
+
+/* Advise to `posix_fadvise'. */
+#ifdef __USE_XOPEN2K
+# define POSIX_FADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_FADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
+# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/ioctls.h b/REORG.TODO/sysdeps/mach/hurd/bits/ioctls.h
new file mode 100644
index 0000000000..d78cfd9be8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/ioctls.h
@@ -0,0 +1,432 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __BITS_IOCTLS_H
+#define __BITS_IOCTLS_H 1
+
+#if !defined _HURD_IOCTL_H && !defined _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <hurd/ioctl.h> instead."
+#endif
+
+/* These macros are also defined in <bits/termios.h> (with numerically
+ identical values) but this serves to shut up cpp's complaining. */
+
+#ifdef NL0
+# undef NL0
+#endif
+#ifdef NL1
+# undef NL1
+#endif
+#ifdef TAB0
+# undef TAB0
+#endif
+#ifdef TAB1
+# undef TAB1
+#endif
+#ifdef TAB2
+# undef TAB2
+#endif
+#ifdef CR0
+# undef CR0
+#endif
+#ifdef CR1
+# undef CR1
+#endif
+#ifdef CR2
+# undef CR2
+#endif
+#ifdef CR3
+# undef CR3
+#endif
+#ifdef FF0
+# undef FF0
+#endif
+#ifdef FF1
+# undef FF1
+#endif
+#ifdef BS0
+# undef BS0
+#endif
+#ifdef BS1
+# undef BS1
+#endif
+#ifdef MDMBUF
+# undef MDMBUF
+#endif
+#ifdef ECHO
+# undef ECHO
+#endif
+#ifdef TOSTOP
+# undef TOSTOP
+#endif
+#ifdef FLUSHO
+# undef FLUSHO
+#endif
+#ifdef PENDIN
+# undef PENDIN
+#endif
+#ifdef NOFLSH
+# undef NOFLSH
+#endif
+
+/* Hurd ioctl request are made up of several fields:
+
+ 10987654321098765432109876543210
+ IOt0t1t2cc0c0cc1c1cc2ggggccccccc
+
+ bits [31,30]: inout direction (enum __ioctl_dir)
+ bits [29,11]: 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)
+ [24,25]: datum #2 type (enum __ioctl_datum)
+ [23,19]: datum #0 count [0,31]
+ [18,14]: datum #1 count [0,31]
+ [13,11]: datum #2 count [0,3]
+ bits [07,10]: group (letter - 'f': ['f','v'])
+ bits [00,06]: 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, IOC_64 };
+
+/* 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) & 0xf))
+#define _IOC_COMMAND(request) ((unsigned int) (request) & 0x7f)
+#define _IOC_TYPE(request) (((unsigned int) (request) >> 11) & 0x7ffff)
+#define _IOC_NOTYPE(request) ((unsigned int) (request) & 0x3ff)
+
+/* 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) & 7)
+
+/* 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)))
+
+/* Construct an individual type field for TYPE. */
+#define _IOTS(type) \
+ (sizeof (type) == 8 ? IOC_64 : (enum __ioctl_datum) (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__IOTBASE_char _IOT_SIMPLE (char)
+#define _IOT__IOTBASE_short _IOT_SIMPLE (short)
+#define _IOT__IOTBASE_int _IOT_SIMPLE (int)
+#define _IOT__IOTBASE_long _IOT_SIMPLE (long)
+#define _IOT_char _IOT_SIMPLE (char)
+#define _IOT_short _IOT_SIMPLE (short)
+#define _IOT_int _IOT_SIMPLE (int)
+#define _IOT_long _IOT_SIMPLE (long)
+
+#define _IOT__IOTBASE_int8_t _IOT_SIMPLE (int8_t)
+#define _IOT__IOTBASE_uint8_t _IOT_SIMPLE (uint8_t)
+#define _IOT__IOTBASE_int16_t _IOT_SIMPLE (int16_t)
+#define _IOT__IOTBASE_uint16_t _IOT_SIMPLE (uint16_t)
+#define _IOT__IOTBASE_int32_t _IOT_SIMPLE (int32_t)
+#define _IOT__IOTBASE_uint32_t _IOT_SIMPLE (uint32_t)
+#define _IOT__IOTBASE_int64_t _IOT_SIMPLE (int64_t)
+#define _IOT__IOTBASE_uint64_t _IOT_SIMPLE (uint64_t)
+
+#define _IOT__IOTBASE_size_t _IOT_SIMPLE (size_t)
+#define _IOT__IOTBASE_ssize_t _IOT_SIMPLE (ssize_t)
+
+
+/* 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 _IOIW(g, n, t) _IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t))
+#define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t))
+#define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t))
+#define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t))
+
+/* These macros do some preprocessor gymnastics to turn a TYPESPEC of
+ `struct foobar' into the identifier `_IOT_foobar', which is generally
+ defined using `_IOT' (above) in whatever file defines `struct foobar'.
+ For a TYPESPEC that does not begin with `struct' produces a different
+ identifier: `int' produces `_IOT__IOTBASE_int'. These identifiers
+ are defined for the basic C types above. */
+#define _IOC_ENCODE_TYPE(typespec) _IOC_ENCODE_TYPE_1(_IOTBASE_##typespec)
+#define _IOTBASE_struct
+#define _IOC_ENCODE_TYPE_1(typespec) _IOC_ENCODE_TYPE_2(typespec)
+#define _IOC_ENCODE_TYPE_2(typespec) _IOT_##typespec
+
+/* Also, ignore signedness. */
+#define _IOTBASE_unsigned
+#define _IOTBASE_signed
+
+
+/* ioctls verbatim from 4.4 <sys/ioctl.h>. */
+
+#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 SIOCGIFHWADDR _IOWR('i',39, struct ifreq) /* get hwaddress */
+#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_short)/* set ifnet flags */
+#define SIOCGIFFLAGS _IOWR('i',17, struct ifreq_short)/* 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_int) /* get IF metric */
+#define SIOCSIFMETRIC _IOW('i',24, struct ifreq_int) /* 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 */
+
+#define SIOCGIFMTU _IOWR('i', 51, struct ifreq_int)/* get IF mtu */
+#define SIOCSIFMTU _IOW('i', 52, struct ifreq_int) /* set IF mtu */
+
+#define SIOCGIFINDEX _IOWR('i', 90, struct ifreq_int)/* get IF index */
+#define SIOCGIFNAME _IOWR('i', 91, struct ifreq_int)/* set IF name */
+
+
+/* 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 /* bits/ioctls.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/local_lim.h b/REORG.TODO/sysdeps/mach/hurd/bits/local_lim.h
new file mode 100644
index 0000000000..dd13074c9b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/local_lim.h
@@ -0,0 +1,34 @@
+/* Minimum guaranteed maximum values for system limits. Hurd version.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* GNU has no arbitrary fixed limits on most of 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'. */
+
+/* This one value is actually constrained by the `struct dirent'
+ layout, in which the `d_namlen' member is only 8 bits wide. */
+
+#define NAME_MAX 255
+
+/* 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
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/param.h b/REORG.TODO/sysdeps/mach/hurd/bits/param.h
new file mode 100644
index 0000000000..6ebd7eeaa5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/param.h
@@ -0,0 +1,85 @@
+/* Old-style Unix parameters and limits. Hurd version.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_PARAM_H
+# error "Never use <bits/param.h> directly; include <sys/param.h> instead."
+#endif
+
+/* 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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
+ */
+
+
+/* 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. */
+
+
+/* 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
+
+
+/* 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)
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/posix_opt.h b/REORG.TODO/sysdeps/mach/hurd/bits/posix_opt.h
new file mode 100644
index 0000000000..18734c86bc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/posix_opt.h
@@ -0,0 +1,182 @@
+/* Define POSIX options for GNU/Hurd.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _UNISTD_H
+#error "Never include this file directly; use <unistd.h> instead."
+#endif
+
+#ifndef _BITS_POSIX_OPT_H
+#define _BITS_POSIX_OPT_H 1
+
+
+/* Job control is supported. */
+#define _POSIX_JOB_CONTROL 1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID. */
+#define _POSIX_SAVED_IDS 1
+
+/* Priority scheduling is not supported. */
+#undef _POSIX_PRIORITY_SCHEDULING
+
+/* Synchronizing file data is supported, but msync is missing. */
+#undef _POSIX_SYNCHRONIZED_IO
+
+/* The fsync function is present. */
+#define _POSIX_FSYNC 200809L
+
+/* Mapping of files to memory is supported. */
+#define _POSIX_MAPPED_FILES 200809L
+
+/* Locking of all memory could be supported in future. */
+#define _POSIX_MEMLOCK 0
+
+/* Locking of ranges of memory is supported. */
+#define _POSIX_MEMLOCK_RANGE 200809L
+
+/* Setting of memory protections is supported. */
+#define _POSIX_MEMORY_PROTECTION 200809L
+
+/* Elements of the `c_cc' member of `struct termios' structure
+ can be disabled by using the value _POSIX_VDISABLE. */
+#define _POSIX_VDISABLE ((unsigned char) -1)
+
+
+/* Different Hurd filesystems might do these differently.
+ You must query the particular file with `pathconf' or `fpathconf'. */
+#undef _POSIX_CHOWN_RESTRICTED /* Only root can change owner of file? */
+#undef _POSIX_NO_TRUNC /* Overlong file names get error? */
+#undef _POSIX_SYNC_IO /* File supports O_SYNC et al? */
+
+/* X/Open realtime support is not supported. */
+#undef _XOPEN_REALTIME
+
+/* X/Open thread realtime support is not supported. */
+#undef _XOPEN_REALTIME_THREADS
+
+/* XPG4.2 shared memory is not supported. */
+#undef _XOPEN_SHM
+
+/* We do not have the POSIX threads interface. */
+#define _POSIX_THREADS -1
+
+/* We have the reentrant functions described in POSIX. */
+#define _POSIX_REENTRANT_FUNCTIONS 1
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
+
+/* These are all things that won't be supported when _POSIX_THREADS is not. */
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+#define _POSIX_THREAD_ATTR_STACKSIZE -1
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+#define _POSIX_THREAD_PRIO_INHERIT -1
+#define _POSIX_THREAD_PRIO_PROTECT -1
+#ifdef __USE_XOPEN2K8
+# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1
+# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1
+#endif
+#define _POSIX_SEMAPHORES -1
+
+/* Real-time signals are not yet supported. */
+#define _POSIX_REALTIME_SIGNALS -1
+
+/* Asynchronous I/O might supported with the existing ABI. */
+#define _POSIX_ASYNCHRONOUS_IO 0
+#undef _POSIX_ASYNC_IO
+/* Alternative name for Unix98. */
+#define _LFS_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO
+/* Support for prioritization is not available. */
+#undef _POSIX_PRIORITIZED_IO
+
+/* The LFS support in asynchronous I/O is also available. */
+#define _LFS64_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO
+
+/* The rest of the LFS is also available. */
+#define _LFS_LARGEFILE 1
+#define _LFS64_LARGEFILE 1
+#define _LFS64_STDIO 1
+
+/* POSIX.4 shared memory objects are supported (using regular files). */
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_MAPPED_FILES
+
+/* CPU-time clocks support needs to be checked at runtime. */
+#define _POSIX_CPUTIME 0
+
+/* Clock support in threads must be also checked at runtime. */
+#define _POSIX_THREAD_CPUTIME 0
+
+/* GNU libc provides regular expression handling. */
+#define _POSIX_REGEXP 1
+
+/* Reader/Writer locks are not available. */
+#define _POSIX_READER_WRITER_LOCKS -1
+
+/* We have a POSIX shell. */
+#define _POSIX_SHELL 1
+
+/* We cannot support the Timeouts option without _POSIX_THREADS. */
+#define _POSIX_TIMEOUTS -1
+
+/* We do not support spinlocks. */
+#define _POSIX_SPIN_LOCKS -1
+
+/* The `spawn' function family is supported. */
+#define _POSIX_SPAWN 200809L
+
+/* We do not have POSIX timers, but could in future without ABI change. */
+#define _POSIX_TIMERS 0
+
+/* The barrier functions are not available. */
+#define _POSIX_BARRIERS -1
+
+/* POSIX message queues could be available in future. */
+#define _POSIX_MESSAGE_PASSING 0
+
+/* Thread process-shared synchronization is not supported. */
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+/* The monotonic clock might be available. */
+#define _POSIX_MONOTONIC_CLOCK 0
+
+/* The clock selection interfaces are available. */
+#define _POSIX_CLOCK_SELECTION 200809L
+
+/* Advisory information interfaces could be available in future. */
+#define _POSIX_ADVISORY_INFO 0
+
+/* IPv6 support is available. */
+#define _POSIX_IPV6 200809L
+
+/* Raw socket support is available. */
+#define _POSIX_RAW_SOCKETS 200809L
+
+/* We have at least one terminal. */
+#define _POSIX2_CHAR_TERM 200809L
+
+/* Neither process nor thread sporadic server interfaces is available. */
+#define _POSIX_SPORADIC_SERVER -1
+#define _POSIX_THREAD_SPORADIC_SERVER -1
+
+/* trace.h is not available. */
+#define _POSIX_TRACE -1
+#define _POSIX_TRACE_EVENT_FILTER -1
+#define _POSIX_TRACE_INHERIT -1
+#define _POSIX_TRACE_LOG -1
+
+/* Typed memory objects are not available. */
+#define _POSIX_TYPED_MEMORY_OBJECTS -1
+
+#endif /* bits/posix_opt.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/socket.h b/REORG.TODO/sysdeps/mach/hurd/bits/socket.h
new file mode 100644
index 0000000000..6eb09a0ab3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/socket.h
@@ -0,0 +1,362 @@
+/* System-specific socket constants and types. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H 1
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
+#endif
+
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+#include <limits.h> /* XXX Is this allowed? */
+#include <bits/types.h>
+
+/* Type for length arguments in socket calls. */
+#ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+# define __socklen_t_defined
+#endif
+
+
+/* Types of sockets. */
+enum __socket_type
+{
+ SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
+ byte streams. */
+#define SOCK_STREAM SOCK_STREAM
+ SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams
+ of fixed maximum length. */
+#define SOCK_DGRAM SOCK_DGRAM
+ SOCK_RAW = 3, /* Raw protocol interface. */
+#define SOCK_RAW SOCK_RAW
+ SOCK_RDM = 4, /* Reliably-delivered messages. */
+#define SOCK_RDM SOCK_RDM
+ SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
+ datagrams of fixed maximum length. */
+#define SOCK_SEQPACKET SOCK_SEQPACKET
+
+#define SOCK_MAX (SOCK_SEQPACKET + 1)
+ /* Mask which covers at least up to SOCK_MASK-1. The
+ remaining bits are used as flags. */
+#define SOCK_TYPE_MASK 0xf
+
+ /* Flags to be ORed into the type parameter of socket and socketpair and
+ used for the flags parameter of accept4. */
+
+ SOCK_CLOEXEC = 0x00400000, /* Atomically set close-on-exec flag for the
+ new descriptor(s). */
+#define SOCK_CLOEXEC SOCK_CLOEXEC
+
+ /* Changed from the O_NONBLOCK value (0x8, which is unusable for us as it is
+ conflicting with the original SOCK_* flags' values) to the Linux value
+ (04000). TODO: is there a ``better'' value? */
+ SOCK_NONBLOCK = 0x0800 /* Atomically mark descriptor(s) as
+ non-blocking. */
+#define SOCK_NONBLOCK SOCK_NONBLOCK
+};
+
+/* 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_FILE PF_LOCAL /* POSIX 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_INET6 26 /* IP version 6. */
+#define PF_MAX 27
+
+/* Address families. */
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX PF_UNIX
+#define AF_FILE PF_FILE
+#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_INET6 PF_INET6
+#define AF_MAX PF_MAX
+
+/* Maximum queue length specifiable by listen. */
+#define SOMAXCONN 128 /* 5 on the origional 4.4 BSD. */
+
+/* Get the definition of the macro to define the common sockaddr members. */
+#include <bits/sockaddr.h>
+
+/* Structure describing a generic socket address. */
+struct sockaddr
+ {
+ __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
+ char sa_data[14]; /* Address data. */
+ };
+
+
+/* Structure large enough to hold any socket address (with the historical
+ exception of AF_UNIX). */
+#if ULONG_MAX > 0xffffffff
+# define __ss_aligntype __uint64_t
+#else
+# define __ss_aligntype __uint32_t
+#endif
+#define _SS_PADSIZE \
+ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
+
+struct sockaddr_storage
+ {
+ __SOCKADDR_COMMON (ss_); /* Address family, etc. */
+ char __ss_padding[_SS_PADSIZE];
+ __ss_aligntype __ss_align; /* Force desired alignment. */
+ };
+
+
+/* Bits in the FLAGS argument to `send', `recv', et al. */
+enum
+ {
+ MSG_OOB = 0x01, /* Process out-of-band data. */
+#define MSG_OOB MSG_OOB
+ MSG_PEEK = 0x02, /* Peek at incoming messages. */
+#define MSG_PEEK MSG_PEEK
+ MSG_DONTROUTE = 0x04, /* Don't use local routing. */
+#define MSG_DONTROUTE MSG_DONTROUTE
+ MSG_EOR = 0x08, /* Data completes record. */
+#define MSG_EOR MSG_EOR
+ MSG_TRUNC = 0x10, /* Data discarded before delivery. */
+#define MSG_TRUNC MSG_TRUNC
+ MSG_CTRUNC = 0x20, /* Control data lost before delivery. */
+#define MSG_CTRUNC MSG_CTRUNC
+ MSG_WAITALL = 0x40, /* Wait for full request or error. */
+#define MSG_WAITALL MSG_WAITALL
+ MSG_DONTWAIT = 0x80, /* This message should be nonblocking. */
+#define MSG_DONTWAIT MSG_DONTWAIT
+ MSG_NOSIGNAL = 0x0400 /* Do not generate SIGPIPE on EPIPE. */
+#define MSG_NOSIGNAL MSG_NOSIGNAL
+ };
+
+
+/* Structure describing messages sent by
+ `sendmsg' and received by `recvmsg'. */
+struct msghdr
+ {
+ void *msg_name; /* Address to send to/receive from. */
+ socklen_t msg_namelen; /* Length of address data. */
+
+ struct iovec *msg_iov; /* Vector of data to send/receive into. */
+ int msg_iovlen; /* Number of elements in the vector. */
+
+ void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
+ socklen_t msg_controllen; /* Ancillary data buffer length. */
+
+ int msg_flags; /* Flags in received message. */
+ };
+
+/* Structure used for storage of ancillary data object information. */
+struct cmsghdr
+ {
+ socklen_t cmsg_len; /* Length of data in cmsg_data plus length
+ of cmsghdr structure. */
+ int cmsg_level; /* Originating protocol. */
+ int cmsg_type; /* Protocol specific type. */
+#if __glibc_c99_flexarr_available
+ __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */
+#endif
+ };
+
+/* Ancillary data object manipulation macros. */
+#if __glibc_c99_flexarr_available
+# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
+#else
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+#endif
+
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
+
+#define CMSG_FIRSTHDR(mhdr) \
+ ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
+ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
+
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
+ & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
+ + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
+ struct cmsghdr *__cmsg) __THROW;
+#ifdef __USE_EXTERN_INLINES
+# ifndef _EXTERN_INLINE
+# define _EXTERN_INLINE __extern_inline
+# endif
+_EXTERN_INLINE struct cmsghdr *
+__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
+{
+ if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
+ /* The kernel header does this so there may be a reason. */
+ return NULL;
+
+ __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ + CMSG_ALIGN (__cmsg->cmsg_len));
+ if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+ + __mhdr->msg_controllen)
+ || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
+ > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
+ /* No more entries. */
+ return NULL;
+ return __cmsg;
+}
+#endif /* Use `extern inline'. */
+
+/* Socket level message types. */
+enum
+ {
+ SCM_RIGHTS = 0x01, /* Access rights (array of int). */
+#define SCM_RIGHTS SCM_RIGHTS
+ SCM_TIMESTAMP = 0x02, /* Timestamp (struct timeval). */
+#define SCM_TIMESTAMP SCM_TIMESTAMP
+ SCM_CREDS = 0x03 /* Process creds (struct cmsgcred). */
+#define SCM_CREDS SCM_CREDS
+ };
+
+/* Unfortunately, BSD practice dictates this structure be of fixed size.
+ If there are more than CMGROUP_MAX groups, the list is truncated.
+ (On GNU systems, the `cmcred_euid' field is just the first in the
+ list of effective UIDs.) */
+#define CMGROUP_MAX 16
+
+/* Structure delivered by SCM_CREDS. This describes the identity of the
+ sender of the data simultaneously received on the socket. By BSD
+ convention, this is included only when a sender on a AF_LOCAL socket
+ sends cmsg data of this type and size; the sender's structure is
+ ignored, and the system fills in the various IDs of the sender process. */
+struct cmsgcred
+ {
+ __pid_t cmcred_pid;
+ __uid_t cmcred_uid;
+ __uid_t cmcred_euid;
+ __gid_t cmcred_gid;
+ int cmcred_ngroups;
+ __gid_t cmcred_groups[CMGROUP_MAX];
+ };
+
+/* 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. */
+#define SO_DEBUG SO_DEBUG
+ SO_ACCEPTCONN = 0x0002, /* Accept connections on socket. */
+#define SO_ACCEPTCONN SO_ACCEPTCONN
+ SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */
+#define SO_REUSEADDR SO_REUSEADDR
+ SO_KEEPALIVE = 0x0008, /* Keep connections alive and send
+ SIGPIPE when they die. */
+#define SO_KEEPALIVE SO_KEEPALIVE
+ SO_DONTROUTE = 0x0010, /* Don't do local routing. */
+#define SO_DONTROUTE SO_DONTROUTE
+ SO_BROADCAST = 0x0020, /* Allow transmission of
+ broadcast messages. */
+#define SO_BROADCAST SO_BROADCAST
+ SO_USELOOPBACK = 0x0040, /* Use the software loopback to avoid
+ hardware use when possible. */
+#define SO_USELOOPBACK SO_USELOOPBACK
+ SO_LINGER = 0x0080, /* Block on close of a reliable
+ socket to transmit pending data. */
+#define SO_LINGER SO_LINGER
+ SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */
+#define SO_OOBINLINE SO_OOBINLINE
+ SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */
+#define SO_REUSEPORT SO_REUSEPORT
+ SO_SNDBUF = 0x1001, /* Send buffer size. */
+#define SO_SNDBUF SO_SNDBUF
+ SO_RCVBUF = 0x1002, /* Receive buffer. */
+#define SO_RCVBUF SO_RCVBUF
+ SO_SNDLOWAT = 0x1003, /* Send low-water mark. */
+#define SO_SNDLOWAT SO_SNDLOWAT
+ SO_RCVLOWAT = 0x1004, /* Receive low-water mark. */
+#define SO_RCVLOWAT SO_RCVLOWAT
+ SO_SNDTIMEO = 0x1005, /* Send timeout. */
+#define SO_SNDTIMEO SO_SNDTIMEO
+ SO_RCVTIMEO = 0x1006, /* Receive timeout. */
+#define SO_RCVTIMEO SO_RCVTIMEO
+ SO_ERROR = 0x1007, /* Get and clear error status. */
+#define SO_ERROR SO_ERROR
+ SO_STYLE = 0x1008, /* Get socket connection style. */
+#define SO_STYLE SO_STYLE
+ SO_TYPE = SO_STYLE /* Compatible name for SO_STYLE. */
+#define SO_TYPE SO_TYPE
+ };
+
+/* Structure used to manipulate the SO_LINGER option. */
+struct linger
+ {
+ int l_onoff; /* Nonzero to linger on close. */
+ int l_linger; /* Time to linger. */
+ };
+
+#endif /* bits/socket.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/stat.h b/REORG.TODO/sysdeps/mach/hurd/bits/stat.h
new file mode 100644
index 0000000000..b614cc5b28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/stat.h
@@ -0,0 +1,258 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STAT_H
+#define _BITS_STAT_H 1
+
+#include <bits/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
+
+#ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File number. */
+#else
+ __ino64_t st_ino; /* File number. */
+#endif
+ 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. */
+
+#ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size in bytes. */
+#else
+ __off64_t st_size; /* Size in bytes. */
+#endif
+
+#ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+
+ __blksize_t st_blksize; /* Optimal size for I/O. */
+
+#ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number of 512-byte blocks allocated.
+ Not related to `st_blksize'. */
+#else
+ __blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated.
+ Not related to `st_blksize'. */
+#endif
+
+ __uid_t st_author; /* File author. */
+
+ unsigned int st_flags; /* User-defined flags.
+ High 16 bits can be set only by root. */
+
+#ifndef __USE_FILE_OFFSET64
+# define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 12 : 11)
+#else
+# define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 9 : 8)
+#endif
+ int st_spare[_SPARE_SIZE]; /* Room for future expansion. */
+#undef _SPARE_SIZE
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+ int st_fstype; /* File system type. */
+ __fsid_t st_fsid; /* File system ID. */
+# define st_dev st_fsid
+
+ __ino64_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. */
+
+ __off64_t st_size; /* Size in bytes. */
+
+#ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+#else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+#endif
+
+ __blksize_t st_blksize; /* Optimal size for I/O. */
+
+ __blkcnt64_t 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. */
+
+#define _SPARE_SIZE ((sizeof (__fsid_t) == sizeof (int)) ? 9 : 8)
+ int st_spare[_SPARE_SIZE]; /* Room for future expansion. */
+#undef _SPARE_SIZE
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+/* 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. */
+
+/* POSIX.1b objects. */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* 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
+
+/* Read only bits: */
+
+/* There is a passive translator set for this file */
+#define S_IPTRANS 000010000000
+/* There is an active translator running on this file */
+#define S_IATRANS 000020000000
+/* This is the root of a filesystem (or single node translator) */
+#define S_IROOT 000040000000
+/* All the bits relevant to translators */
+#define S_ITRANS 000070000000
+
+/* Definitely no mmaps to this. */
+#define S_IMMAP0 000100000000
+
+/* ALL the unused bits. */
+#define S_ISPARE (~(S_IFMT|S_ITRANS|S_INOCACHE|S_IMMAP0| \
+ S_IUSEUNK|S_IUNKNOWN|07777))
+#endif
+
+#ifdef __USE_MISC
+/* Default file creation mask (umask). */
+# define CMASK 0022
+
+/* Definitions of flags stored in file flags word. */
+
+/* Super-user and owner changeable flags. */
+# define UF_SETTABLE 0x0000ffff /* mask of owner changeable flags */
+# define UF_NODUMP 0x00000001 /* do not dump file */
+# define UF_IMMUTABLE 0x00000002 /* file may not be changed */
+# define UF_APPEND 0x00000004 /* writes to file may only append */
+# define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */
+# define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */
+
+/* Super-user changeable flags. */
+# define SF_SETTABLE 0xffff0000 /* mask of superuser changeable flags */
+# define SF_ARCHIVED 0x00010000 /* file is archived */
+# define SF_IMMUTABLE 0x00020000 /* file may not be changed */
+# define SF_APPEND 0x00040000 /* writes to file may only append */
+# define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */
+# define SF_SNAPSHOT 0x00200000 /* snapshot inode */
+
+__BEGIN_DECLS
+
+/* Set file flags for FILE to FLAGS. */
+extern int chflags (__const char *__file, unsigned long int __flags) __THROW;
+
+/* Set file flags of the file referred to by FD to FLAGS. */
+extern int fchflags (int __fd, unsigned long int __flags) __THROW;
+
+__END_DECLS
+#endif
+
+#endif /* bits/stat.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/statfs.h b/REORG.TODO/sysdeps/mach/hurd/bits/statfs.h
new file mode 100644
index 0000000000..4613f0f34a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/statfs.h
@@ -0,0 +1,86 @@
+/* Definition of `struct statfs', information about a filesystem.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* GNU Hurd NOTE: The size of this structure (16 ints) is known in
+ <hurd/hurd_types.defs>, since it is used in the `file_statfs' 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.
+
+ Note also that `struct statvfs' in <bits/statvfs.h> is laid out
+ identically to `struct statfs', so they can be used interchangeably.
+ Any changes made here must also be made in that file. */
+
+struct statfs
+ {
+ unsigned int f_type;
+ unsigned int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsblkcnt_t f_files;
+ __fsblkcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsblkcnt64_t f_files;
+ __fsblkcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ unsigned int f_namelen;
+#ifndef __USE_FILE_OFFSET64
+ __fsfilcnt_t f_favail;
+#else
+ __fsfilcnt64_t f_favail;
+#endif
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+ {
+ unsigned int f_type;
+ unsigned int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsblkcnt64_t f_files;
+ __fsblkcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ unsigned int f_namelen;
+ __fsfilcnt64_t f_favail;
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+#endif
+
+/* Tell code we have this member. */
+#define _STATFS_F_NAMELEN
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/statvfs.h b/REORG.TODO/sysdeps/mach/hurd/bits/statvfs.h
new file mode 100644
index 0000000000..3dcf460444
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/statvfs.h
@@ -0,0 +1,95 @@
+/* Definition of `struct statvfs', information about a filesystem.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_STATVFS_H
+# error "Never include <bits/statvfs.h> directly; use <sys/statvfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* GNU Hurd NOTE: This structure is carefully laid out such that we
+ can use the `file_statfs' RPC to implement `statvfs' and
+ `fstatvfs'. Please keep this file in sync with <bits/statfs.h>,
+ and pay attention to the note in that file. */
+
+struct statvfs
+ {
+ unsigned int __f_type;
+ unsigned int f_bsize;
+#ifndef __USE_FILE_OFFSET64
+ __fsblkcnt_t f_blocks;
+ __fsblkcnt_t f_bfree;
+ __fsblkcnt_t f_bavail;
+ __fsfilcnt_t f_files;
+ __fsfilcnt_t f_ffree;
+#else
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+#endif
+ __fsid_t f_fsid;
+ unsigned int f_namemax; /* NOTE: f_namelen in `struct statfs'. */
+#ifndef __USE_FILE_OFFSET64
+ __fsfilcnt_t f_favail;
+#else
+ __fsfilcnt64_t f_favail;
+#endif
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+
+#ifdef __USE_LARGEFILE64
+struct statvfs64
+ {
+ unsigned int __f_type;
+ unsigned int f_bsize;
+ __fsblkcnt64_t f_blocks;
+ __fsblkcnt64_t f_bfree;
+ __fsblkcnt64_t f_bavail;
+ __fsfilcnt64_t f_files;
+ __fsfilcnt64_t f_ffree;
+ __fsid_t f_fsid;
+ unsigned int f_namemax;
+ __fsfilcnt64_t f_favail;
+ unsigned int f_frsize;
+ unsigned int f_flag;
+ unsigned int f_spare[3];
+ };
+#endif
+
+/* Definitions for the flag in `f_flag'.
+ The values for the non-standard flags come from Linux. */
+enum
+{
+ ST_RDONLY = 1,
+#define ST_RDONLY ST_RDONLY
+ ST_NOSUID = 2
+#define ST_NOSUID ST_NOSUID
+#ifdef __USE_GNU
+ ,
+ ST_NOEXEC = 8,
+# define ST_NOEXEC ST_NOEXEC
+ ST_SYNCHRONOUS = 16,
+# define ST_SYNCHRONOUS ST_SYNCHRONOUS
+ ST_NOATIME = 32 /* Do not update access times. */
+# define ST_NOATIME ST_NOATIME
+#endif
+};
diff --git a/REORG.TODO/sysdeps/mach/hurd/bits/typesizes.h b/REORG.TODO/sysdeps/mach/hurd/bits/typesizes.h
new file mode 100644
index 0000000000..e87ad60517
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/bits/typesizes.h
@@ -0,0 +1,68 @@
+/* bits/typesizes.h -- underlying types for *_t. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_TYPESIZES_H
+#define _BITS_TYPESIZES_H 1
+
+/* See <bits/types.h> for the meaning of these macros. This file exists so
+ that <bits/types.h> need not vary across different GNU platforms. */
+
+#define __DEV_T_TYPE __U32_TYPE
+#define __UID_T_TYPE __U32_TYPE
+#define __GID_T_TYPE __U32_TYPE
+#define __INO_T_TYPE __ULONGWORD_TYPE
+#define __INO64_T_TYPE __UQUAD_TYPE
+#define __MODE_T_TYPE __U32_TYPE
+#define __NLINK_T_TYPE __UWORD_TYPE
+#define __OFF_T_TYPE __SLONGWORD_TYPE
+#define __OFF64_T_TYPE __SQUAD_TYPE
+#define __PID_T_TYPE __S32_TYPE
+#define __RLIM_T_TYPE __ULONGWORD_TYPE
+#define __RLIM64_T_TYPE __UQUAD_TYPE
+#define __BLKCNT_T_TYPE __SLONGWORD_TYPE
+#define __BLKCNT64_T_TYPE __SQUAD_TYPE
+#define __FSBLKCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSBLKCNT64_T_TYPE __UQUAD_TYPE
+#define __FSFILCNT_T_TYPE __ULONGWORD_TYPE
+#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
+#define __FSWORD_T_TYPE __SWORD_TYPE
+#define __ID_T_TYPE __U32_TYPE
+#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __USECONDS_T_TYPE __U32_TYPE
+#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
+#define __DADDR_T_TYPE __S32_TYPE
+#define __KEY_T_TYPE __S32_TYPE
+#define __CLOCKID_T_TYPE __S32_TYPE
+#define __TIMER_T_TYPE __S32_TYPE
+#define __BLKSIZE_T_TYPE __SLONGWORD_TYPE
+#define __FSID_T_TYPE __UQUAD_TYPE
+#define __SSIZE_T_TYPE __SWORD_TYPE
+#define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
+#define __SYSCALL_ULONG_TYPE __ULONGWORD_TYPE
+#define __CPU_MASK_TYPE __ULONGWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'. */
+#define __FD_SETSIZE 256
+
+
+#endif /* bits/typesizes.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/brk.c b/REORG.TODO/sysdeps/mach/hurd/brk.c
new file mode 100644
index 0000000000..a9154bffdd
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/brk.c
@@ -0,0 +1,166 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+#include <cthreads.h> /* For `struct mutex'. */
+
+
+/* Initial maximum size of the data segment (this is arbitrary). */
+#define DATA_SIZE (128 * 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 = 0;
+
+/* This name is used by the Linux crtbeginS.o for reasons you don't even
+ want to think about it. It's just easier to provide some definition for
+ it than even to explain the braindamage involved. */
+weak_alias (_hurd_brk, ___brk_addr)
+
+struct mutex _hurd_brk_lock;
+
+extern int __data_start, _end;
+weak_extern (__data_start)
+static vm_address_t static_data_start;
+
+
+/* Set the end of the process's data space to INADDR.
+ Return 0 if successful, -1 if not. */
+int
+__brk (void *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 = 0;
+ vm_address_t pagend = round_page (addr);
+ vm_address_t pagebrk = round_page (_hurd_brk);
+ long int rlimit;
+
+ if (pagend <= pagebrk)
+ {
+ if (pagend < pagebrk)
+ {
+ /* XXX wish this were atomic... */
+ /* First deallocate the memory to release its backing space. */
+ __vm_deallocate (__mach_task_self (), pagend, pagebrk - pagend);
+ /* Now reallocate it with no access allowed. */
+ err = __vm_map (__mach_task_self (),
+ &pagend, pagebrk - pagend,
+ 0, 0, MACH_PORT_NULL, 0, 0,
+ 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
+ VM_INHERIT_COPY);
+ /* XXX what if error? */
+ }
+ _hurd_brk = addr;
+ return 0;
+ }
+
+ __mutex_lock (&_hurd_rlimit_lock);
+ rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur;
+ __mutex_unlock (&_hurd_rlimit_lock);
+
+ if (addr - static_data_start > rlimit)
+ {
+ /* Need to increase the resource limit. */
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (pagend > _hurd_data_end)
+ {
+ vm_address_t alloc_start = _hurd_data_end;
+
+ /* We didn't allocate enough space! Hopefully we can get some more! */
+
+ if (_hurd_data_end > pagebrk)
+ /* First finish allocation. */
+ err = __vm_protect (__mach_task_self (), pagebrk,
+ alloc_start - pagebrk, 0,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ if (! err)
+ _hurd_brk = alloc_start;
+
+ if (! err)
+ err = __vm_allocate (__mach_task_self (), &alloc_start,
+ pagend - alloc_start, 0);
+
+ if (! err)
+ _hurd_data_end = pagend;
+ }
+ else
+ /* Make the memory accessible. */
+ err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk,
+ 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+
+ if (err)
+ return __hurd_fail (err);
+
+ _hurd_brk = addr;
+ return 0;
+}
+
+static void
+init_brk (void)
+{
+ vm_address_t pagend;
+
+ __mutex_init (&_hurd_brk_lock);
+
+ static_data_start = (vm_address_t) (&__data_start ?: &_end);
+
+ /* 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 = round_page (static_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/REORG.TODO/sysdeps/mach/hurd/chdir.c b/REORG.TODO/sysdeps/mach/hurd/chdir.c
new file mode 100644
index 0000000000..99305540d6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/chdir.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+#include <hurd/port.h>
+
+/* Change the current directory to FILE_NAME. */
+int
+__chdir (const char *file_name)
+{
+ return _hurd_change_directory_port_from_name (&_hurd_ports[INIT_PORT_CWDIR],
+ file_name);
+}
+
+weak_alias (__chdir, chdir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/check_fds.c b/REORG.TODO/sysdeps/mach/hurd/check_fds.c
new file mode 100644
index 0000000000..69dc11e257
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/check_fds.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+
+#include <set-hooks.h>
+
+/* Try to get a machine dependent instruction which will make the
+ program crash. This is used in case everything else fails. */
+#include <abort-instr.h>
+#ifndef ABORT_INSTRUCTION
+/* No such instruction is available. */
+# define ABORT_INSTRUCTION
+#endif
+
+static void
+check_one_fd (int fd, int mode)
+{
+ struct hurd_fd *d;
+
+ d = _hurd_fd_get (fd);
+ if (d == NULL)
+ {
+ /* This descriptor hasn't been opened. We try to allocate the
+ descriptor and open /dev/null on it so that the SUID program
+ we are about to start does not accidentally use this
+ descriptor. */
+ d = _hurd_alloc_fd (NULL, fd);
+ if (d != NULL)
+ {
+ mach_port_t port;
+
+ port = __file_name_lookup (_PATH_DEVNULL, mode, 0);
+ if (port)
+ {
+ /* Since /dev/null isn't supposed to be a terminal, we
+ avoid any ctty magic. */
+ d->port.port = port;
+ d->flags = 0;
+
+ __spin_unlock (&d->port.lock);
+ return;
+ }
+ }
+
+ /* We cannot even give an error message here since it would run
+ into the same problems. */
+ while (1)
+ /* Try for ever and ever. */
+ ABORT_INSTRUCTION;
+ }
+}
+
+static void
+check_standard_fds (void)
+{
+ /* Check all three standard file descriptors. */
+ check_one_fd (STDIN_FILENO, O_RDONLY);
+ check_one_fd (STDOUT_FILENO, O_RDWR);
+ check_one_fd (STDERR_FILENO, O_RDWR);
+}
+
+static void
+init_standard_fds (void)
+{
+ /* Now that we have FDs, make sure that, if this is a SUID program,
+ FDs 0, 1 and 2 are allocated. If necessary we'll set them up
+ ourselves. If that's not possible we stop the program. */
+ if (__builtin_expect (__libc_enable_secure, 0))
+ check_standard_fds ();
+
+ (void) &init_standard_fds; /* Avoid "defined but not used" warning. */
+}
+text_set_element (_hurd_fd_subinit, init_standard_fds);
+
+
+#ifndef SHARED
+void
+__libc_check_standard_fds (void)
+{
+ /* We don't check the standard file descriptors here. They will be
+ checked when we initialize the file descriptor table, as part of
+ the _hurd_fd_subinit hook.
+
+ This function is only present to make sure that this module gets
+ linked in when part of the static libc. */
+}
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/chflags.c b/REORG.TODO/sysdeps/mach/hurd/chflags.c
new file mode 100644
index 0000000000..d231f68327
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/chflags.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the flags of FILE to FLAGS. */
+
+/* XXX shouldn't this be __chflags? */
+int
+chflags (const char *file, unsigned long 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/REORG.TODO/sysdeps/mach/hurd/chmod.c b/REORG.TODO/sysdeps/mach/hurd/chmod.c
new file mode 100644
index 0000000000..943f9855d4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/chmod.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the protections of FILE to MODE. */
+int
+__chmod (const char *file, 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/REORG.TODO/sysdeps/mach/hurd/chown.c b/REORG.TODO/sysdeps/mach/hurd/chown.c
new file mode 100644
index 0000000000..0a15181f3f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/chown.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Change the owner and group of FILE. */
+int
+__chown (const char *file, uid_t owner, 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;
+}
+libc_hidden_def (__chown)
+weak_alias (__chown, chown)
diff --git a/REORG.TODO/sysdeps/mach/hurd/chroot.c b/REORG.TODO/sysdeps/mach/hurd/chroot.c
new file mode 100644
index 0000000000..04054ca93e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/chroot.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Make PATH be the root directory (the starting point for absolute
+ paths). Note that while on traditional UNIX systems this call is
+ restricted to the super-user, it isn't on the Hurd. */
+int
+chroot (const char *path)
+{
+ const char *lookup;
+ size_t len;
+ file_t dir, root;
+ error_t err;
+
+ /* Append trailing "/." to directory name to force ENOTDIR if it's not a
+ directory and EACCES if we don't have search permission. */
+ len = strlen (path);
+ if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.')
+ lookup = path;
+ else if (len == 0)
+ /* Special-case empty file name according to POSIX. */
+ return __hurd_fail (ENOENT);
+ else
+ {
+ char *n = alloca (len + 3);
+ memcpy (n, path, len);
+ n[len] = '/';
+ n[len + 1] = '.';
+ n[len + 2] = '\0';
+ lookup = n;
+ }
+
+ dir = __file_name_lookup (lookup, 0, 0);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Prevent going through DIR's .. */
+ err = __file_reparent (dir, MACH_PORT_NULL, &root);
+ __mach_port_deallocate (__mach_task_self (), dir);
+ if (err)
+ return __hurd_fail (err);
+
+ _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/clock.c b/REORG.TODO/sysdeps/mach/hurd/clock.c
new file mode 100644
index 0000000000..98534268c8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/clock.c
@@ -0,0 +1,53 @@
+/* Return the CPU time used by the program so far. Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+#include <sys/time.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+/* Return the time used by the program so far (user time + system time). */
+clock_t
+clock (void)
+{
+ struct task_basic_info bi;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ clock_t total;
+ error_t err;
+
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ total = bi.user_time.seconds * 1000000 + bi.user_time.microseconds;
+ total += tti.user_time.seconds * 1000000 + tti.user_time.microseconds;
+ total += bi.system_time.seconds * 1000000 + bi.system_time.microseconds;
+ total += tti.system_time.seconds * 1000000 + tti.system_time.microseconds;
+
+ return total;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/close.c b/REORG.TODO/sysdeps/mach/hurd/close.c
new file mode 100644
index 0000000000..e672dfb72c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/close.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Close the file descriptor FD. */
+int
+__close (int fd)
+{
+ error_t err;
+
+ err = HURD_FD_USE (fd, _hurd_fd_close (descriptor));
+
+ return err ? __hurd_fail (err) : 0;
+}
+libc_hidden_def (__close)
+weak_alias (__close, close)
diff --git a/REORG.TODO/sysdeps/mach/hurd/closedir.c b/REORG.TODO/sysdeps/mach/hurd/closedir.c
new file mode 100644
index 0000000000..0d3805c06c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/closedir.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Close the directory stream DIRP.
+ Return 0 if successful, -1 if not. */
+int
+__closedir (DIR *dirp)
+{
+ error_t err;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+ err = __vm_deallocate (__mach_task_self (),
+ (vm_address_t) dirp->__data, dirp->__allocation);
+ dirp->__data = NULL;
+ err = _hurd_fd_close (dirp->__fd);
+
+ if (err)
+ {
+ /* Unlock the DIR. A failing closedir can be repeated (and may fail
+ again, but shouldn't deadlock). */
+ __libc_lock_unlock (dirp->__lock);
+ return __hurd_fail (err);
+ }
+
+ /* Clean up the lock and free the structure. */
+ __libc_lock_fini (dirp->__lock);
+ free (dirp);
+
+ return 0;
+}
+weak_alias (__closedir, closedir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/configure b/REORG.TODO/sysdeps/mach/hurd/configure
new file mode 100644
index 0000000000..163b5c7730
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/configure
@@ -0,0 +1,49 @@
+# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
+
+$as_echo "#define NO_HIDDEN 1" >>confdefs.h
+
+
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Hurd header version" >&5
+$as_echo_n "checking Hurd header version... " >&6; }
+if ${libc_cv_hurd_version+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <hurd/version.h>
+int
+main ()
+{
+
+#define NEED_VERSION 20020609
+#if HURD_INTERFACE_VERSION < NEED_VERSION
+# error Hurd version too old: HURD_INTERFACE_VERSION < NEED_VERSION
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libc_cv_hurd_version=ok
+else
+ libc_cv_hurd_version=bad
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_hurd_version" >&5
+$as_echo "$libc_cv_hurd_version" >&6; }
+if test "x$libc_cv_hurd_version" != xok; then
+ as_fn_error $? "Hurd headers not installed or too old" "$LINENO" 5
+fi
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
+
+libc_cv_ld_gnu_indirect_function=no
diff --git a/REORG.TODO/sysdeps/mach/hurd/configure.ac b/REORG.TODO/sysdeps/mach/hurd/configure.ac
new file mode 100644
index 0000000000..5539a8c8af
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/configure.ac
@@ -0,0 +1,32 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+dnl We need this setting because of the need for PLT calls in ld.so.
+dnl See Roland's comment in
+dnl https://sourceware.org/bugzilla/show_bug.cgi?id=15605
+AC_DEFINE([NO_HIDDEN])
+
+if test -n "$sysheaders"; then
+ OLD_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $SYSINCLUDES"
+fi
+
+AC_CACHE_CHECK(Hurd header version, libc_cv_hurd_version, [dnl
+AC_TRY_COMPILE(dnl
+[#include <hurd/version.h>], [
+#define NEED_VERSION 20020609
+#if HURD_INTERFACE_VERSION < NEED_VERSION
+# error Hurd version too old: HURD_INTERFACE_VERSION < NEED_VERSION
+#endif],
+ libc_cv_hurd_version=ok,
+ libc_cv_hurd_version=bad)])
+if test "x$libc_cv_hurd_version" != xok; then
+ AC_MSG_ERROR(Hurd headers not installed or too old)
+fi
+
+if test -n "$sysheaders"; then
+ CPPFLAGS=$OLD_CPPFLAGS
+fi
+
+dnl ifunc does not work yet for static binaries
+dnl http://www.gnu.org/software/hurd/open_issues/ifunc.html
+libc_cv_ld_gnu_indirect_function=no
diff --git a/REORG.TODO/sysdeps/mach/hurd/connect.c b/REORG.TODO/sysdeps/mach/hurd/connect.c
new file mode 100644
index 0000000000..36c9eeb9fb
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/connect.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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>
+#include "hurd/hurdsocket.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
+__connect (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len)
+{
+ error_t err;
+ addr_port_t aport;
+ const struct sockaddr_un *addr = addrarg.__sockaddr_un__;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ char *name = _hurd_sun_path_dupa (addr, len);
+ /* For the local domain, we must look up the name as a file and talk
+ to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (name, 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->sun_family,
+ (char *) addr, len,
+ &aport);
+ if (! err)
+ {
+ err = __socket_connect (port, aport);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+
+libc_hidden_def (__connect)
+weak_alias (__connect, connect)
diff --git a/REORG.TODO/sysdeps/mach/hurd/cthreads.c b/REORG.TODO/sysdeps/mach/hurd/cthreads.c
new file mode 100644
index 0000000000..e464714bed
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/cthreads.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libc-lock.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* Placeholder for key creation routine from Hurd cthreads library. */
+int
+weak_function
+cthread_keycreate (cthread_key_t *key)
+{
+ __set_errno (ENOSYS);
+ *key = -1;
+ return -1;
+}
+
+/* Placeholder for key retrieval routine from Hurd cthreads library. */
+int
+weak_function
+cthread_getspecific (cthread_key_t key, void **pval)
+{
+ *pval = NULL;
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+/* Placeholder for key setting routine from Hurd cthreads library. */
+int
+weak_function
+cthread_setspecific (cthread_key_t key, void *val)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+/* Call cthread_getspecific which gets a pointer to the return value instead
+ of just returning it. */
+void *
+__libc_getspecific (cthread_key_t key)
+{
+ void *val;
+ cthread_getspecific (key, &val);
+ return val;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/device-nrs.h b/REORG.TODO/sysdeps/mach/hurd/device-nrs.h
new file mode 100644
index 0000000000..3cbebf8612
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/device-nrs.h
@@ -0,0 +1,27 @@
+/* Device numbers of devices used in the implementation. Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _DEVICE_NRS_H
+#define _DEVICE_NRS_H 1
+
+#include <hurd/hurd_types.h>
+
+/* Check whether a given device is a tty. */
+#define DEV_TTY_P(statp) ((statp)->st_fstype == FSTYPE_TERM)
+
+#endif /* device-nrs.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/dirfd.c b/REORG.TODO/sysdeps/mach/hurd/dirfd.c
new file mode 100644
index 0000000000..0ad290d515
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dirfd.c
@@ -0,0 +1,43 @@
+/* dirfd -- Return the file descriptor used by a DIR stream. Hurd version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <dirstream.h>
+#include <hurd/fd.h>
+#include <errno.h>
+
+int
+dirfd (DIR *dirp)
+{
+ int fd;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_dtable_lock);
+ for (fd = 0; fd < _hurd_dtablesize; ++fd)
+ if (_hurd_dtable[fd] == dirp->__fd)
+ break;
+ if (fd == _hurd_dtablesize)
+ {
+ errno = EINVAL;
+ fd = -1;
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+ HURD_CRITICAL_END;
+
+ return fd;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/dirstream.h b/REORG.TODO/sysdeps/mach/hurd/dirstream.h
new file mode 100644
index 0000000000..01aaa556e0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dirstream.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _DIRSTREAM_H
+
+#define _DIRSTREAM_H 1
+
+#include <libc-lock.h>
+
+/* 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. */
+
+struct __dirstream
+ {
+ void *__fd; /* `struct hurd_fd' pointer for descriptor. */
+ 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. */
+ size_t __allocation; /* Space allocated for the block. */
+ size_t __size; /* Total valid data in the block. */
+ __libc_lock_define (, __lock) /* Mutex lock for this structure. */
+ };
+
+#endif /* dirstream.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-execstack.c b/REORG.TODO/sysdeps/mach/hurd/dl-execstack.c
new file mode 100644
index 0000000000..1168df9262
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-execstack.c
@@ -0,0 +1,51 @@
+/* Stack executability handling for GNU dynamic linker. Hurd version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+#include <hurdstartup.h>
+#include <errno.h>
+
+extern struct hurd_startup_data *_dl_hurd_data attribute_hidden;
+
+/* There is no portable way to know the bounds of the initial thread's stack
+ so as to mprotect it. */
+
+int
+internal_function
+_dl_make_stack_executable (void **stack_endp)
+{
+ /* Challenge the caller. */
+ if (__builtin_expect (*stack_endp != __libc_stack_end, 0))
+ return EPERM;
+ *stack_endp = NULL;
+
+#if IS_IN (rtld)
+ if (__mprotect ((void *)_dl_hurd_data->stack_base, _dl_hurd_data->stack_size,
+ PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
+ return errno;
+
+ /* Remember that we changed the permission. */
+ GL(dl_stack_flags) |= PF_X;
+
+ return 0;
+#else
+ /* We don't bother to implement this for static linking. */
+ return ENOSYS;
+#endif
+}
+rtld_hidden_def (_dl_make_stack_executable)
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-fcntl.h b/REORG.TODO/sysdeps/mach/hurd/dl-fcntl.h
new file mode 100644
index 0000000000..149481f2e4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-fcntl.h
@@ -0,0 +1,22 @@
+/* Functions with hidden attribute internal to ld.so, which are declared
+ in include/fcntl.h. Hurd version.
+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* __open can't be hidden in ld.so on Hurd since it will be preempted by the
+ one in libc.so after bootstrap. */
+extern __typeof (__fcntl) __fcntl attribute_hidden;
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-mman.h b/REORG.TODO/sysdeps/mach/hurd/dl-mman.h
new file mode 100644
index 0000000000..4e875eec28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-mman.h
@@ -0,0 +1,23 @@
+/* Functions with hidden attribute internal to ld.so, which are declared
+ in include/sys/mman.h. Hurd version.
+ Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Can't hide __mmap on Hurd, since __mmap in ld.so will be preempted by
+ the one in libc.so after bootstrap. */
+extern __typeof (__mprotect) __mprotect attribute_hidden;
+extern __typeof (__munmap) __munmap attribute_hidden;
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.c b/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.c
new file mode 100644
index 0000000000..4f274b4d65
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.c
@@ -0,0 +1,661 @@
+/* Operating system support for run-time dynamic linker. Hurd version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* In the static library, this is all handled by dl-support.c
+ or by the vanilla definitions in the rest of the C library. */
+#ifdef SHARED
+
+#include <hurd.h>
+#include <link.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <ldsodefs.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <sysdep.h>
+#include <mach/mig_support.h>
+#include "hurdstartup.h"
+#include <hurd/lookup.h>
+#include <hurd/auth.h>
+#include <hurd/term.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <entry.h>
+#include <dl-machine.h>
+#include <dl-procinfo.h>
+
+#include <dl-tunables.h>
+
+extern void __mach_init (void);
+
+extern int _dl_argc;
+extern char **_dl_argv;
+extern char **_environ;
+
+int __libc_enable_secure = 0;
+rtld_hidden_data_def (__libc_enable_secure)
+int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion
+ of init-first. */
+/* This variable contains the lowest stack address ever used. */
+void *__libc_stack_end = NULL;
+rtld_hidden_data_def(__libc_stack_end)
+
+#if HP_TIMING_AVAIL
+hp_timing_t _dl_cpuclock_offset;
+#endif
+
+
+struct hurd_startup_data *_dl_hurd_data;
+
+/* This is used only within ld.so, via dl-minimal.c's __errno_location. */
+#undef errno
+int errno attribute_hidden;
+
+/* Defining these variables here avoids the inclusion of hurdsig.c. */
+unsigned long int __hurd_sigthread_stack_base;
+unsigned long int __hurd_sigthread_stack_end;
+unsigned long int *__hurd_sigthread_variables;
+
+/* Defining these variables here avoids the inclusion of init-first.c.
+ We need to provide temporary storage for the per-thread variables
+ of the main user thread here, since it is used for storing the
+ `errno' variable. Note that this information is lost once we
+ relocate the dynamic linker. */
+static unsigned long int threadvars[_HURD_THREADVAR_MAX];
+unsigned long int __hurd_threadvar_stack_offset
+ = (unsigned long int) &threadvars;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#define FMH defined(__i386__)
+#if ! FMH
+# define fmh() ((void)0)
+# define unfmh() ((void)0)
+#else
+/* XXX loser kludge for vm_map kernel bug */
+#undef ELF_MACHINE_USER_ADDRESS_MASK
+#define ELF_MACHINE_USER_ADDRESS_MASK 0
+static vm_address_t fmha;
+static vm_size_t fmhs;
+static void unfmh(void){
+__vm_deallocate(__mach_task_self(),fmha,fmhs);}
+static void fmh(void) {
+ error_t err;int x;vm_offset_t o;mach_port_t p;
+ vm_address_t a=0x08000000U,max=VM_MAX_ADDRESS;
+ while (!(err=__vm_region(__mach_task_self(),&a,&fmhs,&x,&x,&x,&x,&p,&o))){
+ __mach_port_deallocate(__mach_task_self(),p);
+ if (a+fmhs>=0x80000000U){
+ max=a; break;}
+ fmha=a+=fmhs;}
+ if (err) assert(err==KERN_NO_SPACE);
+ if (!fmha)fmhs=0;else{
+ fmhs=max-fmha;
+ err = __vm_map (__mach_task_self (),
+ &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1,
+ VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY);
+ assert_perror(err);}
+ }
+/* XXX loser kludge for vm_map kernel bug */
+#endif
+
+
+ElfW(Addr)
+_dl_sysdep_start (void **start_argptr,
+ void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phent,
+ ElfW(Addr) *user_entry,
+ ElfW(auxv_t) *auxv))
+{
+ void go (intptr_t *argdata)
+ {
+ char **p;
+
+ /* Cache the information in various global variables. */
+ _dl_argc = *argdata;
+ _dl_argv = 1 + (char **) argdata;
+ _environ = &_dl_argv[_dl_argc + 1];
+ for (p = _environ; *p++;); /* Skip environ pointers and terminator. */
+
+ if ((void *) p == _dl_argv[0])
+ {
+ static struct hurd_startup_data nodata;
+ _dl_hurd_data = &nodata;
+ nodata.user_entry = (vm_address_t) ENTRY_POINT;
+ }
+ else
+ _dl_hurd_data = (void *) p;
+
+ __libc_enable_secure = _dl_hurd_data->flags & EXEC_SECURE;
+
+ __tunables_init (_environ);
+
+ if (_dl_hurd_data->flags & EXEC_STACK_ARGS &&
+ _dl_hurd_data->user_entry == 0)
+ _dl_hurd_data->user_entry = (vm_address_t) ENTRY_POINT;
+
+unfmh(); /* XXX */
+
+#if 0 /* XXX make this work for real someday... */
+ if (_dl_hurd_data->user_entry == (vm_address_t) ENTRY_POINT)
+ /* We were invoked as a command, not as the program interpreter.
+ The generic ld.so code supports this: it will parse the args
+ as "ld.so PROGRAM [ARGS...]". For booting the Hurd, we
+ support an additional special syntax:
+ ld.so [-LIBS...] PROGRAM [ARGS...]
+ Each LIBS word consists of "FILENAME=MEMOBJ";
+ for example "-/lib/libc.so=123" says that the contents of
+ /lib/libc.so are found in a memory object whose port name
+ in our task is 123. */
+ while (_dl_argc > 2 && _dl_argv[1][0] == '-' && _dl_argv[1][1] != '-')
+ {
+ char *lastslash, *memobjname, *p;
+ struct link_map *l;
+ mach_port_t memobj;
+ error_t err;
+
+ ++_dl_skip_args;
+ --_dl_argc;
+ p = _dl_argv++[1] + 1;
+
+ memobjname = strchr (p, '=');
+ if (! memobjname)
+ _dl_sysdep_fatal ("Bogus library spec: ", p, "\n", NULL);
+ *memobjname++ = '\0';
+ memobj = 0;
+ while (*memobjname != '\0')
+ memobj = (memobj * 10) + (*memobjname++ - '0');
+
+ /* Add a user reference on the memory object port, so we will
+ still have one after _dl_map_object_from_fd calls our
+ `close'. */
+ err = __mach_port_mod_refs (__mach_task_self (), memobj,
+ MACH_PORT_RIGHT_SEND, +1);
+ assert_perror (err);
+
+ lastslash = strrchr (p, '/');
+ l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p, NULL,
+ memobj, strdup (p), 0);
+
+ /* Squirrel away the memory object port where it
+ can be retrieved by the program later. */
+ l->l_info[DT_NULL] = (void *) memobj;
+ }
+#endif
+
+ /* Call elf/rtld.c's main program. It will set everything
+ up and leave us to transfer control to USER_ENTRY. */
+ (*dl_main) ((const ElfW(Phdr) *) _dl_hurd_data->phdr,
+ _dl_hurd_data->phdrsz / sizeof (ElfW(Phdr)),
+ &_dl_hurd_data->user_entry, NULL);
+
+ /* The call above might screw a few things up.
+
+ First of all, if _dl_skip_args is nonzero, we are ignoring
+ the first few arguments. However, if we have no Hurd startup
+ data, it is the magical convention that ARGV[0] == P. The
+ startup code in init-first.c will get confused if this is not
+ the case, so we must rearrange things to make it so. We'll
+ overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].
+
+ Secondly, if we need to be secure, it removes some dangerous
+ environment variables. If we have no Hurd startup date this
+ changes P (since that's the location after the terminating
+ NULL in the list of environment variables). We do the same
+ thing as in the first case but make sure we recalculate P.
+ If we do have Hurd startup data, we have to move the data
+ such that it starts just after the terminating NULL in the
+ environment list.
+
+ We use memmove, since the locations might overlap. */
+ if (__libc_enable_secure || _dl_skip_args)
+ {
+ char **newp;
+
+ for (newp = _environ; *newp++;);
+
+ if (_dl_argv[-_dl_skip_args] == (char *) p)
+ {
+ if ((char *) newp != _dl_argv[0])
+ {
+ assert ((char *) newp < _dl_argv[0]);
+ _dl_argv[0] = memmove ((char *) newp, _dl_argv[0],
+ strlen (_dl_argv[0]) + 1);
+ }
+ }
+ else
+ {
+ if ((void *) newp != _dl_hurd_data)
+ memmove (newp, _dl_hurd_data, sizeof (*_dl_hurd_data));
+ }
+ }
+
+ {
+ extern void _dl_start_user (void);
+ /* Unwind the stack to ARGDATA and simulate a return from _dl_start
+ to the RTLD_START code which will run the user's entry point. */
+ RETURN_TO (argdata, &_dl_start_user, _dl_hurd_data->user_entry);
+ }
+ }
+
+ /* Set up so we can do RPCs. */
+ __mach_init ();
+
+ /* Initialize frequently used global variable. */
+ GLRO(dl_pagesize) = __getpagesize ();
+
+#if HP_TIMING_AVAIL
+ HP_TIMING_NOW (_dl_cpuclock_offset);
+#endif
+
+fmh(); /* XXX */
+
+ /* See hurd/hurdstartup.c; this deals with getting information
+ from the exec server and slicing up the arguments.
+ Then it will call `go', above. */
+ _hurd_startup (start_argptr, &go);
+
+ LOSE;
+ abort ();
+}
+
+void
+internal_function
+_dl_sysdep_start_cleanup (void)
+{
+ /* Deallocate the reply port and task port rights acquired by
+ __mach_init. We are done with them now, and the user will
+ reacquire them for himself when he wants them. */
+ __mig_dealloc_reply_port (MACH_PORT_NULL);
+ __mach_port_deallocate (__mach_task_self (), __mach_host_self_);
+ __mach_port_deallocate (__mach_task_self (), __mach_task_self_);
+}
+
+/* Minimal open/close/mmap implementation sufficient for initial loading of
+ shared libraries. These are weak definitions so that when the
+ dynamic linker re-relocates itself to be user-visible (for -ldl),
+ it will get the user's definition (i.e. usually libc's). */
+
+/* Open FILE_NAME and return a Hurd I/O for it in *PORT, or return an
+ error. If STAT is non-zero, stat the file into that stat buffer. */
+static error_t
+open_file (const char *file_name, int flags,
+ mach_port_t *port, struct stat64 *stat)
+{
+ enum retry_type doretry;
+ char retryname[1024]; /* XXX string_t LOSES! */
+ file_t startdir;
+ error_t err;
+
+ error_t use_init_port (int which, error_t (*operate) (file_t))
+ {
+ return (which < _dl_hurd_data->portarraysize
+ ? ((*operate) (_dl_hurd_data->portarray[which]))
+ : EGRATUITOUS);
+ }
+ file_t get_dtable_port (int fd)
+ {
+ if ((unsigned int) fd < _dl_hurd_data->dtablesize
+ && _dl_hurd_data->dtable[fd] != MACH_PORT_NULL)
+ {
+ __mach_port_mod_refs (__mach_task_self (), _dl_hurd_data->dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ return _dl_hurd_data->dtable[fd];
+ }
+ errno = EBADF;
+ return MACH_PORT_NULL;
+ }
+
+ assert (!(flags & ~(O_READ | O_CLOEXEC)));
+
+ startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
+ INIT_PORT_CRDIR : INIT_PORT_CWDIR];
+
+ while (file_name[0] == '/')
+ file_name++;
+
+ err = __dir_lookup (startdir, (char *)file_name, O_RDONLY, 0,
+ &doretry, retryname, port);
+
+ if (!err)
+ err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port,
+ __dir_lookup, doretry, retryname,
+ O_RDONLY, 0, port);
+ if (!err && stat)
+ {
+ err = __io_stat (*port, stat);
+ if (err)
+ __mach_port_deallocate (__mach_task_self (), *port);
+ }
+
+ return err;
+}
+
+int weak_function
+__open (const char *file_name, int mode, ...)
+{
+ mach_port_t port;
+ error_t err = open_file (file_name, mode, &port, 0);
+ if (err)
+ return __hurd_fail (err);
+ else
+ return (int)port;
+}
+
+int weak_function
+__close (int fd)
+{
+ if (fd != (int) MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), (mach_port_t) fd);
+ return 0;
+}
+
+__ssize_t weak_function
+__libc_read (int fd, void *buf, size_t nbytes)
+{
+ error_t err;
+ char *data;
+ mach_msg_type_number_t nread;
+
+ data = buf;
+ nread = nbytes;
+ err = __io_read ((mach_port_t) fd, &data, &nread, -1, nbytes);
+ if (err)
+ return __hurd_fail (err);
+
+ if (data != buf)
+ {
+ memcpy (buf, data, nread);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread);
+ }
+
+ return nread;
+}
+libc_hidden_weak (__libc_read)
+
+__ssize_t weak_function
+__libc_write (int fd, const void *buf, size_t nbytes)
+{
+ error_t err;
+ mach_msg_type_number_t nwrote;
+
+ assert (fd < _hurd_init_dtablesize);
+
+ err = __io_write (_hurd_init_dtable[fd], buf, nbytes, -1, &nwrote);
+ if (err)
+ return __hurd_fail (err);
+
+ return nwrote;
+}
+libc_hidden_weak (__libc_write)
+
+/* This is only used for printing messages (see dl-misc.c). */
+__ssize_t weak_function
+__writev (int fd, const struct iovec *iov, int niov)
+{
+ if (fd >= _hurd_init_dtablesize)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ int i;
+ size_t total = 0;
+ for (i = 0; i < niov; ++i)
+ total += iov[i].iov_len;
+
+ if (total != 0)
+ {
+ char buf[total], *bufp = buf;
+ error_t err;
+ mach_msg_type_number_t nwrote;
+
+ for (i = 0; i < niov; ++i)
+ bufp = (memcpy (bufp, iov[i].iov_base, iov[i].iov_len)
+ + iov[i].iov_len);
+
+ err = __io_write (_hurd_init_dtable[fd], buf, total, -1, &nwrote);
+ if (err)
+ return __hurd_fail (err);
+
+ return nwrote;
+ }
+ return 0;
+}
+
+
+off64_t weak_function
+__libc_lseek64 (int fd, off64_t offset, int whence)
+{
+ error_t err;
+
+ err = __io_seek ((mach_port_t) fd, offset, whence, &offset);
+ if (err)
+ return __hurd_fail (err);
+
+ return offset;
+}
+
+__ptr_t weak_function
+__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ error_t err;
+ vm_prot_t vmprot;
+ vm_address_t mapaddr;
+ mach_port_t memobj_rd, memobj_wr;
+
+ 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 (flags & MAP_ANON)
+ memobj_rd = MACH_PORT_NULL;
+ else
+ {
+ assert (!(flags & MAP_SHARED));
+ err = __io_map ((mach_port_t) fd, &memobj_rd, &memobj_wr);
+ if (err)
+ return __hurd_fail (err), MAP_FAILED;
+ if (memobj_wr != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), memobj_wr);
+ }
+
+ mapaddr = (vm_address_t) addr;
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, ELF_MACHINE_USER_ADDRESS_MASK,
+ !(flags & MAP_FIXED),
+ memobj_rd,
+ (vm_offset_t) offset,
+ flags & (MAP_COPY|MAP_PRIVATE),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+ if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (! err)
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len,
+ ELF_MACHINE_USER_ADDRESS_MASK,
+ !(flags & MAP_FIXED),
+ memobj_rd, (vm_offset_t) offset,
+ flags & (MAP_COPY|MAP_PRIVATE),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED)
+ ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+ }
+
+ if ((flags & MAP_ANON) == 0)
+ __mach_port_deallocate (__mach_task_self (), memobj_rd);
+
+ if (err)
+ return __hurd_fail (err), MAP_FAILED;
+ return (__ptr_t) mapaddr;
+}
+
+int weak_function
+__fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+ error_t err;
+
+ assert (vers == _STAT_VER);
+
+ err = __io_stat ((mach_port_t) fd, buf);
+ if (err)
+ return __hurd_fail (err);
+
+ return 0;
+}
+libc_hidden_def (__fxstat64)
+
+int weak_function
+__xstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ mach_port_t port;
+
+ assert (vers == _STAT_VER);
+
+ err = open_file (file, 0, &port, buf);
+ if (err)
+ return __hurd_fail (err);
+
+ __mach_port_deallocate (__mach_task_self (), port);
+
+ return 0;
+}
+libc_hidden_def (__xstat64)
+
+/* This function is called by the dynamic linker (rtld.c) to check
+ whether debugging malloc is allowed even for SUID binaries. This
+ stub will always fail, which means that malloc-debugging is always
+ disabled for SUID binaries. */
+int weak_function
+__access (const char *file, int type)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+pid_t weak_function
+__getpid (void)
+{
+ pid_t pid, ppid;
+ int orphaned;
+
+ if (__proc_getpids (_dl_hurd_data->portarray[INIT_PORT_PROC],
+ &pid, &ppid, &orphaned))
+ return -1;
+
+ return pid;
+}
+
+/* This is called only in some strange cases trying to guess a value
+ for $ORIGIN for the executable. The dynamic linker copes with
+ getcwd failing (dl-object.c), and it's too much hassle to include
+ the functionality here. (We could, it just requires duplicating or
+ reusing getcwd.c's code but using our special lookup function as in
+ `open', above.) */
+char *
+weak_function
+__getcwd (char *buf, size_t size)
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+void weak_function attribute_hidden
+_exit (int status)
+{
+ __proc_mark_exit (_dl_hurd_data->portarray[INIT_PORT_PROC],
+ W_EXITCODE (status, 0), 0);
+ while (__task_terminate (__mach_task_self ()))
+ __mach_task_self_ = (__mach_task_self) ();
+}
+/* We need this alias to satisfy references from libc_pic.a objects
+ that were affected by the libc_hidden_proto declaration for _exit. */
+strong_alias (_exit, __GI__exit)
+
+/* Try to get a machine dependent instruction which will make the
+ program crash. This is used in case everything else fails. */
+#include <abort-instr.h>
+#ifndef ABORT_INSTRUCTION
+/* No such instruction is available. */
+# define ABORT_INSTRUCTION
+#endif
+
+void weak_function
+abort (void)
+{
+ /* Try to abort using the system specific command. */
+ ABORT_INSTRUCTION;
+
+ /* If the abort instruction failed, exit. */
+ _exit (127);
+
+ /* If even this fails, make sure we never return. */
+ while (1)
+ /* Try for ever and ever. */
+ ABORT_INSTRUCTION;
+}
+
+/* We need this alias to satisfy references from libc_pic.a objects
+ that were affected by the libc_hidden_proto declaration for abort. */
+strong_alias (abort, __GI_abort)
+
+/* This function is called by interruptible RPC stubs. For initial
+ dynamic linking, just use the normal mach_msg. Since this defn is
+ weak, the real defn in libc.so will override it if we are linked into
+ the user program (-ldl). */
+
+error_t weak_function
+_hurd_intr_rpc_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)
+{
+ return __mach_msg (msg, option, send_size, rcv_size, rcv_name,
+ timeout, notify);
+}
+
+
+void
+internal_function
+_dl_show_auxv (void)
+{
+ /* There is nothing to print. Hurd has no auxiliary vector. */
+}
+
+
+void weak_function
+_dl_init_first (int argc, ...)
+{
+ /* This no-op definition only gets used if libc is not linked in. */
+}
+
+#endif /* SHARED */
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.h b/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.h
new file mode 100644
index 0000000000..83c4e12fee
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-sysdep.h
@@ -0,0 +1,31 @@
+/* System-specific settings for dynamic linker code. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The private errno doesn't make sense on the Hurd. errno is always the
+ thread-local slot shared with libc, and it matters to share the cell
+ with libc because after startup we use libc functions that set errno
+ (open, mmap, etc). */
+
+#define RTLD_PRIVATE_ERRNO 0
+
+#ifdef SHARED
+/* _dl_argv and __libc_stack_end cannot be attribute_relro, because the stack-switching
+ libc initializer for using cthreads might write into it. */
+# define DL_ARGV_NOT_RELRO 1
+# define LIBC_STACK_END_NOT_RELRO 1
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/dl-unistd.h b/REORG.TODO/sysdeps/mach/hurd/dl-unistd.h
new file mode 100644
index 0000000000..2bb73efae7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dl-unistd.h
@@ -0,0 +1,28 @@
+/* Functions with hidden attribute internal to ld.so, which are declared
+ in include/unistd.h. Hurd version.
+ Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* __close, __getcwd, __getpid, __libc_read and __libc_write can't be
+ hidden in ld.so on Hurd since they will be preempted by the ones in
+ libc.so after bootstrap. */
+extern __typeof (__access) __access attribute_hidden;
+extern __typeof (__brk) __brk attribute_hidden;
+extern __typeof (__lseek) __lseek attribute_hidden;
+extern __typeof (__profil) __profil attribute_hidden;
+extern __typeof (__read) __read attribute_hidden;
+extern __typeof (__sbrk) __sbrk attribute_hidden;
diff --git a/REORG.TODO/sysdeps/mach/hurd/dup2.c b/REORG.TODO/sysdeps/mach/hurd/dup2.c
new file mode 100644
index 0000000000..fb8498876d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dup2.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.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
+__dup2 (int fd, int fd2)
+{
+ int flags = 0;
+
+ if (fd2 == fd)
+ /* See the comment in dup3. */
+ flags = -1;
+
+ return __dup3 (fd, fd2, flags);
+}
+libc_hidden_def (__dup2)
+weak_alias (__dup2, dup2)
diff --git a/REORG.TODO/sysdeps/mach/hurd/dup3.c b/REORG.TODO/sysdeps/mach/hurd/dup3.c
new file mode 100644
index 0000000000..3ad325e49f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/dup3.c
@@ -0,0 +1,139 @@
+/* Duplicate a file descriptor to a given number, with flags. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#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, and setting FD2's flags according to FLAGS.
+ Return FD2 or -1. */
+int
+__dup3 (int fd, int fd2, int flags)
+{
+ struct hurd_fd *d;
+
+ /* Both passing flags different from O_CLOEXEC and FD2 being the same as FD
+ are invalid. */
+ if ((flags & ~O_CLOEXEC
+ || fd2 == fd)
+ /* ... with the exception in case that dup2 behavior is requested: if FD
+ is valid and FD2 is already the same then just return it. */
+ && ! (flags == -1
+ && fd2 == fd))
+ return __hurd_fail (EINVAL);
+
+ /* Extract the ports and flags from FD. */
+ d = _hurd_fd_get (fd);
+ if (d == NULL)
+ return __hurd_fail (EBADF);
+
+ HURD_CRITICAL_BEGIN;
+
+ __spin_lock (&d->port.lock);
+ if (d->port.port == MACH_PORT_NULL)
+ {
+ __spin_unlock (&d->port.lock);
+ fd2 = __hurd_fail (EBADF);
+ }
+ else if (fd2 == fd)
+ __spin_unlock (&d->port.lock);
+ else
+ {
+ struct hurd_userlink ulink, ctty_ulink;
+ int d_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. */
+
+ if (fd2 < 0)
+ fd2 = __hurd_fail (EBADF);
+ else
+ {
+ /* Get a hold of the destination descriptor. */
+ struct hurd_fd *d2;
+
+ __mutex_lock (&_hurd_dtable_lock);
+
+ if (fd2 >= _hurd_dtablesize)
+ {
+ /* The table is not large enough to hold the destination
+ descriptor. Enlarge it as necessary to allocate this
+ descriptor. */
+ __mutex_unlock (&_hurd_dtable_lock);
+ d2 = _hurd_alloc_fd (NULL, fd2);
+ if (d2)
+ __spin_unlock (&d2->port.lock);
+ __mutex_lock (&_hurd_dtable_lock);
+ }
+ else
+ {
+ 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);
+ }
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+
+ 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);
+ if (flags & O_CLOEXEC)
+ d2->flags = d_flags | FD_CLOEXEC;
+ else
+ /* dup clears FD_CLOEXEC. */
+ d2->flags = d_flags & ~FD_CLOEXEC;
+ _hurd_port_set (&d2->ctty, ctty);
+ _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */
+ }
+ }
+
+ _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;
+}
+libc_hidden_def (__dup3)
+weak_alias (__dup3, dup3)
diff --git a/REORG.TODO/sysdeps/mach/hurd/eloop-threshold.h b/REORG.TODO/sysdeps/mach/hurd/eloop-threshold.h
new file mode 100644
index 0000000000..58f05616e1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/eloop-threshold.h
@@ -0,0 +1,37 @@
+/* Threshold at which to diagnose ELOOP. Hurd version.
+ Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELOOP_THRESHOLD_H
+#define _ELOOP_THRESHOLD_H 1
+
+/* Return the maximum number of symlink traversals to permit
+ before diagnosing ELOOP.
+
+ In the Hurd version, here we are actually setting the only policy
+ there is on the system. We use a literal number here rather than
+ defining SYMLOOP_MAX so that programs don't compile in a number
+ but instead use sysconf and the number can be changed here to
+ affect sysconf's result. */
+
+static inline unsigned int __attribute__ ((const))
+__eloop_threshold (void)
+{
+ return 32;
+}
+
+#endif /* eloop-threshold.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/enbl-secure.c b/REORG.TODO/sysdeps/mach/hurd/enbl-secure.c
new file mode 100644
index 0000000000..9aeb0fafa6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/enbl-secure.c
@@ -0,0 +1,23 @@
+/* Define and initialize the `__libc_enable_secure' flag. Hurd version.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* There is no need for this file in the Hurd; it is just a placeholder
+ to prevent inclusion of the sysdeps/generic version.
+ In the shared library, the `__libc_enable_secure' variable is defined
+ by the dynamic linker in dl-sysdep.c and set there.
+ In the static library, it is defined in init-first.c and set there. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/err_hurd.sub b/REORG.TODO/sysdeps/mach/hurd/err_hurd.sub
new file mode 100644
index 0000000000..4a4dee3aa3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/err_hurd.sub
@@ -0,0 +1,12 @@
+/* This file defines the Mach error system for Hurd server errors. */
+
+#include <errno.h>
+
+extern const char *const _hurd_errlist[];
+
+/* 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 *) _hurd_errlist },
+ };
diff --git a/REORG.TODO/sysdeps/mach/hurd/errlist.c b/REORG.TODO/sysdeps/mach/hurd/errlist.c
new file mode 100644
index 0000000000..6815f3d83d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/errlist.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* sys_errlist cannot have Unix semantics on the Hurd, so it is easier just
+ to rename it. We also need to remap error codes to array indices by
+ taking their subcode. */
+#define _sys_errlist_internal _hurd_errlist
+#define _sys_nerr_internal _hurd_nerr
+#define ERRLIST_NO_COMPAT 1
+
+#include <mach/error.h>
+#define ERR_REMAP(n) (err_get_code (n))
+
+#include <sysdeps/gnu/errlist.c>
diff --git a/REORG.TODO/sysdeps/mach/hurd/errno-loc.c b/REORG.TODO/sysdeps/mach/hurd/errno-loc.c
new file mode 100644
index 0000000000..039c9fc748
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/errno-loc.c
@@ -0,0 +1,28 @@
+/* __errno_location -- helper function for locating per-thread errno value
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <hurd/threadvar.h>
+
+int *
+__errno_location (void)
+{
+ return (int *) __hurd_threadvar_location (_HURD_THREADVAR_ERRNO);
+}
+strong_alias (__errno_location, __hurd_errno_location)
+libc_hidden_def (__errno_location)
diff --git a/REORG.TODO/sysdeps/mach/hurd/errno.c b/REORG.TODO/sysdeps/mach/hurd/errno.c
new file mode 100644
index 0000000000..a29091b5e2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/errno.c
@@ -0,0 +1 @@
+/* No definition of `errno' variable on the Hurd. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/errnos.awk b/REORG.TODO/sysdeps/mach/hurd/errnos.awk
new file mode 100644
index 0000000000..1cd2a0ac96
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/errnos.awk
@@ -0,0 +1,165 @@
+# Copyright (C) 1991-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# errno.texinfo contains lines like:
+# @errno{ENOSYS, 123, Function not implemented}
+
+BEGIN {
+ print "/* This file generated by errnos.awk. */";
+ 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{";
+ print "\t/* The value zero always means success and it is perfectly fine for";
+ print "\t code to use 0 explicitly (or implicitly, e.g. via Boolean coercion).";
+ print "\t Having an enum entry for zero both makes the debugger print the name";
+ print "\t for error_t-typed zero values, and prevents the compiler from";
+ print "\t issuing warnings about 'case 0:' in a switch on an error_t-typed";
+ print "\t value. */";
+ print "\tESUCCESS = 0,"
+ print "";
+ maxerrno = 0;
+ in_mach_errors = "";
+ in_math = 0;
+ edom = erange = "";
+ print "#undef EDOM\n#undef ERANGE";
+ lno = 0;
+ }
+
+/^@errno\{/ \
+ {
+ etext = "";
+ for (i = 3; i <= NF; ++i)
+ etext = etext " " $i;
+ etext = substr(etext, 1, length(etext)-1)
+
+ e = substr($1, 8, length($1)-8)
+ if (e == "EWOULDBLOCK")
+ {
+ lines[lno++]="#define EWOULDBLOCK EAGAIN /* Operation would block */";
+ next;
+ }
+
+ errno = substr($2, 1, length($2)-1) + 0
+ if (errno == 0)
+ next;
+ if (errno > maxerrno) maxerrno = errno;
+ 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;
+ comma[lno] = 1;
+ lines[lno++] = sprintf("\t%-16s= _HURD_ERRNO (%d)", e, errno);
+ lines[lno++] = x;
+ next;
+ }
+
+NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \
+ {
+ in_mach_errors = FILENAME;
+ lines[lno++] = "\n\t/* Errors from <mach/message.h>. */";
+ }
+NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \
+ {
+ in_mach_errors = FILENAME;
+ lines[lno++] = "\n\t/* Errors from <mach/kern_return.h>. */";
+ next;
+ }
+
+in_mach_errors != "" && $2 == "MACH_IPC_COMPAT" \
+ {
+ in_mach_errors = "";
+ }
+
+in_mach_errors == FILENAME && NF == 3 && $1 == "#define" \
+ {
+ comma[lno] = 1;
+ lines[lno++] = sprintf("\t%-32s= %s", "E" $2, $3);
+ }
+
+$1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \
+ {
+ in_mig_errors = 1;
+ lines[lno++] = "\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" && /D_/ && NF > 3) \
+ {
+ comment = "";
+ for (i = 4; i <= NF; ++i)
+ comment = comment " " $i;
+ comma[lno] = 1;
+ lines[lno++] = sprintf("%-32s", sprintf ("\t%-24s= %s", "E" $2, $3)) comment;
+ }
+
+$1 == "#define" && $2 == "D_SUCCESS" \
+ {
+ in_device_errors = 1;
+ lines[lno++] = "\n\t/* Errors from <device/device_types.h>. */";
+ next;
+ }
+in_device_errors && $1 == "#endif" \
+ {
+ in_device_errors = 0;
+ }
+
+
+END \
+ {
+ for (i = 0; i < lno - 1; ++i)
+ printf "%s%s\n", lines[i], (comma[i] ? "," : "");
+ print lines[i];
+ 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 "#define __error_t_defined\t1"
+ print "#endif";
+ print "";
+ print "\
+/* Return the current thread's location for `errno'.\n\
+ The syntax of this function allows redeclarations like `int errno'. */\n\
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));\n\
+\n\
+#define errno (*__errno_location ())\n\
+";
+ 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/REORG.TODO/sysdeps/mach/hurd/euidaccess.c b/REORG.TODO/sysdeps/mach/hurd/euidaccess.c
new file mode 100644
index 0000000000..d2926d5dae
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/euidaccess.c
@@ -0,0 +1,57 @@
+/* Test for access to FILE using effective UID and GID. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+int
+__euidaccess (const char *file, int type)
+{
+ error_t err;
+ file_t port;
+ int allowed, flags;
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (port, &allowed);
+ __mach_port_deallocate (__mach_task_self (), port);
+ 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 (__euidaccess, euidaccess)
+weak_alias (__euidaccess, eaccess)
diff --git a/REORG.TODO/sysdeps/mach/hurd/execve.c b/REORG.TODO/sysdeps/mach/hurd/execve.c
new file mode 100644
index 0000000000..08d9322354
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/execve.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__execve (const char *file_name, char *const argv[], 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/REORG.TODO/sysdeps/mach/hurd/faccessat.c b/REORG.TODO/sysdeps/mach/hurd/faccessat.c
new file mode 100644
index 0000000000..d55bc5027b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/faccessat.c
@@ -0,0 +1,65 @@
+/* Test for access to file, relative to open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+faccessat (int fd, const char *file, int type, int flag)
+{
+ error_t err;
+ file_t port;
+ int allowed, flags;
+
+ if ((flag & AT_EACCESS) == 0)
+ {
+ if (fd == AT_FDCWD || file[0] == '/')
+ return __access (file, type);
+ __set_errno (ENOTSUP); /* XXX later */
+ return -1;
+ }
+
+ port = __file_name_lookup_at (fd, flag &~ AT_EACCESS, file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ /* Find out what types of access we are allowed to this file. */
+ err = __file_check_access (port, &allowed);
+ __mach_port_deallocate (__mach_task_self (), port);
+ 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;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fchdir.c b/REORG.TODO/sysdeps/mach/hurd/fchdir.c
new file mode 100644
index 0000000000..6e6063f853
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchdir.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/fd.h>
+
+/* Change the current directory to FD. */
+
+int
+__fchdir (int fd)
+{
+ return _hurd_change_directory_port_from_fd (&_hurd_ports[INIT_PORT_CWDIR],
+ fd);
+}
+weak_alias (__fchdir, fchdir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fchflags.c b/REORG.TODO/sysdeps/mach/hurd/fchflags.c
new file mode 100644
index 0000000000..bf565030c4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchflags.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the flags of the file referenced by FD to FLAGS. */
+
+/* XXX should be __fchflags? */
+int
+fchflags (int fd, unsigned long 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/REORG.TODO/sysdeps/mach/hurd/fchmod.c b/REORG.TODO/sysdeps/mach/hurd/fchmod.c
new file mode 100644
index 0000000000..767ad4e5a8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchmod.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the permissions of the file referenced by FD to MODE. */
+int
+__fchmod (int fd, 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/REORG.TODO/sysdeps/mach/hurd/fchmodat.c b/REORG.TODO/sysdeps/mach/hurd/fchmodat.c
new file mode 100644
index 0000000000..8581127a7e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchmodat.c
@@ -0,0 +1,39 @@
+/* Change the protections of file relative to open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+fchmodat (int fd, const char *file, mode_t mode, int flag)
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, 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;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fchown.c b/REORG.TODO/sysdeps/mach/hurd/fchown.c
new file mode 100644
index 0000000000..cd4738bdc1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchown.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__fchown (int fd, uid_t owner, 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/REORG.TODO/sysdeps/mach/hurd/fchownat.c b/REORG.TODO/sysdeps/mach/hurd/fchownat.c
new file mode 100644
index 0000000000..bdfb468f50
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fchownat.c
@@ -0,0 +1,40 @@
+/* Change owner and group of a file relative to open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the owner and group of FILE. */
+int
+fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
+{
+ error_t err;
+ file_t port = __file_name_lookup_at (fd, flag, 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;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fcntl.c b/REORG.TODO/sysdeps/mach/hurd/fcntl.c
new file mode 100644
index 0000000000..174e408edc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fcntl.c
@@ -0,0 +1,212 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <stdarg.h>
+#include <sys/file.h> /* XXX for LOCK_* */
+
+/* Perform file control operations on FD. */
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ 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. */
+ case F_DUPFD_CLOEXEC:
+ {
+ 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. */
+
+ if (cmd == F_DUPFD_CLOEXEC)
+ flags |= FD_CLOEXEC;
+ else
+ /* Duplication clears the FD_CLOEXEC flag. */
+ flags &= ~FD_CLOEXEC;
+
+ /* 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);
+ new->flags = flags;
+ _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:
+ {
+ /* XXX
+ We need new RPCs to support POSIX.1 fcntl file locking!!
+ For the time being we support the whole-file case only,
+ with all kinds of WRONG WRONG WRONG semantics,
+ by using flock. This is definitely the Wrong Thing,
+ but it might be better than nothing (?). */
+ struct flock *fl = va_arg (ap, struct flock *);
+ va_end (ap);
+ switch (cmd)
+ {
+ case F_GETLK:
+ errno = ENOSYS;
+ return -1;
+ case F_SETLK:
+ cmd = LOCK_NB;
+ break;
+ default:
+ cmd = 0;
+ break;
+ }
+ switch (fl->l_type)
+ {
+ case F_RDLCK: cmd |= LOCK_SH; break;
+ case F_WRLCK: cmd |= LOCK_EX; break;
+ case F_UNLCK: cmd |= LOCK_UN; break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ switch (fl->l_whence)
+ {
+ case SEEK_SET:
+ if (fl->l_start == 0 && fl->l_len == 0) /* Whole file request. */
+ break;
+ /* It seems to be common for applications to lock the first
+ byte of the file when they are really doing whole-file locking.
+ So, since it's so wrong already, might as well do that too. */
+ if (fl->l_start == 0 && fl->l_len == 1)
+ break;
+ /* FALLTHROUGH */
+ case SEEK_CUR:
+ case SEEK_END:
+ errno = ENOTSUP;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return __flock (fd, cmd);
+ }
+
+ 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;
+ break;
+
+ 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;
+}
+libc_hidden_def (__libc_fcntl)
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fdatasync.c b/REORG.TODO/sysdeps/mach/hurd/fdatasync.c
new file mode 100644
index 0000000000..379f8b6f9e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fdatasync.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Make all changes done to FD's file data actually appear on disk. */
+int
+fdatasync (int fd)
+{
+ error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1, 1));
+ if (err)
+ {
+ if (err == EOPNOTSUPP)
+ /* If the file descriptor does not support sync, return EINVAL
+ as POSIX specifies. */
+ err = EINVAL;
+ return __hurd_dfail (fd, err);
+ }
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fdopendir.c b/REORG.TODO/sysdeps/mach/hurd/fdopendir.c
new file mode 100644
index 0000000000..676182fe9f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fdopendir.c
@@ -0,0 +1,57 @@
+/* Open a directory stream from a file descriptor. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+
+DIR *_hurd_fd_opendir (struct hurd_fd *d); /* opendir.c */
+
+/* Open a directory stream on FD. */
+DIR *
+__fdopendir (int fd)
+{
+ struct hurd_fd *d = _hurd_fd_get (fd);
+
+ if (d == NULL)
+ {
+ errno = EBADF;
+ return NULL;
+ }
+
+ /* Ensure that it's a directory. */
+ error_t err = HURD_FD_PORT_USE
+ (d, ({
+ file_t dir = __file_name_lookup_under (port, "/",
+ O_DIRECTORY | O_NOTRANS, 0);;
+ if (dir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), dir);
+ dir != MACH_PORT_NULL ? 0 : errno;
+ }));
+
+ if (err)
+ {
+ errno = err;
+ return NULL;
+ }
+
+ return _hurd_fd_opendir (d);
+}
+weak_alias (__fdopendir, fdopendir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fexecve.c b/REORG.TODO/sysdeps/mach/hurd/fexecve.c
new file mode 100644
index 0000000000..93a8f36e97
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fexecve.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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/REORG.TODO/sysdeps/mach/hurd/fgetxattr.c b/REORG.TODO/sysdeps/mach/hurd/fgetxattr.c
new file mode 100644
index 0000000000..b0c051285a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fgetxattr.c
@@ -0,0 +1,33 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+fgetxattr (int fd, const char *name, void *value, size_t size)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_get (port, name, value, &size));
+
+ return err ? __hurd_dfail (fd, err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/flistxattr.c b/REORG.TODO/sysdeps/mach/hurd/flistxattr.c
new file mode 100644
index 0000000000..58a3514dcc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/flistxattr.c
@@ -0,0 +1,33 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+flistxattr (int fd, char *list, size_t size)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_list (port, list, &size));
+
+ return err ? __hurd_dfail (fd, err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/flock.c b/REORG.TODO/sysdeps/mach/hurd/flock.c
new file mode 100644
index 0000000000..4aed048eb0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/flock.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__flock (int fd, 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/REORG.TODO/sysdeps/mach/hurd/fork.c b/REORG.TODO/sysdeps/mach/hurd/fork.c
new file mode 100644
index 0000000000..582273ee14
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fork.c
@@ -0,0 +1,733 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 */
+#include <tls.h>
+#include <malloc/malloc-internal.h>
+
+#undef __fork
+
+
+/* Things that want to be locked while forking. */
+symbol_set_declare (_hurd_fork_locks)
+
+
+/* Application callbacks registered through pthread_atfork. */
+DEFINE_HOOK (_hurd_atfork_prepare_hook, (void));
+DEFINE_HOOK (_hurd_atfork_child_hook, (void));
+DEFINE_HOOK (_hurd_atfork_parent_hook, (void));
+
+/* 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;
+
+ RUN_HOOK (_hurd_atfork_prepare_hook, ());
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->critical_section_lock);
+
+#undef LOSE
+#define LOSE do { assert_perror (err); goto lose; } while (0) /* 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);
+
+ /* Acquire malloc locks. This needs to come last because fork
+ handlers may use malloc, and the libio list lock has an
+ indirect malloc dependency as well (via the getdelim
+ function). */
+ call_function_static_weak (__malloc_fork_lock_parent);
+ _hurd_malloc_fork_prepare ();
+
+ 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;
+
+
+ /* Keep our SS locked while stopping other threads, so they don't get a
+ chance to have it locked in the copied space. */
+ __spin_lock (&ss->lock);
+ /* Stop all other threads while copying the address space,
+ so nothing changes. */
+ err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
+ __spin_unlock (&ss->lock);
+ 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 (),
+#ifdef KERN_INVALID_LEDGER
+ NULL, 0, /* OSF Mach */
+#endif
+ 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,
+ &notify_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 =
+#ifdef TASK_EXCEPTION_PORT
+ __task_set_special_port (newtask,
+ TASK_EXCEPTION_PORT,
+ port)
+#elif defined (EXC_MASK_ALL)
+ __task_set_exception_ports
+ (newtask, EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
+ | EXC_MASK_MACH_SYSCALL
+ | EXC_MASK_RPC_ALERT),
+ port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
+#else
+# error task_set_exception_port?
+#endif
+ )
+ 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 = 0, *record_refs = NULL;
+ mach_port_t insert;
+ mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
+ if (portnames[i] == newtask || portnames[i] == newproc)
+ /* Skip the name we use for the child's task or proc ports. */
+ 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)
+ {
+ /* Use the proc server port for the new task. */
+ insert = newproc;
+ insert_type = MACH_MSG_TYPE_COPY_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, insert_type);
+ 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;
+ if (thread_refs > 1 &&
+ (err = __mach_port_mod_refs (newtask, ss->thread,
+ MACH_PORT_RIGHT_SEND,
+ thread_refs - 1)))
+ 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;
+#ifdef STACK_GROWTH_UP
+#define THREADVAR_SPACE (__hurd_threadvar_max \
+ * sizeof *__hurd_sightread_variables)
+ if (__hurd_sigthread_stack_base == 0)
+ {
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset + THREADVAR_SPACE;
+ }
+ else
+ state.SP = __hurd_sigthread_stack_base;
+#else
+ if (__hurd_sigthread_stack_end == 0)
+ {
+ /* The signal thread has a normal stack assigned by cthreads.
+ The threadvar_stack variables conveniently tell us how
+ to get to the highest address in the stack, just below
+ the per-thread variables. */
+ state.SP &= __hurd_threadvar_stack_mask;
+ state.SP += __hurd_threadvar_stack_offset;
+ }
+ 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);
+
+ /* Do special thread setup for TLS if needed. */
+ if (err = _hurd_tls_fork (thread, &state))
+ LOSE;
+
+ 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));
+ }
+
+ /* Release malloc locks. */
+ _hurd_malloc_fork_parent ();
+ call_function_static_weak (__malloc_fork_unlock_parent);
+
+ /* 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 one of the (exactly) two threads in this new task, we
+ will take the task-global signals. */
+ _hurd_sigthread = ss->thread;
+
+ /* Claim our sigstate structure and unchain the rest: the
+ threads 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. Before we finish cleaning up,
+ we will reclaim the signal thread's sigstate structure (if
+ it had one). */
+ 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);
+
+ /* Release malloc locks. */
+ _hurd_malloc_fork_child ();
+ call_function_static_weak (__malloc_fork_unlock_child);
+
+ /* 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);
+
+ /* Reclaim the signal thread's sigstate structure and free the
+ other old sigstate structures. */
+ while (oldstates != NULL)
+ {
+ struct hurd_sigstate *next = oldstates->next;
+
+ if (oldstates->thread == _hurd_msgport_thread)
+ {
+ /* If we have a second signal state structure then we
+ must have been through here before--not good. */
+ assert (_hurd_sigstates->next == 0);
+ _hurd_sigstates->next = oldstates;
+ oldstates->next = 0;
+ }
+ else
+ 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);
+
+ if (!err)
+ {
+ if (pid != 0)
+ RUN_HOOK (_hurd_atfork_parent_hook, ());
+ else
+ RUN_HOOK (_hurd_atfork_child_hook, ());
+ }
+
+ return err ? __hurd_fail (err) : pid;
+}
+libc_hidden_def (__fork)
+
+weak_alias (__fork, fork)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fpathconf.c b/REORG.TODO/sysdeps/mach/hurd/fpathconf.c
new file mode 100644
index 0000000000..65f3ecb789
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fpathconf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get file-specific information about descriptor FD. */
+long int
+__fpathconf (int fd, int name)
+{
+ error_t err;
+ int value;
+
+ if (err = HURD_DPORT_USE (fd, __io_pathconf (port, name, &value)))
+ return __hurd_dfail (fd, err), -1L;
+
+ return value;
+}
+
+weak_alias (__fpathconf, fpathconf)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fremovexattr.c b/REORG.TODO/sysdeps/mach/hurd/fremovexattr.c
new file mode 100644
index 0000000000..052556dc21
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fremovexattr.c
@@ -0,0 +1,33 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+int
+fremovexattr (int fd, const char *name)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_remove (port, name));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fsetxattr.c b/REORG.TODO/sysdeps/mach/hurd/fsetxattr.c
new file mode 100644
index 0000000000..7d26b75bbd
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fsetxattr.c
@@ -0,0 +1,33 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <hurd/fd.h>
+
+ssize_t
+fsetxattr (int fd, const char *name, const void *value, size_t size, int flags)
+{
+ error_t err;
+
+ err = HURD_DPORT_USE (fd, _hurd_xattr_set (port, name, value, size, flags));
+
+ return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fstatfs.c b/REORG.TODO/sysdeps/mach/hurd/fstatfs.c
new file mode 100644
index 0000000000..be9f7da321
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fstatfs.c
@@ -0,0 +1,31 @@
+/* fstatfs -- Return information about the filesystem on which FD resides.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatfs (int fd, struct statfs *buf)
+{
+ struct statfs64 buf64;
+ return __fstatfs64 (fd, &buf64) ?: statfs64_conv (buf, &buf64);
+}
+
+weak_alias (__fstatfs, fstatfs)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fstatfs64.c b/REORG.TODO/sysdeps/mach/hurd/fstatfs64.c
new file mode 100644
index 0000000000..68ecd7ce70
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fstatfs64.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FD resides. */
+int
+__fstatfs64 (int fd, struct statfs64 *buf)
+{
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __file_statfs (port, buf)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+weak_alias (__fstatfs64, fstatfs64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fstatvfs.c b/REORG.TODO/sysdeps/mach/hurd/fstatvfs.c
new file mode 100644
index 0000000000..79f6b20288
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fstatvfs.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+fstatvfs (int fd, struct statvfs *buf)
+{
+ /* `struct statvfs' is in fact identical to `struct statfs' so we
+ can simply call fstatfs. */
+ return __fstatfs (fd, (struct statfs *)buf);
+}
+libc_hidden_def (fstatvfs)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fstatvfs64.c b/REORG.TODO/sysdeps/mach/hurd/fstatvfs64.c
new file mode 100644
index 0000000000..26692ae1a7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fstatvfs64.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+fstatvfs64 (int fd, struct statvfs64 *buf)
+{
+ /* `struct statvfs64' is in fact identical to `struct statfs64' so
+ we can simply call fstatfs64. */
+ return __fstatfs64 (fd, (struct statfs64 *)buf);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/fsync.c b/REORG.TODO/sysdeps/mach/hurd/fsync.c
new file mode 100644
index 0000000000..a96e2a460f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fsync.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Make all changes done to FD actually appear on disk. */
+int
+fsync (int fd)
+{
+ error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1, 0));
+ if (err)
+ {
+ if (err == EOPNOTSUPP)
+ /* If the file descriptor does not support sync, return EINVAL
+ as POSIX specifies. */
+ err = EINVAL;
+ return __hurd_dfail (fd, err);
+ }
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/ftruncate.c b/REORG.TODO/sysdeps/mach/hurd/ftruncate.c
new file mode 100644
index 0000000000..c24df25114
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ftruncate.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Truncate the file referenced by FD to LENGTH bytes. */
+int
+__ftruncate (int fd, __off_t length)
+{
+ error_t err;
+ if (err = HURD_DPORT_USE (fd, __file_set_size (port, length)))
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__ftruncate, ftruncate)
diff --git a/REORG.TODO/sysdeps/mach/hurd/ftruncate64.c b/REORG.TODO/sysdeps/mach/hurd/ftruncate64.c
new file mode 100644
index 0000000000..53c4f64afc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ftruncate64.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Truncate the file referenced by FD to LENGTH bytes. */
+int
+__ftruncate64 (int fd, off64_t length)
+{
+ error_t err;
+ if (err = HURD_DPORT_USE (fd, __file_set_size (port, length)))
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__ftruncate64, ftruncate64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/futimes.c b/REORG.TODO/sysdeps/mach/hurd/futimes.c
new file mode 100644
index 0000000000..6ea8d25aab
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/futimes.c
@@ -0,0 +1,50 @@
+/* futimes -- change access and modification times of open file. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the access time of FD to TVP[0] and
+ the modification time of FD to TVP[1]. */
+int
+__futimes (int fd, const struct timeval tvp[2])
+{
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
+ error_t err;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
+ }
+
+ err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt));
+ return err ? __hurd_dfail (fd, err) : 0;
+}
+weak_alias (__futimes, futimes)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fxstat.c b/REORG.TODO/sysdeps/mach/hurd/fxstat.c
new file mode 100644
index 0000000000..e534a054a1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fxstat.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __fxstat64 (vers, fd, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fxstat64.c b/REORG.TODO/sysdeps/mach/hurd/fxstat64.c
new file mode 100644
index 0000000000..6d5ffdf0e7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fxstat64.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef RTLD_STAT64 /* dl-fxstat64.c, but we don't want it. */
+
+#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
+__fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+ error_t err;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ if (err = HURD_DPORT_USE (fd, __io_stat (port, buf)))
+ return __hurd_dfail (fd, err);
+
+ return 0;
+}
+hidden_def (__fxstat64)
+
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/fxstatat.c b/REORG.TODO/sysdeps/mach/hurd/fxstatat.c
new file mode 100644
index 0000000000..a7810ea0a9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fxstatat.c
@@ -0,0 +1,32 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+int
+__fxstatat (int vers, int fd, const char *filename, struct stat *buf, int flag)
+{
+ struct stat64 buf64;
+ return (__fxstatat64 (vers, fd, filename, &buf64, flag)
+ ?: xstat64_conv (buf, &buf64));
+}
+libc_hidden_def (__fxstatat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/fxstatat64.c b/REORG.TODO/sysdeps/mach/hurd/fxstatat64.c
new file mode 100644
index 0000000000..385fa39ee2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/fxstatat64.c
@@ -0,0 +1,46 @@
+/* Get information about file named relative to open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.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
+__fxstatat64 (int vers, int fd, const char *filename, struct stat64 *buf,
+ int flag)
+{
+ error_t err;
+ io_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ port = __file_name_lookup_at (fd, flag, filename, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+
+ return __hurd_fail (err);
+}
+libc_hidden_def (__fxstatat64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getclktck.c b/REORG.TODO/sysdeps/mach/hurd/getclktck.c
new file mode 100644
index 0000000000..08b787a135
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getclktck.c
@@ -0,0 +1,36 @@
+/* Return run-time value of CLK_TCK for Hurd.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+/* Return frequency of `times'.
+ Since Mach reports CPU times in microseconds, we always use 1 million. */
+int
+__getclktck (void)
+{
+ return 1000000;
+}
+
+/* Before glibc 2.2, the Hurd actually did this differently, so we
+ need to keep a compatibility symbol. */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_1_1, GLIBC_2_2)
+compat_symbol (libc, __getclktck, __libc_clk_tck, GLIBC_2_1_1);
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/getcwd.c b/REORG.TODO/sysdeps/mach/hurd/getcwd.c
new file mode 100644
index 0000000000..9b371b041a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getcwd.c
@@ -0,0 +1,320 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 canonical absolute name of the given directory port, 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.
+ If our root directory cannot be reached, the result will not begin with
+ a slash to indicate that it is relative to some unknown root directory. */
+
+char *
+_hurd_canonicalize_directory_name_internal (file_t thisdir,
+ char *buf,
+ size_t size)
+{
+ error_t err;
+ mach_port_t rootid, thisid, rootdevid, thisdevid;
+ ino64_t rootino, thisino;
+ char *file_name;
+ char *file_namep;
+ file_t parent;
+ char *dirbuf = NULL;
+ unsigned int dirbufsize = 0;
+ const size_t orig_size = size;
+
+ inline void cleanup (void)
+ {
+ if (parent != thisdir)
+ __mach_port_deallocate (__mach_task_self (), parent);
+
+ __mach_port_deallocate (__mach_task_self (), thisid);
+ __mach_port_deallocate (__mach_task_self (), thisdevid);
+ __mach_port_deallocate (__mach_task_self (), rootid);
+
+ 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 get its identity. */
+
+ if (err = __USEPORT (CRDIR, __io_identity (port,
+ &rootid, &rootdevid, &rootino)))
+ return __hurd_fail (err), NULL;
+ __mach_port_deallocate (__mach_task_self (), rootdevid);
+
+ /* Stat the port to the directory of interest. */
+
+ if (err = __io_identity (thisdir, &thisid, &thisdevid, &thisino))
+ {
+ __mach_port_deallocate (__mach_task_self (), rootid);
+ return __hurd_fail (err), NULL;
+ }
+
+ parent = thisdir;
+ while (thisid != rootid)
+ {
+ /* PARENT is a port to the directory we are currently on;
+ THISID, THISDEV, and THISINO are its identity.
+ Look in its parent (..) for a file with the same file number. */
+
+ struct dirent64 *d;
+ mach_port_t dotid, dotdevid;
+ ino64_t dotino;
+ int mount_point;
+ file_t newp;
+ char *dirdata;
+ size_t dirdatasize;
+ int direntry, nentries;
+
+
+ /* Look at the parent directory. */
+ newp = __file_name_lookup_under (parent, "..", O_READ, 0);
+ if (newp == MACH_PORT_NULL)
+ goto lose;
+ if (parent != thisdir)
+ __mach_port_deallocate (__mach_task_self (), parent);
+ parent = newp;
+
+ /* Get this directory's identity and figure out if it's a mount
+ point. */
+ if (err = __io_identity (parent, &dotid, &dotdevid, &dotino))
+ goto errlose;
+ mount_point = dotdevid != thisdevid;
+
+ if (thisid == dotid)
+ {
+ /* `..' == `.' but it is not our root directory. */
+ __mach_port_deallocate (__mach_task_self (), dotid);
+ __mach_port_deallocate (__mach_task_self (), dotdevid);
+ break;
+ }
+
+ /* 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 dirent64 *) &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 = __file_name_lookup_under (parent, d->d_name,
+ O_NOLINK, 0);
+ file_t id, devid;
+ ino64_t fileno;
+ if (try == MACH_PORT_NULL)
+ goto lose;
+ err = __io_identity (try, &id, &devid, &fileno);
+ __mach_port_deallocate (__mach_task_self (), try);
+ if (err)
+ goto inner_errlose;
+ __mach_port_deallocate (__mach_task_self (), id);
+ __mach_port_deallocate (__mach_task_self (), devid);
+ if (id == thisid)
+ goto found;
+ }
+ }
+ }
+
+ if (err)
+ {
+ inner_errlose: /* Goto ERRLOSE: after cleaning up. */
+ __mach_port_deallocate (__mach_task_self (), dotid);
+ __mach_port_deallocate (__mach_task_self (), dotdevid);
+ goto errlose;
+ }
+ else if (nentries == 0)
+ {
+ /* We got to the end of the directory without finding anything!
+ We are in a directory that has been unlinked, or something is
+ broken. */
+ err = ENOENT;
+ goto inner_errlose;
+ }
+ else
+ found:
+ {
+ /* Prepend the directory name just discovered. */
+
+ if (file_namep - file_name < d->d_namlen + 1)
+ {
+ if (orig_size > 0)
+ {
+ 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 + size / 2];
+ file_name = buf;
+ /* Move current contents up to the end of the buffer.
+ This is guaranteed to be non-overlapping. */
+ memcpy (file_namep, file_namep - size / 2,
+ file_name + size - file_namep);
+ }
+ }
+ 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. */
+ __mach_port_deallocate (__mach_task_self (), thisid);
+ __mach_port_deallocate (__mach_task_self (), thisdevid);
+ thisid = dotid;
+ thisdevid = dotdevid;
+ 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 = '/';
+
+ if (thisid != rootid)
+ /* We did not get to our root directory. The returned name should
+ not begin with a slash. */
+ ++file_namep;
+
+ memmove (file_name, file_namep, file_name + size - file_namep);
+ cleanup ();
+ return file_name;
+
+ errlose:
+ /* Set errno. */
+ (void) __hurd_fail (err);
+ lose:
+ cleanup ();
+ return NULL;
+}
+
+char *
+__canonicalize_directory_name_internal (const char *thisdir, char *buf,
+ size_t size)
+{
+ char *result;
+ file_t port = __file_name_lookup (thisdir, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return NULL;
+ result = _hurd_canonicalize_directory_name_internal (port, buf, size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return result;
+}
+
+/* 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)
+{
+ char *cwd =
+ __USEPORT (CWDIR,
+ _hurd_canonicalize_directory_name_internal (port,
+ buf, size));
+ if (cwd && cwd[0] != '/')
+ {
+ /* `cwd' is an unknown root directory. */
+ if (buf == NULL)
+ free (cwd);
+ return __hurd_fail (EGRATUITOUS), NULL;
+ }
+ return cwd;
+}
+weak_alias (__getcwd, getcwd)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getdents.c b/REORG.TODO/sysdeps/mach/hurd/getdents.c
new file mode 100644
index 0000000000..d15be3b8f3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getdents.c
@@ -0,0 +1 @@
+#include <dirent/getdents.c>
diff --git a/REORG.TODO/sysdeps/mach/hurd/getdomain.c b/REORG.TODO/sysdeps/mach/hurd/getdomain.c
new file mode 100644
index 0000000000..b75e9ac5e3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getdomain.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Put the name of the current NIS 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
+getdomainname (char *name, size_t len)
+{
+ /* The NIS domain name is just the contents of the file /etc/nisdomain. */
+ ssize_t n = _hurd_get_host_config ("/etc/nisdomain", name, len);
+ return n < 0 ? -1 : 0;
+}
+libc_hidden_def (getdomainname)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getdtsz.c b/REORG.TODO/sysdeps/mach/hurd/getdtsz.c
new file mode 100644
index 0000000000..f44bdf9eac
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getdtsz.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/resource.h>
+
+/* Return the maximum number of file descriptors the current process
+ could possibly have (until it raises the resource limit). */
+int
+__getdtablesize (void)
+{
+ rlim_t limit;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ limit = _hurd_rlimits[RLIMIT_NOFILE].rlim_cur;
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ /* RLIM_INFINITY is not meaningful to our caller. -1 is a good choice
+ because `sysconf (_SC_OPEN_MAX)' calls us, and -1 from sysconf means
+ "no determinable limit". */
+ return limit == RLIM_INFINITY ? -1 : (int) limit;
+}
+
+weak_alias (__getdtablesize, getdtablesize)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getegid.c b/REORG.TODO/sysdeps/mach/hurd/getegid.c
new file mode 100644
index 0000000000..0a9a74a9b3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getegid.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective group ID of the calling process. */
+gid_t
+__getegid (void)
+{
+ 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/REORG.TODO/sysdeps/mach/hurd/geteuid.c b/REORG.TODO/sysdeps/mach/hurd/geteuid.c
new file mode 100644
index 0000000000..5f6deb7a92
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/geteuid.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective user ID of the calling process. */
+uid_t
+__geteuid (void)
+{
+ 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/REORG.TODO/sysdeps/mach/hurd/getgid.c b/REORG.TODO/sysdeps/mach/hurd/getgid.c
new file mode 100644
index 0000000000..557119e5a3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getgid.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real group ID of the calling process. */
+gid_t
+__getgid (void)
+{
+ 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/REORG.TODO/sysdeps/mach/hurd/getgroups.c b/REORG.TODO/sysdeps/mach/hurd/getgroups.c
new file mode 100644
index 0000000000..5141796101
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getgroups.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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;
+
+ if (n < 0)
+ return __hurd_fail (EINVAL);
+
+ 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)
+ return __hurd_fail (EINVAL);
+ 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/REORG.TODO/sysdeps/mach/hurd/gethostid.c b/REORG.TODO/sysdeps/mach/hurd/gethostid.c
new file mode 100644
index 0000000000..b263e9b1ad
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/gethostid.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include "hurdhost.h"
+
+/* Return the current machine's Internet number. */
+long int
+gethostid (void)
+{
+ /* The hostid is just the contents of the file /etc/hostid,
+ kept as text of hexadecimal digits. */
+ /* XXX this is supposed to come from the hardware serial number */
+ char buf[8];
+ ssize_t n = _hurd_get_host_config ("/etc/hostid", buf, sizeof buf);
+ if (n < 0)
+ return -1;
+ return strtol (buf, NULL, 16);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/gethostname.c b/REORG.TODO/sysdeps/mach/hurd/gethostname.c
new file mode 100644
index 0000000000..2d8befd533
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/gethostname.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include "hurdhost.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
+__gethostname (char *name, size_t len)
+{
+ /* The host name is just the contents of the file /etc/hostname. */
+ ssize_t n = _hurd_get_host_config ("/etc/hostname", name, len);
+ return n < 0 ? -1 : 0;
+}
+
+weak_alias (__gethostname, gethostname)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getitimer.c b/REORG.TODO/sysdeps/mach/hurd/getitimer.c
new file mode 100644
index 0000000000..23ff376743
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getitimer.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__getitimer (enum __itimer_which which, 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/REORG.TODO/sysdeps/mach/hurd/getlogin.c b/REORG.TODO/sysdeps/mach/hurd/getlogin.c
new file mode 100644
index 0000000000..47947202be
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getlogin.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 *
+getlogin (void)
+{
+ 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/REORG.TODO/sysdeps/mach/hurd/getlogin_r.c b/REORG.TODO/sysdeps/mach/hurd/getlogin_r.c
new file mode 100644
index 0000000000..e11e05b216
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getlogin_r.c
@@ -0,0 +1,48 @@
+/* Reentrant function to return the current login name. Hurd version.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <string.h>
+
+/* Return at most NAME_LEN characters of the login name of the user in NAME.
+ If it cannot be determined or some other error occurred, return the error
+ code. Otherwise return 0. */
+int
+__getlogin_r (char *name, size_t name_len)
+{
+ string_t login;
+ error_t err;
+
+ if (err = __USEPORT (PROC, __proc_getlogin (port, login)))
+ return errno = err;
+
+ size_t len = __strnlen (login, sizeof login - 1) + 1;
+ if (len > name_len)
+ {
+ errno = ERANGE;
+ return errno;
+ }
+
+ memcpy (name, login, len);
+ return 0;
+}
+libc_hidden_def (__getlogin_r)
+weak_alias (__getlogin_r, getlogin_r)
+libc_hidden_weak (getlogin_r)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getpeername.c b/REORG.TODO/sysdeps/mach/hurd/getpeername.c
new file mode 100644
index 0000000000..fed9c0163a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getpeername.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/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
+__getpeername (int fd, __SOCKADDR_ARG addrarg, socklen_t *len)
+{
+ error_t err;
+ mach_msg_type_number_t buflen = *len;
+ int type;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ char *buf = (char *) addr;
+ 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 (*len > buflen)
+ *len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ const sa_family_t family = type;
+ if (*len > offsetof (struct sockaddr, sa_family))
+ {
+ if (*len < (char *) (&addr->sa_family + 1) - (char *) addr)
+ memcpy (&addr->sa_family, &family,
+ *len - offsetof (struct sockaddr, sa_family));
+ else
+ addr->sa_family = family;
+ }
+
+ return 0;
+}
+
+weak_alias (__getpeername, getpeername)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getpgid.c b/REORG.TODO/sysdeps/mach/hurd/getpgid.c
new file mode 100644
index 0000000000..51d5ff581c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getpgid.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Get the process group ID of process PID. */
+int
+__getpgid (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;
+}
+libc_hidden_def (__getpgid)
+weak_alias (__getpgid, getpgid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getpid.c b/REORG.TODO/sysdeps/mach/hurd/getpid.c
new file mode 100644
index 0000000000..ac18d0a481
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getpid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Get the process ID of the calling process. */
+pid_t
+__getpid (void)
+{
+ /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */
+ return _hurd_pid;
+}
+libc_hidden_def (__getpid)
+weak_alias (__getpid, getpid)
+libc_hidden_weak (getpid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getppid.c b/REORG.TODO/sysdeps/mach/hurd/getppid.c
new file mode 100644
index 0000000000..982082a278
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getppid.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+
+
+/* Get the parent process ID of the calling process. */
+pid_t
+__getppid (void)
+{
+ /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */
+ return _hurd_ppid;
+}
+
+weak_alias (__getppid, getppid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getpriority.c b/REORG.TODO/sysdeps/mach/hurd/getpriority.c
new file mode 100644
index 0000000000..8bf464c1e1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getpriority.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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, id_t 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;
+ size_t pisize = sizeof pibuf / sizeof pibuf[0];
+
+ error_t getonepriority (pid_t pid, struct procinfo *pip)
+ {
+ if (pip)
+ onerr = 0;
+ else
+ {
+ int *oldpi = pi;
+ size_t oldpisize = pisize;
+ char *tw = 0;
+ size_t twsz = 0;
+ int flags = PI_FETCH_TASKINFO;
+ onerr = __USEPORT (PROC, __proc_getprocinfo (port, pid, &flags,
+ &pi, &pisize,
+ &tw, &twsz));
+ if (twsz)
+ __vm_deallocate (__mach_task_self (), (vm_address_t) tw, twsz);
+ 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;
+ }
+#ifdef TASK_SCHED_TIMESHARE_INFO
+ if (!onerr && pip->timeshare_base_info.base_priority > maxpri)
+ maxpri = pip->timeshare_base_info.base_priority;
+#else
+ if (!onerr && pip->taskinfo.base_priority > maxpri)
+ maxpri = pip->taskinfo.base_priority;
+#endif
+ return 0;
+ }
+
+ onerr = 0;
+ err = _hurd_priority_which_map (which, who,
+ getonepriority, PI_FETCH_TASKINFO);
+
+ 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);
+}
+libc_hidden_def (__getpriority)
+weak_alias (__getpriority, getpriority)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getresgid.c b/REORG.TODO/sysdeps/mach/hurd/getresgid.c
new file mode 100644
index 0000000000..2bd873f428
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getresgid.c
@@ -0,0 +1,61 @@
+/* getresgid -- fetch real group ID, effective group ID, and saved-set group ID
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Fetch the real group ID, effective group ID, and saved-set group ID,
+ of the calling process. */
+int
+__getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+ error_t err;
+ gid_t real, eff, saved;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (!err)
+ {
+ if (_hurd_id.aux.ngids < 1)
+ /* We do not even have a real GID. */
+ err = EGRATUITOUS;
+ else
+ {
+ real = _hurd_id.aux.gids[0];
+ eff = _hurd_id.gen.ngids < 1 ? real : _hurd_id.gen.gids[0];
+ saved = _hurd_id.aux.ngids < 2 ? real : _hurd_id.aux.gids[1];
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ *rgid = real;
+ *egid = eff;
+ *sgid = saved;
+ return 0;
+}
+libc_hidden_def (__getresgid)
+weak_alias (__getresgid, getresgid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getresuid.c b/REORG.TODO/sysdeps/mach/hurd/getresuid.c
new file mode 100644
index 0000000000..1abea2e18f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getresuid.c
@@ -0,0 +1,61 @@
+/* getresuid -- fetch real user ID, effective user ID, and saved-set user ID
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Fetch the real user ID, effective user ID, and saved-set user ID,
+ of the calling process. */
+int
+__getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
+{
+ error_t err;
+ uid_t real, eff, saved;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (!err)
+ {
+ if (_hurd_id.aux.nuids < 1)
+ /* We do not even have a real UID. */
+ err = EGRATUITOUS;
+ else
+ {
+ real = _hurd_id.aux.uids[0];
+ eff = _hurd_id.gen.nuids < 1 ? real : _hurd_id.gen.uids[0];
+ saved = _hurd_id.aux.nuids < 2 ? real : _hurd_id.aux.uids[1];
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ HURD_CRITICAL_END;
+
+ if (err)
+ return __hurd_fail (err);
+
+ *ruid = real;
+ *euid = eff;
+ *suid = saved;
+ return 0;
+}
+libc_hidden_def (__getresuid)
+weak_alias (__getresuid, getresuid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getrlimit.c b/REORG.TODO/sysdeps/mach/hurd/getrlimit.c
new file mode 100644
index 0000000000..9e28ca2127
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getrlimit.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)
+{
+ struct rlimit lim;
+
+ if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ lim = _hurd_rlimits[resource];
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ *rlimits = lim;
+
+ return 0;
+}
+libc_hidden_def (__getrlimit)
+weak_alias (__getrlimit, getrlimit)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getrusage.c b/REORG.TODO/sysdeps/mach/hurd/getrusage.c
new file mode 100644
index 0000000000..7849518f39
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getrusage.c
@@ -0,0 +1,91 @@
+/* getrusage -- Get resource usage information about processes. Hurd version.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+/* Return resource usage information on process indicated by WHO
+ and put it in *USAGE. Returns 0 for success, -1 for failure. */
+int
+__getrusage (enum __rusage_who who, struct rusage *usage)
+{
+ struct task_basic_info bi;
+ struct task_events_info ei;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ error_t err;
+
+ switch (who)
+ {
+ case RUSAGE_SELF:
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_EVENTS_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_EVENTS_INFO,
+ (task_info_t) &ei, &count);
+ if (err == KERN_INVALID_ARGUMENT) /* microkernel doesn't implement it */
+ memset (&ei, 0, sizeof ei);
+ else if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ time_value_add (&bi.user_time, &tti.user_time);
+ time_value_add (&bi.system_time, &tti.system_time);
+
+ memset (usage, 0, sizeof (struct rusage));
+
+ usage->ru_utime.tv_sec = bi.user_time.seconds;
+ usage->ru_utime.tv_usec = bi.user_time.microseconds;
+ usage->ru_stime.tv_sec = bi.system_time.seconds;
+ usage->ru_stime.tv_usec = bi.system_time.microseconds;
+
+ /* These statistics map only approximately. */
+ usage->ru_majflt = ei.pageins;
+ usage->ru_minflt = ei.faults - ei.pageins;
+ usage->ru_msgsnd = ei.messages_sent; /* Mach IPC, not SysV IPC */
+ usage->ru_msgrcv = ei.messages_received; /* Mach IPC, not SysV IPC */
+ break;
+
+ case RUSAGE_CHILDREN:
+ /* XXX Not implemented yet. However, zero out USAGE to be
+ consistent with the wait3 and wait4 functions. */
+ memset (usage, 0, sizeof (struct rusage));
+
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+weak_alias (__getrusage, getrusage)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getsid.c b/REORG.TODO/sysdeps/mach/hurd/getsid.c
new file mode 100644
index 0000000000..cf3e97830f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getsid.c
@@ -0,0 +1,38 @@
+/* getsid -- Return session ID of a process. Hurd version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+
+pid_t
+getsid (pid_t pid)
+{
+ error_t err;
+ pid_t sid;
+
+ if (pid == 0)
+ pid = _hurd_pid;
+
+ err = __USEPORT (PROC, __proc_getsid (port, pid, &sid));
+ if (err)
+ return (pid_t) __hurd_fail (err);
+ return sid;
+}
+libc_hidden_def (getsid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getsockname.c b/REORG.TODO/sysdeps/mach/hurd/getsockname.c
new file mode 100644
index 0000000000..3b7f71eb9e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getsockname.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Put the local address of FD into *ADDR and its length in *LEN. */
+int
+__getsockname (int fd, __SOCKADDR_ARG addrarg, socklen_t *len)
+{
+ error_t err;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+ 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 (*len > buflen)
+ *len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ addr->sa_family = type;
+
+ return 0;
+}
+
+weak_alias (__getsockname, getsockname)
diff --git a/REORG.TODO/sysdeps/mach/hurd/getsockopt.c b/REORG.TODO/sysdeps/mach/hurd/getsockopt.c
new file mode 100644
index 0000000000..9974b61ef5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getsockopt.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+
+/* XXX should be __getsockopt ? */
+int
+getsockopt (int fd,
+ int level,
+ int optname,
+ void *optval,
+ socklen_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 (*optlen > buflen)
+ *optlen = buflen;
+ if (buf != optval)
+ {
+ memcpy (optval, buf, *optlen);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/getuid.c b/REORG.TODO/sysdeps/mach/hurd/getuid.c
new file mode 100644
index 0000000000..ff95fd58b8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getuid.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real user ID of the calling process. */
+uid_t
+__getuid (void)
+{
+ 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/REORG.TODO/sysdeps/mach/hurd/getxattr.c b/REORG.TODO/sysdeps/mach/hurd/getxattr.c
new file mode 100644
index 0000000000..7a38088fe8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/getxattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+getxattr (const char *path, const char *name, void *value, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_get (port, name, value, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/group_member.c b/REORG.TODO/sysdeps/mach/hurd/group_member.c
new file mode 100644
index 0000000000..a0fc359fe6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/group_member.c
@@ -0,0 +1,54 @@
+/* `group_member' -- test if process is in a given group. Hurd version.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+int
+__group_member (gid_t gid)
+{
+ int member = 0;
+ error_t err;
+ void *crit;
+
+ crit = _hurd_critical_section_lock ();
+ __mutex_lock (&_hurd_id.lock);
+
+ err = _hurd_check_ids ();
+ if (! err)
+ {
+ size_t i;
+ for (i = 0; i < _hurd_id.gen.ngids; ++i)
+ if (_hurd_id.gen.gids[i] == gid)
+ {
+ member = 1;
+ break;
+ }
+ }
+
+ __mutex_unlock (&_hurd_id.lock);
+ _hurd_critical_section_unlock (crit);
+
+ if (err)
+ __hurd_fail (err);
+ return member;
+}
+
+weak_alias (__group_member, group_member)
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/Makefile b/REORG.TODO/sysdeps/mach/hurd/i386/Makefile
new file mode 100644
index 0000000000..5f988097c2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/Makefile
@@ -0,0 +1,8 @@
+ifeq ($(subdir),misc)
+sysdep_routines += ioperm
+sysdep_headers += sys/io.h
+endif
+
+ifeq ($(subdir),debug)
+gen-as-const-headers += signal-defines.sym
+endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/Versions b/REORG.TODO/sysdeps/mach/hurd/i386/Versions
new file mode 100644
index 0000000000..67e6d94204
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/Versions
@@ -0,0 +1,10 @@
+libc {
+ GLIBC_2.0 {
+ # Exception handling support functions from libgcc
+ __register_frame; __register_frame_table; __deregister_frame;
+ __frame_state_for; __register_frame_info_table;
+ }
+ GLIBC_2.2.6 {
+ ioperm;
+ }
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/____longjmp_chk.S b/REORG.TODO/sysdeps/mach/hurd/i386/____longjmp_chk.S
new file mode 100644
index 0000000000..ac28c94e13
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/____longjmp_chk.S
@@ -0,0 +1,114 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
+#include <asm-syntax.h>
+
+#include <signal-defines.h>
+/* #include <signal.h> */
+#define SS_ONSTACK 1
+
+
+ .section .rodata.str1.1,"aMS",@progbits,1
+ .type longjmp_msg,@object
+longjmp_msg:
+ .string "longjmp causes uninitialized stack frame"
+ .size longjmp_msg, .-longjmp_msg
+
+
+#ifdef PIC
+# define CALL_FAIL movl %ebx, %ecx; /* TODO: what's this mov good for? */ \
+ cfi_register(%ebx,%ecx); \
+ LOAD_PIC_REG (bx); \
+ leal longjmp_msg@GOTOFF(%ebx), %eax; \
+ call HIDDEN_JUMPTARGET(__fortify_fail)
+#else
+# define CALL_FAIL movl $longjmp_msg, %eax; \
+ call HIDDEN_JUMPTARGET(__fortify_fail)
+#endif
+
+
+ .text
+ENTRY (____longjmp_chk)
+ movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */
+
+ /* Save the return address now. */
+ movl (JB_PC*4)(%ecx), %edx
+ /* Get the stack pointer. */
+ movl (JB_SP*4)(%ecx), %edi
+ cfi_undefined(%edi)
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (%edx)
+ PTR_DEMANGLE (%edi)
+#endif
+
+ cmpl %edi, %esp
+ /* Jumping to a higher-address frame is always allowed. */
+ jbe .Lok
+
+ /* Passing here, we're either about to do something invalid, or we're
+ executing on an alternative signal stack. */
+
+ /* TODO: need locking? */
+ /* struct hurd_sigstate * _hurd_self_sigstate (void) */
+#ifdef PIC
+ call 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#endif
+ call JUMPTARGET(_hurd_self_sigstate)
+ /* TODO: %eax and %eax->sigaltstack are always valid? */
+
+ testl $SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_FLAGS__OFFSET)(%eax)
+ /* Fail if SS_ONSTACK is not set. */
+ jz .Lfail
+
+ movl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SP__OFFSET)(%eax), %ebx
+ addl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+ subl %edi, %ebx
+ cmpl (HURD_SIGSTATE__SIGALTSTACK__OFFSET + SIGALTSTACK__SS_SIZE__OFFSET)(%eax), %ebx
+ /* TODO: comment this calculation. */
+ jae .Lok
+
+.Lfail: CALL_FAIL
+
+.Lok: /* We add unwind information for the target here. */
+ cfi_def_cfa(%ecx, 0)
+ cfi_register(%eip, %edx)
+ cfi_register(%esp, %edi)
+ cfi_offset(%ebx, JB_BX*4)
+ cfi_offset(%esi, JB_SI*4)
+ cfi_offset(%edi, JB_DI*4)
+ cfi_offset(%ebp, JB_BP*4)
+
+ movl 8(%esp), %eax /* Second argument is return value. */
+ movl %edi, %esp
+
+ /* Restore registers. */
+ movl (JB_BX*4)(%ecx), %ebx
+ movl (JB_SI*4)(%ecx), %esi
+ movl (JB_DI*4)(%ecx), %edi
+ movl (JB_BP*4)(%ecx), %ebp
+ cfi_restore(%ebx)
+ cfi_restore(%esi)
+ cfi_restore(%edi)
+ cfi_restore(%ebp)
+
+ /* Jump to saved PC. */
+ jmp *%edx
+END (____longjmp_chk)
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/bits/sigcontext.h b/REORG.TODO/sysdeps/mach/hurd/i386/bits/sigcontext.h
new file mode 100644
index 0000000000..3d5a6736aa
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/bits/sigcontext.h
@@ -0,0 +1,121 @@
+/* Machine-dependent signal context structure for GNU Hurd. i386 version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+/* Signal handlers are actually called:
+ void handler (int sig, int code, struct sigcontext *scp); */
+
+#include <bits/types/__sigset_t.h>
+#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. */
+ };
+
+/* Traditional BSD names for some members. */
+#define sc_sp sc_uesp /* Stack pointer. */
+#define sc_fp sc_ebp /* Frame pointer. */
+#define sc_pc sc_eip /* Process counter. */
+#define sc_ps sc_efl
+
+
+/* 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 */
+
+#endif /* bits/sigcontext.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/c++-types.data b/REORG.TODO/sysdeps/mach/hurd/i386/c++-types.data
new file mode 100644
index 0000000000..4cde3ca667
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/c++-types.data
@@ -0,0 +1,67 @@
+blkcnt64_t:x
+blkcnt_t:l
+blksize_t:l
+caddr_t:Pc
+clockid_t:i
+clock_t:l
+daddr_t:i
+dev_t:j
+fd_mask:l
+fsblkcnt64_t:y
+fsblkcnt_t:m
+fsfilcnt64_t:y
+fsfilcnt_t:m
+fsid_t:y
+gid_t:j
+id_t:j
+ino64_t:y
+ino_t:m
+int16_t:s
+int32_t:i
+int64_t:x
+int8_t:a
+intptr_t:i
+key_t:i
+loff_t:x
+mode_t:j
+nlink_t:j
+off64_t:x
+off_t:l
+pid_t:i
+pthread_attr_t:14__pthread_attr
+pthread_barrier_t:17__pthread_barrier
+pthread_barrierattr_t:21__pthread_barrierattr
+pthread_cond_t:14__pthread_cond
+pthread_condattr_t:18__pthread_condattr
+pthread_key_t:i
+pthread_mutex_t:15__pthread_mutex
+pthread_mutexattr_t:19__pthread_mutexattr
+pthread_once_t:14__pthread_once
+pthread_rwlock_t:16__pthread_rwlock
+pthread_rwlockattr_t:20__pthread_rwlockattr
+pthread_spinlock_t:i
+pthread_t:i
+quad_t:x
+register_t:i
+rlim64_t:y
+rlim_t:m
+sigset_t:m
+size_t:j
+socklen_t:j
+ssize_t:i
+suseconds_t:l
+time_t:l
+u_char:h
+uid_t:j
+uint:j
+u_int:j
+u_int16_t:t
+u_int32_t:j
+u_int64_t:y
+u_int8_t:h
+ulong:m
+u_long:m
+u_quad_t:y
+useconds_t:j
+ushort:t
+u_short:t
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/dl-machine.h b/REORG.TODO/sysdeps/mach/hurd/i386/dl-machine.h
new file mode 100644
index 0000000000..40f2ff29d4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/dl-machine.h
@@ -0,0 +1,7 @@
+/* Dynamic linker magic for Hurd/i386.
+ This file just gets us a call to _dl_first_init inserted
+ into the asm in sysdeps/i386/dl-machine.h that contains
+ the initializer code. */
+
+#define RTLD_START_SPECIAL_INIT "call _dl_init_first@PLT; movl (%esp), %edx"
+#include_next "dl-machine.h"
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/exc2signal.c b/REORG.TODO/sysdeps/mach/hurd/i386/exc2signal.c
new file mode 100644
index 0000000000..a731da054c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/exc2signal.c
@@ -0,0 +1,165 @@
+/* Translate Mach exception codes into signal numbers. i386 version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 (struct hurd_signal_detail *detail, int *signo)
+{
+ detail->error = 0;
+
+ switch (detail->exc)
+ {
+ default:
+ *signo = SIGIOT;
+ detail->code = detail->exc;
+ break;
+
+ case EXC_BAD_ACCESS:
+ if (detail->exc_code == KERN_INVALID_ADDRESS
+ || detail->exc_code == KERN_PROTECTION_FAILURE
+ || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
+ *signo = SIGSEGV;
+ else
+ *signo = SIGBUS;
+ detail->code = detail->exc_subcode;
+ detail->error = detail->exc_code;
+ break;
+
+ case EXC_BAD_INSTRUCTION:
+ *signo = SIGILL;
+ if (detail->exc_code == EXC_I386_INVOP)
+ detail->code = ILL_INVOPR_FAULT;
+ else if (detail->exc_code == EXC_I386_STKFLT)
+ detail->code = ILL_STACK_FAULT;
+ else
+ detail->code = 0;
+ break;
+
+ case EXC_ARITHMETIC:
+ switch (detail->exc_code)
+ {
+ case EXC_I386_DIV: /* integer divide by zero */
+ *signo = SIGFPE;
+ detail->code = FPE_INTDIV_FAULT;
+ break;
+
+ case EXC_I386_INTO: /* integer overflow */
+ *signo = SIGFPE;
+ detail->code = 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;
+ detail->code = 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 (detail->exc_subcode & FPS_IE)
+ {
+ *signo = SIGILL;
+ detail->code = ILL_FPEOPR_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_DE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTDNR_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_ZE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTDIV_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_OE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTOVF_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_UE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTUND_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_PE)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_FLTINX_FAULT;
+ }
+ else
+ {
+ *signo = SIGFPE;
+ detail->code = 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;
+ detail->code = FPE_EMERR_FAULT;
+ break;
+ case EXC_I386_BOUND:
+ *signo = SIGFPE;
+ detail->code = FPE_EMBND_FAULT;
+ break;
+ }
+ break;
+
+ case EXC_EMULATION:
+ /* 3.0 doesn't give this one, why, I don't know. */
+ *signo = SIGEMT;
+ detail->code = 0;
+ break;
+
+ case EXC_SOFTWARE:
+ /* The only time we get this in Mach 3.0
+ is for an out of bounds trap. */
+ if (detail->exc_code == EXC_I386_BOUND)
+ {
+ *signo = SIGFPE;
+ detail->code = FPE_SUBRNG_FAULT;
+ }
+ else
+ {
+ *signo = SIGEMT;
+ detail->code = 0;
+ }
+ break;
+
+ case EXC_BREAKPOINT:
+ *signo = SIGTRAP;
+ if (detail->exc_code == EXC_I386_SGL)
+ detail->code = DBG_SINGLE_TRAP;
+ else if (detail->exc_code == EXC_I386_BPT)
+ detail->code = DBG_BRKPNT_FAULT;
+ else
+ detail->code = 0;
+ break;
+ }
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/init-first.c b/REORG.TODO/sysdeps/mach/hurd/i386/init-first.c
new file mode 100644
index 0000000000..6a6a694719
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/init-first.c
@@ -0,0 +1,410 @@
+/* Initialization code run first thing by the ELF startup code. For i386/Hurd.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <ctype.h>
+#include <hurd.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sysdep.h>
+#include <set-hooks.h>
+#include "hurdstartup.h"
+#include "hurdmalloc.h" /* XXX */
+#include "../locale/localeinfo.h"
+
+#include <ldsodefs.h>
+#include <fpu_control.h>
+
+extern void __mach_init (void);
+extern void __init_misc (int, char **, char **);
+extern void __libc_global_ctors (void);
+
+unsigned int __hurd_threadvar_max;
+unsigned long int __hurd_threadvar_stack_offset;
+unsigned long int __hurd_threadvar_stack_mask;
+
+#ifndef SHARED
+int __libc_enable_secure;
+#endif
+int __libc_multiple_libcs attribute_hidden = 1;
+
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+extern char **_dl_argv;
+
+extern void *(*_cthread_init_routine) (void) __attribute__ ((weak));
+void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
+
+/* 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));
+
+
+/* We call this once the Hurd magic is all set up and we are ready to be a
+ Posixoid program. This does the same things the generic version does. */
+static void
+posixland_init (int argc, char **argv, char **envp)
+{
+ __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
+
+ /* Make sure we don't initialize twice. */
+ if (!__libc_multiple_libcs)
+ {
+ /* Set the FPU control word to the proper default value. */
+ __setfpucw (__fpu_control);
+ }
+ else
+ {
+ /* Initialize data structures so the additional libc can do RPCs. */
+ __mach_init ();
+ }
+
+ /* Save the command-line arguments. */
+ __libc_argc = argc;
+ __libc_argv = argv;
+ __environ = envp;
+
+#ifndef SHARED
+ _dl_non_dynamic_init ();
+#endif
+ __init_misc (argc, argv, envp);
+
+ /* Initialize ctype data. */
+ __ctype_init ();
+
+#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
+ __libc_global_ctors ();
+#endif
+}
+
+
+static void
+init1 (int argc, char *arg0, ...)
+{
+ char **argv = &arg0;
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* If we are the bootstrap task started by the kernel,
+ then after the environment pointers there is no Hurd
+ data block; the argument strings start there. */
+ if ((void *) d == argv[0])
+ {
+#ifndef SHARED
+ /* With a new enough linker (binutils-2.23 or better),
+ the magic __ehdr_start symbol will be available and
+ __libc_start_main will have done this that way already. */
+ if (_dl_phdr == NULL)
+ {
+ /* We may need to see our own phdrs, e.g. for TLS setup.
+ Try the usual kludge to find the headers without help from
+ the exec server. */
+ extern const void __executable_start;
+ const ElfW(Ehdr) *const ehdr = &__executable_start;
+ _dl_phdr = (const void *) ehdr + ehdr->e_phoff;
+ _dl_phnum = ehdr->e_phnum;
+ assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+ }
+#endif
+ return;
+ }
+
+#ifndef SHARED
+ __libc_enable_secure = d->flags & EXEC_SECURE;
+
+ _dl_phdr = (ElfW(Phdr) *) d->phdr;
+ _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
+ assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
+#endif
+
+ _hurd_init_dtable = d->dtable;
+ _hurd_init_dtablesize = d->dtablesize;
+
+ {
+ /* 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 (d->stack_size != 0 && (newsp < d->stack_base ||
+ newsp - d->stack_base > d->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 (), d->stack_base, d->stack_size);
+ }
+
+ if (d->portarray || d->intarray)
+ /* Initialize library data structures, start signal processing, etc. */
+ _hurd_init (d->flags, argv,
+ d->portarray, d->portarraysize,
+ d->intarray, d->intarraysize);
+}
+
+
+static inline void
+init (int *data)
+{
+ int argc = *data;
+ char **argv = (void *) (data + 1);
+ char **envp = &argv[argc + 1];
+ struct hurd_startup_data *d;
+ unsigned long int threadvars[_HURD_THREADVAR_MAX];
+
+ /* Provide temporary storage for thread-specific variables on the
+ startup stack so the cthreads initialization code can use them
+ for malloc et al, or so we can use malloc below for the real
+ threadvars array. */
+ memset (threadvars, 0, sizeof threadvars);
+ threadvars[_HURD_THREADVAR_LOCALE] = (unsigned long int) &_nl_global_locale;
+ __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
+
+ /* Since the cthreads initialization code uses malloc, and the
+ malloc initialization code needs to get at the environment, make
+ sure we can find it. We'll need to do this again later on since
+ switching stacks changes the location where the environment is
+ stored. */
+ __environ = envp;
+
+ while (*envp)
+ ++envp;
+ d = (void *) ++envp;
+
+ /* 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;
+
+
+ /* After possibly switching stacks, call `init1' (above) with the user
+ code as the return address, and the argument data immediately above
+ that on the stack. */
+
+ if (&_cthread_init_routine && _cthread_init_routine)
+ {
+ /* Initialize cthreads, which will allocate us a new stack to run on. */
+ int *newsp = (*_cthread_init_routine) ();
+ struct hurd_startup_data *od;
+
+ void switch_stacks (void);
+
+ __libc_stack_end = newsp;
+
+ /* Copy per-thread variables from that temporary
+ area onto the new cthread stack. */
+ memcpy (__hurd_threadvar_location_from_sp (0, newsp),
+ threadvars, sizeof threadvars);
+
+ /* Copy the argdata from the old stack to the new one. */
+ newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
+ (char *) d - (char *) data);
+
+#ifdef SHARED
+ /* And readjust the dynamic linker's idea of where the argument
+ vector lives. */
+ assert (_dl_argv == argv);
+ _dl_argv = (void *) (newsp + 1);
+#endif
+
+ /* Set up the Hurd startup data block immediately following
+ the argument and environment pointers on the new stack. */
+ od = ((void *) newsp + ((char *) d - (char *) data));
+ if ((void *) argv[0] == d)
+ /* We were started up by the kernel with arguments on the stack.
+ There is no Hurd startup data, so zero the block. */
+ memset (od, 0, sizeof *od);
+ else
+ /* Copy the Hurd startup data block to the new stack. */
+ *od = *d;
+
+ /* Push the user code address on the top of the new stack. It will
+ be the return address for `init1'; we will jump there with NEWSP
+ as the stack pointer. */
+ /* The following expression would typically be written as
+ ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't
+ recognize that this read operation may alias the following write
+ operation, and thus is free to reorder the two, clobbering the
+ original return address. */
+ *--newsp = *((int *) __builtin_frame_address (0) + 1);
+ /* GCC 4.4.6 also wants us to force loading *NEWSP already here. */
+ asm volatile ("# %0" : : "X" (*newsp));
+ *((void **) __builtin_frame_address (0) + 1) = &switch_stacks;
+ /* Force NEWSP into %eax and &init1 into %ecx, which are not restored
+ by function return. */
+ asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1));
+ }
+ else
+ {
+ /* 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 *array;
+ unsigned int i;
+ int usercode;
+
+ void call_init1 (void);
+
+ array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+ if (array == NULL)
+ __libc_fatal ("Can't allocate single-threaded thread variables.");
+
+ /* Copy per-thread variables from the temporary array into the
+ newly malloc'd space. */
+ memcpy (array, threadvars, sizeof threadvars);
+ __hurd_threadvar_stack_offset = (unsigned long int) array;
+ for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
+ array[i] = 0;
+
+ /* The argument data is just above the stack frame we will unwind by
+ returning. Mutate our own return address to run the code below. */
+ /* The following expression would typically be written as
+ ``__builtin_return_address (0)''. But, for example, GCC 4.4.6 doesn't
+ recognize that this read operation may alias the following write
+ operation, and thus is free to reorder the two, clobbering the
+ original return address. */
+ usercode = *((int *) __builtin_frame_address (0) + 1);
+ /* GCC 4.4.6 also wants us to force loading USERCODE already here. */
+ asm volatile ("# %0" : : "X" (usercode));
+ *((void **) __builtin_frame_address (0) + 1) = &call_init1;
+ /* Force USERCODE into %eax and &init1 into %ecx, which are not
+ restored by function return. */
+ asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1));
+ }
+}
+
+/* These bits of inline assembler used to be located inside `init'.
+ However they were optimized away by gcc 2.95. */
+
+/* The return address of `init' above, was redirected to here, so at
+ this point our stack is unwound and callers' registers restored.
+ Only %ecx and %eax are call-clobbered and thus still have the
+ values we set just above. Fetch from there the new stack pointer
+ we will run on, and jmp to the run-time address of `init1'; when it
+ returns, it will run the user code with the argument data at the
+ top of the stack. */
+asm ("switch_stacks:\n"
+ " movl %eax, %esp\n"
+ " jmp *%ecx");
+
+/* As in the stack-switching case, at this point our stack is unwound
+ and callers' registers restored, and only %ecx and %eax communicate
+ values from the lines above. In this case we have stashed in %eax
+ the user code return address. Push it on the top of the stack so
+ it acts as init1's return address, and then jump there. */
+asm ("call_init1:\n"
+ " push %eax\n"
+ " jmp *%ecx\n");
+
+
+/* Do the first essential initializations that must precede all else. */
+static inline void
+first_init (void)
+{
+ /* Initialize data structures so we can do RPCs. */
+ __mach_init ();
+
+ RUN_HOOK (_hurd_preinit_hook, ());
+}
+
+#ifdef SHARED
+/* This function is called specially by the dynamic linker to do early
+ initialization of the shared C library before normal initializers
+ expecting a Posixoid environment can run. It gets called with the
+ stack set up just as the user will see it, so it can switch stacks. */
+
+void
+_dl_init_first (int argc, ...)
+{
+ first_init ();
+
+ /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets confused. */
+ init (&argc);
+}
+#endif
+
+
+#ifdef SHARED
+/* The regular posixland initialization is what goes into libc's
+ normal initializer. */
+/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
+ pointer in the dynamic section based solely on that. It is convention
+ for this function to be in the `.init' section, but the symbol name is
+ the only thing that really matters!! */
+strong_alias (posixland_init, _init);
+
+void
+__libc_init_first (int argc, char **argv, char **envp)
+{
+ /* Everything was done in the shared library initializer, _init. */
+}
+#else
+strong_alias (posixland_init, __libc_init_first);
+
+
+/* XXX This is all a crock and I am not happy with it.
+ This poorly-named function is called by static-start.S,
+ which should not exist at all. */
+void
+_hurd_stack_setup (void)
+{
+ intptr_t caller = (intptr_t) __builtin_return_address (0);
+
+ void doinit (intptr_t *data)
+ {
+ /* This function gets called with the argument data at TOS. */
+ void doinit1 (int argc, ...)
+ {
+ /* If we use ``__builtin_frame_address (0) + 2'' here, GCC gets
+ confused. */
+ init ((int *) &argc);
+ }
+
+ /* Push the user return address after the argument data, and then
+ jump to `doinit1' (above), so it is as if __libc_init_first's
+ caller had called `doinit1' with the argument data already on the
+ stack. */
+ *--data = caller;
+ asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack. */
+ "movl $0, %%ebp\n" /* Clear outermost frame pointer. */
+ "jmp *%1" : : "r" (data), "r" (&doinit1) : "sp");
+ /* NOTREACHED */
+ }
+
+ first_init ();
+
+ _hurd_startup ((void **) __builtin_frame_address (0) + 2, &doinit);
+}
+#endif
+
+
+/* This function is defined here so that if this file ever gets into
+ ld.so we will get a link error. Having this file silently included
+ in ld.so causes disaster, because the _init definition above will
+ cause ld.so to gain an init function, which is not a cool thing. */
+
+void
+_dl_start (void)
+{
+ abort ();
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/intr-msg.h b/REORG.TODO/sysdeps/mach/hurd/i386/intr-msg.h
new file mode 100644
index 0000000000..43cd79bc28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/intr-msg.h
@@ -0,0 +1,112 @@
+/* Machine-dependent details of interruptible RPC messaging. i386 version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+
+/* Note that we must mark OPTION and TIMEOUT as outputs of this operation,
+ to indicate that the signal thread might mutate them as part
+ of sending us to a signal handler. */
+#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
+({ \
+ error_t err; \
+ asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
+ ".globl _hurd_intr_rpc_msg_in_trap\n" \
+ ".globl _hurd_intr_rpc_msg_cx_sp\n" \
+ ".globl _hurd_intr_rpc_msg_sp_restored\n" \
+ " movl %%esp, %%ecx\n" \
+ " leal %3, %%esp\n" \
+ "_hurd_intr_rpc_msg_cx_sp: movl $-25, %%eax\n" \
+ "_hurd_intr_rpc_msg_do_trap: lcall $7, $0 # status in %0\n" \
+ "_hurd_intr_rpc_msg_in_trap: movl %%ecx, %%esp\n" \
+ "_hurd_intr_rpc_msg_sp_restored:" \
+ : "=a" (err), "+m" (option), "+m" (timeout) \
+ : "m" ((&msg)[-1]) \
+ : "ecx"); \
+ err; \
+})
+
+
+static void inline
+INTR_MSG_BACK_OUT (struct i386_thread_state *state)
+{
+ extern const void _hurd_intr_rpc_msg_cx_sp;
+ if (state->eip >= (natural_t) &_hurd_intr_rpc_msg_cx_sp)
+ state->uesp = state->ecx;
+ else
+ state->ecx = state->uesp;
+}
+
+#include "hurdfault.h"
+
+/* This cannot be an inline function because it calls setjmp. */
+#define SYSCALL_EXAMINE(state, callno) \
+({ \
+ struct { unsigned int c[2]; } *p = (void *) ((state)->eip - 7); \
+ int result; \
+ if (_hurdsig_catch_memory_fault (p)) \
+ return 0; \
+ if (result = p->c[0] == 0x0000009a && (p->c[1] & 0x00ffffff) == 0x00000700) \
+ /* The PC is just after an `lcall $7,$0' instruction. \
+ This is a system call in progress; %eax holds the call number. */ \
+ *(callno) = (state)->eax; \
+ _hurdsig_end_catch_fault (); \
+ result; \
+})
+
+
+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;
+ };
+
+
+/* This cannot be an inline function because it calls setjmp. */
+#define MSG_EXAMINE(state, msgid, rcvname, send_name, opt, tmout) \
+({ \
+ const struct mach_msg_trap_args *args = (const void *) (state)->uesp; \
+ mach_msg_header_t *msg; \
+ _hurdsig_catch_memory_fault (args) ? -1 : \
+ ({ \
+ msg = args->msg; \
+ *(opt) = args->option; \
+ *(tmout) = args->timeout; \
+ *(rcvname) = args->rcv_name; \
+ _hurdsig_end_catch_fault (); \
+ if (msg == 0) \
+ { \
+ *(send_name) = MACH_PORT_NULL; \
+ *(msgid) = 0; \
+ } \
+ else \
+ { \
+ if (_hurdsig_catch_memory_fault (msg)) \
+ return -1; \
+ *(send_name) = msg->msgh_remote_port; \
+ *(msgid) = msg->msgh_id; \
+ _hurdsig_end_catch_fault (); \
+ } \
+ 0; \
+ }); \
+})
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/ioperm.c b/REORG.TODO/sysdeps/mach/hurd/i386/ioperm.c
new file mode 100644
index 0000000000..c3dc1a3354
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/ioperm.c
@@ -0,0 +1,53 @@
+/* Access to hardware i/o ports. Hurd/x86 version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/io.h>
+#include <hurd.h>
+#include <mach/i386/mach_i386.h>
+
+int
+ioperm (unsigned long int from, unsigned long int num, int turn_on)
+{
+#if ! HAVE_I386_IO_PERM_MODIFY
+ return __hurd_fail (ENOSYS);
+#else
+ error_t err;
+ device_t devmaster;
+
+ /* With the device master port we get a capability that represents
+ this range of io ports. */
+ err = __get_privileged_ports (NULL, &devmaster);
+ if (! err)
+ {
+ io_perm_t perm;
+ err = __i386_io_perm_create (devmaster, from, from + num - 1, &perm);
+ __mach_port_deallocate (__mach_task_self (), devmaster);
+ if (! err)
+ {
+ /* Now we add or remove that set from our task's bitmap. */
+ err = __i386_io_perm_modify (__mach_task_self (), perm, turn_on);
+ __mach_port_deallocate (__mach_task_self (), perm);
+ }
+
+ if (err == MIG_BAD_ID) /* Old kernels don't have these RPCs. */
+ err = ENOSYS;
+ }
+
+ return err ? __hurd_fail (err) : 0;
+#endif
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/longjmp-ts.c b/REORG.TODO/sysdeps/mach/hurd/i386/longjmp-ts.c
new file mode 100644
index 0000000000..ef84c665ec
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/longjmp-ts.c
@@ -0,0 +1,39 @@
+/* Perform a `longjmp' on a Mach thread_state. i386 version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <jmpbuf-offsets.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[JB_BX];
+ ts->esi = env[0].__jmpbuf[JB_SI];
+ ts->edi = env[0].__jmpbuf[JB_DI];
+ ts->ebp = env[0].__jmpbuf[JB_BP];
+ ts->uesp = env[0].__jmpbuf[JB_SP];
+ ts->eip = env[0].__jmpbuf[JB_PC];
+ ts->eax = val ?: 1;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/sigcontextinfo.h b/REORG.TODO/sysdeps/mach/hurd/i386/sigcontextinfo.h
new file mode 100644
index 0000000000..a8be1455d5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/sigcontextinfo.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define SIGCONTEXT struct sigcontext
+#define SIGCONTEXT_EXTRA_ARGS
+#define GET_PC(ctx) ((void *) (ctx).sc_eip)
+#define GET_FRAME(ctx) ((void *) (ctx).sc_ebp)
+#define GET_STACK(ctx) ((void *) (ctx).sc_uesp)
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/signal-defines.sym b/REORG.TODO/sysdeps/mach/hurd/i386/signal-defines.sym
new file mode 100644
index 0000000000..e42bbbe061
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/signal-defines.sym
@@ -0,0 +1,10 @@
+#include <hurd/signal.h>
+#include <signal.h>
+
+--
+
+HURD_SIGSTATE__SIGALTSTACK__OFFSET offsetof(struct hurd_sigstate, sigaltstack)
+
+SIGALTSTACK__SS_SP__OFFSET offsetof(stack_t, ss_sp)
+SIGALTSTACK__SS_SIZE__OFFSET offsetof(stack_t, ss_size)
+SIGALTSTACK__SS_FLAGS__OFFSET offsetof(stack_t, ss_flags)
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/sigreturn.c b/REORG.TODO/sysdeps/mach/hurd/i386/sigreturn.c
new file mode 100644
index 0000000000..ce0f656ff0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/sigreturn.c
@@ -0,0 +1,139 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+register int *sp asm ("%esp");
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <hurd/msg.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+ struct hurd_sigstate *ss;
+ struct hurd_userlink *link = (void *) &scp[1];
+ 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);
+
+ /* Remove the link on the `active resources' chain added by
+ _hurd_setup_sighandler. Its purpose was to make sure
+ that we got called; now we have, it is done. */
+ _hurd_userlink_unlink (link);
+
+ /* 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;
+ __spin_unlock (&ss->lock);
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+ /* If a pending signal was handled, sig_post never returned.
+ If it did return, the pending signal didn't run a handler;
+ proceed as usual. */
+ __spin_lock (&ss->lock);
+ ss->context = NULL;
+ }
+
+ if (scp->sc_onstack)
+ {
+ ss->sigaltstack.ss_flags &= ~SS_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_t port = *reply_port;
+
+ /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
+ get another reply port, but avoids mig_dealloc_reply_port trying to
+ deallocate it after the receive fails (which it will, because the
+ reply port will be bogus, whether we do this or not). */
+ *reply_port = MACH_PORT_DEAD;
+
+ __mach_port_destroy (__mach_task_self (), port);
+ }
+ *reply_port = scp->sc_reply_port;
+
+ if (scp->sc_fpused)
+ /* Restore the FPU state. Mach conveniently stores the state
+ in the format the i387 `frstor' instruction uses to restore it. */
+ asm volatile ("frstor %0" : : "m" (scp->sc_fpsave));
+
+ {
+ /* 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/REORG.TODO/sysdeps/mach/hurd/i386/static-start.S b/REORG.TODO/sysdeps/mach/hurd/i386/static-start.S
new file mode 100644
index 0000000000..03eb204f9d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/static-start.S
@@ -0,0 +1,27 @@
+/* Startup code for statically linked Hurd/i386 binaries.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+ .text
+ .globl _start
+_start:
+ call _hurd_stack_setup
+ xorl %edx, %edx
+ jmp _start1
+
+#define _start _start1
+#include <sysdeps/i386/start.S>
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/sys/io.h b/REORG.TODO/sysdeps/mach/hurd/i386/sys/io.h
new file mode 100644
index 0000000000..9f3dbfffa7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/sys/io.h
@@ -0,0 +1,177 @@
+/* Access to hardware i/o ports. GNU/x86 version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IO_H
+#define _SYS_IO_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* If TURN_ON is TRUE, request for permission to do direct i/o on the
+ port numbers in the range [FROM,FROM+NUM-1]. Otherwise, turn I/O
+ permission off for that range. This call requires root privileges. */
+extern int ioperm (unsigned long int __from, unsigned long int __num,
+ int __turn_on) __THROW;
+
+/* Set the I/O privilege level to LEVEL. If LEVEL>3, permission to
+ access any I/O port is granted. This call requires root
+ privileges. */
+extern int iopl (int __level) __THROW;
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+static __inline unsigned char
+inb (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned char
+inb_p (unsigned short int port)
+{
+ unsigned char _v;
+
+ __asm__ __volatile__ ("inb %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw (unsigned short int port)
+{
+ unsigned short _v;
+
+ __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned short int
+inw_p (unsigned short int port)
+{
+ unsigned short int _v;
+
+ __asm__ __volatile__ ("inw %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl (unsigned short int port)
+{
+ unsigned int _v;
+
+ __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline unsigned int
+inl_p (unsigned short int port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("inl %w1,%0\noutb %%al,$0x80":"=a" (_v):"Nd" (port));
+ return _v;
+}
+
+static __inline void
+outb (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outb_p (unsigned char value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outw (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+outw_p (unsigned short int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outw %w0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+outl (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+outl_p (unsigned int value, unsigned short int port)
+{
+ __asm__ __volatile__ ("outl %0,%w1\noutb %%al,$0x80": :"a" (value),
+ "Nd" (port));
+}
+
+static __inline void
+insb (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insb":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insw (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insw":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+insl (unsigned short int port, void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; insl":"=D" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsb (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsb":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsw (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsw":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+static __inline void
+outsl (unsigned short int port, const void *addr, unsigned long int count)
+{
+ __asm__ __volatile__ ("cld ; rep ; outsl":"=S" (addr),
+ "=c" (count):"d" (port), "0" (addr), "1" (count));
+}
+
+#endif /* GNU C */
+
+__END_DECLS
+#endif /* _SYS_IO_H */
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/tls.h b/REORG.TODO/sysdeps/mach/hurd/i386/tls.h
new file mode 100644
index 0000000000..74b444ef19
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/tls.h
@@ -0,0 +1,169 @@
+/* Definitions for thread-local data handling. Hurd/i386 version.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _I386_TLS_H
+#define _I386_TLS_H
+
+
+/* Some things really need not be machine-dependent. */
+#include <sysdeps/mach/hurd/tls.h>
+
+
+#ifndef __ASSEMBLER__
+# include <dl-dtv.h>
+
+/* Type of the TCB. */
+typedef struct
+{
+ void *tcb; /* Points to this structure. */
+ dtv_t *dtv; /* Vector of pointers to TLS data. */
+ thread_t self; /* This thread's control port. */
+ int multiple_threads;
+ uintptr_t sysinfo;
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
+ int gscope_flag;
+ int private_futex;
+ /* Reservation of some values for the TM ABI. */
+ void *__private_tm[4];
+ /* GCC split stack support. */
+ void *__private_ss;
+} tcbhead_t;
+#endif
+
+
+/* The TCB can have any size and the memory following the address the
+ thread pointer points to is unspecified. Allocate the TCB there. */
+#define TLS_TCB_AT_TP 1
+#define TLS_DTV_AT_TP 0
+
+#ifndef __ASSEMBLER__
+
+/* Use i386-specific RPCs to arrange that %gs segment register prefix
+ addresses the TCB in each thread. */
+# include <mach/i386/mach_i386.h>
+
+# ifndef HAVE_I386_SET_GDT
+# define __i386_set_gdt(thr, sel, desc) ((void) (thr), (void) (sel), (void) (desc), MIG_BAD_ID)
+# endif
+
+# include <errno.h>
+# include <assert.h>
+
+# define HURD_TLS_DESC_DECL(desc, tcb) \
+ struct descriptor desc = \
+ { /* low word: */ \
+ 0xffff /* limit 0..15 */ \
+ | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \
+ , /* high word: */ \
+ ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \
+ | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \
+ | (0xf << 16) /* limit 16..19 */ \
+ | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \
+ | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \
+ }
+
+
+static inline const char * __attribute__ ((unused))
+_hurd_tls_init (tcbhead_t *tcb)
+{
+ HURD_TLS_DESC_DECL (desc, tcb);
+
+ /* This field is used by TLS accesses to get our "thread pointer"
+ from the TLS point of view. */
+ tcb->tcb = tcb;
+
+ /* Cache our thread port. */
+ tcb->self = __mach_thread_self ();
+
+ /* Get the first available selector. */
+ int sel = -1;
+ error_t err = __i386_set_gdt (tcb->self, &sel, desc);
+ if (err == MIG_BAD_ID)
+ {
+ /* Old kernel, use a per-thread LDT. */
+ sel = 0x27;
+ err = __i386_set_ldt (tcb->self, sel, &desc, 1);
+ assert_perror (err);
+ if (err)
+ return "i386_set_ldt failed";
+ }
+ else if (err)
+ {
+ assert_perror (err); /* Separate from above with different line #. */
+ return "i386_set_gdt failed";
+ }
+
+ /* Now install the new selector. */
+ asm volatile ("mov %w0, %%gs" :: "q" (sel));
+
+ return 0;
+}
+
+/* Code to initially initialize the thread pointer. This might need
+ special attention since 'errno' is not yet available and if the
+ operation can cause a failure 'errno' must not be touched. */
+# define TLS_INIT_TP(descr) \
+ _hurd_tls_init ((tcbhead_t *) (descr))
+
+/* Return the TCB address of the current thread. */
+# define THREAD_SELF \
+ ({ tcbhead_t *__tcb; \
+ __asm__ ("movl %%gs:%c1,%0" : "=r" (__tcb) \
+ : "i" (offsetof (tcbhead_t, tcb))); \
+ __tcb;})
+
+/* Install new dtv for current thread. */
+# define INSTALL_NEW_DTV(dtvp) \
+ ({ asm volatile ("movl %0,%%gs:%P1" \
+ : : "ir" (dtvp), "i" (offsetof (tcbhead_t, dtv))); })
+
+/* Return the address of the dtv for the current thread. */
+# define THREAD_DTV() \
+ ({ dtv_t *_dtv; \
+ asm ("movl %%gs:%P1,%0" : "=q" (_dtv) : "i" (offsetof (tcbhead_t, dtv)));\
+ _dtv; })
+
+# include <mach/machine/thread_status.h>
+
+/* Set up TLS in the new thread of a fork child, copying from our own. */
+static inline error_t __attribute__ ((unused))
+_hurd_tls_fork (thread_t child, struct i386_thread_state *state)
+{
+ /* Fetch the selector set by _hurd_tls_init. */
+ int sel;
+ asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0));
+ if (sel == state->ds) /* _hurd_tls_init was never called. */
+ return 0;
+
+ tcbhead_t *const tcb = THREAD_SELF;
+ HURD_TLS_DESC_DECL (desc, tcb);
+ error_t err;
+
+ if (__builtin_expect (sel, 0x50) & 4) /* LDT selector */
+ err = __i386_set_ldt (child, sel, &desc, 1);
+ else
+ err = __i386_set_gdt (child, &sel, desc);
+
+ state->gs = sel;
+ return err;
+}
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* i386/tls.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/i386/trampoline.c b/REORG.TODO/sysdeps/mach/hurd/i386/trampoline.c
new file mode 100644
index 0000000000..002415929c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/i386/trampoline.c
@@ -0,0 +1,265 @@
+/* Set thread_state for sighandler, and sigcontext to recover. i386 version.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <hurd/signal.h>
+#include <hurd/userlink.h>
+#include <thread_state.h>
+#include <mach/machine/eflags.h>
+#include <assert.h>
+#include <errno.h>
+#include "hurdfault.h"
+#include <intr-msg.h>
+
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ int signo, struct hurd_signal_detail *detail,
+ volatile int rpc_wait,
+ struct machine_thread_all_state *state)
+{
+ void trampoline (void);
+ void rpc_wait_trampoline (void);
+ void firewall (void);
+ extern const void _hurd_intr_rpc_msg_cx_sp;
+ extern const void _hurd_intr_rpc_msg_sp_restored;
+ void *volatile sigsp;
+ struct sigcontext *scp;
+ struct
+ {
+ int signo;
+ long int sigcode;
+ struct sigcontext *scp; /* Points to ctx, below. */
+ void *sigreturn_addr;
+ void *sigreturn_returns_here;
+ struct sigcontext *return_scp; /* Same; arg to sigreturn. */
+ struct sigcontext ctx;
+ struct hurd_userlink link;
+ } *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_memory_fault (ss->context))
+ {
+ 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);
+ }
+ }
+
+ if (! machine_get_basic_state (ss->thread, state))
+ return NULL;
+
+ /* Save the original SP in the gratuitous `esp' slot.
+ We may need to reset the SP (the `uesp' slot) to avoid clobbering an
+ interrupted RPC frame. */
+ state->basic.esp = state->basic.uesp;
+
+ if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+ !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
+ {
+ sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+ ss->sigaltstack.ss_flags |= SS_ONSTACK;
+ /* XXX need to set up base of new stack for
+ per-thread variables, cthreads. */
+ }
+ /* This code has intimate knowledge of the special mach_msg system call
+ done in intr-msg.c; that code does (see intr-msg.h):
+ movl %esp, %ecx
+ leal ARGS, %esp
+ _hurd_intr_rpc_msg_cx_sp: movl $-25, %eax
+ _hurd_intr_rpc_msg_do_trap: lcall $7, $0
+ _hurd_intr_rpc_msg_in_trap: movl %ecx, %esp
+ _hurd_intr_rpc_msg_sp_restored:
+ We must check for the window during which %esp points at the
+ mach_msg arguments. The space below until %ecx is used by
+ the _hurd_intr_rpc_mach_msg frame, and must not be clobbered. */
+ else if (state->basic.eip >= (int) &_hurd_intr_rpc_msg_cx_sp &&
+ state->basic.eip < (int) &_hurd_intr_rpc_msg_sp_restored)
+ /* The SP now points at the mach_msg args, but there is more stack
+ space used below it. The real SP is saved in %ecx; we must push the
+ new frame below there, and restore that value as the SP on
+ sigreturn. */
+ sigsp = (char *) (state->basic.uesp = state->basic.ecx);
+ else
+ sigsp = (char *) state->basic.uesp;
+
+ /* Push the arguments to call `trampoline' on the stack. */
+ sigsp -= sizeof (*stackframe);
+ stackframe = sigsp;
+
+ if (_hurdsig_catch_memory_fault (stackframe))
+ {
+ /* 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;
+
+ extern void _hurdsig_longjmp_from_handler (void *, jmp_buf, int);
+
+ /* Add a link to the thread's active-resources list. We mark this as
+ the only user of the "resource", so the cleanup function will be
+ called by any longjmp which is unwinding past the signal frame.
+ The cleanup function (in sigunwind.c) will make sure that all the
+ appropriate cleanups done by sigreturn are taken care of. */
+ stackframe->link.cleanup = &_hurdsig_longjmp_from_handler;
+ stackframe->link.cleanup_data = &stackframe->ctx;
+ stackframe->link.resource.next = NULL;
+ stackframe->link.resource.prevp = NULL;
+ stackframe->link.thread.next = ss->active_resources;
+ stackframe->link.thread.prevp = &ss->active_resources;
+ if (stackframe->link.thread.next)
+ stackframe->link.thread.next->thread.prevp
+ = &stackframe->link.thread.next;
+ ss->active_resources = &stackframe->link;
+
+ /* Set up the arguments for the signal handler. */
+ stackframe->signo = signo;
+ stackframe->sigcode = detail->code;
+ stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
+ stackframe->sigreturn_addr = &__sigreturn;
+ stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
+
+ /* Set up the sigcontext from the current state of the thread. */
+
+ scp->sc_onstack = ss->sigaltstack.ss_flags & SS_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.esp;
+
+ if (_hurdsig_catch_memory_fault (args))
+ {
+ /* 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;
+
+ /* Limit the time to receive the reply message, in case the server
+ claimed that `interrupt_operation' succeeded but in fact the RPC
+ is hung. */
+ args->option |= MACH_RCV_TIMEOUT;
+ args->timeout = _hurd_interrupted_rpc_timeout;
+
+ _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.uesp = state->basic.esp; /* Restore mach_msg syscall SP. */
+ 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;
+
+ /* The x86 ABI says the DF bit is clear on entry to any function. */
+ state->basic.efl &= ~EFL_DF;
+
+ return scp;
+}
+
+/* The trampoline code follows. This used to be located inside
+ _hurd_setup_sighandler, but was optimized away by gcc 2.95. */
+
+asm ("rpc_wait_trampoline:\n");
+ /* 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 (/* 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");
+
+ asm ("trampoline:\n");
+ /* 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 ("call *%edx\n" /* Call the handler function. */
+ "addl $12, %esp\n" /* Pop its args. */
+ /* The word at the top of stack is &__sigreturn; following are a dummy
+ word to fill the slot for the address for __sigreturn to return to,
+ and a copy of SCP for __sigreturn's argument. "Return" to calling
+ __sigreturn (SCP); this call never returns. */
+ "ret");
+
+asm ("firewall:\n"
+ "hlt");
diff --git a/REORG.TODO/sysdeps/mach/hurd/if_index.c b/REORG.TODO/sysdeps/mach/hurd/if_index.c
new file mode 100644
index 0000000000..2b9041a3ba
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/if_index.c
@@ -0,0 +1,196 @@
+/* Find network interface names and index numbers. Hurd version.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <error.h>
+#include <net/if.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/ioctl.h>
+#include <hurd/pfinet.h>
+
+/* Return the interface index corresponding to interface IFNAME.
+ On error, return 0. */
+unsigned int
+__if_nametoindex (const char *ifname)
+{
+ struct ifreq ifr;
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
+ strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
+ if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
+ {
+ int saved_errno = errno;
+ __close (fd);
+ if (saved_errno == EINVAL || saved_errno == ENOTTY)
+ __set_errno (ENOSYS);
+ return 0;
+ }
+ __close (fd);
+ return ifr.ifr_ifindex;
+}
+libc_hidden_def (__if_nametoindex)
+weak_alias (__if_nametoindex, if_nametoindex)
+libc_hidden_weak (if_nametoindex)
+
+/* Free the structure IFN returned by if_nameindex. */
+void
+__if_freenameindex (struct if_nameindex *ifn)
+{
+ struct if_nameindex *ptr = ifn;
+ while (ptr->if_name || ptr->if_index)
+ {
+ free (ptr->if_name);
+ ++ptr;
+ }
+ free (ifn);
+}
+libc_hidden_def (__if_freenameindex)
+weak_alias (__if_freenameindex, if_freenameindex)
+libc_hidden_weak (if_freenameindex)
+
+/* Return an array of if_nameindex structures, one for each network
+ interface present, plus one indicating the end of the array. On
+ error, return NULL. */
+struct if_nameindex *
+__if_nameindex (void)
+{
+ error_t err = 0;
+ char data[2048];
+ file_t server;
+ int fd = __opensock ();
+ struct ifconf ifc;
+ unsigned int nifs, i;
+ struct if_nameindex *idx = NULL;
+
+ ifc.ifc_buf = data;
+
+ if (fd < 0)
+ return NULL;
+
+ server = _hurd_socket_server (PF_INET, 0);
+ if (server == MACH_PORT_NULL)
+ nifs = 0;
+ else
+ {
+ size_t len = sizeof data;
+ err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
+ 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_INET, 1);
+ if (server == MACH_PORT_NULL)
+ goto out;
+ err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
+ }
+ if (err)
+ goto out;
+
+ ifc.ifc_len = len;
+ nifs = len / sizeof (struct ifreq);
+ }
+
+ idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+ if (idx == NULL)
+ {
+ err = ENOBUFS;
+ goto out;
+ }
+
+ for (i = 0; i < nifs; ++i)
+ {
+ struct ifreq *ifr = &ifc.ifc_req[i];
+ idx[i].if_name = __strdup (ifr->ifr_name);
+ if (idx[i].if_name == NULL
+ || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
+ {
+ unsigned int j;
+ err = errno;
+
+ for (j = 0; j < i; ++j)
+ free (idx[j].if_name);
+ free (idx);
+ idx = NULL;
+
+ if (err == EINVAL)
+ err = ENOSYS;
+ else if (err == ENOMEM)
+ err = ENOBUFS;
+ goto out;
+ }
+ idx[i].if_index = ifr->ifr_ifindex;
+ }
+
+ idx[i].if_index = 0;
+ idx[i].if_name = NULL;
+
+ out:
+ __close (fd);
+ if (data != ifc.ifc_buf)
+ __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf,
+ ifc.ifc_len);
+ __set_errno (err);
+ return idx;
+}
+weak_alias (__if_nameindex, if_nameindex)
+libc_hidden_weak (if_nameindex)
+
+/* Store the name of the interface corresponding to index IFINDEX in
+ IFNAME (which has space for at least IFNAMSIZ characters). Return
+ IFNAME, or NULL on error. */
+char *
+__if_indextoname (unsigned int ifindex, char *ifname)
+{
+ struct ifreq ifr;
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return NULL;
+
+ ifr.ifr_ifindex = ifindex;
+ if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0)
+ {
+ int saved_errno = errno;
+ __close (fd);
+ if (saved_errno == EINVAL || saved_errno == ENOTTY)
+ __set_errno (ENOSYS);
+ else if (saved_errno == ENODEV)
+ __set_errno (ENXIO);
+ return NULL;
+ }
+ __close (fd);
+ return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
+}
+weak_alias (__if_indextoname, if_indextoname)
+libc_hidden_weak (if_indextoname)
+
+#if 0
+void
+internal_function
+__protocol_available (int *have_inet, int *have_inet6)
+{
+ *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL;
+ *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL;
+}
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/ifreq.c b/REORG.TODO/sysdeps/mach/hurd/ifreq.c
new file mode 100644
index 0000000000..fedc68d8fb
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ifreq.c
@@ -0,0 +1,64 @@
+/* Fetch the host's network interface list. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ifreq.h>
+#include <hurd.h>
+#include <hurd/pfinet.h>
+#include <sys/mman.h>
+
+
+void
+__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
+{
+ file_t server;
+
+ server = _hurd_socket_server (PF_INET, 0);
+ if (server == MACH_PORT_NULL)
+ {
+ out:
+ *num_ifs = 0;
+ *ifreqs = NULL;
+ }
+ else
+ {
+ char *data = NULL;
+ size_t len = 0;
+ error_t err = __pfinet_siocgifconf (server, -1, &data, &len);
+ 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_INET, 1);
+ if (server == MACH_PORT_NULL)
+ goto out;
+ err = __pfinet_siocgifconf (server, -1, (data_t *) ifreqs, &len);
+ }
+ if (err)
+ goto out;
+
+ if (len % sizeof (struct ifreq) != 0)
+ {
+ munmap (data, len);
+ errno = EGRATUITOUS;
+ goto out;
+ }
+ *num_ifs = len / sizeof (struct ifreq);
+ *ifreqs = (struct ifreq *) data;
+ }
+
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/ifreq.h b/REORG.TODO/sysdeps/mach/hurd/ifreq.h
new file mode 100644
index 0000000000..eceeb7a2c3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ifreq.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+static inline struct ifreq *
+__if_nextreq (struct ifreq *ifr)
+{
+#ifdef _HAVE_SA_LEN
+ if (ifr->ifr_addr.sa_len > sizeof ifr->ifr_addr)
+ return (struct ifreq *) ((char *) &ifr->ifr_addr + ifr->ifr_addr.sa_len);
+#endif
+ return ifr + 1;
+}
+
+extern void __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd);
+
+
+static inline void
+__if_freereq (struct ifreq *ifreqs, int num_ifs)
+{
+ munmap (ifreqs, num_ifs * sizeof (struct ifreq));
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/init-posix.c b/REORG.TODO/sysdeps/mach/hurd/init-posix.c
new file mode 100644
index 0000000000..eaf6332fe1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/init-posix.c
@@ -0,0 +1,2 @@
+/* We don't need the unix/bsd version. */
+#include <posix/init-posix.c>
diff --git a/REORG.TODO/sysdeps/mach/hurd/ioctl.c b/REORG.TODO/sysdeps/mach/hurd/ioctl.c
new file mode 100644
index 0000000000..7ce521c4fa
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ioctl.c
@@ -0,0 +1,326 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 <stdint.h>
+#include <hurd/ioctl.h>
+#include <mach/mig_support.h>
+
+#include <hurd/ioctls.defs>
+
+#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
+__ioctl (int fd, unsigned long int request, ...)
+{
+#ifdef MACH_MSG_TYPE_CHAR
+ /* 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,
+ MACH_MSG_TYPE_INTEGER_64 };
+#define io2mach_type(count, type) \
+ ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#endif
+
+ /* Extract the type information encoded in the request. */
+ unsigned int type = _IOC_TYPE (request);
+
+ /* Message buffer. */
+#define msg_align(x) \
+ (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
+ struct
+ {
+#ifdef MACH_MSG_TYPE_BIT
+ union
+ {
+ mig_reply_header_t header;
+ struct
+ {
+ mach_msg_header_t Head;
+ int RetCodeType;
+ kern_return_t RetCode;
+ } header_typecheck;
+ };
+ char data[3 * sizeof (mach_msg_type_t) +
+ msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
+ msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
+ _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+#else /* Untyped Mach IPC format. */
+ mig_reply_error_t header;
+ char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+ _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+ _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+ mach_msg_trailer_t trailer;
+#endif
+ } msg;
+ mach_msg_header_t *const m = &msg.header.Head;
+ mach_msg_id_t msgid;
+ unsigned int reply_size;
+#ifdef MACH_MSG_TYPE_BIT
+ mach_msg_type_t *t;
+#else
+ void *p;
+#endif
+
+ void *arg = NULL;
+
+ 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;
+#ifdef MACH_MSG_TYPE_BIT
+ mach_msg_type_t *t = &msg.header.RetCodeType;
+#else
+ void *p = &msg.header.RetCode;
+#endif
+
+ /* Marshal the request arguments into the message buffer.
+ We must redo this work each time we retry the RPC after a SIGTTOU,
+ because the reply message containing the EBACKGROUND error code
+ clobbers the same message buffer also used for the request. */
+
+ if (_IOC_INOUT (request) & IOC_IN)
+ {
+ /* We don't want to advance ARG since it will be used to copy out
+ too if IOC_OUT is also set. */
+ void *argptr = arg;
+
+ /* Pack an argument into the message buffer. */
+ void in (unsigned int count, enum __ioctl_datum type)
+ {
+ if (count > 0)
+ {
+ const size_t len = count * typesize ((unsigned int) type);
+#ifdef MACH_MSG_TYPE_BIT
+ void *p = &t[1];
+ *t = io2mach_type (count, type);
+ p = __mempcpy (p, argptr, len);
+ p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
+ & ~(sizeof (*t) - 1));
+ t = p;
+#else
+ p = __mempcpy (p, argptr, len);
+#endif
+ argptr += len;
+ }
+ }
+
+ /* 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));
+ }
+ else if (_IOC_INOUT (request) == IOC_VOID && _IOT_COUNT0 (type) != 0)
+ {
+ /* The RPC takes a single integer_t argument.
+ Rather than pointing to the value, ARG is the value itself. */
+#ifdef MACH_MSG_TYPE_BIT
+ *t++ = io2mach_type (1, _IOTS (integer_t));
+ *(integer_t *) t = (integer_t) arg;
+ t = (void *) t + sizeof (integer_t);
+#else
+ *(integer_t *) p = (integer_t) arg;
+ p = (void *) p + sizeof (integer_t);
+#endif
+ }
+
+ memset (m, 0, sizeof *m); /* Clear unused fields. */
+ m->msgh_size = (
+#ifdef MACH_MSG_TYPE_BIT
+ (char *) t
+#else
+ (char *) p
+#endif
+ - (char *) &msg);
+ m->msgh_remote_port = ioport;
+ m->msgh_local_port = __mig_get_reply_port ();
+ m->msgh_id = msgid;
+ m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE);
+ err = _hurd_intr_rpc_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 msg.header)
+ return MIG_TYPE_ERROR;
+
+#ifdef MACH_MSG_TYPE_BIT
+ if (msg.header_typecheck.RetCodeType !=
+ ((union { mach_msg_type_t t; int i; })
+ { t: io2mach_type (1, _IOTS (msg.header.RetCode)) }).i)
+ return MIG_TYPE_ERROR;
+#endif
+ return msg.header.RetCode;
+ }
+
+ if (_IOT_COUNT0 (type) != 0)
+ {
+ /* Data need either be sent, received, or even both. */
+ 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. */
+ int save = errno;
+ int result = (*handler) (fd, request, arg);
+ if (result != -1 || errno != ENOTTY)
+ return result;
+
+ /* The handler doesn't really grok this one.
+ Try the normal RPC translation. */
+ errno = save;
+ }
+ }
+
+ /* Compute the Mach message ID for the RPC from the group and command
+ parts of the ioctl request. */
+ msgid = IOC_MSGID (request);
+
+ /* 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 msg.header;
+
+ if (_IOC_INOUT (request) & IOC_OUT)
+ {
+ inline void figure_reply (unsigned int count, enum __ioctl_datum type)
+ {
+ if (count > 0)
+ {
+#ifdef MACH_MSG_TYPE_BIT
+ /* 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);
+#else
+ reply_size += typesize (type) * count;
+#endif
+ }
+ }
+ figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+ figure_reply (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+ figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+ }
+
+ /* Marshal the arguments into the request message and make the RPC.
+ This wrapper function handles EBACKGROUND returns, turning them
+ into either SIGTTOU or EIO. */
+ err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
+
+#ifdef MACH_MSG_TYPE_BIT
+ t = (mach_msg_type_t *) msg.data;
+#else
+ p = (void *) msg.data;
+#endif
+ 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);
+#ifdef MACH_MSG_TYPE_BIT
+ 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 *) (((uintptr_t) t + len + sizeof (*t) - 1)
+ & ~(sizeof (*t) - 1));
+#else
+ memcpy (store, p, len);
+ p += len;
+ if (update != NULL)
+ *update += len;
+#endif
+ }
+ 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/REORG.TODO/sysdeps/mach/hurd/isatty.c b/REORG.TODO/sysdeps/mach/hurd/isatty.c
new file mode 100644
index 0000000000..5916a7d1bd
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/isatty.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__isatty (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/REORG.TODO/sysdeps/mach/hurd/jmp-unwind.c b/REORG.TODO/sysdeps/mach/hurd/jmp-unwind.c
new file mode 100644
index 0000000000..97cedd80f1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/jmp-unwind.c
@@ -0,0 +1,79 @@
+/* _longjmp_unwind -- Clean up stack frames unwound by longjmp. Hurd version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <jmpbuf-unwind.h>
+#include <hurd/userlink.h>
+#include <hurd/signal.h>
+#include <hurd/sigpreempt.h>
+#include <assert.h>
+#include <stdint.h>
+
+
+#ifndef _JMPBUF_UNWINDS
+#error "<jmpbuf-unwind.h> fails to define _JMPBUF_UNWINDS"
+#endif
+
+static inline uintptr_t
+demangle_ptr (uintptr_t x)
+{
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (x);
+# endif
+ return x;
+}
+
+/* This function is called by `longjmp' (with its arguments) to restore
+ active resources to a sane state before the frames code using them are
+ jumped out of. */
+
+void
+_longjmp_unwind (jmp_buf env, int val)
+{
+ struct hurd_sigstate *ss = _hurd_self_sigstate ();
+ struct hurd_userlink *link;
+
+ /* All access to SS->active_resources must take place inside a critical
+ section where signal handlers cannot run. */
+ __spin_lock (&ss->lock);
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+ /* Remove local signal preemptors being unwound past. */
+ while (ss->preemptors &&
+ _JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preemptors, demangle_ptr))
+ ss->preemptors = ss->preemptors->next;
+
+ __spin_unlock (&ss->lock);
+
+ /* Iterate over the current thread's list of active resources.
+ Process the head portion of the list whose links reside
+ in stack frames being unwound by this jump. */
+
+ for (link = ss->active_resources;
+ link && _JMPBUF_UNWINDS (env[0].__jmpbuf, link, demangle_ptr);
+ link = link->thread.next)
+ /* Remove this link from the resource's users list,
+ since the frame using the resource is being unwound.
+ This call returns nonzero if that was the last user. */
+ if (_hurd_userlink_unlink (link))
+ /* One of the frames being unwound by the longjmp was the last user
+ of its resource. Call the cleanup function to deallocate it. */
+ (*link->cleanup) (link->cleanup_data, env, val);
+
+ _hurd_critical_section_unlock (ss);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/kernel-features.h b/REORG.TODO/sysdeps/mach/hurd/kernel-features.h
new file mode 100644
index 0000000000..196638829f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/kernel-features.h
@@ -0,0 +1,21 @@
+/* Set flags signalling availability of certain operating system features.
+ Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file can define __ASSUME_* macros checked by certain source files.
+ Almost none of these are used outside of sysdeps/unix/sysv/linux code.
+ But those referring to POSIX-level features like O_* flags can be. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/kill.c b/REORG.TODO/sysdeps/mach/hurd/kill.c
new file mode 100644
index 0000000000..2d556dd2ff
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/kill.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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;
+
+ 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);
+ /* Ignore zombies. */
+ if (!err && refport != MACH_PORT_NULL)
+ {
+ err = __task_terminate (refport);
+ __mach_port_deallocate (__mach_task_self (), refport);
+ }
+ } while (err == MACH_SEND_INVALID_DEST ||
+ err == MIG_SERVER_DIED);
+ else
+ {
+ error_t taskerr;
+ error_t kill_port (mach_port_t msgport, mach_port_t refport)
+ {
+ if (msgport != MACH_PORT_NULL)
+ /* Send a signal message to his message port. */
+ return __msg_sig_post (msgport, sig, 0, refport);
+
+ /* The process has no message port. Perhaps try direct
+ frobnication of the task. */
+
+ if (taskerr)
+ /* If we could not get the task port, we can do nothing. */
+ return taskerr;
+
+ if (refport == MACH_PORT_NULL)
+ /* proc_pid2task returned success with a null task port.
+ That means the process is a zombie. Signals
+ to zombies should return success and do nothing. */
+ return 0;
+
+ /* For user convenience in the case of a task that has
+ not registered any message port with the proc server,
+ translate a few signals to direct task operations. */
+ switch (sig)
+ {
+ /* The only signals that really make sense for an
+ unregistered task are kill, suspend, and continue. */
+ case SIGSTOP:
+ case SIGTSTP:
+ return __task_suspend (refport);
+ case SIGCONT:
+ return __task_resume (refport);
+ case SIGTERM:
+ case SIGQUIT:
+ case SIGINT:
+ return __task_terminate (refport);
+ default:
+ /* We have full permission to send signals, but there is
+ no meaningful way to express this signal. */
+ return EPERM;
+ }
+ }
+ err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
+ (taskerr = __proc_pid2task (proc, pid,
+ &refport)) ?
+ __proc_getsidport (proc, &refport) : 0, 1,
+ kill_port (msgport, 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/REORG.TODO/sysdeps/mach/hurd/lchmod.c b/REORG.TODO/sysdeps/mach/hurd/lchmod.c
new file mode 100644
index 0000000000..00bd9a3e28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lchmod.c
@@ -0,0 +1,38 @@
+/* lchmod -- Change the protections of a file or symbolic link. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+/* Change the protections of FILE to MODE. */
+int
+lchmod (const char *file, mode_t mode)
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, O_NOLINK, 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;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/lchown.c b/REORG.TODO/sysdeps/mach/hurd/lchown.c
new file mode 100644
index 0000000000..9f155b1a81
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lchown.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Change the owner and group of FILE; if it's a link, do the link and
+ not the target. */
+int
+__lchown (const char *file, uid_t owner, gid_t group)
+{
+ error_t err;
+ file_t port = __file_name_lookup (file, O_NOLINK, 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 (__lchown, lchown)
diff --git a/REORG.TODO/sysdeps/mach/hurd/lgetxattr.c b/REORG.TODO/sysdeps/mach/hurd/lgetxattr.c
new file mode 100644
index 0000000000..b1333fbeee
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lgetxattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+lgetxattr (const char *path, const char *name, void *value, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_get (port, name, value, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/libc-ldscript b/REORG.TODO/sysdeps/mach/hurd/libc-ldscript
new file mode 100644
index 0000000000..499a2b2b99
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/libc-ldscript
@@ -0,0 +1,6 @@
+/* GNU ld script
+ 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/REORG.TODO/sysdeps/mach/hurd/libc-lock.h b/REORG.TODO/sysdeps/mach/hurd/libc-lock.h
new file mode 100644
index 0000000000..18496588b3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/libc-lock.h
@@ -0,0 +1,216 @@
+/* libc-internal interface for mutex locks. Hurd version using Mach cthreads.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCK_H
+#define _LIBC_LOCK_H 1
+
+#if (_LIBC - 0) || (_CTHREADS_ - 0)
+#include <cthreads.h>
+#include <hurd/threadvar.h>
+
+/* The locking here is very inexpensive, even for inlining. */
+#define _IO_lock_inexpensive 1
+
+typedef struct mutex __libc_lock_t;
+typedef struct
+{
+ struct mutex mutex;
+ void *owner;
+ int count;
+} __libc_lock_recursive_t;
+typedef __libc_lock_recursive_t __rtld_lock_recursive_t;
+
+#define __libc_lock_owner_self() ((void *) __hurd_threadvar_location (0))
+
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+#endif
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS. */
+#define _LIBC_LOCK_INITIALIZER MUTEX_INITIALIZER
+#define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = _LIBC_LOCK_INITIALIZER;
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#define __libc_lock_init(NAME) __mutex_init (&(NAME))
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
+#define __libc_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
+#define __rtld_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
+
+
+/* Lock the named lock variable. */
+#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
+
+/* Unlock the named lock variable. */
+#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
+
+
+#define __libc_lock_define_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME;
+#define _LIBC_LOCK_RECURSIVE_INITIALIZER { MUTEX_INITIALIZER, 0, 0 }
+#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+ CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+ __libc_lock_define_recursive (CLASS, NAME)
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+ _LIBC_LOCK_RECURSIVE_INITIALIZER
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+ __libc_lock_define_initialized_recursive (CLASS, NAME)
+
+#define __libc_lock_init_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ __lock->owner = 0; mutex_init (&__lock->mutex); })
+
+#define __libc_lock_trylock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ void *__self = __libc_lock_owner_self (); \
+ __mutex_trylock (&__lock->mutex) \
+ ? (__lock->owner = __self, __lock->count = 1, 0) \
+ : __lock->owner == __self ? (++__lock->count, 0) : 1; })
+
+#define __libc_lock_lock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ void *__self = __libc_lock_owner_self (); \
+ if (__mutex_trylock (&__lock->mutex) \
+ || (__lock->owner != __self \
+ && (__mutex_lock (&__lock->mutex), 1))) \
+ __lock->owner = __self, __lock->count = 1; \
+ else \
+ ++__lock->count; \
+ })
+#define __libc_lock_unlock_recursive(NAME) \
+ ({ __libc_lock_recursive_t *const __lock = &(NAME); \
+ if (--__lock->count == 0) \
+ { \
+ __lock->owner = 0; \
+ __mutex_unlock (&__lock->mutex); \
+ } \
+ })
+
+
+#define __rtld_lock_initialize(NAME) \
+ (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER)
+#define __rtld_lock_trylock_recursive(NAME) \
+ __libc_lock_trylock_recursive (NAME)
+#define __rtld_lock_lock_recursive(NAME) \
+ __libc_lock_lock_recursive(NAME)
+#define __rtld_lock_unlock_recursive(NAME) \
+ __libc_lock_unlock_recursive (NAME)
+
+
+/* XXX for now */
+#define __libc_rwlock_define __libc_lock_define
+#define __libc_rwlock_define_initialized __libc_lock_define_initialized
+#define __libc_rwlock_init __libc_lock_init
+#define __libc_rwlock_fini __libc_lock_fini
+#define __libc_rwlock_rdlock __libc_lock_lock
+#define __libc_rwlock_wrlock __libc_lock_lock
+#define __libc_rwlock_tryrdlock __libc_lock_trylock
+#define __libc_rwlock_trywrlock __libc_lock_trylock
+#define __libc_rwlock_unlock __libc_lock_unlock
+
+
+/* Start a critical region with a cleanup function */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+{ \
+ typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0; \
+ typeof (ARG) __save_ARG = ARG; \
+ /* close brace is in __libc_cleanup_region_end below. */
+
+/* End a critical region started with __libc_cleanup_region_start. */
+#define __libc_cleanup_region_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+}
+
+/* Sometimes we have to exit the block in the middle. */
+#define __libc_cleanup_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+
+#define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg)
+#define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute)
+
+#if (_CTHREADS_ - 0)
+
+/* Use mutexes as once control variables. */
+
+struct __libc_once
+ {
+ __libc_lock_t lock;
+ int done;
+ };
+
+#define __libc_once_define(CLASS,NAME) \
+ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
+
+/* Call handler iff the first call. */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+ do { \
+ __libc_lock_lock (ONCE_CONTROL.lock); \
+ if (!ONCE_CONTROL.done) \
+ (INIT_FUNCTION) (); \
+ ONCE_CONTROL.done = 1; \
+ __libc_lock_unlock (ONCE_CONTROL.lock); \
+ } while (0)
+
+/* Get once control variable. */
+#define __libc_once_get(ONCE_CONTROL) ((ONCE_CONTROL).done != 0)
+
+#ifdef _LIBC
+/* We need portable names for some functions. E.g., when they are
+ used as argument to __libc_cleanup_region_start. */
+#define __libc_mutex_unlock __mutex_unlock
+#endif
+
+/* Type for key of thread specific data. */
+typedef cthread_key_t __libc_key_t;
+
+#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
+#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+void *__libc_getspecific (__libc_key_t key);
+
+#endif /* _CTHREADS_ */
+
+/* Hide the definitions which are only supposed to be used inside libc in
+ a separate file. This file is not present in the installation! */
+#ifdef _LIBC
+# include <libc-lockP.h>
+#endif
+
+#endif /* libc-lock.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/libc-tsd.h b/REORG.TODO/sysdeps/mach/hurd/libc-tsd.h
new file mode 100644
index 0000000000..0878d61aed
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/libc-tsd.h
@@ -0,0 +1,34 @@
+/* libc-internal interface for thread-specific data. Hurd version.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_TSD_H
+#define _LIBC_TSD_H 1
+
+#include <hurd/threadvar.h>
+
+#define __libc_tsd_define(CLASS, TYPE, KEY) /* nothing, always have threadvars */
+
+#define __libc_tsd_address(TYPE, KEY) \
+ ((TYPE *) __hurd_threadvar_location (_HURD_THREADVAR_##KEY))
+
+#define __libc_tsd_get(TYPE, KEY) \
+ (*__libc_tsd_address (TYPE, KEY))
+#define __libc_tsd_set(TYPE, KEY, VALUE) \
+ (*__libc_tsd_address (TYPE, KEY) = (VALUE))
+
+#endif /* libc-tsd.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/libc_p-ldscript b/REORG.TODO/sysdeps/mach/hurd/libc_p-ldscript
new file mode 100644
index 0000000000..7dcd52eec4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/libc_p-ldscript
@@ -0,0 +1,6 @@
+/* GNU ld script
+ This linker script is installed as /lib/libc_p.a.
+ It makes -lc_p become just like -( -lcrt_p -lmachuser_p -lhurduser_p -).
+ */
+
+GROUP ( libcrt_p.a libmachuser_p.a libhurduser_p.a )
diff --git a/REORG.TODO/sysdeps/mach/hurd/link.c b/REORG.TODO/sysdeps/mach/hurd/link.c
new file mode 100644
index 0000000000..b9e00b2e1b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/link.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make a link to FROM called TO. */
+int
+__link (const char *from, 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 (todir, linknode, toname, 1);
+ __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/REORG.TODO/sysdeps/mach/hurd/linkat.c b/REORG.TODO/sysdeps/mach/hurd/linkat.c
new file mode 100644
index 0000000000..676827891a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/linkat.c
@@ -0,0 +1,62 @@
+/* Make a link between file names relative to open directories. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Make a link to FROM relative to FROMFD called TO relative to TOFD. */
+int
+linkat (int fromfd, const char *from, int tofd, const char *to, int flags)
+{
+ error_t err;
+ file_t oldfile, linknode, todir;
+ char *toname;
+
+ /* POSIX says linkat doesn't follow symlinks by default, so pass
+ O_NOLINK. That can be overridden by AT_SYMLINK_FOLLOW in FLAGS. */
+ oldfile = __file_name_lookup_at (fromfd, flags, from, O_NOLINK, 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_at (tofd, to, &toname);
+ if (todir != MACH_PORT_NULL)
+ {
+ err = __dir_link (todir, linknode, toname, 1);
+ __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;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/listen.c b/REORG.TODO/sysdeps/mach/hurd/listen.c
new file mode 100644
index 0000000000..26add84e92
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/listen.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__listen (int fd, int n)
+{
+ error_t err = HURD_DPORT_USE (fd, __socket_listen (port, n));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
+
+weak_alias (__listen, listen)
diff --git a/REORG.TODO/sysdeps/mach/hurd/listxattr.c b/REORG.TODO/sysdeps/mach/hurd/listxattr.c
new file mode 100644
index 0000000000..8c8c361213
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/listxattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+listxattr (const char *path, char *list, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_list (port, list, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/llistxattr.c b/REORG.TODO/sysdeps/mach/hurd/llistxattr.c
new file mode 100644
index 0000000000..646eacf80a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/llistxattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+llistxattr (const char *path, char *list, size_t size)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_list (port, list, &size);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/lremovexattr.c b/REORG.TODO/sysdeps/mach/hurd/lremovexattr.c
new file mode 100644
index 0000000000..bab92da7db
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lremovexattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+lremovexattr (const char *path, const char *name)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_remove (port, name);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return __hurd_fail (err);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/lseek.c b/REORG.TODO/sysdeps/mach/hurd/lseek.c
new file mode 100644
index 0000000000..a6168f540f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lseek.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE. */
+off_t
+__libc_lseek (int fd, off_t offset, int whence)
+{
+ return __libc_lseek64 (fd, (off64_t) offset, whence);
+}
+
+weak_alias (__libc_lseek, __lseek)
+libc_hidden_def (__lseek)
+weak_alias (__libc_lseek, lseek)
diff --git a/REORG.TODO/sysdeps/mach/hurd/lseek64.c b/REORG.TODO/sysdeps/mach/hurd/lseek64.c
new file mode 100644
index 0000000000..320da05fc4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lseek64.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE. */
+off64_t
+__libc_lseek64 (int fd, off64_t offset, 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 (__libc_lseek64, __lseek64)
+weak_alias (__libc_lseek64, lseek64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/lsetxattr.c b/REORG.TODO/sysdeps/mach/hurd/lsetxattr.c
new file mode 100644
index 0000000000..668698147b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lsetxattr.c
@@ -0,0 +1,36 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+#include <fcntl.h>
+
+ssize_t
+lsetxattr (const char *path, const char *name, const void *value, size_t size,
+ int flags)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_set (port, name, value, size, flags);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return err ? __hurd_fail (err) : size;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/lutimes.c b/REORG.TODO/sysdeps/mach/hurd/lutimes.c
new file mode 100644
index 0000000000..00013ab6ad
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lutimes.c
@@ -0,0 +1,57 @@
+/* lutimes -- change access and modification times of a symlink. Hurd version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Change the access time of FILE to TVP[0] and
+ the modification time of FILE to TVP[1]. */
+int
+__lutimes (const char *file, const struct timeval tvp[2])
+{
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
+ error_t err;
+ file_t port;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
+ }
+
+ port = __file_name_lookup (file, O_NOLINK, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_utimes (port, u[0].tvt, u[1].tvt);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__lutimes, lutimes)
diff --git a/REORG.TODO/sysdeps/mach/hurd/lxstat.c b/REORG.TODO/sysdeps/mach/hurd/lxstat.c
new file mode 100644
index 0000000000..9ddc481018
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lxstat.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <stddef.h>
+
+#include "xstatconv.c"
+
+int
+__lxstat (int vers, const char *file, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __lxstat64 (vers, file, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__lxstat)
+weak_alias (__lxstat, _lxstat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/lxstat64.c b/REORG.TODO/sysdeps/mach/hurd/lxstat64.c
new file mode 100644
index 0000000000..953d4fb1d1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/lxstat64.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__lxstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ 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;
+}
+hidden_def (__lxstat64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/malloc-machine.h b/REORG.TODO/sysdeps/mach/hurd/malloc-machine.h
new file mode 100644
index 0000000000..00b4e9714a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/malloc-machine.h
@@ -0,0 +1,36 @@
+/* Basic platform-independent macro definitions for mutexes,
+ thread-specific data and parameters for malloc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MALLOC_MACHINE_H
+#define _MALLOC_MACHINE_H
+
+#include <atomic.h>
+#include <libc-lock.h>
+
+/* madvise is a stub on Hurd, so don't bother calling it. */
+
+#include <sys/mman.h>
+
+#undef __madvise
+#define __madvise(addr, len, advice) \
+ ((void) (addr), (void) (len), (void) (advice))
+
+#include <sysdeps/generic/malloc-machine.h>
+
+#endif /* !defined(_MALLOC_MACHINE_H) */
diff --git a/REORG.TODO/sysdeps/mach/hurd/mig-reply.c b/REORG.TODO/sysdeps/mach/hurd/mig-reply.c
new file mode 100644
index 0000000000..dde3fbf86c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mig-reply.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+
+ if (MACH_PORT_VALID (port))
+ __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/REORG.TODO/sysdeps/mach/hurd/mkdir.c b/REORG.TODO/sysdeps/mach/hurd/mkdir.c
new file mode 100644
index 0000000000..58c2ac4291
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mkdir.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <string.h>
+
+/* Create a directory named FILE_NAME with protections MODE. */
+int
+__mkdir (const char *file_name, mode_t mode)
+{
+ error_t err;
+ const char *name;
+ file_t parent;
+ if (!strcmp (file_name, "/"))
+ return __hurd_fail (EEXIST);
+ parent = __directory_name_split (file_name, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__mkdir, mkdir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/mkdirat.c b/REORG.TODO/sysdeps/mach/hurd/mkdirat.c
new file mode 100644
index 0000000000..7c5f639008
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mkdirat.c
@@ -0,0 +1,42 @@
+/* Create a directory named relative to another open directory. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <string.h>
+
+int
+mkdirat (int fd, const char *path, mode_t mode)
+{
+ error_t err;
+ const char *name;
+ file_t parent;
+ if (!strcmp (path, "/"))
+ return __hurd_fail (EEXIST);
+ parent = __directory_name_split_at (fd, path, (char **) &name);
+ if (parent == MACH_PORT_NULL)
+ return -1;
+ err = __dir_mkdir (parent, name, mode & ~_hurd_umask);
+ __mach_port_deallocate (__mach_task_self (), parent);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/mlock.c b/REORG.TODO/sysdeps/mach/hurd/mlock.c
new file mode 100644
index 0000000000..3eb415bc9d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mlock.c
@@ -0,0 +1,47 @@
+/* mlock -- guarantee pages are resident in memory. Mach/Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach_host.h>
+
+/* Guarantee all whole pages mapped by the range [ADDR,ADDR+LEN) to
+ be memory resident. */
+
+int
+mlock (const void *addr, size_t len)
+{
+ mach_port_t host;
+ vm_address_t page;
+ error_t err;
+
+ err = __get_privileged_ports (&host, NULL);
+ if (err)
+ host = __mach_host_self();
+
+ page = trunc_page ((vm_address_t) addr);
+ len = round_page ((vm_address_t) addr + len) - page;
+
+ err = __vm_wire (host, __mach_task_self (), page, len, VM_PROT_READ);
+ if (host != __mach_host_self())
+ __mach_port_deallocate (__mach_task_self (), host);
+
+ return err ? __hurd_fail (err) : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/mmap.c b/REORG.TODO/sysdeps/mach/hurd/mmap.c
new file mode 100644
index 0000000000..dbd718a688
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mmap.c
@@ -0,0 +1,188 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 (__ptr_t) -1
+ for errors (in which case `errno' is set). A successful `mmap' call
+ deallocates any previous mapping for the affected region. */
+
+__ptr_t
+__mmap (__ptr_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;
+
+ mapaddr = (vm_address_t) addr;
+
+ /* ADDR and OFFSET must be page-aligned. */
+ if ((mapaddr & (__vm_page_size - 1)) || (offset & (__vm_page_size - 1)))
+ return (__ptr_t) (long int) __hurd_fail (EINVAL);
+
+ if ((flags & (MAP_TYPE|MAP_INHERIT)) == MAP_ANON
+ && prot == (PROT_READ|PROT_WRITE)) /* cf VM_PROT_DEFAULT */
+ {
+ /* vm_allocate has (a little) less overhead in the kernel too. */
+ err = __vm_allocate (__mach_task_self (), &mapaddr, len, mapaddr == 0);
+
+ if (err == KERN_NO_SPACE)
+ {
+ if (flags & MAP_FIXED)
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (!err)
+ err = __vm_allocate (__mach_task_self (), &mapaddr, len, 0);
+ }
+ else if (mapaddr != 0)
+ err = __vm_allocate (__mach_task_self (), &mapaddr, len, 1);
+ }
+
+ return err ? (__ptr_t) (long int) __hurd_fail (err) : (__ptr_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 (__ptr_t) (long int) __hurd_fail (EINVAL);
+
+ case MAP_ANON:
+ memobj = MACH_PORT_NULL;
+ break;
+
+ case MAP_FILE:
+ case 0: /* Allow, e.g., just MAP_SHARED. */
+ {
+ mach_port_t robj, wobj;
+ if (err = HURD_DPORT_USE (fd, __io_map (port, &robj, &wobj)))
+ {
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP || err == ENOSYS)
+ err = ENODEV; /* File descriptor doesn't support mmap. */
+ return (__ptr_t) (long int) __hurd_dfail (fd, err);
+ }
+ switch (prot & (PROT_READ|PROT_WRITE))
+ {
+ /* Although it apparently doesn't make sense to map a file with
+ protection set to PROT_NONE, it is actually sometimes done.
+ In particular, that's how localedef reserves some space for
+ the locale archive file, the rationale being that some
+ implementations take into account whether the mapping is
+ anonymous or not when selecting addresses. */
+ case PROT_NONE:
+ case PROT_READ:
+ memobj = robj;
+ if (wobj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), wobj);
+ break;
+ case PROT_WRITE:
+ memobj = wobj;
+ if (robj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), robj);
+ break;
+ case PROT_READ|PROT_WRITE:
+ if (robj == wobj)
+ {
+ memobj = wobj;
+ /* Remove extra reference. */
+ __mach_port_deallocate (__mach_task_self (), memobj);
+ }
+ else if (wobj == MACH_PORT_NULL && /* Not writable by mapping. */
+ !(flags & MAP_SHARED))
+ /* The file can only be mapped for reading. Since we are
+ making a private mapping, we will never try to write the
+ object anyway, so we don't care. */
+ memobj = robj;
+ else
+ {
+ __mach_port_deallocate (__mach_task_self (), wobj);
+ return (__ptr_t) (long int) __hurd_fail (EACCES);
+ }
+ break;
+ default:
+ __builtin_unreachable ();
+ }
+ break;
+ /* XXX handle MAP_NOEXTEND */
+ }
+ }
+
+ /* XXX handle MAP_INHERIT */
+
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+ mapaddr == 0,
+ memobj, (vm_offset_t) offset,
+ ! (flags & MAP_SHARED),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
+
+ if (err == KERN_NO_SPACE)
+ {
+ if (flags & MAP_FIXED)
+ {
+ /* XXX this is not atomic as it is in unix! */
+ /* The region is already allocated; deallocate it first. */
+ err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+ if (! err)
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+ 0, memobj, (vm_offset_t) offset,
+ ! (flags & MAP_SHARED),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE
+ : VM_INHERIT_COPY);
+ }
+ else if (mapaddr != 0)
+ err = __vm_map (__mach_task_self (),
+ &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+ 1, memobj, (vm_offset_t) offset,
+ ! (flags & MAP_SHARED),
+ vmprot, VM_PROT_ALL,
+ (flags & MAP_SHARED) ? VM_INHERIT_SHARE
+ : VM_INHERIT_COPY);
+ }
+
+ if (memobj != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), memobj);
+
+ if (err)
+ return (__ptr_t) (long int) __hurd_fail (err);
+
+ return (__ptr_t) mapaddr;
+}
+
+weak_alias (__mmap, mmap)
diff --git a/REORG.TODO/sysdeps/mach/hurd/mmap64.c b/REORG.TODO/sysdeps/mach/hurd/mmap64.c
new file mode 100644
index 0000000000..ced469db18
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/mmap64.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.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 MAP_FAILED
+ for errors (in which case `errno' is set). A successful `mmap' call
+ deallocates any previous mapping for the affected region. */
+
+__ptr_t
+__mmap64 (__ptr_t addr, size_t len, int prot, int flags, int fd,
+ __off64_t offset)
+{
+ vm_offset_t small_offset = (vm_offset_t) offset;
+
+ if (small_offset != offset)
+ {
+ /* We cannot do this since the offset is too large. */
+ __set_errno (EOVERFLOW);
+ return MAP_FAILED;
+ }
+
+ return __mmap (addr, len, prot, flags, fd, small_offset);
+}
+
+weak_alias (__mmap64, mmap64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/munlock.c b/REORG.TODO/sysdeps/mach/hurd/munlock.c
new file mode 100644
index 0000000000..ee8235ecf0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/munlock.c
@@ -0,0 +1,46 @@
+/* munlock -- undo the effects of prior mlock calls. Mach/Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach_host.h>
+
+/* Undo the effects on these whole pages of any prior mlock calls. */
+
+int
+munlock (const void *addr, size_t len)
+{
+ mach_port_t host;
+ vm_address_t page;
+ error_t err;
+
+ err = __get_privileged_ports (&host, NULL);
+ if (err)
+ host = __mach_host_self();
+
+ page = trunc_page ((vm_address_t) addr);
+ len = round_page ((vm_address_t) addr + len) - page;
+
+ err = __vm_wire (host, __mach_task_self (), page, len, VM_PROT_NONE);
+ if (host != __mach_host_self())
+ __mach_port_deallocate (__mach_task_self (), host);
+
+ return err ? __hurd_fail (err) : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/net/ethernet.h b/REORG.TODO/sysdeps/mach/hurd/net/ethernet.h
new file mode 100644
index 0000000000..05201e6983
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/net/ethernet.h
@@ -0,0 +1,75 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Based on the FreeBSD version of this file. Curiously, that file
+ lacks a copyright in the header. */
+
+#ifndef __NET_ETHERNET_H
+#define __NET_ETHERNET_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <net/if_ether.h> /* IEEE 802.3 Ethernet constants */
+
+__BEGIN_DECLS
+
+/* This is a name for the 48 bit ethernet address available on many
+ systems. */
+struct ether_addr
+{
+ uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+/* 10Mb/s ethernet header */
+struct ether_header
+{
+ uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
+ uint8_t ether_shost[ETH_ALEN]; /* source ether addr */
+ uint16_t ether_type; /* packet type ID field */
+};
+
+/* Ethernet protocol ID's */
+#define ETHERTYPE_PUP 0x0200 /* Xerox PUP */
+#define ETHERTYPE_IP 0x0800 /* IP */
+#define ETHERTYPE_ARP 0x0806 /* Address resolution */
+#define ETHERTYPE_REVARP 0x8035 /* Reverse ARP */
+
+#define ETHER_ADDR_LEN ETH_ALEN /* size of ethernet addr */
+#define ETHER_TYPE_LEN 2 /* bytes in type field */
+#define ETHER_CRC_LEN 4 /* bytes in CRC field */
+#define ETHER_HDR_LEN ETH_HLEN /* total octets in header */
+#define ETHER_MIN_LEN (ETH_ZLEN + ETH_CRC_LEN) /* min packet length */
+#define ETHER_MAX_LEN (ETH_FRAME_LEN + ETH_CRC_LEN) /* max packet length */
+
+/* make sure ethenet length is valid */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
+#define ETHERTYPE_NTRAILER 16
+
+#define ETHERMTU ETH_DATA_LEN
+#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+
+__END_DECLS
+
+#endif /* net/ethernet.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/net/if_arp.h b/REORG.TODO/sysdeps/mach/hurd/net/if_arp.h
new file mode 100644
index 0000000000..59c5f92926
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/net/if_arp.h
@@ -0,0 +1,144 @@
+/* Definitions for Address Resolution Protocol.
+ Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_IF_ARP_H
+
+#define _NET_IF_ARP_H 1
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* Some internals from deep down in the kernel. */
+#define MAX_ADDR_LEN 7
+
+
+/* This structure defines an ethernet arp header. */
+
+/* ARP protocol opcodes. */
+#define ARPOP_REQUEST 1 /* ARP request. */
+#define ARPOP_REPLY 2 /* ARP reply. */
+#define ARPOP_RREQUEST 3 /* RARP request. */
+#define ARPOP_RREPLY 4 /* RARP reply. */
+
+/* See RFC 826 for protocol description. ARP packets are variable
+ in size; the arphdr structure defines the fixed-length portion.
+ Protocol type values are the same as those for 10 Mb/s Ethernet.
+ It is followed by the variable-sized fields ar_sha, arp_spa,
+ arp_tha and arp_tpa in that order, according to the lengths
+ specified. Field names used correspond to RFC 826. */
+
+struct arphdr
+ {
+ unsigned short int ar_hrd; /* Format of hardware address. */
+ unsigned short int ar_pro; /* Format of protocol address. */
+ unsigned char ar_hln; /* Length of hardware address. */
+ unsigned char ar_pln; /* Length of protocol address. */
+ unsigned short int ar_op; /* ARP opcode (command). */
+#if 0
+ /* Ethernet looks like this : This bit is variable sized
+ however... */
+ unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
+ unsigned char __ar_sip[4]; /* Sender IP address. */
+ unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
+ unsigned char __ar_tip[4]; /* Target IP address. */
+#endif
+ };
+
+
+/* ARP protocol HARDWARE identifiers. */
+#define ARPHRD_NETROM 0 /* From KA9Q: NET/ROM pseudo. */
+#define ARPHRD_ETHER 1 /* Ethernet 10Mbps. */
+#define ARPHRD_EETHER 2 /* Experimental Ethernet. */
+#define ARPHRD_AX25 3 /* AX.25 Level 2. */
+#define ARPHRD_PRONET 4 /* PROnet token ring. */
+#define ARPHRD_CHAOS 5 /* Chaosnet. */
+#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB. */
+#define ARPHRD_ARCNET 7 /* ARCnet. */
+#define ARPHRD_APPLETLK 8 /* APPLEtalk. */
+#define ARPHRD_DLCI 15 /* Frame Relay DLCI. */
+#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id). */
+
+/* Dummy types for non ARP hardware */
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260 /* Notional KISS type. */
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271 /* CCITT X.25. */
+#define ARPHRD_PPP 512
+#define ARPHRD_HDLC 513 /* (Cisco) HDLC. */
+#define ARPHRD_LAPB 516 /* LAPB. */
+
+#define ARPHRD_TUNNEL 768 /* IPIP tunnel. */
+#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel. */
+#define ARPHRD_FRAD 770 /* Frame Relay Access Device. */
+#define ARPHRD_SKIP 771 /* SKIP vif. */
+#define ARPHRD_LOOPBACK 772 /* Loopback device. */
+#define ARPHRD_LOCALTLK 773 /* Localtalk device. */
+#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface. */
+#define ARPHRD_BIF 775 /* AP1000 BIF. */
+#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4. */
+
+
+/* ARP ioctl request. */
+struct arpreq
+ {
+ struct sockaddr arp_pa; /* Protocol address. */
+ struct sockaddr arp_ha; /* Hardware address. */
+ int arp_flags; /* Flags. */
+ struct sockaddr arp_netmask; /* Netmask (only for proxy arps). */
+ char arp_dev[16];
+ };
+
+/* ARP Flag values. */
+#define ATF_COM 0x02 /* Completed entry (ha valid). */
+#define ATF_PERM 0x04 /* Permanent entry. */
+#define ATF_PUBL 0x08 /* Publish entry. */
+#define ATF_USETRAILERS 0x10 /* Has requested trailers. */
+#define ATF_NETMASK 0x20 /* Want to use a netmask (only
+ for proxy entries). */
+#define ATF_DONTPUB 0x40 /* Don't answer this addresses. */
+#define ATF_MAGIC 0x80 /* Automatically added entry. */
+
+
+/* Support for the user space arp daemon, arpd. */
+#define ARPD_UPDATE 0x01
+#define ARPD_LOOKUP 0x02
+#define ARPD_FLUSH 0x03
+
+struct arpd_request
+ {
+ unsigned short int req; /* Request type. */
+ uint32_t ip; /* IP address of entry. */
+ unsigned long int dev; /* Device entry is tied to. */
+ unsigned long int stamp;
+ unsigned long int updated;
+ unsigned char ha[MAX_ADDR_LEN]; /* Hardware address. */
+ };
+
+__END_DECLS
+
+#endif /* net/if_arp.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/net/if_ether.h b/REORG.TODO/sysdeps/mach/hurd/net/if_ether.h
new file mode 100644
index 0000000000..3fd09229e1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/net/if_ether.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _NET_IF_ETHER_H
+#define _NET_IF_ETHER_H 1
+
+/*
+ * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
+ * and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+#define ETH_HLEN 14 /* Total octets in header. */
+#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN 1500 /* Max. octets in payload */
+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
+
+/*
+ * These are the defined Ethernet Protocol ID's.
+ */
+
+#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
+#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */
+#define ETH_P_PUP 0x0400 /* Xerox PUP packet */
+#define ETH_P_IP 0x0800 /* Internet Protocol packet */
+#define ETH_P_X25 0x0805 /* CCITT X.25 */
+#define ETH_P_ARP 0x0806 /* Address Resolution packet */
+#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
+#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
+#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
+#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
+#define ETH_P_LAT 0x6004 /* DEC LAT */
+#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
+#define ETH_P_CUST 0x6006 /* DEC Customer use */
+#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
+#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
+#define ETH_P_ATALK 0x809B /* Appletalk DDP */
+#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
+#define ETH_P_IPX 0x8137 /* IPX over DIX */
+#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
+
+/*
+ * Non DIX types. Won't clash for 1500 types.
+ */
+
+#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
+#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
+#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
+#define ETH_P_802_2 0x0004 /* 802.2 frames */
+#define ETH_P_SNAP 0x0005 /* Internal only */
+#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
+#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
+#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
+#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
+#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
+
+/*
+ * This is an Ethernet frame header.
+ */
+
+struct ethhdr
+{
+ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
+ unsigned char h_source[ETH_ALEN]; /* source ether addr */
+ unsigned short int h_proto; /* packet type ID field */
+};
+
+#endif /* net/if_ether.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/net/if_ppp.h b/REORG.TODO/sysdeps/mach/hurd/net/if_ppp.h
new file mode 100644
index 0000000000..8ee620bd03
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/net/if_ppp.h
@@ -0,0 +1,172 @@
+/* From: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * ==FILEVERSION 960926==
+ *
+ * NOTE TO MAINTAINERS:
+ * If you modify this file at all, please set the above date.
+ * if_ppp.h is shipped with a PPP distribution as well as with the kernel;
+ * if everyone increases the FILEVERSION number above, then scripts
+ * can do the right thing when deciding whether to install a new if_ppp.h
+ * file. Don't change the format of that line otherwise, so the
+ * installation script can recognize it.
+ */
+
+
+#ifndef __NET_IF_PPP_H
+#define __NET_IF_PPP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <net/ppp_defs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Packet sizes
+ */
+
+#define PPP_MTU 1500 /* Default MTU (size of Info field) */
+#define PPP_MAXMRU 65000 /* Largest MRU we allow */
+#define PPP_VERSION "2.2.0"
+#define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */
+#define PROTO_IPX 0x002b /* protocol numbers */
+#define PROTO_DNA_RT 0x0027 /* DNA Routing */
+
+
+/*
+ * Bit definitions for flags.
+ */
+
+#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */
+#define SC_COMP_AC 0x00000002 /* header compression (output) */
+#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */
+#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */
+#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */
+#define SC_COMP_RUN 0x00001000 /* compressor has been inited */
+#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */
+#define SC_DEBUG 0x00010000 /* enable debug messages */
+#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
+#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
+#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
+#define SC_MASK 0x0fE0ffff /* bits that user can change */
+
+/* state bits */
+#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */
+#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */
+#define SC_VJ_RESET 0x20000000 /* Need to reset the VJ decompressor */
+#define SC_XMIT_BUSY 0x10000000 /* ppp_write_wakeup is active */
+#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */
+#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */
+#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */
+#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */
+#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */
+#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+ int protocol; /* PPP protocol, e.g. PPP_IP */
+ enum NPmode mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+ uint8_t *ptr;
+ uint32_t length;
+ int transmit;
+};
+
+/* 'struct ifreq' is only available from net/if.h under __USE_MISC. */
+#ifdef __USE_MISC
+struct ifpppstatsreq {
+ struct ifreq b;
+ struct ppp_stats stats; /* statistic information */
+};
+
+struct ifpppcstatsreq {
+ struct ifreq b;
+ struct ppp_comp_stats stats;
+};
+
+#define ifr__name b.ifr_ifrn.ifrn_name
+#define stats_ptr b.ifr_ifru.ifru_data
+#endif
+
+/*
+ * Ioctl definitions.
+ */
+
+#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */
+#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */
+#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */
+#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */
+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
+#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */
+#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */
+#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */
+#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */
+#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */
+#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */
+#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */
+#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */
+#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */
+
+#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */
+#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu ifr_ifru.ifru_metric
+#endif
+
+__END_DECLS
+
+#endif /* net/if_ppp.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/net/route.h b/REORG.TODO/sysdeps/mach/hurd/net/route.h
new file mode 100644
index 0000000000..93f11ef4da
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/net/route.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc..
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Based on the 4.4BSD and Linux version of this file. */
+
+#ifndef _NET_ROUTE_H
+
+#define _NET_ROUTE_H 1
+#include <features.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+
+/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
+struct rtentry
+ {
+ unsigned long int rt_pad1;
+ struct sockaddr rt_dst; /* Target address. */
+ struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */
+ struct sockaddr rt_genmask; /* Target network mask (IP). */
+ unsigned short int rt_flags;
+ short int rt_pad2;
+ unsigned long int rt_pad3;
+ unsigned char rt_tos;
+ unsigned char rt_class;
+ short int rt_pad4;
+ short int rt_metric; /* +1 for binary compatibility! */
+ char *rt_dev; /* Forcing the device at add. */
+ unsigned long int rt_mtu; /* Per route MTU/Window. */
+ unsigned long int rt_window; /* Window clamping. */
+ unsigned short int rt_irtt; /* Initial RTT. */
+ };
+/* Compatibility hack. */
+#define rt_mss rt_mtu
+
+
+struct in6_rtmsg
+ {
+ struct in6_addr rtmsg_dst;
+ struct in6_addr rtmsg_src;
+ struct in6_addr rtmsg_gateway;
+ uint32_t rtmsg_type;
+ uint16_t rtmsg_dst_len;
+ uint16_t rtmsg_src_len;
+ uint32_t rtmsg_metric;
+ unsigned long int rtmsg_info;
+ uint32_t rtmsg_flags;
+ int rtmsg_ifindex;
+ };
+
+
+#define RTF_UP 0x0001 /* Route usable. */
+#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */
+
+#define RTF_HOST 0x0004 /* Host entry (net otherwise). */
+#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */
+#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */
+#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */
+#define RTF_MTU 0x0040 /* Specific MTU for this route. */
+#define RTF_MSS RTF_MTU /* Compatibility. */
+#define RTF_WINDOW 0x0080 /* Per route window clamping. */
+#define RTF_IRTT 0x0100 /* Initial round trip time. */
+#define RTF_REJECT 0x0200 /* Reject route. */
+#define RTF_STATIC 0x0400 /* Manually injected route. */
+#define RTF_XRESOLVE 0x0800 /* External resolver. */
+#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */
+#define RTF_THROW 0x2000 /* Go to next class. */
+#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */
+
+/* for IPv6 */
+#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
+#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */
+#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
+
+#define RTF_LINKRT 0x00100000 /* link specific - device match */
+#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
+
+#define RTF_CACHE 0x01000000 /* cache entry */
+#define RTF_FLOW 0x02000000 /* flow significant route */
+#define RTF_POLICY 0x04000000 /* policy route */
+
+#define RTCF_VALVE 0x00200000
+#define RTCF_MASQ 0x00400000
+#define RTCF_NAT 0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG 0x02000000
+#define RTCF_DIRECTSRC 0x04000000
+
+#define RTF_LOCAL 0x80000000
+#define RTF_INTERFACE 0x40000000
+#define RTF_MULTICAST 0x20000000
+#define RTF_BROADCAST 0x10000000
+#define RTF_NAT 0x08000000
+
+#define RTF_ADDRCLASSMASK 0xF8000000
+#define RT_ADDRCLASS(flags) ((uint32_t) flags >> 23)
+
+#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \
+ == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC 0
+#define RT_CLASS_DEFAULT 253
+
+#define RT_CLASS_MAIN 254
+#define RT_CLASS_LOCAL 255
+#define RT_CLASS_MAX 255
+
+
+#define RTMSG_ACK NLMSG_ACK
+#define RTMSG_OVERRUN NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE 0x11
+#define RTMSG_DELDEVICE 0x12
+#define RTMSG_NEWROUTE 0x21
+#define RTMSG_DELROUTE 0x22
+#define RTMSG_NEWRULE 0x31
+#define RTMSG_DELRULE 0x32
+#define RTMSG_CONTROL 0x40
+
+#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */
+
+#endif /* net/route.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/open.c b/REORG.TODO/sysdeps/mach/hurd/open.c
new file mode 100644
index 0000000000..d25754205b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/open.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
+ a third argument is the file protection. */
+int
+__libc_open (const char *file, int oflag, ...)
+{
+ mode_t mode;
+ io_t port;
+
+ if (__OPEN_NEEDS_MODE (oflag))
+ {
+ 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);
+}
+
+libc_hidden_def (__libc_open)
+weak_alias (__libc_open, __open)
+libc_hidden_weak (__open)
+weak_alias (__libc_open, open)
+
+
+/* open64 is just the same as open for us. */
+weak_alias (__libc_open, __libc_open64)
+weak_alias (__libc_open, __open64)
+libc_hidden_weak (__open64)
+weak_alias (__libc_open, open64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/open64.c b/REORG.TODO/sysdeps/mach/hurd/open64.c
new file mode 100644
index 0000000000..018ac94f28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/open64.c
@@ -0,0 +1 @@
+/* open64 is defined in open.c as an alias. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/openat.c b/REORG.TODO/sysdeps/mach/hurd/openat.c
new file mode 100644
index 0000000000..1213b663ac
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/openat.c
@@ -0,0 +1,59 @@
+/* openat -- Open a file named relative to an open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG. Interpret relative paths relative to
+ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a
+ third argument is the file protection. */
+int
+__openat (int fd, const char *file, int oflag, ...)
+{
+ mode_t mode;
+ io_t port;
+
+ if (__OPEN_NEEDS_MODE (oflag))
+ {
+ va_list arg;
+ va_start (arg, oflag);
+ mode = va_arg (arg, mode_t);
+ va_end (arg);
+ }
+ else
+ mode = 0;
+
+ port = __file_name_lookup_at (fd, 0, file, oflag, mode);
+ if (port == MACH_PORT_NULL)
+ return -1;
+
+ return _hurd_intern_fd (port, oflag, 1);
+}
+libc_hidden_def (__openat)
+weak_alias (__openat, openat)
+
+/* openat64 is just the same as openat for us. */
+weak_alias (__openat, __openat64)
+libc_hidden_weak (__openat64)
+weak_alias (__openat, openat64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/openat64.c b/REORG.TODO/sysdeps/mach/hurd/openat64.c
new file mode 100644
index 0000000000..15d9d6a183
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/openat64.c
@@ -0,0 +1 @@
+/* openat64 is defined in openat.c as an alias. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/opendir.c b/REORG.TODO/sysdeps/mach/hurd/opendir.c
new file mode 100644
index 0000000000..b3dab24da1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/opendir.c
@@ -0,0 +1,130 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <not-cancel.h>
+#include "dirstream.h"
+
+
+/* Open a directory stream on a file descriptor in Hurd internal form.
+ We do no checking here on the descriptor. */
+DIR *
+_hurd_fd_opendir (struct hurd_fd *d)
+{
+ DIR *dirp;
+
+ if (d == NULL)
+ {
+ errno = EBADF;
+ return NULL;
+ }
+
+ dirp = (DIR *) malloc (sizeof (DIR));
+ if (dirp == NULL)
+ return NULL;
+
+ /* Set the descriptor to close on exec. */
+ HURD_CRITICAL_BEGIN;
+ __spin_lock (&d->port.lock);
+ d->flags |= FD_CLOEXEC;
+ __spin_unlock (&d->port.lock);
+ HURD_CRITICAL_END;
+
+ dirp->__fd = d;
+ dirp->__data = dirp->__ptr = NULL;
+ dirp->__entry_data = dirp->__entry_ptr = 0;
+ dirp->__allocation = 0;
+ dirp->__size = 0;
+
+ __libc_lock_init (dirp->__lock);
+
+ return dirp;
+}
+
+
+DIR *
+internal_function
+__opendirat (int dfd, const char *name)
+{
+ if (name[0] == '\0')
+ {
+ /* POSIX.1-1990 says an empty name gets ENOENT;
+ but `open' might like it fine. */
+ __set_errno (ENOENT);
+ return NULL;
+ }
+
+ int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC;
+ int fd;
+#if IS_IN (rtld)
+ assert (dfd == AT_FDCWD);
+ fd = open_not_cancel_2 (name, flags);
+#else
+ fd = openat_not_cancel_3 (dfd, name, flags);
+#endif
+ if (fd < 0)
+ return NULL;
+
+ /* Extract the pointer to the descriptor structure. */
+ DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd));
+ if (dirp == NULL)
+ __close (fd);
+
+ return dirp;
+}
+
+
+/* Open a directory stream on NAME. */
+DIR *
+__opendir (const char *name)
+{
+#if 0 /* TODO. */
+ return __opendirat (AT_FDCWD, name);
+#else
+ if (name[0] == '\0')
+ {
+ /* POSIX.1-1990 says an empty name gets ENOENT;
+ but `open' might like it fine. */
+ __set_errno (ENOENT);
+ return NULL;
+ }
+
+ int fd = __open (name, O_RDONLY | O_NONBLOCK | O_DIRECTORY);
+ if (fd < 0)
+ return NULL;
+
+ /* Extract the pointer to the descriptor structure. */
+ DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd));
+ if (dirp == NULL)
+ __close (fd);
+
+ return dirp;
+#endif
+}
+weak_alias (__opendir, opendir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/pathconf.c b/REORG.TODO/sysdeps/mach/hurd/pathconf.c
new file mode 100644
index 0000000000..bae055ac98
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pathconf.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get file-specific information about FILE. */
+long int
+__pathconf (const char *file, int name)
+{
+ error_t err;
+ int value; /* RPC returns an `int', not a `long int'. */
+ file_t port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1L;
+ err = __io_pathconf (port, name, &value);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err), -1L;
+ return value;
+}
+
+weak_alias (__pathconf, pathconf)
diff --git a/REORG.TODO/sysdeps/mach/hurd/pipe.c b/REORG.TODO/sysdeps/mach/hurd/pipe.c
new file mode 100644
index 0000000000..9525fd9ef0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pipe.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* Create a one-way communication channel (pipe).
+ Actually the channel is two-way on the Hurd.
+ If successful, 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
+__pipe (int fds[2])
+{
+ int save_errno = errno;
+ int result;
+
+ /* The magic S_IFIFO protocol tells the pflocal server to create
+ sockets which report themselves as FIFOs, as POSIX requires for
+ pipes. */
+ result = __socketpair (PF_LOCAL, SOCK_STREAM, S_IFIFO, fds);
+ if (result == -1 && errno == EPROTONOSUPPORT)
+ {
+ /* We contacted an "old" pflocal server that doesn't support the
+ magic S_IFIFO protocol.
+ FIXME: Remove this junk somewhere in the future. */
+ __set_errno (save_errno);
+ return __socketpair (PF_LOCAL, SOCK_STREAM, 0, fds);
+ }
+
+ return result;
+}
+libc_hidden_def (__pipe)
+weak_alias (__pipe, pipe)
diff --git a/REORG.TODO/sysdeps/mach/hurd/poll.c b/REORG.TODO/sysdeps/mach/hurd/poll.c
new file mode 100644
index 0000000000..0625d5db8f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/poll.c
@@ -0,0 +1,47 @@
+/* poll file descriptors. Hurd version.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.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 (struct pollfd *fds, nfds_t nfds, int timeout)
+{
+ struct timespec ts, *to;
+
+ if (timeout < 0)
+ to = NULL;
+ else
+ {
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ to = &ts;
+ }
+
+ return _hurd_select (nfds, fds, NULL, NULL, NULL, to, NULL);
+}
+libc_hidden_def (__poll)
+weak_alias (__poll, poll)
diff --git a/REORG.TODO/sysdeps/mach/hurd/ppoll.c b/REORG.TODO/sysdeps/mach/hurd/ppoll.c
new file mode 100644
index 0000000000..432b1713b7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ppoll.c
@@ -0,0 +1,30 @@
+/* poll file descriptors. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+ppoll (struct pollfd *fds, nfds_t nfds,
+ const struct timespec *timeout, const sigset_t *sigmask)
+{
+ return _hurd_select (nfds, fds, NULL, NULL, NULL, timeout, sigmask);
+}
+libc_hidden_def (ppoll)
diff --git a/REORG.TODO/sysdeps/mach/hurd/pread.c b/REORG.TODO/sysdeps/mach/hurd/pread.c
new file mode 100644
index 0000000000..7d732cc4d7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pread.c
@@ -0,0 +1,32 @@
+/* Read block from given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+
+ssize_t
+__libc_pread (int fd, void *buf, size_t nbytes, off_t offset)
+{
+ return __libc_pread64 (fd, buf, nbytes, (off64_t) offset);
+}
+
+#ifndef __libc_pread
+strong_alias (__libc_pread, __pread)
+weak_alias (__libc_pread, pread)
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/pread64.c b/REORG.TODO/sysdeps/mach/hurd/pread64.c
new file mode 100644
index 0000000000..c4a61c92e2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pread64.c
@@ -0,0 +1,38 @@
+/* Read block from given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_pread64 (int fd, void *buf, size_t nbytes, off64_t offset)
+{
+ error_t err;
+ if (offset < 0)
+ err = EINVAL;
+ else
+ err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes, offset));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+#ifndef __libc_pread64
+weak_alias (__libc_pread64, __pread64)
+weak_alias (__libc_pread64, pread64)
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/prof-freq.c b/REORG.TODO/sysdeps/mach/hurd/prof-freq.c
new file mode 100644
index 0000000000..a3707033a6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/prof-freq.c
@@ -0,0 +1,2 @@
+/* __profile_frequency is in sysdeps/mach/hurd/profil.c. This file
+is here as a place-holder to prevent the use of sysdeps/generic/prof-freq.c. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/profil.c b/REORG.TODO/sysdeps/mach/hurd/profil.c
new file mode 100644
index 0000000000..6830e0facc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/profil.c
@@ -0,0 +1,285 @@
+/* Low-level statistical profiling support function. Mach/Hurd version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+#include <mach/mach4.h>
+#include <mach/pc_sample.h>
+#include <cthreads.h>
+#include <assert.h>
+#include <libc-internal.h>
+
+
+#define MAX_PC_SAMPLES 512 /* XXX ought to be exported in kernel hdr */
+
+static thread_t profile_thread = MACH_PORT_NULL;
+static u_short *samples;
+static size_t maxsamples;
+static size_t pc_offset;
+static size_t sample_scale;
+static sampled_pc_seqno_t seqno;
+static spin_lock_t lock = SPIN_LOCK_INITIALIZER;
+static mach_msg_timeout_t collector_timeout; /* ms between collections. */
+static int profile_tick;
+
+/* Reply port used by profiler thread */
+static mach_port_t profil_reply_port = MACH_PORT_NULL;
+
+/* Forwards */
+static kern_return_t profil_task_get_sampled_pcs (mach_port_t,
+ sampled_pc_seqno_t *,
+ sampled_pc_array_t,
+ mach_msg_type_number_t *);
+static void fetch_samples (void);
+static void profile_waiter (void);
+
+/* Enable statistical profiling, writing samples of the PC into at most
+ SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling
+ is enabled, the system examines the user PC and increments
+ SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536]. If SCALE is zero,
+ disable profiling. Returns zero on success, -1 on error. */
+
+static error_t
+update_waiter (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+{
+ error_t err;
+
+ if (profile_thread == MACH_PORT_NULL)
+ {
+ if (profil_reply_port == MACH_PORT_NULL)
+ profil_reply_port = __mach_reply_port ();
+ /* Set up the profiling collector thread. */
+ err = __thread_create (__mach_task_self (), &profile_thread);
+ if (! err)
+ err = __mach_setup_thread (__mach_task_self (), profile_thread,
+ &profile_waiter, NULL, NULL);
+ }
+ else
+ err = 0;
+
+ if (! err)
+ {
+ err = __task_enable_pc_sampling (__mach_task_self (), &profile_tick,
+ SAMPLED_PC_PERIODIC);
+ if (!err && sample_scale == 0)
+ /* Profiling was not turned on, so the collector thread was
+ suspended. Resume it. */
+ err = __thread_resume (profile_thread);
+ if (! err)
+ {
+ samples = sample_buffer;
+ maxsamples = size / sizeof *sample_buffer;
+ pc_offset = offset;
+ sample_scale = scale;
+ /* Calculate a good period for the collector thread. From TICK
+ and the kernel buffer size we get the length of time it takes
+ to fill the buffer; translate that to milliseconds for
+ mach_msg, and chop it in half for general lag factor. */
+ collector_timeout = MAX_PC_SAMPLES * profile_tick / 1000 / 2;
+ }
+ }
+
+ return err;
+}
+
+int
+__profile_frequency (void)
+{
+ return 1000000 / profile_tick;
+}
+libc_hidden_def (__profile_frequency)
+
+int
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+{
+ error_t err;
+
+ __spin_lock (&lock);
+
+ if (scale == 0)
+ {
+ /* Disable profiling. */
+ int count;
+
+ if (profile_thread != MACH_PORT_NULL)
+ __thread_suspend (profile_thread);
+
+ /* Fetch the last set of samples */
+ if (sample_scale)
+ fetch_samples ();
+
+ err = __task_disable_pc_sampling (__mach_task_self (), &count);
+ sample_scale = 0;
+ seqno = 0;
+ }
+ else
+ err = update_waiter (sample_buffer, size, offset, scale);
+
+ __spin_unlock (&lock);
+
+ return err ? __hurd_fail (err) : 0;
+}
+weak_alias (__profil, profil)
+
+/* Fetch PC samples. This function must be very careful not to depend
+ on Hurd threadvar variables. We arrange that by using a special
+ stub arranged for at the end of this file. */
+static void
+fetch_samples (void)
+{
+ sampled_pc_t pc_samples[MAX_PC_SAMPLES];
+ mach_msg_type_number_t nsamples, i;
+ error_t err;
+
+ nsamples = MAX_PC_SAMPLES;
+
+ err = profil_task_get_sampled_pcs (__mach_task_self (), &seqno,
+ pc_samples, &nsamples);
+ if (err)
+ {
+ static error_t special_profil_failure;
+ static volatile int a, b, c;
+
+ special_profil_failure = err;
+ a = 1;
+ b = 0;
+ while (1)
+ c = a / b;
+ }
+
+ for (i = 0; i < nsamples; ++i)
+ {
+ /* Do arithmetic in long long to avoid overflow problems. */
+ long long pc_difference = pc_samples[i].pc - pc_offset;
+ size_t idx = ((pc_difference / 2) * sample_scale) / 65536;
+ if (idx < maxsamples)
+ ++samples[idx];
+ }
+}
+
+
+/* This function must be very careful not to depend on Hurd threadvar
+ variables. We arrange that by using special stubs arranged for at the
+ end of this file. */
+static void
+profile_waiter (void)
+{
+ mach_msg_header_t msg;
+ mach_port_t timeout_reply_port;
+
+ timeout_reply_port = __mach_reply_port ();
+
+ while (1)
+ {
+ __spin_lock (&lock);
+
+ fetch_samples ();
+
+ __spin_unlock (&lock);
+
+ __mach_msg (&msg, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof msg,
+ timeout_reply_port, collector_timeout, MACH_PORT_NULL);
+ }
+}
+
+/* Fork interaction */
+
+/* Before fork, lock the interlock so that we are in a clean state. */
+static void
+fork_profil_prepare (void)
+{
+ __spin_lock (&lock);
+}
+text_set_element (_hurd_fork_prepare_hook, fork_profil_prepare);
+
+/* In the parent, unlock the interlock once fork is complete. */
+static void
+fork_profil_parent (void)
+{
+ __spin_unlock (&lock);
+}
+text_set_element (_hurd_fork_parent_hook, fork_profil_parent);
+
+/* In the child, unlock the interlock, and start a profiling thread up
+ if necessary. */
+static void
+fork_profil_child (void)
+{
+ u_short *sb;
+ size_t n, o, ss;
+ error_t err;
+
+ __spin_unlock (&lock);
+
+ if (profile_thread != MACH_PORT_NULL)
+ {
+ __mach_port_deallocate (__mach_task_self (), profile_thread);
+ profile_thread = MACH_PORT_NULL;
+ }
+
+ sb = samples;
+ samples = NULL;
+ n = maxsamples;
+ maxsamples = 0;
+ o = pc_offset;
+ pc_offset = 0;
+ ss = sample_scale;
+ sample_scale = 0;
+
+ if (ss != 0)
+ {
+ err = update_waiter (sb, n * sizeof *sb, o, ss);
+ assert_perror (err);
+ }
+}
+text_set_element (_hurd_fork_child_hook, fork_profil_child);
+
+
+
+
+/* Special RPC stubs for profile_waiter are made by including the normal
+ source code, with special CPP state to prevent it from doing the
+ usual thing. */
+
+/* Include these first; then our #define's will take full effect, not
+ being overridden. */
+#include <mach/mig_support.h>
+
+/* This need not do anything; it is always associated with errors, which
+ are fatal in profile_waiter anyhow. */
+#define __mig_put_reply_port(foo)
+
+/* Use our static variable instead of the usual threadvar mechanism for
+ this. */
+#define __mig_get_reply_port() profil_reply_port
+
+/* Make the functions show up as static */
+#define mig_external static
+
+/* Turn off the attempt to generate ld aliasing records. */
+#undef weak_alias
+#define weak_alias(a,b)
+
+/* And change their names to avoid confusing disasters. */
+#define __vm_deallocate_rpc profil_vm_deallocate
+#define __task_get_sampled_pcs profil_task_get_sampled_pcs
+
+/* And include the source code */
+#include <../mach/RPC_task_get_sampled_pcs.c>
diff --git a/REORG.TODO/sysdeps/mach/hurd/pselect.c b/REORG.TODO/sysdeps/mach/hurd/pselect.c
new file mode 100644
index 0000000000..007416ca11
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pselect.c
@@ -0,0 +1,39 @@
+/* pselect for Hurd.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <hurd.h>
+#include <hurd/fd.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. Additionally set the sigmask
+ SIGMASK for this call. Returns the number of ready descriptors, or -1 for
+ errors. */
+int
+__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ const struct timespec *timeout, const sigset_t *sigmask)
+{
+ return _hurd_select (nfds, NULL,
+ readfds, writefds, exceptfds, timeout, sigmask);
+}
+weak_alias (__pselect, pselect)
diff --git a/REORG.TODO/sysdeps/mach/hurd/ptrace.c b/REORG.TODO/sysdeps/mach/hurd/ptrace.c
new file mode 100644
index 0000000000..f8ea7375b3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ptrace.c
@@ -0,0 +1,385 @@
+/* Process tracing interface `ptrace' for GNU Hurd.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+ __sigfillset (&_hurdsig_traced);
+ __USEPORT (PROC, __proc_mark_traced (port));
+ 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
+ {
+ if (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);
+ }
+ else
+ err = 0;
+
+ if (! err)
+ /* Tell the process to take the signal (or just resume if 0). */
+ err = HURD_MSGPORT_RPC
+ (__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)),
+ 0, 0, __msg_sig_post_untraced (msgport, data, 0, task));
+ }
+ __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 __hurd_fail (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 = __msg_set_init_int (msgport, task, INIT_TRACEMASK,
+ request == PTRACE_DETACH ? 0 :
+ ~(sigset_t) 0);
+ if (! err)
+ {
+ if (request == PTRACE_ATTACH)
+ /* Now stop the process. */
+ err = __msg_sig_post (msgport, SIGSTOP, 0, task);
+ else
+ /* Resume the process from tracing stop. */
+ err = __msg_sig_post_untraced (msgport, 0, 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 __hurd_fail (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 __hurd_fail (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 __hurd_fail (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/REORG.TODO/sysdeps/mach/hurd/ptsname.c b/REORG.TODO/sysdeps/mach/hurd/ptsname.c
new file mode 100644
index 0000000000..7625aeed95
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ptsname.c
@@ -0,0 +1,64 @@
+/* ptsname -- return the name of a pty slave given an FD to the pty master
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/term.h>
+
+
+/* Return the pathname of the pseudo terminal slave associated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+char *
+ptsname (int fd)
+{
+ static string_t peername;
+ error_t err;
+
+ err = __ptsname_r (fd, peername, sizeof (peername));
+
+ return err ? NULL : peername;
+}
+
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+int
+__ptsname_r (int fd, char *buf, size_t buflen)
+{
+ string_t peername;
+ size_t len;
+ error_t err;
+
+ if (err = HURD_DPORT_USE (fd, __term_get_peername (port, peername)))
+ return __hurd_dfail (fd, err), errno;
+
+ len = __strnlen (peername, sizeof peername - 1) + 1;
+ if (len > buflen)
+ {
+ errno = ERANGE;
+ return ERANGE;
+ }
+
+ memcpy (buf, peername, len);
+ return 0;
+}
+weak_alias (__ptsname_r, ptsname_r)
diff --git a/REORG.TODO/sysdeps/mach/hurd/pwrite.c b/REORG.TODO/sysdeps/mach/hurd/pwrite.c
new file mode 100644
index 0000000000..10ddfe2bb8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pwrite.c
@@ -0,0 +1,34 @@
+/* Write block at given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Write NBYTES of BUF to FD at given position OFFSET without changing
+ the file position. Return the number written, or -1. */
+ssize_t
+__libc_pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
+{
+ return __libc_pwrite64 (fd, buf, nbytes, (off64_t) offset);
+}
+
+#ifndef __libc_pwrite
+strong_alias (__libc_pwrite, __pwrite)
+weak_alias (__libc_pwrite, pwrite)
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/pwrite64.c b/REORG.TODO/sysdeps/mach/hurd/pwrite64.c
new file mode 100644
index 0000000000..d4aa8f2c4a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/pwrite64.c
@@ -0,0 +1,39 @@
+/* Write block to given position in file without changing file pointer.
+ Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_pwrite64 (int fd, const void *buf, size_t nbytes, off64_t offset)
+{
+ error_t err;
+ if (offset < 0)
+ err = EINVAL;
+ else
+ err = HURD_FD_USE (fd, _hurd_fd_write (descriptor, buf, &nbytes, offset));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+#ifndef __libc_pwrite64
+weak_alias (__libc_pwrite64, __pwrite64)
+libc_hidden_weak (__pwrite64)
+weak_alias (__libc_pwrite64, pwrite64)
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/read.c b/REORG.TODO/sysdeps/mach/hurd/read.c
new file mode 100644
index 0000000000..5cef0b415f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/read.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+/* Read NBYTES into BUF from FD. Return the number read or -1. */
+ssize_t
+__libc_read (int fd, void *buf, size_t nbytes)
+{
+ error_t err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes, -1));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+libc_hidden_def (__libc_read)
+weak_alias (__libc_read, __read)
+libc_hidden_weak (__read)
+weak_alias (__libc_read, read)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readdir.c b/REORG.TODO/sysdeps/mach/hurd/readdir.c
new file mode 100644
index 0000000000..147a0bc469
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readdir.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <endian.h>
+#include <assert.h>
+
+/* Read a directory entry from DIRP. */
+struct dirent *
+__readdir (DIR *dirp)
+{
+ struct dirent64 *entry64 = __readdir64 (dirp);
+
+ if (sizeof (struct dirent64) == sizeof (struct dirent))
+ /* We should in fact just be an alias to readdir64 on this machine. */
+ return (struct dirent *) entry64;
+
+ /* These are all compile-time constants. We know that d_ino is the first
+ member and that the layout of the following members matches exactly in
+ both structures. */
+ assert (offsetof (struct dirent, d_ino) == 0);
+ assert (offsetof (struct dirent64, d_ino) == 0);
+# define MATCH(memb) \
+ assert (offsetof (struct dirent64, memb) - sizeof (entry64->d_ino) \
+ == offsetof (struct dirent, memb) - sizeof (ino_t))
+ MATCH (d_reclen);
+ MATCH (d_type);
+ MATCH (d_namlen);
+# undef MATCH
+
+ if (entry64 == NULL)
+ return NULL;
+
+ struct dirent *const entry = ((void *) (&entry64->d_ino + 1)
+ - sizeof entry->d_ino);
+ const ino_t d_ino = entry64->d_ino;
+ if (d_ino != entry64->d_ino)
+ {
+ __set_errno (EOVERFLOW);
+ return NULL;
+ }
+# if BYTE_ORDER != BIG_ENDIAN /* We just skipped over the zero high word. */
+ entry->d_ino = d_ino; /* ... or the nonzero low word, swap it. */
+# endif
+ entry->d_reclen -= sizeof entry64->d_ino - sizeof entry->d_ino;
+ return entry;
+}
+
+weak_alias (__readdir, readdir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readdir64.c b/REORG.TODO/sysdeps/mach/hurd/readdir64.c
new file mode 100644
index 0000000000..f422fcff04
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readdir64.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Read a directory entry from DIRP. */
+struct dirent64 *
+__readdir64 (DIR *dirp)
+{
+ struct dirent64 *dp;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+
+ 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 = HURD_FD_PORT_USE (dirp->__fd,
+ __dir_readdir (port,
+ &data, &dirp->__size,
+ dirp->__entry_ptr,
+ -1, 0, &nentries)))
+ {
+ __hurd_fail (err);
+ dp = NULL;
+ break;
+ }
+
+ /* 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. */
+ dp = NULL;
+ break;
+ }
+
+ /* We trust the filesystem to return correct data and so we
+ ignore NENTRIES. */
+ }
+
+ dp = (struct dirent64 *) dirp->__ptr;
+ dirp->__ptr += dp->d_reclen;
+ ++dirp->__entry_ptr;
+
+ /* Loop to ignore deleted files. */
+ } while (dp->d_fileno == 0);
+
+ __libc_lock_unlock (dirp->__lock);
+
+ return dp;
+}
+
+weak_alias (__readdir64, readdir64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readdir64_r.c b/REORG.TODO/sysdeps/mach/hurd/readdir64_r.c
new file mode 100644
index 0000000000..9534783521
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readdir64_r.c
@@ -0,0 +1,111 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <stddef.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+/* Read a directory entry from DIRP. */
+int
+__readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
+{
+ struct dirent64 *dp;
+ error_t err = 0;
+
+ if (dirp == NULL)
+ {
+ errno = EINVAL;
+ return errno;
+ }
+
+ __libc_lock_lock (dirp->__lock);
+
+ do
+ {
+ if (dirp->__ptr - dirp->__data >= dirp->__size)
+ {
+ /* We've emptied out our buffer. Refill it. */
+
+ char *data = dirp->__data;
+ int nentries;
+
+ if (err = HURD_FD_PORT_USE (dirp->__fd,
+ __dir_readdir (port,
+ &data, &dirp->__size,
+ dirp->__entry_ptr,
+ -1, 0, &nentries)))
+ {
+ __hurd_fail (err);
+ dp = NULL;
+ break;
+ }
+
+ /* 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. */
+ dp = NULL;
+ break;
+ }
+
+ /* We trust the filesystem to return correct data and so we
+ ignore NENTRIES. */
+ }
+
+ dp = (struct dirent64 *) dirp->__ptr;
+ dirp->__ptr += dp->d_reclen;
+ ++dirp->__entry_ptr;
+
+ /* Loop to ignore deleted files. */
+ } while (dp->d_fileno == 0);
+
+ if (dp)
+ {
+ *entry = *dp;
+ memcpy (entry->d_name, dp->d_name, dp->d_namlen + 1);
+ *result = entry;
+ }
+ else
+ *result = NULL;
+
+ __libc_lock_unlock (dirp->__lock);
+
+ return dp ? 0 : err ? errno : 0;
+}
+
+weak_alias (__readdir64_r, readdir64_r)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readdir_r.c b/REORG.TODO/sysdeps/mach/hurd/readdir_r.c
new file mode 100644
index 0000000000..6acbb7c811
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readdir_r.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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>
+#include <hurd/fd.h>
+#include "dirstream.h"
+
+
+/* Read a directory entry from DIRP. */
+int
+__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ if (sizeof (struct dirent64) == sizeof (struct dirent))
+ /* We should in fact just be an alias to readdir64_r on this machine. */
+ return __readdir64_r (dirp,
+ (struct dirent64 *) entry,
+ (struct dirent64 **) result);
+
+ struct dirent64 *result64;
+ union
+ {
+ struct dirent64 d;
+ char b[offsetof (struct dirent64, d_name) + UCHAR_MAX + 1];
+ } u;
+ int err;
+
+ err = __readdir64_r (dirp, &u.d, &result64);
+ if (result64)
+ {
+ entry->d_fileno = result64->d_fileno;
+ entry->d_reclen = result64->d_reclen;
+ entry->d_type = result64->d_type;
+ entry->d_namlen = result64->d_namlen;
+ memcpy (entry->d_name, result64->d_name, result64->d_namlen + 1);
+ *result = entry;
+ }
+ else
+ *result = NULL;
+
+ return err;
+}
+
+weak_alias (__readdir_r, readdir_r)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readlink.c b/REORG.TODO/sysdeps/mach/hurd/readlink.c
new file mode 100644
index 0000000000..96295dede9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readlink.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__readlink (const char *file_name, char *buf, size_t len)
+{
+ error_t err;
+ file_t file;
+ struct stat64 st;
+
+ file = __file_name_lookup (file_name, O_READ | O_NOLINK, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (file, &st);
+ if (! err)
+ if (S_ISLNK (st.st_mode))
+ {
+ char *rbuf = buf;
+
+ err = __io_read (file, &rbuf, &len, 0, len);
+ if (!err && rbuf != buf)
+ {
+ memcpy (buf, rbuf, len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len);
+ }
+ }
+ else
+ err = EINVAL;
+
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ else
+ return len;
+}
+weak_alias (__readlink, readlink)
diff --git a/REORG.TODO/sysdeps/mach/hurd/readlinkat.c b/REORG.TODO/sysdeps/mach/hurd/readlinkat.c
new file mode 100644
index 0000000000..fa1640fd72
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/readlinkat.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* Read the contents of the symbolic link FILE_NAME relative to FD 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
+readlinkat (int fd, const char *file_name, char *buf, size_t len)
+{
+ error_t err;
+ file_t file;
+ struct stat64 st;
+
+ file = __file_name_lookup_at (fd, 0, file_name, O_READ | O_NOLINK, 0);
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_stat (file, &st);
+ if (! err)
+ if (S_ISLNK (st.st_mode))
+ {
+ char *rbuf = buf;
+
+ err = __io_read (file, &rbuf, &len, 0, len);
+ if (!err && rbuf != buf)
+ {
+ memcpy (buf, rbuf, len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len);
+ }
+ }
+ else
+ err = EINVAL;
+
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ return err ? __hurd_fail (err) : len;
+}
+libc_hidden_def (readlinkat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/reboot.c b/REORG.TODO/sysdeps/mach/hurd/reboot.c
new file mode 100644
index 0000000000..0ad3553707
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/reboot.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+#include <sys/reboot.h>
+
+/* Reboot the system. */
+int
+reboot (int howto)
+{
+ error_t err;
+ startup_t init;
+ mach_port_t hostpriv;
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ 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/REORG.TODO/sysdeps/mach/hurd/recv.c b/REORG.TODO/sysdeps/mach/hurd/recv.c
new file mode 100644
index 0000000000..133f49dfaa
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/recv.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+
+ssize_t
+__recv (int fd, void *buf, size_t n, 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 = 0;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+
+ err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+ flags, &bufp, &nread,
+ &ports, &nports,
+ &cdata, &clen,
+ &flags,
+ n));
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* The file did not grok the socket protocol. */
+ err = ENOTSOCK;
+ if (err)
+ return __hurd_sockfail (fd, flags, 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;
+}
+libc_hidden_def (__recv)
+weak_alias (__recv, recv)
diff --git a/REORG.TODO/sysdeps/mach/hurd/recvfrom.c b/REORG.TODO/sysdeps/mach/hurd/recvfrom.c
new file mode 100644
index 0000000000..4b909174ff
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/recvfrom.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* 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. */
+ssize_t
+__recvfrom (int fd, void *buf, size_t n, int flags, __SOCKADDR_ARG addrarg,
+ socklen_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 = 0;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+ struct sockaddr *addr = addrarg.__sockaddr__;
+
+ if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+ flags, &bufp, &nread,
+ &ports, &nports,
+ &cdata, &clen,
+ &flags,
+ n)))
+ return __hurd_sockfail (fd, flags, err);
+
+ /* Get address data for the returned address port if requested. */
+ if (addr != NULL && addrport != MACH_PORT_NULL)
+ {
+ char *buf = (char *) addr;
+ mach_msg_type_number_t buflen = *addr_len;
+ int type;
+
+ err = __socket_whatis_address (addrport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = (char *)addr;
+ buflen = 0;
+ err = 0;
+ }
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), addrport);
+ return __hurd_sockfail (fd, flags, err);
+ }
+
+ if (*addr_len > buflen)
+ *addr_len = buflen;
+
+ if (buf != (char *) addr)
+ {
+ memcpy (addr, buf, *addr_len);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ addr->sa_family = type;
+ }
+ else if (addr_len != NULL)
+ *addr_len = 0;
+
+ __mach_port_deallocate (__mach_task_self (), addrport);
+
+ /* 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;
+}
+
+weak_alias (__recvfrom, recvfrom)
diff --git a/REORG.TODO/sysdeps/mach/hurd/recvmsg.c b/REORG.TODO/sysdeps/mach/hurd/recvmsg.c
new file mode 100644
index 0000000000..59038dd6d6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/recvmsg.c
@@ -0,0 +1,146 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+
+/* Receive a message as described by MESSAGE from socket FD.
+ Returns the number of bytes read or -1 for errors. */
+ssize_t
+__libc_recvmsg (int fd, struct msghdr *message, int flags)
+{
+ error_t err;
+ addr_port_t aport;
+ char *data = NULL;
+ mach_msg_type_number_t len = 0;
+ mach_port_t *ports;
+ mach_msg_type_number_t nports = 0;
+ char *cdata = NULL;
+ mach_msg_type_number_t clen = 0;
+ size_t amount;
+ char *buf;
+ int i;
+
+ /* Find the total number of bytes to be read. */
+ amount = 0;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+ amount += message->msg_iov[i].iov_len;
+
+ /* As an optimization, we set the initial values of DATA and LEN
+ from the first non-empty iovec. This kicks-in in the case
+ where the whole packet fits into that iovec buffer. */
+ if (data == NULL && message->msg_iov[i].iov_len > 0)
+ {
+ data = message->msg_iov[i].iov_base;
+ len = message->msg_iov[i].iov_len;
+ }
+ }
+
+ buf = data;
+ if (err = HURD_DPORT_USE (fd, __socket_recv (port, &aport,
+ flags, &data, &len,
+ &ports, &nports,
+ &cdata, &clen,
+ &message->msg_flags, amount)))
+ return __hurd_sockfail (fd, flags, err);
+
+ if (message->msg_name != NULL && aport != MACH_PORT_NULL)
+ {
+ char *buf = message->msg_name;
+ mach_msg_type_number_t buflen = message->msg_namelen;
+ int type;
+
+ err = __socket_whatis_address (aport, &type, &buf, &buflen);
+ if (err == EOPNOTSUPP)
+ /* If the protocol server can't tell us the address, just return a
+ zero-length one. */
+ {
+ buf = message->msg_name;
+ buflen = 0;
+ err = 0;
+ }
+
+ if (err)
+ {
+ __mach_port_deallocate (__mach_task_self (), aport);
+ return __hurd_sockfail (fd, flags, err);
+ }
+
+ if (message->msg_namelen > buflen)
+ message->msg_namelen = buflen;
+
+ if (buf != message->msg_name)
+ {
+ memcpy (message->msg_name, buf, message->msg_namelen);
+ __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+ }
+
+ if (buflen > 0)
+ ((struct sockaddr *) message->msg_name)->sa_family = type;
+ }
+ else if (message->msg_name != NULL)
+ message->msg_namelen = 0;
+
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ if (buf == data)
+ buf += len;
+ else
+ {
+ /* Copy the data into MSG. */
+ if (len > amount)
+ message->msg_flags |= MSG_TRUNC;
+ else
+ amount = len;
+
+ buf = data;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+#define min(a, b) ((a) > (b) ? (b) : (a))
+ size_t copy = min (message->msg_iov[i].iov_len, amount);
+
+ memcpy (message->msg_iov[i].iov_base, buf, copy);
+
+ buf += copy;
+ amount -= copy;
+ if (len == 0)
+ break;
+ }
+
+ __vm_deallocate (__mach_task_self (), (vm_address_t) data, len);
+ }
+
+ /* Copy the control message into MSG. */
+ if (clen > message->msg_controllen)
+ message->msg_flags |= MSG_CTRUNC;
+ else
+ message->msg_controllen = clen;
+ memcpy (message->msg_control, cdata, message->msg_controllen);
+
+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+ return (buf - data);
+}
+
+weak_alias (__libc_recvmsg, recvmsg)
+weak_alias (__libc_recvmsg, __recvmsg)
diff --git a/REORG.TODO/sysdeps/mach/hurd/removexattr.c b/REORG.TODO/sysdeps/mach/hurd/removexattr.c
new file mode 100644
index 0000000000..a3edd3d607
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/removexattr.c
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+removexattr (const char *path, const char *name)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_remove (port, name);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return __hurd_fail (err);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/rename.c b/REORG.TODO/sysdeps/mach/hurd/rename.c
new file mode 100644
index 0000000000..1b50f30588
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/rename.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <hurd.h>
+
+/* Rename the file OLD to NEW. */
+int
+rename (const char *old, const char *new)
+{
+ error_t err;
+ file_t olddir, newdir;
+ const char *oldname, *newname;
+
+ olddir = __directory_name_split (old, (char **) &oldname);
+ if (olddir == MACH_PORT_NULL)
+ return -1;
+ newdir = __directory_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, 0);
+ __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/REORG.TODO/sysdeps/mach/hurd/renameat.c b/REORG.TODO/sysdeps/mach/hurd/renameat.c
new file mode 100644
index 0000000000..f2d69d4bc5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/renameat.c
@@ -0,0 +1,47 @@
+/* Rename a file using relative source and destination names. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */
+int
+renameat (int oldfd, const char *old, int newfd, const char *new)
+{
+ error_t err;
+ file_t olddir, newdir;
+ const char *oldname, *newname;
+
+ olddir = __directory_name_split_at (oldfd, old, (char **) &oldname);
+ if (olddir == MACH_PORT_NULL)
+ return -1;
+ newdir = __directory_name_split_at (newfd, new, (char **) &newname);
+ if (newdir == MACH_PORT_NULL)
+ {
+ __mach_port_deallocate (__mach_task_self (), olddir);
+ return -1;
+ }
+
+ err = __dir_rename (olddir, oldname, newdir, newname, 0);
+ __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/REORG.TODO/sysdeps/mach/hurd/revoke.c b/REORG.TODO/sysdeps/mach/hurd/revoke.c
new file mode 100644
index 0000000000..15b955b733
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/revoke.c
@@ -0,0 +1,38 @@
+/* Revoke the access of all descriptors currently open on a file. Hurd version
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <errno.h>
+#include <hurd.h>
+
+int
+revoke (const char *file_name)
+{
+ error_t err;
+ file_t file = __file_name_lookup (file_name, 0, 0);
+
+ if (file == MACH_PORT_NULL)
+ return -1;
+
+ err = __io_revoke (file);
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/rewinddir.c b/REORG.TODO/sysdeps/mach/hurd/rewinddir.c
new file mode 100644
index 0000000000..b6791d95c3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/rewinddir.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Rewind DIRP to the beginning of the directory. */
+void
+__rewinddir (DIR *dirp)
+{
+ seekdir (dirp, (off_t) 0L);
+}
+libc_hidden_def (__rewinddir)
+weak_alias (__rewinddir, rewinddir)
diff --git a/REORG.TODO/sysdeps/mach/hurd/rmdir.c b/REORG.TODO/sysdeps/mach/hurd/rmdir.c
new file mode 100644
index 0000000000..e37245653e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/rmdir.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Remove the directory FILE_NAME. */
+int
+__rmdir (const char *file_name)
+{
+ error_t err;
+ const char *name;
+ file_t parent = __directory_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/REORG.TODO/sysdeps/mach/hurd/sbrk.c b/REORG.TODO/sysdeps/mach/hurd/sbrk.c
new file mode 100644
index 0000000000..5c9555a31c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sbrk.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <unistd.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. */
+void *
+__sbrk (intptr_t increment)
+{
+ void *result;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_brk_lock);
+ result = (void *) _hurd_brk;
+ if (increment != 0 && _hurd_set_brk (_hurd_brk + increment) < 0)
+ result = (void *) -1;
+ __mutex_unlock (&_hurd_brk_lock);
+ HURD_CRITICAL_END;
+
+ return result;
+}
+libc_hidden_def (__sbrk)
+weak_alias (__sbrk, sbrk)
diff --git a/REORG.TODO/sysdeps/mach/hurd/seekdir.c b/REORG.TODO/sysdeps/mach/hurd/seekdir.c
new file mode 100644
index 0000000000..8d3020b02c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/seekdir.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include "dirstream.h"
+
+/* Seek to position POS in DIRP. */
+/* XXX should be __seekdir ? */
+void
+seekdir (DIR *dirp, long int pos)
+{
+ __libc_lock_lock (dirp->__lock);
+ /* 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;
+ __libc_lock_unlock (dirp->__lock);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/select.c b/REORG.TODO/sysdeps/mach/hurd/select.c
new file mode 100644
index 0000000000..e39cf8dc91
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/select.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/fd.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
+__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *timeout)
+{
+ struct timespec ts, *to;
+
+ if (timeout)
+ {
+ to = &ts;
+ TIMEVAL_TO_TIMESPEC (timeout, to);
+ }
+ else
+ to = NULL;
+
+ return _hurd_select (nfds, NULL, readfds, writefds, exceptfds, to, NULL);
+}
+libc_hidden_def (__select)
+weak_alias (__select, select)
diff --git a/REORG.TODO/sysdeps/mach/hurd/send.c b/REORG.TODO/sysdeps/mach/hurd/send.c
new file mode 100644
index 0000000000..98ffcbf562
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/send.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+ssize_t
+__send (int fd, const void *buf, size_t n, int flags)
+{
+ error_t err;
+ size_t 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));
+
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ /* The file did not grok the socket protocol. */
+ err = ENOTSOCK;
+
+ return err ? __hurd_sockfail (fd, flags, err) : wrote;
+}
+libc_hidden_def (__send)
+weak_alias (__send, send)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sendfile.c b/REORG.TODO/sysdeps/mach/hurd/sendfile.c
new file mode 100644
index 0000000000..e318de16a9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sendfile.c
@@ -0,0 +1,36 @@
+/* sendfile -- copy data directly from one file descriptor to another
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/sendfile.h>
+#include <stddef.h>
+
+/* Send COUNT bytes from file associated with IN_FD starting at OFFSET to
+ descriptor OUT_FD. */
+ssize_t
+sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
+{
+ if (offset == NULL || sizeof (off_t) == sizeof (off64_t))
+ return sendfile64 (out_fd, in_fd, (off64_t *) offset, count);
+ else
+ {
+ off64_t ofs = *offset;
+ ssize_t ret = sendfile64 (out_fd, in_fd, &ofs, count);
+ *offset = ofs;
+ return ret;
+ }
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sendfile64.c b/REORG.TODO/sysdeps/mach/hurd/sendfile64.c
new file mode 100644
index 0000000000..0b3d156c28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sendfile64.c
@@ -0,0 +1,59 @@
+/* sendfile -- copy data directly from one file descriptor to another
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/sendfile.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/mman.h>
+
+/* Send COUNT bytes from file associated with IN_FD starting at OFFSET to
+ descriptor OUT_FD. */
+ssize_t
+sendfile64 (int out_fd, int in_fd, off64_t *offset, size_t count)
+{
+ /* We just do a vanilla io_read followed by a vanilla io_write here.
+ In theory the IN_FD filesystem can return us out-of-line data that
+ we then send out-of-line to the OUT_FD filesystem and no copying
+ takes place until those pages need to be flushed or packaged by
+ that filesystem (e.g. packetized by a network socket). However,
+ we momentarily consume COUNT bytes of our local address space,
+ which might blow if it's huge or address space is real tight. */
+
+ char *data = 0;
+ size_t datalen = 0;
+ error_t err = HURD_DPORT_USE (in_fd,
+ __io_read (port, &data, &datalen,
+ offset ? *offset : (off_t) -1,
+ count));
+ if (err == 0)
+ {
+ size_t nwrote;
+ if (datalen == 0)
+ return 0;
+ err = HURD_DPORT_USE (out_fd, __io_write (port, data, datalen,
+ (off_t) -1, &nwrote));
+ munmap (data, datalen);
+ if (err == 0)
+ {
+ if (offset)
+ *offset += datalen;
+ return nwrote;
+ }
+ }
+ return __hurd_fail (err);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sendmsg.c b/REORG.TODO/sysdeps/mach/hurd/sendmsg.c
new file mode 100644
index 0000000000..2f01efe0f7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sendmsg.c
@@ -0,0 +1,165 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/ifsock.h>
+#include <hurd/socket.h>
+#include "hurd/hurdsocket.h"
+
+/* Send a message described MESSAGE on socket FD.
+ Returns the number of bytes sent, or -1 for errors. */
+ssize_t
+__libc_sendmsg (int fd, const struct msghdr *message, int flags)
+{
+ error_t err = 0;
+ struct sockaddr_un *addr = message->msg_name;
+ socklen_t addr_len = message->msg_namelen;
+ addr_port_t aport = MACH_PORT_NULL;
+ union
+ {
+ char *ptr;
+ vm_address_t addr;
+ } data = { .ptr = NULL };
+ char data_buf[2048];
+ mach_msg_type_number_t len;
+ mach_msg_type_number_t amount;
+ int dealloc = 0;
+ int i;
+
+ /* Find the total number of bytes to be written. */
+ len = 0;
+ for (i = 0; i < message->msg_iovlen; i++)
+ {
+ if (message->msg_iov[i].iov_len > 0)
+ {
+ /* As an optimization, if we only have a single non-empty
+ iovec, we set DATA and LEN from it. */
+ if (len == 0)
+ data.ptr = message->msg_iov[i].iov_base;
+ else
+ data.ptr = NULL;
+
+ len += message->msg_iov[i].iov_len;
+ }
+ }
+
+ if (data.ptr == NULL)
+ {
+ size_t to_copy;
+ char *buf;
+
+ /* Allocate a temporary buffer to hold the data. For small
+ amounts of data, we allocate a buffer on the stack. Larger
+ amounts of data are stored in a page-aligned buffer. The
+ limit of 2048 bytes is inspired by the MiG stubs. */
+ if (len > 2048)
+ {
+ err = __vm_allocate (__mach_task_self (), &data.addr, len, 1);
+ if (err)
+ {
+ __set_errno (err);
+ return -1;
+ }
+ dealloc = 1;
+ }
+ else
+ data.ptr = data_buf;
+
+ /* Copy the data into DATA. */
+ to_copy = len;
+ buf = data.ptr;
+ for (i = 0; i < len; i++)
+ {
+#define min(a, b) ((a) > (b) ? (b) : (a))
+ size_t copy = min (message->msg_iov[i].iov_len, to_copy);
+
+ buf = __mempcpy (buf, message->msg_iov[i].iov_base, copy);
+
+ to_copy -= copy;
+ if (to_copy == 0)
+ break;
+ }
+ }
+
+ if (addr)
+ {
+ if (addr->sun_family == AF_LOCAL)
+ {
+ char *name = _hurd_sun_path_dupa (addr, addr_len);
+ /* For the local domain, we must look up the name as a file
+ and talk to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (name, 0, 0);
+ if (file == MACH_PORT_NULL)
+ {
+ if (dealloc)
+ __vm_deallocate (__mach_task_self (), data.addr, len);
+ 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)
+ {
+ if (dealloc)
+ __vm_deallocate (__mach_task_self (), data.addr, len);
+ return __hurd_fail (err);
+ }
+ }
+ else
+ err = EIEIO;
+ }
+
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (err)
+ err = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr,
+ addr_len,
+ &aport);
+ if (! err)
+ {
+ /* Send the data. */
+ err = __socket_send (port, aport,
+ flags, data.ptr, len,
+ NULL,
+ MACH_MSG_TYPE_COPY_SEND, 0,
+ message->msg_control,
+ message->msg_controllen,
+ &amount);
+ __mach_port_deallocate (__mach_task_self (),
+ aport);
+ }
+ err;
+ }));
+
+ if (dealloc)
+ __vm_deallocate (__mach_task_self (), data.addr, len);
+
+ return err ? __hurd_sockfail (fd, flags, err) : amount;
+}
+
+weak_alias (__libc_sendmsg, sendmsg)
+weak_alias (__libc_sendmsg, __sendmsg)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sendto.c b/REORG.TODO/sysdeps/mach/hurd/sendto.c
new file mode 100644
index 0000000000..326999d27b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sendto.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/ifsock.h>
+#include <hurd/socket.h>
+#include "hurd/hurdsocket.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. */
+ssize_t
+__sendto (int fd,
+ const void *buf,
+ size_t n,
+ int flags,
+ const struct sockaddr_un *addr,
+ socklen_t addr_len)
+{
+ addr_port_t aport = MACH_PORT_NULL;
+ error_t err;
+ size_t wrote;
+
+ /* Get an address port for the desired destination address. */
+ error_t create_address_port (io_t port,
+ const struct sockaddr_un *addr,
+ socklen_t addr_len,
+ addr_port_t *aport)
+ {
+ error_t err_port;
+
+ if (addr->sun_family == AF_LOCAL)
+ {
+ char *name = _hurd_sun_path_dupa (addr, addr_len);
+ /* For the local domain, we must look up the name as a file and talk
+ to it with the ifsock protocol. */
+ file_t file = __file_name_lookup (name, 0, 0);
+ if (file == MACH_PORT_NULL)
+ return errno;
+ err_port = __ifsock_getsockaddr (file, aport);
+ __mach_port_deallocate (__mach_task_self (), file);
+ if (err_port == MIG_BAD_ID || err_port == EOPNOTSUPP)
+ /* The file did not grok the ifsock protocol. */
+ err_port = ENOTSOCK;
+ }
+ else
+ {
+ err_port = __socket_create_address (port,
+ addr->sun_family,
+ (char *) addr,
+ addr_len,
+ aport);
+ }
+
+ return err_port;
+ }
+
+ err = HURD_DPORT_USE (fd,
+ ({
+ if (addr != NULL)
+ err = create_address_port (port, addr, addr_len,
+ &aport);
+ else
+ err = 0;
+ if (! err)
+ {
+ /* Send the data. */
+ err = __socket_send (port, aport,
+ flags, buf, n,
+ NULL,
+ MACH_MSG_TYPE_COPY_SEND, 0,
+ NULL, 0, &wrote);
+ }
+ err;
+ }));
+
+ if (aport != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), aport);
+
+ return err ? __hurd_sockfail (fd, flags, err) : wrote;
+}
+
+weak_alias (__sendto, sendto)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setdomain.c b/REORG.TODO/sysdeps/mach/hurd/setdomain.c
new file mode 100644
index 0000000000..0186927212
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setdomain.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include "hurdhost.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
+setdomainname (const char *name, size_t len)
+{
+ /* The NIS domain name is just the contents of the file /etc/nisdomain. */
+ ssize_t n = _hurd_set_host_config ("/etc/nisdomain", name, len);
+ return n < 0 ? -1 : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/setegid.c b/REORG.TODO/sysdeps/mach/hurd/setegid.c
new file mode 100644
index 0000000000..ee0dacf0eb
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setegid.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+setegid (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. */
+
+ if (_hurd_id.gen.ngids > 0)
+ {
+ _hurd_id.gen.gids[0] = gid;
+ _hurd_id.valid = 0;
+ }
+
+ 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,
+ _hurd_id.gen.ngids ? _hurd_id.gen.gids : &gid,
+ _hurd_id.gen.ngids ?: 1,
+ _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;
+}
+libc_hidden_def (setegid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/seteuid.c b/REORG.TODO/sysdeps/mach/hurd/seteuid.c
new file mode 100644
index 0000000000..561f6b0369
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/seteuid.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+seteuid (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. */
+
+ if (_hurd_id.gen.nuids > 0)
+ {
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ }
+
+ err = __USEPORT (AUTH, __auth_makeauth
+ (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.gen.nuids ? _hurd_id.gen.uids : &uid,
+ _hurd_id.gen.nuids ?: 1,
+ _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;
+}
+libc_hidden_def (seteuid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setgid.c b/REORG.TODO/sysdeps/mach/hurd/setgid.c
new file mode 100644
index 0000000000..2311571c23
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setgid.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__setgid (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, *newaux, auxbuf[2];
+ size_t ngen, naux;
+
+ if (_hurd_id.gen.ngids == 0)
+ {
+ /* No effective gids now. The new set will be just GID. */
+ newgen = &gid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.gids[0] = gid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.gids;
+ ngen = _hurd_id.gen.ngids;
+ }
+
+ newaux = _hurd_id.aux.gids;
+ naux = _hurd_id.aux.ngids;
+ if (_hurd_id.gen.nuids > 0 && _hurd_id.gen.uids[0] == 0)
+ {
+ /* We are root; set the real and saved IDs too. */
+ _hurd_id.valid = 0;
+ if (_hurd_id.aux.ngids < 2)
+ {
+ newaux = auxbuf;
+ naux = 2;
+ }
+ newaux[0] = newaux[1] = gid;
+ }
+
+ 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, 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 (__setgid, setgid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setgroups.c b/REORG.TODO/sysdeps/mach/hurd/setgroups.c
new file mode 100644
index 0000000000..7742534b60
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setgroups.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+setgroups (size_t n, 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;
+}
+libc_hidden_def (setgroups)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sethostid.c b/REORG.TODO/sysdeps/mach/hurd/sethostid.c
new file mode 100644
index 0000000000..b1cecd2262
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sethostid.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include "hurdhost.h"
+#include <_itoa.h>
+
+/* Set the current machine's Internet number to ID.
+ This call is restricted to the super-user. */
+/* XXX should be __sethostid?
+ isn't hostid supposed to be hardwired and unchangeable? */
+int
+sethostid (long int id)
+{
+ char buf[8], *bp;
+ ssize_t n;
+
+ /* The hostid is kept in the file /etc/hostid,
+ eight characters of upper-case hexadecimal. */
+
+ bp = _itoa_word (id, &buf[sizeof buf], 16, 1);
+ while (bp > buf)
+ *--bp = '0';
+
+ n = _hurd_set_host_config ("/etc/hostid", buf, sizeof buf);
+ return n < 0 ? -1 : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sethostname.c b/REORG.TODO/sysdeps/mach/hurd/sethostname.c
new file mode 100644
index 0000000000..26615faa28
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sethostname.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include "hurdhost.h"
+
+/* Set the name of the current host to NAME, which is LEN bytes long.
+ This call is restricted to the super-user. */
+/* XXX should be __sethostname ? */
+int
+sethostname (const char *name, size_t len)
+{
+ /* The host name is just the contents of the file /etc/hostname. */
+ ssize_t n = _hurd_set_host_config ("/etc/hostname", name, len);
+ return n < 0 ? -1 : 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/setitimer.c b/REORG.TODO/sysdeps/mach/hurd/setitimer.c
new file mode 100644
index 0000000000..a5ab55405b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setitimer.c
@@ -0,0 +1,372 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <time.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/sigpreempt.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_size_t _hurd_itimer_thread_stack_size; /* Size of its stack. */
+struct timeval _hurd_itimer_started; /* Time the thread started waiting. */
+
+static void
+quantize_timeval (struct timeval *tv)
+{
+ static time_t quantum = -1;
+
+ if (quantum == -1)
+ quantum = 1000000 / __getclktck ();
+
+ tv->tv_usec = ((tv->tv_usec + (quantum - 1)) / quantum) * quantum;
+ if (tv->tv_usec >= 1000000)
+ {
+ ++tv->tv_sec;
+ tv->tv_usec -= 1000000;
+ }
+}
+
+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, 0, __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 int setitimer_locked (const struct itimerval *new,
+ struct itimerval *old, void *crit);
+
+static sighandler_t
+restart_itimer (struct hurd_signal_preemptor *preemptor,
+ struct hurd_sigstate *ss,
+ int *signo, struct hurd_signal_detail *detail)
+{
+ /* This function gets called in the signal thread
+ each time a SIGALRM is arriving (even if blocked). */
+ struct itimerval it;
+
+ /* Either reload or disable the itimer. */
+ __spin_lock (&_hurd_itimer_lock);
+ it.it_value = it.it_interval = _hurd_itimerval.it_interval;
+ setitimer_locked (&it, NULL, NULL);
+
+ /* Continue with normal delivery (or hold, etc.) of SIGALRM. */
+ return SIG_ERR;
+}
+
+
+/* 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;
+ 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 (!new)
+ {
+ /* Just return the current value in OLD without changing anything.
+ This is what BSD does, even though it's not documented. */
+ if (old)
+ *old = _hurd_itimerval;
+ spin_unlock (&_hurd_itimer_lock);
+ _hurd_critical_section_unlock (crit);
+ return 0;
+ }
+
+ newval = *new;
+ quantize_timeval (&newval.it_interval);
+ quantize_timeval (&newval.it_value);
+ if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0)
+ {
+ /* Make sure the itimer thread is set up. */
+
+ /* Set up a signal preemptor global for all threads to
+ run `restart_itimer' each time a SIGALRM would arrive. */
+ static struct hurd_signal_preemptor preemptor =
+ {
+ __sigmask (SIGALRM), 0, 0,
+ &restart_itimer,
+ };
+ __mutex_lock (&_hurd_siglock);
+ if (! preemptor.next && _hurdsig_preemptors != &preemptor)
+ {
+ preemptor.next = _hurdsig_preemptors;
+ _hurdsig_preemptors = &preemptor;
+ }
+ __mutex_unlock (&_hurd_siglock);
+
+ 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))
+ goto out;
+ _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 != newval.it_value.tv_sec ||
+ remaining.tv_usec != newval.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
+__setitimer (enum __itimer_which which, const struct itimerval *new,
+ 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 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);
+
+ (void) &fork_itimer; /* Avoid gcc optimizing out the function. */
+}
+text_set_element (_hurd_fork_child_hook, fork_itimer);
+
+weak_alias (__setitimer, setitimer)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setlogin.c b/REORG.TODO/sysdeps/mach/hurd/setlogin.c
new file mode 100644
index 0000000000..bdac6d1147
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setlogin.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Set the login name returned by `getlogin'. */
+int
+setlogin (const char *name)
+{
+ error_t err;
+ if (err = __USEPORT (PROC, __proc_setlogin (port, name)))
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/setpgid.c b/REORG.TODO/sysdeps/mach/hurd/setpgid.c
new file mode 100644
index 0000000000..1de4c574d5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setpgid.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__setpgid (pid_t pid, 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;
+
+}
+libc_hidden_def (__setpgid)
+weak_alias (__setpgid, setpgid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setpriority.c b/REORG.TODO/sysdeps/mach/hurd/setpriority.c
new file mode 100644
index 0000000000..86992a1f6a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setpriority.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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, id_t 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;
+#ifdef POLICY_TIMESHARE_BASE_COUNT
+ {
+ /* XXX This assumes timeshare policy. */
+ struct policy_timeshare_base base
+ = { NICE_TO_MACH_PRIORITY (prio) };
+ prierr = __task_policy (task, POLICY_TIMESHARE,
+ (policy_base_t) &base,
+ POLICY_TIMESHARE_BASE_COUNT,
+ 0, 1);
+ }
+#else
+ prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1);
+#endif
+ __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, 0);
+
+ 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;
+}
+libc_hidden_def (__setpriority)
+weak_alias (__setpriority, setpriority)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setregid.c b/REORG.TODO/sysdeps/mach/hurd/setregid.c
new file mode 100644
index 0000000000..2fe37bdf8d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setregid.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+
+ gid_t *newgen, *newaux;
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.gids;
+ ngen = _hurd_id.gen.ngids;
+ if (egid != -1)
+ {
+ if (_hurd_id.gen.ngids == 0)
+ {
+ /* No effective gids now. The new set will be just GID. */
+ newgen = &egid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.gids[0] = egid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.gids;
+ naux = _hurd_id.aux.ngids;
+ if (rgid != -1)
+ {
+ if (_hurd_id.aux.ngids == 0)
+ {
+ newaux = &rgid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.gids[0] = rgid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ 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, 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/REORG.TODO/sysdeps/mach/hurd/setresgid.c b/REORG.TODO/sysdeps/mach/hurd/setresgid.c
new file mode 100644
index 0000000000..0eb5d422b7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setresgid.c
@@ -0,0 +1,123 @@
+/* setresgid -- set real group ID, effective group ID, and saved-set group ID
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the real group ID, effective group ID, and saved-set group ID,
+ of the calling process to RGID, EGID, and SGID, respectively. */
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ 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. */
+
+ uid_t *newgen, *newaux;
+ uid_t auxs[2] = { rgid, sgid };
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.gids;
+ ngen = _hurd_id.gen.ngids;
+ if (egid != -1)
+ {
+ if (_hurd_id.gen.ngids == 0)
+ {
+ /* No effective gids now. The new set will be just UID. */
+ newgen = &egid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.gids[0] = egid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.gids;
+ naux = _hurd_id.aux.ngids;
+ if (rgid != -1)
+ {
+ if (_hurd_id.aux.ngids == 0)
+ {
+ newaux = &rgid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.gids[0] = rgid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ if (sgid != -1)
+ {
+ if (rgid == -1)
+ {
+ if (_hurd_id.aux.ngids >= 1)
+ auxs[0] = _hurd_id.aux.gids[0];
+ else if (_hurd_id.gen.ngids >= 1)
+ auxs[0] = _hurd_id.gen.gids[0];
+ else
+ /* Not even an effective GID.
+ Fall back to the only GID we have. */
+ auxs[0] = sgid;
+ }
+ if (_hurd_id.aux.ngids <= 1)
+ {
+ /* No saved gids now. The new set will be just UID. */
+ newaux = auxs;
+ naux = 2;
+ }
+ else
+ {
+ _hurd_id.aux.gids[1] = sgid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ 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, 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;
+}
+libc_hidden_def (__setresgid)
+weak_alias (__setresgid, setresgid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setresuid.c b/REORG.TODO/sysdeps/mach/hurd/setresuid.c
new file mode 100644
index 0000000000..39f64d44e0
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setresuid.c
@@ -0,0 +1,124 @@
+/* setresuid -- set real user ID, effective user ID, and saved-set user ID
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the real user ID, effective user ID, and saved-set user ID,
+ of the calling process to RUID, EUID, and SUID, respectively. */
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ 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. */
+
+ uid_t *newgen, *newaux;
+ uid_t auxs[2] = { ruid, suid };
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ if (euid != -1)
+ {
+ if (_hurd_id.gen.nuids == 0)
+ {
+ /* No effective uids now. The new set will be just UID. */
+ newgen = &euid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.uids[0] = euid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.uids;
+ naux = _hurd_id.aux.nuids;
+ if (ruid != -1)
+ {
+ if (_hurd_id.aux.nuids == 0)
+ {
+ newaux = &ruid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.uids[0] = ruid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ if (suid != -1)
+ {
+ if (ruid == -1)
+ {
+ if (_hurd_id.aux.nuids >= 1)
+ auxs[0] = _hurd_id.aux.uids[0];
+ else if (_hurd_id.gen.nuids >= 1)
+ auxs[0] = _hurd_id.gen.uids[0];
+ else
+ /* Not even an effective UID.
+ Fall back to the only UID we have. */
+ auxs[0] = suid;
+ }
+ if (_hurd_id.aux.nuids <= 1)
+ {
+ /* No saved uids now. The new set will be just UID. */
+ newaux = auxs;
+ naux = 2;
+ }
+ else
+ {
+ _hurd_id.aux.uids[1] = suid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ 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;
+}
+libc_hidden_def (__setresuid)
+weak_alias (__setresuid, setresuid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setreuid.c b/REORG.TODO/sysdeps/mach/hurd/setreuid.c
new file mode 100644
index 0000000000..5fdaa877e3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setreuid.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+
+ uid_t *newgen, *newaux;
+ size_t ngen, naux;
+
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ if (euid != -1)
+ {
+ if (_hurd_id.gen.nuids == 0)
+ {
+ /* No effective uids now. The new set will be just UID. */
+ newgen = &euid;
+ ngen = 1;
+ }
+ else
+ {
+ _hurd_id.gen.uids[0] = euid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ newaux = _hurd_id.aux.uids;
+ naux = _hurd_id.aux.nuids;
+ if (ruid != -1)
+ {
+ if (_hurd_id.aux.nuids == 0)
+ {
+ newaux = &ruid;
+ naux = 1;
+ }
+ else
+ {
+ _hurd_id.aux.uids[0] = ruid;
+ _hurd_id.valid = 0;
+ }
+ }
+
+ 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/REORG.TODO/sysdeps/mach/hurd/setrlimit.c b/REORG.TODO/sysdeps/mach/hurd/setrlimit.c
new file mode 100644
index 0000000000..3ea9af2e7c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setrlimit.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/resource.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
+__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
+{
+ struct rlimit lim;
+
+ if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ lim = *rlimits;
+
+ /* Even though most limits do nothing, there is no inheritance, and hard
+ limits are not really hard, we just let any old call succeed to make
+ life easier for programs that expect normal behavior. */
+
+ if (lim.rlim_cur > lim.rlim_max)
+ lim.rlim_cur = lim.rlim_max;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_rlimit_lock);
+ _hurd_rlimits[resource] = lim;
+ __mutex_unlock (&_hurd_rlimit_lock);
+ HURD_CRITICAL_END;
+
+ return 0;
+}
+
+weak_alias (__setrlimit, setrlimit)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setsid.c b/REORG.TODO/sysdeps/mach/hurd/setsid.c
new file mode 100644
index 0000000000..60794df7b8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setsid.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/fd.h>
+#include <hurd/ioctl.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. */
+pid_t
+__setsid (void)
+{
+ error_t err;
+ unsigned int stamp;
+
+ HURD_CRITICAL_BEGIN;
+ __mutex_lock (&_hurd_dtable_lock);
+
+ stamp = _hurd_pids_changed_stamp; /* Atomic fetch. */
+
+ /* Tell the proc server we want to start a new session. */
+ err = __USEPORT (PROC, __proc_setsid (port));
+ if (err)
+ __mutex_unlock (&_hurd_dtable_lock);
+ else
+ {
+ /* Punt our current ctty, and update the dtable accordingly. We hold
+ the dtable lock from before the proc_setsid call through clearing
+ the cttyid port and processing the dtable, so that we can be sure
+ that it's all done by the time the signal thread processes the
+ pgrp change notification. */
+ _hurd_locked_install_cttyid (MACH_PORT_NULL);
+
+ /* Synchronize with the signal thread to make sure we have received
+ and processed proc_newids before returning to the user.
+ This is necessary to ensure that _hurd_pgrp (and thus the value
+ returned by `getpgrp ()' in other threads) has been updated before
+ we return. */
+ 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
+ }
+ }
+
+ HURD_CRITICAL_END;
+
+ return err ? __hurd_fail (err) : _hurd_pgrp;
+}
+
+weak_alias (__setsid, setsid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setsockopt.c b/REORG.TODO/sysdeps/mach/hurd/setsockopt.c
new file mode 100644
index 0000000000..de041e991c
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setsockopt.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__setsockopt (int fd,
+ int level,
+ int optname,
+ const void *optval,
+ socklen_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;
+}
+
+weak_alias (__setsockopt, setsockopt)
diff --git a/REORG.TODO/sysdeps/mach/hurd/settimeofday.c b/REORG.TODO/sysdeps/mach/hurd/settimeofday.c
new file mode 100644
index 0000000000..71225ee3dc
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/settimeofday.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__settimeofday (const struct timeval *tv, const struct timezone *tz)
+{
+ error_t err;
+ mach_port_t hostpriv;
+
+ if (tz != NULL)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ err = __get_privileged_ports (&hostpriv, NULL);
+ if (err)
+ return __hurd_fail (EPERM);
+
+ /* `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/REORG.TODO/sysdeps/mach/hurd/setuid.c b/REORG.TODO/sysdeps/mach/hurd/setuid.c
new file mode 100644
index 0000000000..e78c5dd48f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setuid.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__setuid (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, *newaux, auxbuf[2];
+ size_t ngen, naux;
+
+ newaux = _hurd_id.aux.uids;
+ naux = _hurd_id.aux.nuids;
+ if (_hurd_id.gen.nuids == 0)
+ {
+ /* No effective uids now. The new set will be just UID. */
+ newgen = &uid;
+ ngen = 1;
+ }
+ else if (_hurd_id.gen.uids[0] == 0)
+ {
+ /* We are root; set the effective, real, and saved to UID. */
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ if (_hurd_id.aux.nuids < 2)
+ {
+ newaux = auxbuf;
+ naux = 2;
+ }
+ newaux[0] = newaux[1] = uid;
+ }
+ else
+ {
+ /* We are not root; just change the effective UID. */
+ /* XXX that implies an unprivileged setuid(0) will give
+ the caller root, no questions asked! */
+ _hurd_id.gen.uids[0] = uid;
+ _hurd_id.valid = 0;
+ newgen = _hurd_id.gen.uids;
+ ngen = _hurd_id.gen.nuids;
+ }
+
+ 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 (__setuid, setuid)
diff --git a/REORG.TODO/sysdeps/mach/hurd/setxattr.c b/REORG.TODO/sysdeps/mach/hurd/setxattr.c
new file mode 100644
index 0000000000..0dc7fb4777
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/setxattr.c
@@ -0,0 +1,35 @@
+/* Access to extended attributes on files. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/xattr.h>
+#include <hurd.h>
+#include <hurd/xattr.h>
+
+ssize_t
+setxattr (const char *path, const char *name, const void *value, size_t size,
+ int flags)
+{
+ error_t err;
+ file_t port = __file_name_lookup (path, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = _hurd_xattr_set (port, name, value, size, flags);
+ __mach_port_deallocate (__mach_task_self (), port);
+ return __hurd_fail (err);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/shlib-versions b/REORG.TODO/sysdeps/mach/hurd/shlib-versions
new file mode 100644
index 0000000000..edbc3014a6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/shlib-versions
@@ -0,0 +1,12 @@
+DEFAULT GLIBC_2.2.6
+
+libm=6
+
+# libmachuser.so.1 corresponds to mach/*.defs as of Utah's UK22 release.
+libmachuser=1
+
+# libhurduser.so.0.3 corresponds to hurd/*.defs as of 11 June 2002.
+libhurduser=0.3
+
+# libc.so.0.3 is the first Hurd libc using libio.
+libc=0.3
diff --git a/REORG.TODO/sysdeps/mach/hurd/shutdown.c b/REORG.TODO/sysdeps/mach/hurd/shutdown.c
new file mode 100644
index 0000000000..0869a777c8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/shutdown.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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. */
+/* XXX should be __shutdown ? */
+int
+shutdown (int fd, 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/REORG.TODO/sysdeps/mach/hurd/sigaction.c b/REORG.TODO/sysdeps/mach/hurd/sigaction.c
new file mode 100644
index 0000000000..c01d3a1979
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigaction.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__sigaction (int sig, const struct sigaction *act, 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->critical_section_lock);
+ __spin_lock (&ss->lock);
+ old = ss->actions[sig];
+ if (act != NULL)
+ ss->actions[sig] = a;
+
+ if (act != NULL && sig == SIGCHLD &&
+ (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
+ {
+ __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);
+ pending = ss->pending & ~ss->blocked;
+ }
+ else if (act != NULL && (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL))
+ /* We are changing to an action that might be to ignore SIG signals.
+ If SIG is blocked and pending and the new action is to ignore it, we
+ must remove it from the pending set now; if the action is changed
+ back and then SIG is unblocked, the signal pending now should not
+ arrive. So wake up the signal thread to check the new state and do
+ the right thing. */
+ pending = ss->pending & __sigmask (sig);
+ else
+ pending = 0;
+
+ __spin_unlock (&ss->lock);
+ __spin_unlock (&ss->critical_section_lock);
+
+ if (pending)
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+
+ if (oact != NULL)
+ *oact = old;
+
+ return 0;
+}
+libc_hidden_def (__sigaction)
+weak_alias (__sigaction, sigaction)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sigaltstack.c b/REORG.TODO/sysdeps/mach/hurd/sigaltstack.c
new file mode 100644
index 0000000000..4fba69e766
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigaltstack.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__sigaltstack (const stack_t *argss, stack_t *oss)
+{
+ struct hurd_sigstate *s;
+ stack_t ss, old;
+
+ /* Fault before taking any locks. */
+ if (argss != NULL)
+ ss = *argss;
+ if (oss != NULL)
+ *(volatile stack_t *) oss = *oss;
+
+ s = _hurd_self_sigstate ();
+ __spin_lock (&s->lock);
+
+ if (argss != NULL &&
+ (ss.ss_flags & SS_DISABLE) && (s->sigaltstack.ss_flags & SS_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;
+}
+weak_alias (__sigaltstack, sigaltstack)
diff --git a/REORG.TODO/sysdeps/mach/hurd/siglist.h b/REORG.TODO/sysdeps/mach/hurd/siglist.h
new file mode 100644
index 0000000000..a87718c6d9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/siglist.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is included multiple times. */
+
+#include_next <siglist.h> /* Get the canonical list. */
+
+#define OLD_SIGLIST_SIZE 33 /* For GLIBC_2.0 binary compatibility. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/sigpending.c b/REORG.TODO/sysdeps/mach/hurd/sigpending.c
new file mode 100644
index 0000000000..c5510239c8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigpending.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+
+/* Store in SET all signals that are blocked and pending. */
+/* XXX should be __sigpending ? */
+int
+sigpending (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/REORG.TODO/sysdeps/mach/hurd/sigprocmask.c b/REORG.TODO/sysdeps/mach/hurd/sigprocmask.c
new file mode 100644
index 0000000000..a4ebe580ff
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigprocmask.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__sigprocmask (int how, const sigset_t *set, 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:
+ __sigorset (&ss->blocked, &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, 0, __mach_task_self ());
+
+ return 0;
+}
+
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sigstack.c b/REORG.TODO/sysdeps/mach/hurd/sigstack.c
new file mode 100644
index 0000000000..484efb627a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigstack.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+sigstack (struct sigstack *ss, struct sigstack *oss)
+{
+ stack_t 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 & SS_ONSTACK;
+ }
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sigsuspend.c b/REORG.TODO/sysdeps/mach/hurd/sigsuspend.c
new file mode 100644
index 0000000000..4f5af1d302
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigsuspend.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__sigsuspend (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, 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, 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;
+}
+libc_hidden_def (__sigsuspend)
+strong_alias (__sigsuspend, sigsuspend_not_cancel)
+weak_alias (__sigsuspend, sigsuspend)
diff --git a/REORG.TODO/sysdeps/mach/hurd/sigwait.c b/REORG.TODO/sysdeps/mach/hurd/sigwait.c
new file mode 100644
index 0000000000..c9fd8fce88
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sigwait.c
@@ -0,0 +1,133 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+#include <hurd/sigpreempt.h>
+#include <assert.h>
+
+/* Select any of pending signals from SET or wait for any to arrive. */
+int
+__sigwait (const sigset_t *set, int *sig)
+{
+ struct hurd_sigstate *ss;
+ sigset_t mask, ready;
+ int signo = 0;
+ struct hurd_signal_preemptor preemptor;
+ jmp_buf buf;
+ mach_port_t wait;
+ mach_msg_header_t msg;
+
+ sighandler_t
+ preempt_fun (struct hurd_signal_preemptor *pe,
+ struct hurd_sigstate *ss,
+ int *sigp,
+ struct hurd_signal_detail *detail)
+ {
+ if (signo)
+ /* We've already been run; don't interfere. */
+ return SIG_ERR;
+
+ signo = *sigp;
+
+ /* Make sure this is all kosher */
+ assert (__sigismember (&mask, signo));
+
+ /* Make sure this signal is unblocked */
+ __sigdelset (&ss->blocked, signo);
+
+ return pe->handler;
+ }
+
+ void
+ handler (int sig)
+ {
+ assert (sig == signo);
+ longjmp (buf, 1);
+ }
+
+ wait = __mach_reply_port ();
+
+ if (set != NULL)
+ /* Crash before locking */
+ mask = *set;
+ else
+ __sigemptyset (&mask);
+
+ ss = _hurd_self_sigstate ();
+ __spin_lock (&ss->lock);
+
+ /* See if one of these signals is currently pending. */
+ __sigandset (&ready, &ss->pending, &mask);
+ if (! __sigisemptyset (&ready))
+ {
+ for (signo = 1; signo < NSIG; signo++)
+ if (__sigismember (&ready, signo))
+ {
+ __sigdelset (&ready, signo);
+ goto all_done;
+ }
+ /* Huh? Where'd it go? */
+ abort ();
+ }
+
+ /* Wait for one of them to show up. */
+
+ if (!setjmp (buf))
+ {
+ /* Make the preemptor */
+ preemptor.signals = mask;
+ preemptor.first = 0;
+ preemptor.last = -1;
+ preemptor.preemptor = preempt_fun;
+ preemptor.handler = handler;
+
+ /* Install this preemptor */
+ preemptor.next = ss->preemptors;
+ ss->preemptors = &preemptor;
+
+ __spin_unlock (&ss->lock);
+
+ /* Wait. */
+ __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ abort ();
+ }
+ else
+ {
+ assert (signo);
+
+ __spin_lock (&ss->lock);
+
+ /* Delete our preemptor. */
+ assert (ss->preemptors == &preemptor);
+ ss->preemptors = preemptor.next;
+ }
+
+
+all_done:
+ spin_unlock (&ss->lock);
+
+ __mach_port_destroy (__mach_task_self (), wait);
+ *sig = signo;
+ return 0;
+}
+
+libc_hidden_def (__sigwait)
+weak_alias (__sigwait, sigwait)
diff --git a/REORG.TODO/sysdeps/mach/hurd/socket.c b/REORG.TODO/sysdeps/mach/hurd/socket.c
new file mode 100644
index 0000000000..9412821d14
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/socket.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__socket (int domain, int type, 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
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ {
+ /* 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);
+ }
+
+ /* These errors all mean that the server node doesn't support the
+ socket.defs protocol, which we'll take to mean that the protocol
+ isn't supported. */
+ if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ err = EAFNOSUPPORT;
+
+ if (err)
+ return __hurd_fail (err);
+
+ return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1);
+}
+
+libc_hidden_def (__socket)
+weak_alias (__socket, socket)
diff --git a/REORG.TODO/sysdeps/mach/hurd/socketpair.c b/REORG.TODO/sysdeps/mach/hurd/socketpair.c
new file mode 100644
index 0000000000..f3cbf8c19b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/socketpair.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/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
+__socketpair (int domain, int type, int protocol, 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
+ || err == MIG_BAD_ID || err == EOPNOTSUPP)
+ {
+ /* 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;
+}
+
+weak_alias (__socketpair, socketpair)
diff --git a/REORG.TODO/sysdeps/mach/hurd/spawni.c b/REORG.TODO/sysdeps/mach/hurd/spawni.c
new file mode 100644
index 0000000000..74303839e4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/spawni.c
@@ -0,0 +1,758 @@
+/* spawn a new process running an executable. Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/fd.h>
+#include <hurd/id.h>
+#include <hurd/lookup.h>
+#include <hurd/resource.h>
+#include <assert.h>
+#include <argz.h>
+#include "spawn_int.h"
+
+/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
+ Before running the process perform the actions described in FILE-ACTIONS. */
+int
+__spawni (pid_t *pid, const char *file,
+ const posix_spawn_file_actions_t *file_actions,
+ const posix_spawnattr_t *attrp,
+ char *const argv[], char *const envp[],
+ int xflags)
+{
+ pid_t new_pid;
+ char *path, *p, *name;
+ size_t len;
+ size_t pathlen;
+ short int flags;
+
+ /* The generic POSIX.1 implementation of posix_spawn uses fork and exec.
+ In traditional POSIX systems (Unix, Linux, etc), the only way to
+ create a new process is by fork, which also copies all the things from
+ the parent process that will be immediately wiped and replaced by the
+ exec.
+
+ This Hurd implementation works by doing an exec on a fresh task,
+ without ever doing all the work of fork. The only work done by fork
+ that remains visible after an exec is registration with the proc
+ server, and the inheritance of various values and ports. All those
+ inherited values and ports are what get collected up and passed in the
+ file_exec RPC by an exec call. So we do the proc server registration
+ here, following the model of fork (see fork.c). We then collect up
+ the inherited values and ports from this (parent) process following
+ the model of exec (see hurd/hurdexec.c), modify or replace each value
+ that fork would (plus the specific changes demanded by ATTRP and
+ FILE_ACTIONS), and make the file_exec RPC on the requested executable
+ file with the child process's task port rather than our own. This
+ should be indistinguishable from the fork + exec implementation,
+ except that all errors will be detected here (in the parent process)
+ and return proper errno codes rather than the child dying with 127.
+
+ XXX The one exception to this supposed indistinguishableness is that
+ when posix_spawn_file_actions_addopen has been used, the parent
+ process can do various filesystem RPCs on the child's behalf, rather
+ than the child process doing it. If these block due to a broken or
+ malicious filesystem server or just a blocked network fs or a serial
+ port waiting for carrier detect (!!), the parent's posix_spawn call
+ can block arbitrarily rather than just the child blocking. Possible
+ solutions include:
+ * punt to plain fork + exec implementation if addopen was used
+ ** easy to do
+ ** gives up all benefits of this implementation in that case
+ * if addopen was used, don't do any file actions at all here;
+ instead, exec an installed helper program e.g.:
+ /libexec/spawn-helper close 3 dup2 1 2 open 0 /file 0x123 0666 exec /bin/foo foo a1 a2
+ ** extra exec might be more or less overhead than fork
+ * could do some weird half-fork thing where the child would inherit
+ our vm and run some code here, but not do the full work of fork
+
+ XXX Actually, the parent opens the executable file on behalf of
+ the child, and that has all the same issues.
+
+ I am favoring the half-fork solution. That is, we do task_create with
+ vm inheritance, and we setjmp/longjmp the child like fork does. But
+ rather than all the fork hair, the parent just packs up init/dtable
+ ports and does a single IPC to a receive right inserted in the child. */
+
+ error_t err;
+ task_t task;
+ file_t execfile;
+ process_t proc;
+ auth_t auth;
+ int ints[INIT_INT_MAX];
+ file_t *dtable;
+ unsigned int dtablesize, orig_dtablesize, i;
+ struct hurd_port **dtable_cells;
+ char *dtable_cloexec;
+ struct hurd_userlink *ulink_dtable = NULL;
+ struct hurd_sigstate *ss;
+
+ /* For POSIX_SPAWN_RESETIDS, this reauthenticates our root/current
+ directory ports with the new AUTH port. */
+ file_t rcrdir = MACH_PORT_NULL, rcwdir = MACH_PORT_NULL;
+ error_t reauthenticate (int which, file_t *result)
+ {
+ error_t err;
+ mach_port_t ref;
+ if (*result != MACH_PORT_NULL)
+ return 0;
+ ref = __mach_reply_port ();
+ err = HURD_PORT_USE
+ (&_hurd_ports[which],
+ ({
+ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ result);
+ err;
+ }));
+ __mach_port_destroy (__mach_task_self (), ref);
+ return err;
+ }
+
+ /* Reauthenticate one of our file descriptors for the child. A null
+ element of DTABLE_CELLS indicates a descriptor that was already
+ reauthenticated, or was newly opened on behalf of the child. */
+ error_t reauthenticate_fd (int fd)
+ {
+ if (dtable_cells[fd] != NULL)
+ {
+ file_t newfile;
+ mach_port_t ref = __mach_reply_port ();
+ error_t err = __io_reauthenticate (dtable[fd],
+ ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newfile);
+ __mach_port_destroy (__mach_task_self (), ref);
+ if (err)
+ return err;
+ _hurd_port_free (dtable_cells[fd], &ulink_dtable[fd], dtable[fd]);
+ dtable_cells[fd] = NULL;
+ dtable[fd] = newfile;
+ }
+ return 0;
+ }
+
+ /* These callbacks are for looking up file names on behalf of the child. */
+ error_t child_init_port (int which, error_t (*operate) (mach_port_t))
+ {
+ if (flags & POSIX_SPAWN_RESETIDS)
+ switch (which)
+ {
+ case INIT_PORT_AUTH:
+ return (*operate) (auth);
+ case INIT_PORT_CRDIR:
+ return (reauthenticate (INIT_PORT_CRDIR, &rcrdir)
+ ?: (*operate) (rcrdir));
+ case INIT_PORT_CWDIR:
+ return (reauthenticate (INIT_PORT_CWDIR, &rcwdir)
+ ?: (*operate) (rcwdir));
+ }
+ assert (which != INIT_PORT_PROC);
+ return _hurd_ports_use (which, operate);
+ }
+ file_t child_fd (int fd)
+ {
+ if ((unsigned int) fd < dtablesize && dtable[fd] != MACH_PORT_NULL)
+ {
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ /* Reauthenticate this descriptor right now,
+ since it is going to be used on behalf of the child. */
+ errno = reauthenticate_fd (fd);
+ if (errno)
+ return MACH_PORT_NULL;
+ }
+ __mach_port_mod_refs (__mach_task_self (), dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ return dtable[fd];
+ }
+ errno = EBADF;
+ return MACH_PORT_NULL;
+ }
+ inline error_t child_lookup (const char *file, int oflag, mode_t mode,
+ file_t *result)
+ {
+ return __hurd_file_name_lookup (&child_init_port, &child_fd, 0,
+ file, oflag, mode, result);
+ }
+
+
+ /* Do this once. */
+ flags = attrp == NULL ? 0 : attrp->__flags;
+
+ /* Generate the new process. We create a task that does not inherit our
+ memory, and then register it as our child like fork does. See fork.c
+ for comments about the sequencing of these proc operations. */
+
+ err = __task_create (__mach_task_self (),
+#ifdef KERN_INVALID_LEDGER
+ NULL, 0, /* OSF Mach */
+#endif
+ 0, &task);
+ if (err)
+ return __hurd_fail (err);
+ // From here down we must deallocate TASK and PROC before returning.
+ proc = MACH_PORT_NULL;
+ auth = MACH_PORT_NULL;
+ err = __USEPORT (PROC, __proc_task2pid (port, task, &new_pid));
+ if (!err)
+ err = __USEPORT (PROC, __proc_task2proc (port, task, &proc));
+ if (!err)
+ err = __USEPORT (PROC, __proc_child (port, task));
+ if (err)
+ goto out;
+
+ /* Load up the ints to give the new program. */
+ memset (ints, 0, sizeof ints);
+ ints[INIT_UMASK] = _hurd_umask;
+ ints[INIT_TRACEMASK] = _hurdsig_traced;
+
+ ss = _hurd_self_sigstate ();
+
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+ __spin_lock (&ss->lock);
+ ints[INIT_SIGMASK] = ss->blocked;
+ ints[INIT_SIGPENDING] = ss->pending;
+ ints[INIT_SIGIGN] = 0;
+ /* Unless we were asked to reset all handlers to SIG_DFL,
+ pass down the set of signals that were set to SIG_IGN. */
+ if ((flags & POSIX_SPAWN_SETSIGDEF) == 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. */
+
+ __spin_unlock (&ss->lock);
+
+ /* Set signal mask. */
+ if ((flags & POSIX_SPAWN_SETSIGMASK) != 0)
+ ints[INIT_SIGMASK] = attrp->__ss;
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ /* Set the scheduling algorithm and parameters. */
+# error implement me
+ if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
+ == POSIX_SPAWN_SETSCHEDPARAM)
+ {
+ if (__sched_setparam (0, &attrp->__sp) == -1)
+ _exit (SPAWN_ERROR);
+ }
+ else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+ {
+ if (__sched_setscheduler (0, attrp->__policy,
+ (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0
+ ? &attrp->__sp : NULL) == -1)
+ _exit (SPAWN_ERROR);
+ }
+#endif
+
+ if (!err && (flags & POSIX_SPAWN_SETSID) != 0)
+ err = __proc_setsid (proc);
+
+ /* Set the process group ID. */
+ if (!err && (flags & POSIX_SPAWN_SETPGROUP) != 0)
+ err = __proc_setpgrp (proc, new_pid, attrp->__pgrp);
+
+ /* Set the effective user and group IDs. */
+ if (!err && (flags & POSIX_SPAWN_RESETIDS) != 0)
+ {
+ /* We need a different auth port for the child. */
+
+ __mutex_lock (&_hurd_id.lock);
+ err = _hurd_check_ids (); /* Get _hurd_id up to date. */
+ if (!err && _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;
+
+ /* Create a new auth port using our real UID and GID (the first
+ auxiliary UID and GID) as the only effective IDs. */
+ if (!err)
+ err = __USEPORT (AUTH,
+ __auth_makeauth (port,
+ NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+ _hurd_id.aux.uids, 1,
+ _hurd_id.aux.uids,
+ _hurd_id.aux.nuids,
+ _hurd_id.aux.gids, 1,
+ _hurd_id.aux.gids,
+ _hurd_id.aux.ngids,
+ &_hurd_id.rid_auth));
+ }
+ if (!err)
+ {
+ /* Use the real-ID auth port in place of the normal one. */
+ assert (_hurd_id.rid_auth != MACH_PORT_NULL);
+ auth = _hurd_id.rid_auth;
+ __mach_port_mod_refs (__mach_task_self (), auth,
+ MACH_PORT_RIGHT_SEND, +1);
+ }
+ __mutex_unlock (&_hurd_id.lock);
+ }
+ else
+ /* Copy our existing auth port. */
+ err = __USEPORT (AUTH, __mach_port_mod_refs (__mach_task_self (),
+ (auth = port),
+ MACH_PORT_RIGHT_SEND, +1));
+
+ if (err)
+ goto out;
+
+ /* Pack up the descriptor table to give the new program.
+ These descriptors will need to be reauthenticated below
+ if POSIX_SPAWN_RESETIDS is set. */
+ __mutex_lock (&_hurd_dtable_lock);
+ dtablesize = _hurd_dtablesize;
+ orig_dtablesize = _hurd_dtablesize;
+ dtable = __alloca (dtablesize * sizeof (dtable[0]));
+ ulink_dtable = __alloca (dtablesize * sizeof (ulink_dtable[0]));
+ dtable_cells = __alloca (dtablesize * sizeof (dtable_cells[0]));
+ dtable_cloexec = __alloca (dtablesize);
+ for (i = 0; i < dtablesize; ++i)
+ {
+ struct hurd_fd *const d = _hurd_dtable[i];
+ if (d == NULL)
+ {
+ dtable[i] = MACH_PORT_NULL;
+ dtable_cells[i] = NULL;
+ continue;
+ }
+ /* Note that this might return MACH_PORT_NULL. */
+ dtable[i] = _hurd_port_get (&d->port, &ulink_dtable[i]);
+ dtable_cells[i] = &d->port;
+ dtable_cloexec[i] = (d->flags & FD_CLOEXEC) != 0;
+ }
+ __mutex_unlock (&_hurd_dtable_lock);
+
+ /* Safe to let signals happen now. */
+ _hurd_critical_section_unlock (ss);
+
+ /* Execute the file actions. */
+ if (file_actions != NULL)
+ for (i = 0; i < file_actions->__used; ++i)
+ {
+ /* Close a file descriptor in the child. */
+ error_t do_close (int fd)
+ {
+ if ((unsigned int)fd < dtablesize
+ && dtable[fd] != MACH_PORT_NULL)
+ {
+ if (dtable_cells[fd] == NULL)
+ __mach_port_deallocate (__mach_task_self (), dtable[fd]);
+ else
+ {
+ _hurd_port_free (dtable_cells[fd],
+ &ulink_dtable[fd], dtable[fd]);
+ }
+ dtable_cells[fd] = NULL;
+ dtable[fd] = MACH_PORT_NULL;
+ return 0;
+ }
+ return EBADF;
+ }
+
+ /* Make sure the dtable can hold NEWFD. */
+#define EXPAND_DTABLE(newfd) \
+ ({ \
+ if ((unsigned int)newfd >= dtablesize \
+ && newfd < _hurd_rlimits[RLIMIT_OFILE].rlim_cur) \
+ { \
+ /* We need to expand the dtable for the child. */ \
+ NEW_TABLE (dtable, newfd); \
+ NEW_TABLE (ulink_dtable, newfd); \
+ NEW_TABLE (dtable_cells, newfd); \
+ dtablesize = newfd + 1; \
+ } \
+ ((unsigned int)newfd < dtablesize ? 0 : EMFILE); \
+ })
+#define NEW_TABLE(x, newfd) \
+ do { __typeof (x) new_##x = __alloca ((newfd + 1) * sizeof (x[0])); \
+ memcpy (new_##x, x, dtablesize * sizeof (x[0])); \
+ memset (&new_##x[dtablesize], 0, (newfd + 1 - dtablesize) * sizeof (x[0])); \
+ x = new_##x; } while (0)
+
+ struct __spawn_action *action = &file_actions->__actions[i];
+
+ switch (action->tag)
+ {
+ case spawn_do_close:
+ err = do_close (action->action.close_action.fd);
+ break;
+
+ case spawn_do_dup2:
+ if ((unsigned int)action->action.dup2_action.fd < dtablesize
+ && dtable[action->action.dup2_action.fd] != MACH_PORT_NULL)
+ {
+ const int fd = action->action.dup2_action.fd;
+ const int newfd = action->action.dup2_action.newfd;
+ // dup2 always clears any old FD_CLOEXEC flag on the new fd.
+ if (newfd < orig_dtablesize)
+ dtable_cloexec[newfd] = 0;
+ if (fd == newfd)
+ // Same is same as same was.
+ break;
+ err = EXPAND_DTABLE (newfd);
+ if (!err)
+ {
+ /* Close the old NEWFD and replace it with FD's
+ contents, which can be either an original
+ descriptor (DTABLE_CELLS[FD] != 0) or a new
+ right that we acquired in this function. */
+ do_close (newfd);
+ dtable_cells[newfd] = dtable_cells[fd];
+ if (dtable_cells[newfd] != NULL)
+ dtable[newfd] = _hurd_port_get (dtable_cells[newfd],
+ &ulink_dtable[newfd]);
+ else
+ {
+ dtable[newfd] = dtable[fd];
+ err = __mach_port_mod_refs (__mach_task_self (),
+ dtable[fd],
+ MACH_PORT_RIGHT_SEND, +1);
+ }
+ }
+ }
+ else
+ // The old FD specified was bogus.
+ err = EBADF;
+ break;
+
+ case spawn_do_open:
+ /* Open a file on behalf of the child.
+
+ XXX note that this can subject the parent to arbitrary
+ delays waiting for the files to open. I don't know what the
+ spec says about this. If it's not permissible, then this
+ whole forkless implementation is probably untenable. */
+ {
+ const int fd = action->action.open_action.fd;
+
+ do_close (fd);
+ if (fd < orig_dtablesize)
+ dtable_cloexec[fd] = 0;
+ err = EXPAND_DTABLE (fd);
+ if (err)
+ break;
+
+ err = child_lookup (action->action.open_action.path,
+ action->action.open_action.oflag,
+ action->action.open_action.mode,
+ &dtable[fd]);
+ dtable_cells[fd] = NULL;
+ break;
+ }
+ }
+
+ if (err)
+ goto out;
+ }
+
+ /* Only now can we perform FD_CLOEXEC. We had to leave the descriptors
+ unmolested for the file actions to use. Note that the DTABLE_CLOEXEC
+ array is never expanded by file actions, so it might now have fewer
+ than DTABLESIZE elements. */
+ for (i = 0; i < orig_dtablesize; ++i)
+ if (dtable[i] != MACH_PORT_NULL && dtable_cloexec[i])
+ {
+ assert (dtable_cells[i] != NULL);
+ _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
+ dtable[i] = MACH_PORT_NULL;
+ }
+
+ /* Prune trailing null ports from the descriptor table. */
+ while (dtablesize > 0 && dtable[dtablesize - 1] == MACH_PORT_NULL)
+ --dtablesize;
+
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ /* Reauthenticate all the child's ports with its new auth handle. */
+
+ mach_port_t ref;
+ process_t newproc;
+
+ /* Reauthenticate with the proc server. */
+ ref = __mach_reply_port ();
+ err = __proc_reauthenticate (proc, ref, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ err = __auth_user_authenticate (auth,
+ ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newproc);
+ __mach_port_destroy (__mach_task_self (), ref);
+ if (!err)
+ {
+ __mach_port_deallocate (__mach_task_self (), proc);
+ proc = newproc;
+ }
+
+ if (!err)
+ err = reauthenticate (INIT_PORT_CRDIR, &rcrdir);
+ if (!err)
+ err = reauthenticate (INIT_PORT_CWDIR, &rcwdir);
+
+ /* We must reauthenticate all the fds except those that came from
+ `spawn_do_open' file actions, which were opened using the child's
+ auth port to begin with. */
+ for (i = 0; !err && i < dtablesize; ++i)
+ err = reauthenticate_fd (i);
+ }
+ if (err)
+ goto out;
+
+ /* Now we are ready to open the executable file using the child's ports.
+ We do this after performing all the file actions so the order of
+ events is the same as for a fork, exec sequence. This affects things
+ like the meaning of a /dev/fd file name, as well as which error
+ conditions are diagnosed first and what side effects (file creation,
+ etc) can be observed before what errors. */
+
+ if ((xflags & SPAWN_XFLAGS_USE_PATH) == 0 || strchr (file, '/') != NULL)
+ /* The FILE parameter is actually a path. */
+ err = child_lookup (file, O_EXEC, 0, &execfile);
+ else
+ {
+ /* We have to search for FILE on the path. */
+ 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;
+ pathlen = strlen (path);
+ name = __alloca (pathlen + len + 1);
+ /* Copy the file name at the top. */
+ name = (char *) memcpy (name + pathlen + 1, file, len);
+ /* And add the slash. */
+ *--name = '/';
+
+ p = path;
+ do
+ {
+ char *startp;
+
+ path = p;
+ p = __strchrnul (path, ':');
+
+ if (p == path)
+ /* Two adjacent colons, or a colon at the beginning or the end
+ of `PATH' means to search the current directory. */
+ startp = name + 1;
+ else
+ startp = (char *) memcpy (name - (p - path), path, p - path);
+
+ /* Try to open this file name. */
+ err = child_lookup (startp, O_EXEC, 0, &execfile);
+ switch (err)
+ {
+ case EACCES:
+ case ENOENT:
+ case ESTALE:
+ case ENOTDIR:
+ /* Those errors indicate the file is missing or not executable
+ by us, in which case we want to just try the next path
+ directory. */
+ continue;
+
+ case 0: /* Success! */
+ default:
+ /* Some other error means we found an executable file, but
+ something went wrong executing it; return the error to our
+ caller. */
+ break;
+ }
+
+ // We only get here when we are done looking for the file.
+ break;
+ }
+ while (*p++ != '\0');
+ }
+ if (err)
+ goto out;
+
+ /* Almost there! */
+ {
+ mach_port_t ports[_hurd_nports];
+ struct hurd_userlink ulink_ports[_hurd_nports];
+ char *args = NULL, *env = NULL;
+ size_t argslen = 0, envlen = 0;
+
+ inline error_t exec (file_t file)
+ {
+ return __file_exec (file, task,
+ (__sigismember (&_hurdsig_traced, SIGKILL)
+ ? EXEC_SIGTRAP : 0),
+ args, argslen, env, envlen,
+ dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
+ ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
+ ints, INIT_INT_MAX,
+ NULL, 0, NULL, 0);
+ }
+
+ /* Now we are out of things that can fail before the file_exec RPC,
+ for which everything else must be prepared. The only thing left
+ to do is packing up the argument and environment strings,
+ and the array of init ports. */
+
+ if (argv != NULL)
+ err = __argz_create (argv, &args, &argslen);
+ if (!err && envp != NULL)
+ err = __argz_create (envp, &env, &envlen);
+
+ /* Load up the ports to give to the new program.
+ Note the loop/switch below must parallel exactly to release refs. */
+ for (i = 0; i < _hurd_nports; ++i)
+ {
+ switch (i)
+ {
+ case INIT_PORT_AUTH:
+ ports[i] = auth;
+ continue;
+ case INIT_PORT_PROC:
+ ports[i] = proc;
+ continue;
+ case INIT_PORT_CRDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ ports[i] = rcrdir;
+ continue;
+ }
+ break;
+ case INIT_PORT_CWDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ {
+ ports[i] = rcwdir;
+ continue;
+ }
+ break;
+ }
+ ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
+ }
+
+ /* Finally, try executing the file we opened. */
+ if (!err)
+ err = exec (execfile);
+ __mach_port_deallocate (__mach_task_self (), execfile);
+
+ if (err == ENOEXEC)
+ {
+ /* The file is accessible but it is not an executable file.
+ Invoke the shell to interpret it as a script. */
+ err = __argz_insert (&args, &argslen, args, _PATH_BSHELL);
+ if (!err)
+ err = child_lookup (_PATH_BSHELL, O_EXEC, 0, &execfile);
+ if (!err)
+ {
+ err = exec (execfile);
+ __mach_port_deallocate (__mach_task_self (), execfile);
+ }
+ }
+
+ /* Release the references just packed up in PORTS.
+ This switch must always parallel the one above that fills PORTS. */
+ for (i = 0; i < _hurd_nports; ++i)
+ {
+ switch (i)
+ {
+ case INIT_PORT_AUTH:
+ case INIT_PORT_PROC:
+ continue;
+ case INIT_PORT_CRDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ continue;
+ break;
+ case INIT_PORT_CWDIR:
+ if (flags & POSIX_SPAWN_RESETIDS)
+ continue;
+ break;
+ }
+ _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);
+ }
+
+ free (args);
+ free (env);
+ }
+
+ /* We did it! We have a child! */
+ if (pid != NULL)
+ *pid = new_pid;
+
+ out:
+ /* Clean up all the references we are now holding. */
+
+ if (task != MACH_PORT_NULL)
+ {
+ if (err)
+ /* We failed after creating the task, so kill it. */
+ __task_terminate (task);
+ __mach_port_deallocate (__mach_task_self (), task);
+ }
+ __mach_port_deallocate (__mach_task_self (), auth);
+ __mach_port_deallocate (__mach_task_self (), proc);
+ if (rcrdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcrdir);
+ if (rcwdir != MACH_PORT_NULL)
+ __mach_port_deallocate (__mach_task_self (), rcwdir);
+
+ if (ulink_dtable)
+ /* Release references to the file descriptor ports. */
+ for (i = 0; i < dtablesize; ++i)
+ if (dtable[i] != MACH_PORT_NULL)
+ {
+ if (dtable_cells[i] == NULL)
+ __mach_port_deallocate (__mach_task_self (), dtable[i]);
+ else
+ _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
+ }
+
+ if (err)
+ /* This hack canonicalizes the error code that we return. */
+ err = (__hurd_fail (err), errno);
+
+ return err;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/statfs.c b/REORG.TODO/sysdeps/mach/hurd/statfs.c
new file mode 100644
index 0000000000..1fa909c756
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/statfs.c
@@ -0,0 +1,31 @@
+/* statfs -- Return information about the filesystem on which FILE resides.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+
+#include "statfsconv.c"
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statfs (const char *file, struct statfs *buf)
+{
+ struct statfs64 buf64;
+ return __statfs64 (file, &buf64) ?: statfs64_conv (buf, &buf64);
+}
+libc_hidden_def (__statfs)
+weak_alias (__statfs, statfs)
diff --git a/REORG.TODO/sysdeps/mach/hurd/statfs64.c b/REORG.TODO/sysdeps/mach/hurd/statfs64.c
new file mode 100644
index 0000000000..9026ca97bf
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/statfs64.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <hurd.h>
+
+/* Return information about the filesystem on which FILE resides. */
+int
+__statfs64 (const char *file, struct statfs64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_statfs (port, buf);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__statfs64, statfs64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/statfsconv.c b/REORG.TODO/sysdeps/mach/hurd/statfsconv.c
new file mode 100644
index 0000000000..2163b5a932
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/statfsconv.c
@@ -0,0 +1,48 @@
+/* Convert between `struct statfs' format, and `struct statfs64' format.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <errno.h>
+
+static inline int
+statfs64_conv (struct statfs *buf, const struct statfs64 *buf64)
+{
+# define DO(memb) \
+ buf->memb = buf64->memb; \
+ if (sizeof buf->memb != sizeof buf64->memb && buf->memb != buf64->memb) \
+ { \
+ __set_errno (EOVERFLOW); \
+ return -1; \
+ }
+
+ DO (f_type);
+ DO (f_bsize);
+ DO (f_blocks);
+ DO (f_bfree);
+ DO (f_bavail);
+ DO (f_files);
+ DO (f_fsid);
+ DO (f_namelen);
+ DO (f_favail);
+ DO (f_frsize);
+ DO (f_flag);
+
+# undef DO
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/statvfs.c b/REORG.TODO/sysdeps/mach/hurd/statvfs.c
new file mode 100644
index 0000000000..8844e873c8
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/statvfs.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+statvfs (const char *file, struct statvfs *buf)
+{
+ /* `struct statvfs' is in fact identical to `struct statfs' so we
+ can simply call statfs. */
+ return __statfs (file, (struct statfs *)buf);
+}
+libc_hidden_def (statvfs)
diff --git a/REORG.TODO/sysdeps/mach/hurd/statvfs64.c b/REORG.TODO/sysdeps/mach/hurd/statvfs64.c
new file mode 100644
index 0000000000..179ad643ba
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/statvfs64.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
+
+int
+statvfs64 (const char *file, struct statvfs64 *buf)
+{
+ /* `struct statvfs64' is in fact identical to `struct statfs64' so
+ we can simply call statfs64. */
+ return __statfs64 (file, (struct statfs64 *)buf);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/symlink.c b/REORG.TODO/sysdeps/mach/hurd/symlink.c
new file mode 100644
index 0000000000..d5c768b89b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/symlink.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+
+/* Make a link to FROM called TO. */
+int
+__symlink (const char *from, 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 (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), node);
+ }
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__symlink, symlink)
diff --git a/REORG.TODO/sysdeps/mach/hurd/symlinkat.c b/REORG.TODO/sysdeps/mach/hurd/symlinkat.c
new file mode 100644
index 0000000000..19463f2dcd
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/symlinkat.c
@@ -0,0 +1,72 @@
+/* Create a symbolic link named relative to an open directory. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <hurd/fd.h>
+#include <string.h>
+
+
+/* Make a link to FROM called TO relative to FD. */
+int
+symlinkat (const char *from, int fd, 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_at (fd, 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 (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), node);
+ }
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sync.c b/REORG.TODO/sysdeps/mach/hurd/sync.c
new file mode 100644
index 0000000000..ce662446a3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sync.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make all changes done to all files actually appear on disk. */
+void
+sync (void)
+{
+ /* This is not actually synchronous; we don't wait. */
+ error_t err = __USEPORT (CRDIR, __file_syncfs (port, 0, 1));
+ if (err)
+ (void) __hurd_fail (err);
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/syncfs.c b/REORG.TODO/sysdeps/mach/hurd/syncfs.c
new file mode 100644
index 0000000000..82ad09a1c4
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/syncfs.c
@@ -0,0 +1,31 @@
+/* Make all changes done to all files on the file system associated
+ with FD actually appear on disk.
+ Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+int
+syncfs (int fd)
+{
+ error_t err = HURD_DPORT_USE (fd, __file_syncfs (port, 1, 0));
+ if (err)
+ return __hurd_dfail (fd, err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/sysconf.c b/REORG.TODO/sysdeps/mach/hurd/sysconf.c
new file mode 100644
index 0000000000..bc7fdd4b77
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/sysconf.c
@@ -0,0 +1,26 @@
+/* Return values of system parameters. Hurd version.
+ Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <eloop-threshold.h>
+
+#define SYMLOOP_MAX (__eloop_threshold ())
+
+#include <sysdeps/posix/sysconf.c>
diff --git a/REORG.TODO/sysdeps/mach/hurd/telldir.c b/REORG.TODO/sysdeps/mach/hurd/telldir.c
new file mode 100644
index 0000000000..47a52c3d9a
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/telldir.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "dirstream.h"
+
+/* Return the current position of DIRP. */
+/* XXX should be __telldir ? */
+long int
+telldir (DIR *dirp)
+{
+ return dirp->__entry_ptr;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/times.c b/REORG.TODO/sysdeps/mach/hurd/times.c
new file mode 100644
index 0000000000..10ba2f7cb7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/times.c
@@ -0,0 +1,74 @@
+/* Return CPU and real time used by process and its children. Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/resource.h>
+#include <sys/times.h>
+#include <sys/time.h>
+#include <time.h>
+#include <mach.h>
+#include <mach/task_info.h>
+#include <hurd.h>
+
+static inline clock_t
+clock_from_time_value (const time_value_t *t)
+{
+ return t->seconds * 1000000 + t->microseconds;
+}
+
+/* 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
+__times (struct tms *tms)
+{
+ struct task_basic_info bi;
+ struct task_thread_times_info tti;
+ mach_msg_type_number_t count;
+ union { time_value_t tvt; struct timeval tv; } now;
+ error_t err;
+
+ count = TASK_BASIC_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_BASIC_INFO,
+ (task_info_t) &bi, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ count = TASK_THREAD_TIMES_INFO_COUNT;
+ err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
+ (task_info_t) &tti, &count);
+ if (err)
+ return __hurd_fail (err);
+
+ tms->tms_utime = (clock_from_time_value (&bi.user_time)
+ + clock_from_time_value (&tti.user_time));
+ tms->tms_stime = (clock_from_time_value (&bi.system_time)
+ + clock_from_time_value (&tti.system_time));
+
+ /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be. */
+ tms->tms_cutime = tms->tms_cstime = 0;
+
+ if (__gettimeofday (&now.tv, NULL) < 0)
+ return -1;
+
+ return (clock_from_time_value (&now.tvt)
+ - clock_from_time_value (&bi.creation_time));
+}
+weak_alias (__times, times)
diff --git a/REORG.TODO/sysdeps/mach/hurd/tls.h b/REORG.TODO/sysdeps/mach/hurd/tls.h
new file mode 100644
index 0000000000..5e68739655
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/tls.h
@@ -0,0 +1,57 @@
+/* Definitions for thread-local data handling. Hurd version.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <stddef.h>
+# include <stdint.h>
+# include <stdbool.h>
+# include <sysdep.h>
+# include <mach/mig_errors.h>
+# include <mach.h>
+
+
+/* This is the size of the initial TCB. */
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB. */
+# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB. */
+# define TLS_TCB_SIZE TLS_INIT_TCB_SIZE /* XXX */
+
+/* Alignment requirements for the TCB. */
+# define TLS_TCB_ALIGN TLS_INIT_TCB_ALIGN /* XXX */
+
+
+/* Install the dtv pointer. The pointer passed is to the element with
+ index -1 which contain the length. */
+# define INSTALL_DTV(descr, dtvp) \
+ ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Return dtv of given thread descriptor. */
+# define GET_DTV(descr) \
+ (((tcbhead_t *) (descr))->dtv)
+
+#endif /* !ASSEMBLER */
+
+
+#endif /* tls.h */
diff --git a/REORG.TODO/sysdeps/mach/hurd/tmpfile.c b/REORG.TODO/sysdeps/mach/hurd/tmpfile.c
new file mode 100644
index 0000000000..8bcfb81a10
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/tmpfile.c
@@ -0,0 +1,68 @@
+/* Open a stdio stream on an anonymous temporary file. Hurd version.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <hurd.h>
+#include <hurd/fs.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <iolibio.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 *
+__tmpfile (void)
+{
+ error_t err;
+ file_t file;
+ int fd;
+ FILE *f;
+
+ /* Get a port to the directory that will contain the file. */
+ const char *dirname = __libc_secure_getenv ("TMPDIR") ?: P_tmpdir;
+ file_t dir = __file_name_lookup (dirname, 0, 0);
+ if (dir == MACH_PORT_NULL)
+ return NULL;
+
+ /* Create an unnamed file in the temporary directory. */
+ err = __dir_mkfile (dir, O_RDWR, S_IRUSR | S_IWUSR, &file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+ if (err)
+ return __hurd_fail (err), NULL;
+
+ /* Get a file descriptor for that port. POSIX.1 requires that streams
+ returned by tmpfile allocate file descriptors as fopen would. */
+ fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
+ if (fd < 0)
+ return NULL;
+
+ /* Open a stream on the unnamed file.
+ It will cease to exist when this stream is closed. */
+ if ((f = _IO_fdopen (fd, "w+b")) == NULL)
+ __close (fd);
+
+ return f;
+}
+
+#include <shlib-compat.h>
+versioned_symbol (libc, __tmpfile, tmpfile, GLIBC_2_1);
+
+weak_alias (__tmpfile, tmpfile64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/tmpfile64.c b/REORG.TODO/sysdeps/mach/hurd/tmpfile64.c
new file mode 100644
index 0000000000..094304a075
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/tmpfile64.c
@@ -0,0 +1 @@
+/* tmpfile64 is an alias for tmpfile, defined in tmpfile.c. */
diff --git a/REORG.TODO/sysdeps/mach/hurd/truncate.c b/REORG.TODO/sysdeps/mach/hurd/truncate.c
new file mode 100644
index 0000000000..4636f8cc32
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/truncate.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Truncate FILE_NAME to LENGTH bytes. */
+int
+__truncate (const char *file_name, 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_set_size (file, length);
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__truncate, truncate)
diff --git a/REORG.TODO/sysdeps/mach/hurd/truncate64.c b/REORG.TODO/sysdeps/mach/hurd/truncate64.c
new file mode 100644
index 0000000000..a2e2ed2190
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/truncate64.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Truncate FILE_NAME to LENGTH bytes. */
+int
+__truncate64 (const char *file_name, off64_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_set_size (file, length);
+ __mach_port_deallocate (__mach_task_self (), file);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+weak_alias (__truncate64, truncate64)
diff --git a/REORG.TODO/sysdeps/mach/hurd/ttyname.c b/REORG.TODO/sysdeps/mach/hurd/ttyname.c
new file mode 100644
index 0000000000..6da7f21bd7
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ttyname.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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)))
+ {
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ err = ENOTTY;
+ return __hurd_dfail (fd, err), NULL;
+ }
+
+ return nodename;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/ttyname_r.c b/REORG.TODO/sysdeps/mach/hurd/ttyname_r.c
new file mode 100644
index 0000000000..d53c6fff35
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/ttyname_r.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/term.h>
+#include <hurd/fd.h>
+
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+ open on in BUF. Return 0 on success, -1 otherwise. */
+int
+__ttyname_r (int fd, char *buf, size_t buflen)
+{
+ error_t err;
+ char nodename[1024]; /* XXX */
+ size_t len;
+
+ nodename[0] = '\0';
+ if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename)))
+ {
+ if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+ err = ENOTTY;
+ return __hurd_dfail (fd, err), errno;
+ }
+
+ len = strlen (nodename) + 1;
+ if (len > buflen)
+ {
+ errno = ERANGE;
+ return errno;
+ }
+
+ memcpy (buf, nodename, len);
+ return 0;
+}
+
+weak_alias (__ttyname_r, ttyname_r)
diff --git a/REORG.TODO/sysdeps/mach/hurd/umask.c b/REORG.TODO/sysdeps/mach/hurd/umask.c
new file mode 100644
index 0000000000..57498b450d
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/umask.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Set the file creation mask to MASK, returning the old mask. */
+mode_t
+__umask (mode_t mask)
+{
+ mode_t omask;
+ mask &= 0777;
+ omask = _hurd_umask;
+ _hurd_umask = mask;
+ return omask;
+}
+
+weak_alias (__umask, umask)
diff --git a/REORG.TODO/sysdeps/mach/hurd/uname.c b/REORG.TODO/sysdeps/mach/hurd/uname.c
new file mode 100644
index 0000000000..d8457038b5
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/uname.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+
+int
+__uname (struct utsname *uname)
+{
+ error_t err;
+
+ if (err = __USEPORT (PROC, __proc_uname (port, uname)))
+ return __hurd_fail (err);
+
+ /* Fill in the hostname, which the proc server doesn't know. */
+ err = errno;
+ if (__gethostname (uname->nodename, sizeof uname->nodename) < 0)
+ {
+ if (errno == ENAMETOOLONG)
+ /* Ignore the error of the buffer being too small.
+ It is of fixed size, nothing to do about it. */
+ errno = err;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__uname, uname)
+libc_hidden_def (__uname)
+libc_hidden_def (uname)
diff --git a/REORG.TODO/sysdeps/mach/hurd/unlink.c b/REORG.TODO/sysdeps/mach/hurd/unlink.c
new file mode 100644
index 0000000000..606da91ec3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/unlink.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+
+/* Remove the link named NAME. */
+int
+__unlink (const char *name)
+{
+ error_t err;
+ file_t dir;
+ const char *file;
+
+ dir = __directory_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/REORG.TODO/sysdeps/mach/hurd/unlinkat.c b/REORG.TODO/sysdeps/mach/hurd/unlinkat.c
new file mode 100644
index 0000000000..18f4b96290
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/unlinkat.c
@@ -0,0 +1,51 @@
+/* unlinkat -- Remove a name relative to an open directory. Hurd version.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Remove the link named NAME. */
+int
+unlinkat (int fd, const char *name, int flag)
+{
+ error_t err;
+ file_t dir;
+ const char *file;
+
+ if ((flag &~ AT_REMOVEDIR) != 0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ dir = __directory_name_split_at (fd, name, (char **) &file);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ err = ((flag & AT_REMOVEDIR) ? __dir_rmdir : __dir_unlink) (dir, file);
+ __mach_port_deallocate (__mach_task_self (), dir);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/hurd/utimes.c b/REORG.TODO/sysdeps/mach/hurd/utimes.c
new file mode 100644
index 0000000000..337586f966
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/utimes.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__utimes (const char *file, const struct timeval tvp[2])
+{
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
+ error_t err;
+ file_t port;
+
+ if (tvp == NULL)
+ {
+ /* Setting the number of microseconds to `-1' tells the
+ underlying filesystems to use the current time. */
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
+ }
+
+ port = __file_name_lookup (file, 0, 0);
+ if (port == MACH_PORT_NULL)
+ return -1;
+ err = __file_utimes (port, u[0].tvt, u[1].tvt);
+ __mach_port_deallocate (__mach_task_self (), port);
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+weak_alias (__utimes, utimes)
diff --git a/REORG.TODO/sysdeps/mach/hurd/wait4.c b/REORG.TODO/sysdeps/mach/hurd/wait4.c
new file mode 100644
index 0000000000..4d54c0e316
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/wait4.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+pid_t
+__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
+{
+ pid_t dead;
+ error_t err;
+ struct rusage ignored;
+ int sigcode;
+ int dummy;
+
+ err = __USEPORT (PROC, __proc_wait (port, pid, options,
+ stat_loc ?: &dummy, &sigcode,
+ usage ?: &ignored, &dead));
+ switch (err)
+ {
+ case 0: /* Got a child. */
+ return dead;
+ case EAGAIN:
+ /* The RPC returns this error when the WNOHANG flag is set and no
+ selected children are dead (but some are living). In that
+ situation, our return value is zero. (The RPC can't return zero
+ for DEAD without also returning some garbage for the other out
+ parameters, so an error return is much more natural here. Hence
+ the difference between the RPC and the POSIX.1 interface. */
+ return (pid_t) 0;
+ default:
+ return (pid_t) __hurd_fail (err);
+ }
+}
+
+weak_alias (__wait4, wait4)
diff --git a/REORG.TODO/sysdeps/mach/hurd/write.c b/REORG.TODO/sysdeps/mach/hurd/write.c
new file mode 100644
index 0000000000..bfa96735e2
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/write.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+
+ssize_t
+__libc_write (int fd, const void *buf, size_t nbytes)
+{
+ error_t err = HURD_FD_USE (fd, _hurd_fd_write (descriptor,
+ buf, &nbytes, -1));
+ return err ? __hurd_dfail (fd, err) : nbytes;
+}
+libc_hidden_def (__libc_write)
+weak_alias (__libc_write, __write)
+libc_hidden_weak (__write)
+weak_alias (__libc_write, write)
diff --git a/REORG.TODO/sysdeps/mach/hurd/xmknod.c b/REORG.TODO/sysdeps/mach/hurd/xmknod.c
new file mode 100644
index 0000000000..bef58a1a39
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/xmknod.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+/* 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
+__xmknod (int vers, const char *file_name, mode_t mode, dev_t *dev)
+{
+ return __xmknodat (vers, AT_FDCWD, file_name, mode, dev);
+}
+libc_hidden_def (__xmknod)
diff --git a/REORG.TODO/sysdeps/mach/hurd/xmknodat.c b/REORG.TODO/sysdeps/mach/hurd/xmknodat.c
new file mode 100644
index 0000000000..68cdf74ea3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/xmknodat.c
@@ -0,0 +1,119 @@
+/* Create a device file relative to an open directory. Hurd version.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include <_itoa.h>
+#include <string.h>
+#include <sys/types.h>
+
+/* Create a device file named PATH relative to FD, 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
+__xmknodat (int vers, int fd, const char *path, mode_t mode, dev_t *dev)
+{
+ error_t errnode, err;
+ file_t dir, node;
+ char *name;
+ char buf[100], *bp;
+ const char *translator;
+ size_t len;
+
+ if (vers != _MKNOD_VER)
+ return __hurd_fail (EINVAL);
+
+ 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 if (S_ISREG (mode))
+ {
+ translator = NULL;
+ len = 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (translator != NULL && ! 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_at (fd, path, &name);
+ if (dir == MACH_PORT_NULL)
+ return -1;
+
+ /* Create a new, unlinked node in the target directory. */
+ errnode = err = __dir_mkfile (dir, O_WRITE, (mode & ~S_IFMT) & ~_hurd_umask, &node);
+
+ if (! err && translator != NULL)
+ /* 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 (dir, node, name, 1);
+
+ __mach_port_deallocate (__mach_task_self (), dir);
+ if (! errnode)
+ __mach_port_deallocate (__mach_task_self (), node);
+
+ if (err)
+ return __hurd_fail (err);
+ return 0;
+}
+
+libc_hidden_def (__xmknodat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/xstat.c b/REORG.TODO/sysdeps/mach/hurd/xstat.c
new file mode 100644
index 0000000000..11b0a94322
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/xstat.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "xstatconv.c"
+
+/* Get file information about FILE in BUF. */
+int
+__xstat (int vers, const char *file, struct stat *buf)
+{
+ struct stat64 buf64;
+ return __xstat64 (vers, file, &buf64) ?: xstat64_conv (buf, &buf64);
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat)
diff --git a/REORG.TODO/sysdeps/mach/hurd/xstat64.c b/REORG.TODO/sysdeps/mach/hurd/xstat64.c
new file mode 100644
index 0000000000..20e3d82f42
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/xstat64.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef RTLD_STAT64 /* dl-xstat64.c, but we don't want it. */
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Get information about the file descriptor FD in BUF. */
+int
+__xstat64 (int vers, const char *file, struct stat64 *buf)
+{
+ error_t err;
+ file_t port;
+
+ if (vers != _STAT_VER)
+ return __hurd_fail (EINVAL);
+
+ 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;
+}
+hidden_def (__xstat64)
+
+#endif
diff --git a/REORG.TODO/sysdeps/mach/hurd/xstatconv.c b/REORG.TODO/sysdeps/mach/hurd/xstatconv.c
new file mode 100644
index 0000000000..6b51002371
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/hurd/xstatconv.c
@@ -0,0 +1,64 @@
+/* Convert between `struct stat' format, and `struct stat64' format.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sys/stat.h>
+
+static inline int
+xstat64_conv (struct stat *buf, const struct stat64 *buf64)
+{
+ if (sizeof *buf == sizeof *buf64
+ && sizeof buf->st_ino == sizeof buf64->st_ino
+ && sizeof buf->st_size == sizeof buf64->st_size
+ && sizeof buf->st_blocks == sizeof buf64->st_blocks)
+ {
+ *buf = *(struct stat *) buf64;
+ return 0;
+ }
+
+ buf->st_fstype = buf64->st_fstype;
+ buf->st_fsid = buf64->st_fsid;
+ buf->st_ino = buf64->st_ino;
+ buf->st_gen = buf64->st_gen;
+ buf->st_rdev = buf64->st_rdev;
+ buf->st_mode = buf64->st_mode;
+ buf->st_nlink = buf64->st_nlink;
+ buf->st_uid = buf64->st_uid;
+ buf->st_gid = buf64->st_gid;
+ buf->st_size = buf64->st_size;
+ buf->st_atim = buf64->st_atim;
+ buf->st_mtim = buf64->st_mtim;
+ buf->st_ctim = buf64->st_ctim;
+ buf->st_blksize = buf64->st_blksize;
+ buf->st_blocks = buf64->st_blocks;
+ buf->st_author = buf64->st_author;
+ buf->st_flags = buf64->st_flags;
+
+ if ((sizeof buf->st_ino != sizeof buf64->st_ino
+ && buf->st_ino != buf64->st_ino)
+ || (sizeof buf->st_size != sizeof buf64->st_size
+ && buf->st_size != buf64->st_size)
+ || (sizeof buf->st_blocks != sizeof buf64->st_blocks
+ && buf->st_blocks != buf64->st_blocks))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/i386/machine-lock.h b/REORG.TODO/sysdeps/mach/i386/machine-lock.h
new file mode 100644
index 0000000000..540d1a5326
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/i386/machine-lock.h
@@ -0,0 +1,67 @@
+/* Machine-specific definition for spin locks. i386 version.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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)
+ : "memory");
+}
+
+/* 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)
+ : "memory");
+ 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/REORG.TODO/sysdeps/mach/i386/machine-sp.h b/REORG.TODO/sysdeps/mach/i386/machine-sp.h
new file mode 100644
index 0000000000..264facbf1e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/i386/machine-sp.h
@@ -0,0 +1,30 @@
+/* Machine-specific function to return the stack pointer. i386 version.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MACHINE_SP_H
+#define _MACHINE_SP_H
+
+/* Return the current stack pointer. */
+
+#define __thread_stack_pointer() ({ \
+ void *__sp__; \
+ __asm__ ("movl %%esp, %0" : "=r" (__sp__)); \
+ __sp__; \
+})
+
+#endif /* machine-sp.h */
diff --git a/REORG.TODO/sysdeps/mach/i386/syscall.S b/REORG.TODO/sysdeps/mach/i386/syscall.S
new file mode 100644
index 0000000000..562aedd175
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/i386/syscall.S
@@ -0,0 +1,29 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 */
+ popl %ecx /* Pop return address into %ecx. */
+ pushl $0 /* Push back dumb syscall number. */
+ pushl %ecx /* Push back return address. */
+ ret
+END (syscall)
diff --git a/REORG.TODO/sysdeps/mach/i386/sysdep.h b/REORG.TODO/sysdeps/mach/i386/sysdep.h
new file mode 100644
index 0000000000..d5e5f6bcf3
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/i386/sysdep.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MACH_I386_SYSDEP_H
+#define _MACH_I386_SYSDEP_H 1
+
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
+#include <dl-sysdep.h>
+#include <tls.h>
+
+#define LOSE asm volatile ("hlt")
+
+#define SNARF_ARGS(entry_sp, argc, argv, envp) \
+ do \
+ { \
+ char **p; \
+ argc = (int) *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, info, sp) \
+ do { \
+ void **ptr = (void **) sp; \
+ *--(__typeof (info) *) ptr = info; \
+ ptr[-1] = ptr; \
+ --ptr; \
+ asm volatile ("movl %0, %%esp; call %1" : : \
+ "g" (ptr), "m" (*(long int *) (fn)) : "%esp"); \
+ } while (0)
+
+#define RETURN_TO(sp, pc, retval) \
+ asm volatile ("movl %0, %%esp; jmp %*%1 # %2" \
+ : : "g" (sp), "r" (pc), "a" (retval))
+
+
+#define STACK_GROWTH_DOWN
+
+/* Get the machine-independent Mach definitions. */
+#include <sysdeps/mach/sysdep.h>
+
+
+/* This should be rearranged, but at the moment this file provides
+ the most useful definitions for assembler syntax details. */
+#undef ENTRY
+#undef ALIGN
+#include <sysdeps/unix/i386/sysdep.h>
+
+#endif /* mach/i386/sysdep.h */
diff --git a/REORG.TODO/sysdeps/mach/i386/thread_state.h b/REORG.TODO/sysdeps/mach/i386/thread_state.h
new file mode 100644
index 0000000000..2ad2619e34
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/i386/thread_state.h
@@ -0,0 +1,42 @@
+/* Mach thread state definitions for machine-independent code. i386 version.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MACH_I386_THREAD_STATE_H
+#define _MACH_I386_THREAD_STATE_H 1
+
+#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 <sysdeps/mach/thread_state.h>
+
+#endif /* mach/i386/thread_state.h */
diff --git a/REORG.TODO/sysdeps/mach/libc-lock.h b/REORG.TODO/sysdeps/mach/libc-lock.h
new file mode 100644
index 0000000000..9b864a7d50
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/libc-lock.h
@@ -0,0 +1,145 @@
+/* libc-internal interface for mutex locks. Mach cthreads version.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCK_H
+#define _LIBC_LOCK_H 1
+
+#ifdef _LIBC
+#include <cthreads.h>
+#define __libc_lock_t struct mutex
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+#endif
+
+/* Type for key of thread specific data. */
+typedef cthread_key_t __libc_key_t;
+
+/* Define a lock variable NAME with storage class CLASS. The lock must be
+ initialized with __libc_lock_init before it can be used (or define it
+ with __libc_lock_define_initialized, below). Use `extern' for CLASS to
+ declare a lock defined in another module. In public structure
+ definitions you must use a pointer to the lock structure (i.e., NAME
+ begins with a `*'), because its storage size will not be known outside
+ of libc. */
+#define __libc_lock_define(CLASS,NAME) \
+ CLASS __libc_lock_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS. */
+#define __libc_lock_define_initialized(CLASS,NAME) \
+ CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+ state. */
+#define __libc_lock_init(NAME) __mutex_init (&(NAME))
+
+/* Finalize the named lock variable, which must be locked. It cannot be
+ used again until __libc_lock_init is called again on it. This must be
+ called on a lock variable before the containing storage is reused. */
+#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
+
+/* Lock the named lock variable. */
+#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
+
+/* Unlock the named lock variable. */
+#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
+
+
+/* XXX for now */
+#define __libc_rwlock_define __libc_lock_define
+#define __libc_rwlock_define_initialized __libc_lock_define_initialized
+#define __libc_rwlock_init __libc_lock_init
+#define __libc_rwlock_fini __libc_lock_fini
+#define __libc_rwlock_rdlock __libc_lock_lock
+#define __libc_rwlock_wrlock __libc_lock_lock
+#define __libc_rwlock_tryrdlock __libc_lock_trylock
+#define __libc_rwlock_trywrlock __libc_lock_trylock
+#define __libc_rwlock_unlock __libc_lock_unlock
+
+
+/* Start a critical region with a cleanup function */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+{ \
+ typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0; \
+ typeof (ARG) __save_ARG = ARG; \
+ /* close brace is in __libc_cleanup_region_end below. */
+
+/* End a critical region started with __libc_cleanup_region_start. */
+#define __libc_cleanup_region_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+}
+
+/* Sometimes we have to exit the block in the middle. */
+#define __libc_cleanup_end(DOIT) \
+ if ((DOIT) && __save_FCT != 0) \
+ (*__save_FCT)(__save_ARG); \
+
+
+/* Use mutexes as once control variables. */
+
+struct __libc_once
+ {
+ __libc_lock_t lock;
+ int done;
+ };
+
+#define __libc_once_define(CLASS,NAME) \
+ CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
+
+
+/* Call handler iff the first call. */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+ do { \
+ __libc_lock_lock (ONCE_CONTROL.lock); \
+ if (!ONCE_CONTROL.done) \
+ (INIT_FUNCTION) (); \
+ ONCE_CONTROL.done = 1; \
+ __libc_lock_unlock (ONCE_CONTROL.lock); \
+ } while (0)
+
+/* Get once control variable. */
+#define __libc_once_get(ONCE_CONTROL) ((ONCE_CONTROL).done != 0)
+
+#ifdef _LIBC
+/* We need portable names for some functions. E.g., when they are
+ used as argument to __libc_cleanup_region_start. */
+#define __libc_mutex_unlock __mutex_unlock
+#endif
+
+#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
+#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
+void *__libc_getspecific (__libc_key_t key);
+
+/* XXX until cthreads supports recursive locks */
+#define __libc_lock_define_initialized_recursive __libc_lock_define_initialized
+#define __libc_lock_init_recursive __libc_lock_init
+#define __libc_lock_fini_recursive __libc_lock_fini
+#define __libc_lock_trylock_recursive __libc_lock_trylock
+#define __libc_lock_unlock_recursive __libc_lock_unlock
+#define __libc_lock_lock_recursive __libc_lock_lock
+
+#define __rtld_lock_define_initialized_recursive __libc_lock_define_initialized
+#define __rtld_lock_fini_recursive __libc_lock_fini
+#define __rtld_lock_trylock_recursive __libc_lock_trylock
+#define __rtld_lock_unlock_recursive __libc_lock_unlock
+#define __rtld_lock_lock_recursive __libc_lock_lock
+
+#endif /* libc-lock.h */
diff --git a/REORG.TODO/sysdeps/mach/mprotect.c b/REORG.TODO/sysdeps/mach/mprotect.c
new file mode 100644
index 0000000000..477017da39
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/mprotect.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 (__ptr_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;
+}
+weak_alias (__mprotect, mprotect)
diff --git a/REORG.TODO/sysdeps/mach/msync.c b/REORG.TODO/sysdeps/mach/msync.c
new file mode 100644
index 0000000000..f84553269e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/msync.c
@@ -0,0 +1,56 @@
+/* msync -- Synchronize mapped memory to external storage. Mach version.
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <mach.h>
+
+/* Some Mach variants have vm_msync and some don't. Those that have it
+ define the VM_SYNC_* bits when we include <mach/mach_types.h>. */
+
+#ifndef VM_SYNC_SYNCHRONOUS
+# include <misc/msync.c>
+#else
+
+/* 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 (__ptr_t addr, size_t len, int flags)
+{
+ vm_sync_t sync_flags = 0;
+ kern_return_t err;
+
+ if (flags & MS_SYNC)
+ sync_flags |= VM_SYNC_SYNCHRONOUS;
+ if (flags & MS_ASYNC)
+ sync_flags |= VM_SYNC_ASYNCHRONOUS;
+ if (flags & MS_INVALIDATE)
+ sync_flags |= VM_SYNC_INVALIDATE;
+
+ if (err = __vm_msync (__mach_task_self (),
+ (vm_address_t) addr, (vm_size_t) len, sync_flags))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+#endif
diff --git a/REORG.TODO/sysdeps/mach/munmap.c b/REORG.TODO/sysdeps/mach/munmap.c
new file mode 100644
index 0000000000..b5fdaeaf1b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/munmap.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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 (__ptr_t addr, size_t len)
+{
+ kern_return_t err;
+
+ if (addr == 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (err = __vm_deallocate (__mach_task_self (),
+ (vm_address_t) addr, (vm_size_t) len))
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
+weak_alias (__munmap, munmap)
diff --git a/REORG.TODO/sysdeps/mach/nanosleep.c b/REORG.TODO/sysdeps/mach/nanosleep.c
new file mode 100644
index 0000000000..a932e82cf1
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/nanosleep.c
@@ -0,0 +1,70 @@
+/* nanosleep -- sleep for a period specified with a struct timespec
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <mach.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+int
+__libc_nanosleep (const struct timespec *requested_time,
+ struct timespec *remaining)
+{
+ mach_port_t recv;
+ struct timeval before, after;
+
+ if (requested_time->tv_sec < 0
+ || requested_time->tv_nsec < 0
+ || requested_time->tv_nsec >= 1000000000)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ const mach_msg_timeout_t ms
+ = requested_time->tv_sec * 1000
+ + (requested_time->tv_nsec + 999999) / 1000000;
+
+ recv = __mach_reply_port ();
+
+ if (remaining && __gettimeofday (&before, NULL) < 0)
+ return -1;
+ error_t err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+ 0, 0, recv, ms, MACH_PORT_NULL);
+ __mach_port_destroy (mach_task_self (), recv);
+ if (err == EMACH_RCV_INTERRUPTED)
+ {
+ if (remaining && __gettimeofday (&after, NULL) >= 0)
+ {
+ struct timeval req_time, elapsed, rem;
+ TIMESPEC_TO_TIMEVAL (&req_time, requested_time);
+ timersub (&after, &before, &elapsed);
+ timersub (&req_time, &elapsed, &rem);
+ TIMEVAL_TO_TIMESPEC (&rem, remaining);
+ }
+
+ errno = EINTR;
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias(__libc_nanosleep, __nanosleep)
+libc_hidden_def (__nanosleep)
+weak_alias (__libc_nanosleep, nanosleep)
diff --git a/REORG.TODO/sysdeps/mach/pagecopy.h b/REORG.TODO/sysdeps/mach/pagecopy.h
new file mode 100644
index 0000000000..4d9cb688d6
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/pagecopy.h
@@ -0,0 +1,32 @@
+/* Macros for copying by pages; used in memcpy, memmove. Mach version.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <mach.h>
+
+/* Threshold at which vm_copy is more efficient than well-optimized copying
+ by words. This parameter should be tuned as necessary. */
+#define PAGE_THRESHOLD (2 * PAGE_SIZE) /* XXX ? */
+
+#define PAGE_SIZE __vm_page_size
+#define PAGE_COPY_FWD(dstp, srcp, nbytes_left, nbytes) \
+ ((nbytes_left) = ((nbytes) - \
+ (__vm_copy (__mach_task_self (), \
+ (vm_address_t) srcp, trunc_page (nbytes), \
+ (vm_address_t) dstp) == KERN_SUCCESS \
+ ? trunc_page (nbytes) \
+ : 0)))
diff --git a/REORG.TODO/sysdeps/mach/readonly-area.c b/REORG.TODO/sysdeps/mach/readonly-area.c
new file mode 100644
index 0000000000..c187b06a7b
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/readonly-area.c
@@ -0,0 +1,56 @@
+/* Test if a memory region is wholly unwritable. Mach version.
+ Copyright (C) 2004-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <mach.h>
+
+/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
+ Return -1 if it is writable. */
+
+int
+__readonly_area (const char *ptr, size_t size)
+{
+ vm_address_t region_address = (uintptr_t) ptr;
+ vm_size_t region_length = size;
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t is_shared;
+ mach_port_t object_name;
+ vm_offset_t offset;
+
+ while (__vm_region (__mach_task_self (),
+ &region_address, &region_length,
+ &protection, &max_protection, &inheritance, &is_shared,
+ &object_name, &offset) == KERN_SUCCESS
+ && region_address <= (uintptr_t) ptr)
+ {
+ region_address += region_length;
+ if (region_address < (uintptr_t) ptr)
+ continue;
+
+ if (protection & VM_PROT_WRITE)
+ return -1;
+
+ if (region_address - (uintptr_t) ptr >= size)
+ break;
+ }
+
+ return 1;
+}
diff --git a/REORG.TODO/sysdeps/mach/sched_yield.c b/REORG.TODO/sysdeps/mach/sched_yield.c
new file mode 100644
index 0000000000..9f0f2f9ce9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/sched_yield.c
@@ -0,0 +1,31 @@
+/* sched_yield -- yield the processor. Mach version.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sched.h>
+#include <mach.h>
+
+/* Yield the processor. */
+int
+__sched_yield (void)
+{
+ (void) __swtch ();
+ return 0;
+}
+libc_hidden_def (__sched_yield)
+weak_alias (__sched_yield, sched_yield)
diff --git a/REORG.TODO/sysdeps/mach/sleep.c b/REORG.TODO/sysdeps/mach/sleep.c
new file mode 100644
index 0000000000..260280ce34
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/sleep.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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
+__sleep (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);
+}
+weak_alias (__sleep, sleep)
diff --git a/REORG.TODO/sysdeps/mach/strerror_l.c b/REORG.TODO/sysdeps/mach/strerror_l.c
new file mode 100644
index 0000000000..b598286bb9
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/strerror_l.c
@@ -0,0 +1,101 @@
+/* strerror_l - Get errno description string in given locale. Mach version.
+ Copyright (C) 2007-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mach/error.h>
+#include <errorlib.h>
+#include <sys/param.h>
+
+
+static __thread char *last_value;
+
+
+static const char *
+translate (const char *str, locale_t loc)
+{
+ locale_t oldloc = __uselocale (loc);
+ const char *res = _(str);
+ __uselocale (oldloc);
+ return res;
+}
+
+
+/* Return a string describing the errno code in ERRNUM. */
+char *
+strerror_l (int errnum, locale_t loc)
+{
+ 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 || ! __mach_error_systems[system].bad_sub)
+ {
+ free (last_value);
+ if (__asprintf (&last_value, "%s%X",
+ translate ("Error in unknown error system: ", loc),
+ errnum) == -1)
+ last_value = NULL;
+
+ return last_value;
+ }
+
+ es = &__mach_error_systems[system];
+
+ if (sub >= es->max_sub)
+ return (char *) translate (es->bad_sub, loc);
+
+ if (code >= es->subsystem[sub].max_code)
+ {
+ free (last_value);
+ if (__asprintf (&last_value, "%s%s %d",
+ translate ("Unknown error ", loc),
+ translate (es->subsystem[sub].subsys_name, loc),
+ errnum) == -1)
+ last_value = NULL;
+
+ return last_value;
+ }
+
+ return (char *) translate (es->subsystem[sub].codes[code], loc);
+}
+
+
+#ifdef _LIBC
+# ifdef _LIBC_REENTRANT
+/* This is called when a thread is exiting to free the last_value string. */
+static void __attribute__ ((section ("__libc_thread_freeres_fn")))
+strerror_thread_freeres (void)
+{
+ free (last_value);
+}
+text_set_element (__libc_thread_subfreeres, strerror_thread_freeres);
+text_set_element (__libc_subfreeres, strerror_thread_freeres);
+# endif
+#endif
diff --git a/REORG.TODO/sysdeps/mach/sys/reboot.h b/REORG.TODO/sysdeps/mach/sys/reboot.h
new file mode 100644
index 0000000000..9beb8aef72
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/sys/reboot.h
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+/*
+ * (pre-GNU) HISTORY
+ *
+ * Revision 2.8 93/03/11 13:46:40 danner
+ * unsigned long -> unsigned 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, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.*/
+
+/*
+ * @(#)reboot.h 7.5 (Berkeley) 6/27/88
+ */
+
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+#include <features.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 0xf0000000U
+#define B_DEVMAGIC 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
+
+__BEGIN_DECLS
+
+/* Reboot or halt the system. */
+extern int reboot (int __howto) __THROW;
+
+__END_DECLS
+
+
+#endif /* _SYS_REBOOT_H_ */
diff --git a/REORG.TODO/sysdeps/mach/sys/syscall.h b/REORG.TODO/sysdeps/mach/sys/syscall.h
new file mode 100644
index 0000000000..6e4ed4d64e
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/sys/syscall.h
@@ -0,0 +1 @@
+/* The Mach syscalls are in <mach/syscall_sw.h>. */
diff --git a/REORG.TODO/sysdeps/mach/sysdep.h b/REORG.TODO/sysdeps/mach/sysdep.h
new file mode 100644
index 0000000000..6cdcbf366f
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/sysdep.h
@@ -0,0 +1,86 @@
+/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#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##:)
+
+/* For ELF we need to add the `.type' directive to make shared libraries
+ work right. */
+#undef ENTRY
+#define ENTRY(name) \
+ .globl name; \
+ .align ALIGN; \
+ .type name,@function; \
+ name:
+
+#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. */
+#define C_SYMBOL_NAME(name) name
diff --git a/REORG.TODO/sysdeps/mach/thread_state.h b/REORG.TODO/sysdeps/mach/thread_state.h
new file mode 100644
index 0000000000..1a154cd0fa
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/thread_state.h
@@ -0,0 +1,86 @@
+/* Generic definitions for dealing with Mach thread states.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+
+/* 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
+ {
+ /* No one 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/REORG.TODO/sysdeps/mach/usleep.c b/REORG.TODO/sysdeps/mach/usleep.c
new file mode 100644
index 0000000000..49f987df72
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/usleep.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <mach.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off. */
+int
+usleep (useconds_t useconds)
+{
+ mach_port_t recv;
+ struct timeval before, after;
+
+ recv = __mach_reply_port ();
+
+ if (__gettimeofday (&before, NULL) < 0)
+ return -1;
+ (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 -1;
+
+ return 0;
+}
diff --git a/REORG.TODO/sysdeps/mach/xpg-strerror.c b/REORG.TODO/sysdeps/mach/xpg-strerror.c
new file mode 100644
index 0000000000..44d22cc266
--- /dev/null
+++ b/REORG.TODO/sysdeps/mach/xpg-strerror.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <string.h>
+#include <mach/error.h>
+#include <errorlib.h>
+#include <sys/param.h>
+#include <_itoa.h>
+
+/* It is critical here that we always use the `dcgettext' function for
+ the message translation. Since <libintl.h> only defines the macro
+ `dgettext' to use `dcgettext' for optimizing programs this is not
+ always guaranteed. */
+#ifndef dgettext
+# include <locale.h> /* We need LC_MESSAGES. */
+# define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES)
+#endif
+
+/* Fill buf with a string describing the errno code in ERRNUM. */
+int
+__xpg_strerror_r (int errnum, char *buf, size_t buflen)
+{
+ int system;
+ int sub;
+ int code;
+ const struct error_system *es;
+ extern void __mach_error_map_compat (int *);
+ const char *estr;
+
+ __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 || ! __mach_error_systems[system].bad_sub)
+ return EINVAL;
+
+ es = &__mach_error_systems[system];
+
+ if (sub >= es->max_sub)
+ estr = (const char *) es->bad_sub;
+ else if (code >= es->subsystem[sub].max_code)
+ return EINVAL;
+ else
+ estr = (const char *) _(es->subsystem[sub].codes[code]);
+
+ size_t estrlen = strlen (estr) + 1;
+
+ if (buflen < estrlen)
+ return ERANGE;
+
+ memcpy (buf, estr, estrlen);
+ return 0;
+}