This fixes the following:
- On error, poll must not return without polling, including EBADF, and instead
report POLLHUP/POLLERR/POLLNVAL
- Select must report EBADF if some set contains an invalid FD.
The idea is to move error management to after all select calls, in the
poll/select final treatment. The error is instead recorded in a new `error'
field, and a new SELECT_ERROR bit set.
Thanks Svante Signell for the initial version of the patch.
* hurd/hurdselect.c (SELECT_ERROR): New macro.
(_hurd_select):
- Add `error' field to `d' structures array.
- If a poll descriptor is bogus, set EBADF, but continue with a zero
timeout.
- Go through the whole fd_set, not only until _hurd_dtablesize. Return
EBADF there is any bit set above _hurd_dtablesize.
- Do not request io_select on bogus descriptors (SELECT_ERROR).
- On io_select request error, record the error.
- On io_select bogus reply, use EIO error code.
- On io_select bogus or error reply, record the error.
- Do not destroy reply port for bogus FDs.
- On error, make poll set POLLHUP in the EPIPE case, POLLNVAL in the
EBADF case, or else POLLERR.
- On error, make select simulated readiness.
Rely on servers to implement timeouts, so that very short values (including
0) don't make mach_msg return before valid replies can be received. The
purpose of this scheme is to guarantee a full client-server round-trip,
whatever the timeout value.
This change depends on the new io_select_timeout RPC being implemented by
servers.
* hurd/Makefile (user-interfaces): Add io_reply and io_request.
* hurd/hurdselect.c: Include <sys/time.h>, <hurd/io_request.h> and
<limits.h>.
(_hurd_select): Replace the call to __io_select with either
__io_select_request or __io_select_timeout_request, depending on the
timeout. Count the number of ready descriptors (replies for which at
least one type bit is set). Implement the timeout locally when there is
no file descriptor.
The function attempts to optimize this case by performing one IPC system
call with the timeout included among the parameters, but in the absence
of a reply, it will call mach_msg again with the same timeout later,
effectively doubling the total timeout of the select/poll call.
Remove this optimization for the time being.
* hurd/hurdselect.c (_hurd_select): Always call __io_select with no
timeout.
This patch fixes -Wempty-body warnings in Hurd-specific code that show
up building glibc with -Wextra.
Note: there also such warnings on many platforms arising from the
default definition of HP_TIMING_NOW in sysdeps/generic/hp-timing.h,
but no change there is proposed in this patch because of other changes
under discussion in that area that would result in a nonempty
definition.
Tested with build-many-glibcs.py.
* hurd/hurdinit.c (_hurd_init): Use braces around empty body of an
if statement.
* hurd/lookup-at.c (__file_name_lookup_at): When at_flags contains
AT_EMPTY_PATH, call __dir_lookup and __hurd_file_name_lookup_retry
directly instead of __hurd_file_name_lookup.
* hurd/lookup-retry: Include <unistd.h>.
(__hurd_file_name_lookup_retry): Keep a ref on last result in `lastdir'.
Release it on return. Handle "pid" magical lookup retry.
There are a lot more printf variants than there are scanf variants,
and the code for setting up and tearing down their custom FILE
variants around the call to __vf(w)printf is more complicated and
variable. Therefore, I have added _internal versions of all the
v*printf variants, rather than introducing helper routines so that
they can all directly call __vf(w)printf_internal, as was done with
scanf.
As with the scanf changes, in this patch the _internal functions still
look at the environmental mode bits and all callers pass 0 for the
flags parameter.
Several of the affected public functions had _IO_ name aliases that
were not exported (but, in one case, appeared in libio.h anyway);
I was originally planning to leave them as aliases to avoid having
to touch internal callers, but it turns out ldbl_*_alias only work
for exported symbols, so they've all been removed instead. It also
turns out there were hardly any internal callers. _IO_vsprintf and
_IO_vfprintf *are* exported, so those two stick around.
Summary for the changes to each of the affected symbols:
_IO_vfprintf, _IO_vsprintf:
All internal calls removed, thus the internal declarations, as well
as uses of libc_hidden_proto and libc_hidden_def, were also removed.
The external symbol is now exposed via uses of ldbl_strong_alias
to __vfprintf_internal and __vsprintf_internal, respectively.
_IO_vasprintf, _IO_vdprintf, _IO_vsnprintf,
_IO_vfwprintf, _IO_vswprintf,
_IO_obstack_vprintf, _IO_obstack_printf:
All internal calls removed, thus declaration in internal headers
were also removed. They were never exported, so there are no
aliases tying them to the internal functions. I.e.: entirely gone.
__vsnprintf:
Internal calls were always preceded by macros such as
#define __vsnprintf _IO_vsnprintf, and
#define __vsnprintf vsnprintf
The macros were removed and their uses replaced with calls to the
new internal function __vsnprintf_internal. Since there were no
internal calls, the internal declaration was also removed. The
external symbol is preserved with ldbl_weak_alias to ___vsnprintf.
__vfwprintf:
All internal calls converted into calls to __vfwprintf_internal,
thus the internal declaration was removed. The function is now a
wrapper that calls __vfwprintf_internal. The external symbol is
preserved.
__vswprintf:
Similarly, but no external symbol.
__vasprintf, __vdprintf, __vfprintf, __vsprintf:
New internal wrappers. Not exported.
vasprintf, vdprintf, vfprintf, vsprintf, vsnprintf,
vfwprintf, vswprintf,
obstack_vprintf, obstack_printf:
These functions used to be aliases to the respective _IO_* function,
they are now aliases to their respective __* functions.
Tested for powerpc and powerpc64le.
* hurd/hurd/userlink.h (_hurd_userlink_move): New function.
* hurd/hurd/port.h (_hurd_port_move): New function.
* sysdeps/mach/hurd/spawni.c (NEW_ULINK_TABLE): New macro.
(EXPAND_DTABLE): Use NEW_ULINK_TABLE macro for ulink_dtable.
* sysdeps/mach/hurd/i386/intr-msg.h (INTR_MSG_TRAP): Make
_hurd_intr_rpc_msg_about_to global point to start of controlled
assembly snippet. Make it check canceled flag.
* hurd/hurdsig.c (_hurdsig_abort_rpcs): Only mutate thread if it passed
the _hurd_intr_rpc_msg_about_to point.
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Remove comment on mutation
issue, remove cancel flag check.
since we do not actually know whether the RPC was completed or not,
which makes a huge difference for e.g. write(), so better really error
out than letting caller think that the RPC did not happen.
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): When the server does not
answer to interrupt_operation, return EIO instead of EINTR.
Seeing a server not able to get interrupted for 3s is not so surprising when
e.g. a lot of writes are happening. 1 minute allows to actually notice the
issue and be able to debug it.
* hurd/hurdsig.c (_hurd_interrupted_rpc_timeout): Set to 60000.
Exec needs that mach_setup_thread does *not* set up TLS since it works on
another task, so we have to split this into mach_setup_tls.
* mach/mach.h (__mach_setup_tls, mach_setup_tls): Add prototypes.
* mach/setup-thread.c (__mach_setup_thread): Move TLS setup to...
(__mach_setup_tls): ... new function.
(mach_setup_tls): New alias.
* hurd/hurdsig.c (_hurdsig_init): Call __mach_setup_tls after
__mach_setup_thread.
* sysdeps/mach/hurd/profil.c (update_waiter): Likewise.
* sysdeps/mach/hurd/setitimer.c (setitimer_locked): Likewise.
* mach/Versions [libc] (mach_setup_tls): Add symbol.
* sysdeps/mach/hurd/i386/libc.abilist (mach_setup_tls): Likewise.
Appending / to the path to be looked up would make us always follow a final
symlink, even with O_NOTRANS (since the final resolution is after the
'/'). In the O_DIRECTORY | O_NOFOLLOW case, we thus have to really open
the node and stat it, which we already do anyway, and check for
directory type.
* hurd/hurdlookup.c (__hurd_file_name_lookup): Do not append '/' to
path when flags contains O_NOFOLLOW.
* hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Return ENOTDIR
if flags contains O_DIRECTORY and the result is a directory.
The error code documented by POSIX for opening a symlink with O_NOFOLLOW
is ELOOP.
Also, if the translator does not expose symlink as a symlink translator but
as a S_IFLNK file, O_NOFOLLOW needs to return ELOOP too.
* hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Return ELOOP
when opening a symlink with O_NOFOLLOW.
* hurd/Makefile (routines): Add hurdlock.
* hurd/Versions (GLIBC_PRIVATE): Added new entry to export the above
interface.
(HURD_CTHREADS_0.3): Remove __libc_getspecific.
* hurd/hurdpid.c: Include <lowlevellock.h>
(_S_msg_proc_newids): Use lll_wait to synchronize.
* hurd/hurdsig.c: (reauth_proc): Use __mutex_lock and __mutex_unlock.
* hurd/setauth.c: Include <hurdlock.h>, use integer for synchronization.
* mach/Makefile (lock-headers): Remove machine-lock.h.
* mach/lock-intern.h: Include <lowlevellock.h> instead of
<machine-lock.h>.
(__spin_lock_t): New type.
(__SPIN_LOCK_INITIALIZER): New macro.
(__spin_lock, __spin_unlock, __spin_try_lock, __spin_lock_locked,
__mutex_init, __mutex_lock_solid, __mutex_unlock_solid, __mutex_lock,
__mutex_unlock, __mutex_trylock): Use lll to implement locks.
* mach/mutex-init.c: Include <lowlevellock.h> instead of <cthreads.h>.
(__mutex_init): Initialize with lll.
* manual/errno.texi (EOWNERDEAD, ENOTRECOVERABLE): New errno values.
* sysdeps/mach/Makefile: Add libmachuser as dependencies for libs
needing lll.
* sysdeps/mach/hurd/bits/errno.h: Regenerate.
* sysdeps/mach/hurd/cthreads.c (__libc_getspecific): Remove function.
* sysdeps/mach/hurd/bits/libc-lock.h: Remove file.
* sysdeps/mach/hurd/setpgid.c: Include <lowlevellock.h>.
(__setpgid): Use lll for synchronization.
* sysdeps/mach/hurd/setsid.c: Likewise with __setsid.
* sysdeps/mach/bits/libc-lock.h: Include <tls.h> and <lowlevellock.h>
instead of <cthreads.h>.
(_IO_lock_inexpensive): New macro
(__libc_lock_recursive_t, __rtld_lock_recursive_t): New structures.
(__libc_lock_self0): New declaration.
(__libc_lock_owner_self): New macro.
(__libc_key_t): Remove type.
(_LIBC_LOCK_INITIALIZER): New macro.
(__libc_lock_define_initialized, __libc_lock_init, __libc_lock_fini,
__libc_lock_fini_recursive, __rtld_lock_fini_recursive,
__libc_lock_lock, __libc_lock_trylock, __libc_lock_unlock,
__libc_lock_define_initialized_recursive,
__rtld_lock_define_initialized_recursive,
__libc_lock_init_recursive, __libc_lock_trylock_recursive,
__libc_lock_lock_recursive, __libc_lock_unlock_recursive,
__rtld_lock_initialize, __rtld_lock_trylock_recursive,
__rtld_lock_lock_recursive, __rtld_lock_unlock_recursive
__libc_once_define, __libc_mutex_unlock): Reimplement with lll.
(__libc_lock_define_recursive, __rtld_lock_define_recursive,
_LIBC_LOCK_RECURSIVE_INITIALIZER, _RTLD_LOCK_RECURSIVE_INITIALIZER):
New macros.
Include <libc-lockP.h> to reimplement libc_key* with pthread_key*.
* hurd/hurdlock.c: New file.
* hurd/hurdlock.h: New file.
* mach/lowlevellock.h: New file
This gets rid of a lot of kludge and gets closer to other ports.
* hurd/Makefile (headers): Remove threadvar.h.
(inline-headers): Remove threadvar.h.
* hurd/Versions (GLIBC_2.0: Remove __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables,
__hurd_threadvar_max, __hurd_errno_location.
(HURD_CTHREADS_0.3): Add pthread_getattr_np, pthread_attr_getstack.
* hurd/hurd/signal.h: Do not include <hurd/threadvar.h>.
(_hurd_self_sigstate): Use THREAD_SELF to get _hurd_sigstate.
(_HURD_SIGNAL_H_EXTERN_INLINE): Use THREAD_SELF to get _hurd_sigstate,
unless TLS is not initialized yet, in which case we do not need a
critical section yet anyway.
* hurd/hurd/threadvar.h: Include <tls.h>, do not include
<machine-sp.h>.
(__hurd_sigthread_variables, __hurd_threadvar_max): Remove variables
declarations.
(__hurd_threadvar_index): Remove enum.
(_HURD_THREADVAR_H_EXTERN_INLINE): Remove macro.
(__hurd_threadvar_location_from_sp,__hurd_threadvar_location): Remove
inlines.
(__hurd_reply_port0): New variable declaration.
(__hurd_local_reply_port): New macro.
* hurd/hurdsig.c (__hurd_sigthread_variables): Remove variable.
(interrupted_reply_port_location): Add thread_t parameter. Use it
with THREAD_TCB to access thread-local variables.
(_hurdsig_abort_rpcs): Pass ss->thread to
interrupted_reply_port_location.
(_hurd_internal_post_signal): Likewise.
(_hurdsig_init): Use presence of cthread_fork instead of
__hurd_threadvar_stack_mask to start signal thread by hand.
Remove signal thread threadvar initialization.
* hurd/hurdstartup.c: Do not include <hurd/threadvar.h>
* hurd/sigunwind.c: Include <hurd/threadvar.h>
(_hurdsig_longjmp_from_handler): Use __hurd_local_reply_port instead
of threadvar.
* sysdeps/mach/hurd/Versions (libc.GLIBC_PRIVATE): Add
__libc_lock_self0.
(ld.GLIBC_2.0): Remove __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables.
(ld.GLIBC_PRIVATE): Add __libc_lock_self0.
* sysdeps/mach/hurd/cthreads.c: Add __libc_lock_self0.
* sysdeps/mach/hurd/dl-sysdep.c (errno, __hurd_sigthread_stack_base,
__hurd_sigthread_stack_end, __hurd_sigthread_variables, threadvars,
__hurd_threadvar_stack_offset, __hurd_threadvar_stack_mask): Do not
define variables.
* sysdeps/mach/hurd/errno-loc.c: Do not include <errno.h> and
<hurd/threadvar.h>.
[IS_IN(rtld)] (rtld_errno): New variable.
[IS_IN(rtld)] (__errno_location): New weak function.
[!IS_IN(rtld)]: Include "../../../csu/errno-loc.c".
* sysdeps/mach/hurd/errno.c: Remove file.
* sysdeps/mach/hurd/fork.c: Include <hurd/threadvar.h>
(__fork): Remove THREADVAR_SPACE macro and its use.
* sysdeps/mach/hurd/i386/init-first.c (__hurd_threadvar_max): Remove
variable.
(init): Do not initialize threadvar.
* sysdeps/mach/hurd/i386/libc.abilist (__hurd_threadvar_max): Remove
symbol.
* sysdeps/mach/hurd/i386/sigreturn.c (__sigreturn): Use
__hurd_local_reply_port instead of threadvar.
* sysdeps/mach/hurd/i386/tls.h (tcbhead_t): Add reply_port and
_hurd_sigstate fields.
(HURD_DESC_TLS, __LIBC_NO_TLS, THREAD_TCB): New macro.
* sysdeps/mach/hurd/i386/trampoline.c: Remove outdated comment.
* sysdeps/mach/hurd/libc-lock.h: Do not include <hurd/threadvar.h>.
(__libc_lock_owner_self): Use &__libc_lock_self0 and THREAD_SELF
instead of threadvar.
* sysdeps/mach/hurd/libc-tsd.h: Remove file.
* sysdeps/mach/hurd/mig-reply.c (GETPORT, reply_port): Remove macros.
(use_threadvar, global_reply_port): Remove variables.
(__hurd_reply_port0): New variable.
(__mig_get_reply_port): Use __hurd_local_reply_port and
__hurd_reply_port0 instead of threadvar.
(__mig_dealloc_reply_port): Likewise.
(__mig_init): Do not initialize threadvar.
* sysdeps/mach/hurd/profil.c: Fix comment.
* sysdeps/generic/thread_state.h (MACHINE_NEW_THREAD_STATE_FLAVOR):
Define macro.
* sysdeps/mach/thread_state.h (MACHINE_THREAD_STATE_FIX_NEW): New macro.
* sysdeps/mach/i386/thread_state.h
(MACHINE_NEW_THREAD_STATE_FLAVOR): New macro, defined to
i386_THREAD_STATE.
(MACHINE_THREAD_STATE_FLAVOR): Define to i386_REGS_SEGS_STATE instead of
i386_THREAD_STATE.
(MACHINE_THREAD_STATE_FIX_NEW): New macro, reads segments.
* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): Use
i386_REGS_SEGS_STATE instead of i386_THREAD_STATE.
* sysdeps/mach/hurd/i386/tls.h (TCB_ALIGNMENT, HURD_SEL_LDT): New
macros.
(_hurd_tls_fork): Add original thread parameter, Duplicate existing LDT
descriptor instead of creating a new one.
(_hurd_tls_new): New function, creates a new descriptor and updates tcb.
* mach/setup-thread.c: Include <ldsodefs.h>.
(__mach_setup_thread): Call _dl_allocate_tls, pass
MACHINE_NEW_THREAD_STATE_FLAVOR to __thread_set_state instead of
MACHINE_THREAD_STATE_FLAVOR, before getting
MACHINE_THREAD_STATE_FLAVOR, calling _hurd_tls_new, and setting
MACHINE_THREAD_STATE_FLAVOR with the result.
* hurd/hurdfault.c (_hurdsig_fault_init): Call
MACHINE_THREAD_STATE_FIX_NEW.
* sysdeps/mach/hurd/fork.c (__fork): Call _hurd_tls_fork for sigthread
too. Add original thread parameter.
so interfaces needing it can get it.
* stdlib/errno.h (error_t): Move definition to...
* bits/types/error_t.h: ... new header.
* stdlib/Makefile (headers): Add bits/types/error_t.h.
* sysdeps/mach/hurd/bits/errno.h (error_t): Move definition to...
* sysdeps/mach/hurd/bits/types/error_t.h: ... new header.
* sysdeps/mach/hurd/errnos.awk (error_t): Likewise.
* hurd/hurd.h: Include <bits/types/error_t.h>
* hurd/hurd/fd.h: Include <bits/types/error_t.h>
* hurd/hurd/id.h: Include <errno.h> and <bits/types/error_t.h>
* hurd/hurd/lookup.h: Include <errno.h> and <bits/types/error_t.h>
* hurd/hurd/resource.h: Include <bits/types/error_t.h>
* hurd/hurd/signal.h: Include <bits/types/error_t.h>
* hurd/hurd/sigpreempt.h: Include <bits/types/error_t.h>
* hurd/hurd.h: Include <bits/types/sigset_t.h>
* hurd/hurd/fd.h: Include <sys/select.h> and <bits/types/sigset_t.h>
(_hurd_fd_read, _hurd_fd_write): Use __loff_t instead of loff_t.
* hurd/hurd/signal.h: Include <bits/types/stack_t.h> and
<bits/types/sigset_t.h>.
[!defined __USE_GNU]: Do not #error out.
(struct hurd_sigstate): Use _NSIG instead of NSIG.
* hurd/hurd/sigpreempt.h (__need_size_t): Define.
Include <stddef.h> and <bits/types/sigset_t.h>
(struct hurd_signal_preemptor, hurd_catch_signal): Use __sighandler_t
instead of sighandler_t.
thus making <hurd/port.h> and <hurd/userlink.h> includable without
_GNU_SOURCE.
* hurd/hurd/port.h: Do not include <hurd/signal.h>.
* hurd/hurd/userlink.h [!defined __USE_EXTERN_INLINES ||
!defined _LIBC || !IS_IN (libc)]: Do not include <hurd/signal.h>.
This patch mechanically removes all remaining uses, and the
definitions, of the following libio name aliases:
name replaced with
---- -------------
_IO_FILE FILE
_IO_fpos_t __fpos_t
_IO_fpos64_t __fpos64_t
_IO_size_t size_t
_IO_ssize_t ssize_t or __ssize_t
_IO_off_t off_t
_IO_off64_t off64_t
_IO_pid_t pid_t
_IO_uid_t uid_t
_IO_wint_t wint_t
_IO_va_list va_list or __gnuc_va_list
_IO_BUFSIZ BUFSIZ
_IO_cookie_io_functions_t cookie_io_functions_t
__io_read_fn cookie_read_function_t
__io_write_fn cookie_write_function_t
__io_seek_fn cookie_seek_function_t
__io_close_fn cookie_close_function_t
I used __fpos_t and __fpos64_t instead of fpos_t and fpos64_t because
the definitions of fpos_t and fpos64_t depend on the largefile mode.
I used __ssize_t and __gnuc_va_list in a handful of headers where
namespace cleanliness might be relevant even though they're
internal-use-only. In all other cases, I used the public-namespace
name.
There are a tiny handful of places where I left a use of 'struct _IO_FILE'
alone, because it was being used together with 'struct _IO_FILE_plus'
or 'struct _IO_FILE_complete' in the same arithmetic expression.
Because this patch was almost entirely done with search and replace, I
may have introduced indentation botches. I did proofread the diff,
but I may have missed something.
The ChangeLog below calls out all of the places where this was not a
pure search-and-replace change.
Installed stripped libraries and executables are unchanged by this patch,
except that some assertions in vfscanf.c change line numbers.
* libio/libio.h (_IO_FILE): Delete; all uses changed to FILE.
(_IO_fpos_t): Delete; all uses changed to __fpos_t.
(_IO_fpos64_t): Delete; all uses changed to __fpos64_t.
(_IO_size_t): Delete; all uses changed to size_t.
(_IO_ssize_t): Delete; all uses changed to ssize_t or __ssize_t.
(_IO_off_t): Delete; all uses changed to off_t.
(_IO_off64_t): Delete; all uses changed to off64_t.
(_IO_pid_t): Delete; all uses changed to pid_t.
(_IO_uid_t): Delete; all uses changed to uid_t.
(_IO_wint_t): Delete; all uses changed to wint_t.
(_IO_va_list): Delete; all uses changed to va_list or __gnuc_va_list.
(_IO_BUFSIZ): Delete; all uses changed to BUFSIZ.
(_IO_cookie_io_functions_t): Delete; all uses changed to
cookie_io_functions_t.
(__io_read_fn): Delete; all uses changed to cookie_read_function_t.
(__io_write_fn): Delete; all uses changed to cookie_write_function_t.
(__io_seek_fn): Delete; all uses changed to cookie_seek_function_t.
(__io_close_fn): Delete: all uses changed to cookie_close_function_t.
* libio/iofopncook.c: Remove unnecessary forward declarations.
* libio/iolibio.h: Correct outdated commentary.
* malloc/malloc.c (__malloc_stats): Remove unnecessary casts.
* stdio-common/fxprintf.c (__fxprintf_nocancel):
Remove unnecessary casts.
* stdio-common/getline.c: Use _IO_getdelim directly.
Don't redefine ssize_t.
* stdio-common/printf_fp.c, stdio_common/printf_fphex.c
* stdio-common/printf_size.c: Don't redefine size_t or FILE.
Remove outdated comments.
* stdio-common/vfscanf.c: Don't redefine va_list.
* hurd/Versions: Fix version when _hurd_exec_paths was added.
* mach/Versions: Fix version when __mach_host_self_ was added.
* sysdeps/mach/hurd/i386/ld.abilist: New file.
* sysdeps/mach/hurd/i386/libBrokenLocale.abilist: New file.
* sysdeps/mach/hurd/i386/libanl.abilist: New file.
* sysdeps/mach/hurd/i386/libc.abilist: New file.
* sysdeps/mach/hurd/i386/libcrypt.abilist: New file.
* sysdeps/mach/hurd/i386/libdl.abilist: New file.
* sysdeps/mach/hurd/i386/libm.abilist: New file.
* sysdeps/mach/hurd/i386/libnsl.abilist: New file.
* sysdeps/mach/hurd/i386/libresolv.abilist: New file.
* sysdeps/mach/hurd/i386/librt.abilist: New file.
* sysdeps/mach/hurd/i386/libutil.abilist: New file.