From f512321130d6c02332d441812ef4780908bb744d Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 28 Jun 2020 22:41:18 +0000 Subject: [PATCH] hurd: Add remaining cancelation points * hurd/hurdselect.c: Include . (_hurd_select): Surround call to __mach_msg with enabling async cancel. * sysdeps/mach/hurd/accept4.c: Include . (__libc_accept4): Surround call to __socket_accept with enabling async cancel, and use HURD_DPORT_USE_CANCEL instead of HURD_DPORT_USE. * sysdeps/mach/hurd/connect.c: Include . (__connect): Surround call to __file_name_lookup and __socket_connect with enabling async cancel, and use HURD_DPORT_USE_CANCEL instead of HURD_DPORT_USE. * sysdeps/mach/hurd/fdatasync.c: Include . (fdatasync): Surround call to __file_sync with enabling async cancel, and use HURD_DPORT_USE_CANCEL instead of HURD_DPORT_USE. * sysdeps/mach/hurd/fsync.c: Include . (fsync): Surround call to __file_sync with enabling async cancel, and use HURD_DPORT_USE_CANCEL instead of HURD_DPORT_USE. * sysdeps/mach/hurd/ioctl.c: Include . (__ioctl): When request is TIOCDRAIN, surround call to send_rpc with enabling async cancel, and use HURD_DPORT_USE_CANCEL instead of HURD_DPORT_USE. * sysdeps/mach/hurd/msync.c: Include . (msync): Surround call to __vm_object_sync with enabling async cancel. * sysdeps/mach/hurd/sigsuspend.c: Include . (__sigsuspend): Surround call to __mach_msg with enabling async cancel. * sysdeps/mach/hurd/sigwait.c: Include . (__sigwait): Surround wait code with enabling async cancel. * sysdeps/mach/msync.c: Include . (msync): Surround call to __vm_msync with enabling async cancel. * sysdeps/mach/sleep.c: Include . (__sleep): Surround call to __mach_msg with enabling async cancel. * sysdeps/mach/usleep.c: Include . (usleep): Surround call to __vm_msync with enabling async cancel. --- hurd/hurdselect.c | 5 +++++ sysdeps/mach/hurd/accept4.c | 7 ++++++- sysdeps/mach/hurd/connect.c | 11 +++++++++-- sysdeps/mach/hurd/fdatasync.c | 8 +++++++- sysdeps/mach/hurd/fsync.c | 8 +++++++- sysdeps/mach/hurd/ioctl.c | 11 ++++++++++- sysdeps/mach/hurd/msync.c | 4 ++++ sysdeps/mach/hurd/sigsuspend.c | 5 +++++ sysdeps/mach/hurd/sigwait.c | 4 ++++ sysdeps/mach/msync.c | 9 +++++++-- sysdeps/mach/sleep.c | 4 ++++ sysdeps/mach/usleep.c | 4 ++++ 12 files changed, 72 insertions(+), 8 deletions(-) diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c index 69a415c..8da0ccf 100644 --- a/hurd/hurdselect.c +++ b/hurd/hurdselect.c @@ -28,6 +28,7 @@ #include #include #include +#include /* All user select types. */ #define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG) @@ -432,11 +433,14 @@ _hurd_select (int nfds, to = MACH_MSG_TIMEOUT_NONE; } + int cancel_oldtype = LIBC_CANCEL_ASYNC(); while ((msgerr = __mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_INTERRUPT | options, 0, sizeof msg, portset, to, MACH_PORT_NULL)) == MACH_MSG_SUCCESS) { + LIBC_CANCEL_RESET (cancel_oldtype); + /* We got a message. Decode it. */ #ifdef MACH_MSG_TYPE_BIT const union typeword inttype = @@ -527,6 +531,7 @@ _hurd_select (int nfds, options |= MACH_RCV_TIMEOUT; } } + LIBC_CANCEL_RESET (cancel_oldtype); if (msgerr == MACH_RCV_INTERRUPTED) /* Interruption on our side (e.g. signal reception). */ diff --git a/sysdeps/mach/hurd/accept4.c b/sysdeps/mach/hurd/accept4.c index 639f159..2da7a8b 100644 --- a/sysdeps/mach/hurd/accept4.c +++ b/sysdeps/mach/hurd/accept4.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Await a connection on socket FD. When a connection arrives, open a new socket to communicate with it, @@ -41,13 +42,17 @@ __libc_accept4 (int fd, __SOCKADDR_ARG addrarg, socklen_t *addr_len, int flags) char *buf = (char *) addr; mach_msg_type_number_t buflen; int type; + int cancel_oldtype; 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))) + cancel_oldtype = LIBC_CANCEL_ASYNC(); + err = HURD_DPORT_USE_CANCEL (fd, __socket_accept (port, &new, &aport)); + LIBC_CANCEL_RESET (cancel_oldtype); + if (err) return __hurd_dfail (fd, err); if (addr != NULL) diff --git a/sysdeps/mach/hurd/connect.c b/sysdeps/mach/hurd/connect.c index b9b9fdd..2b03b87 100644 --- a/sysdeps/mach/hurd/connect.c +++ b/sysdeps/mach/hurd/connect.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "hurd/hurdsocket.h" /* Open a connection on socket FD to peer at ADDR (which LEN bytes long). @@ -34,13 +35,17 @@ __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__; + int cancel_oldtype; 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); + file_t file; + cancel_oldtype = LIBC_CANCEL_ASYNC(); + file = __file_name_lookup (name, 0, 0); + LIBC_CANCEL_RESET (cancel_oldtype); if (file == MACH_PORT_NULL) return -1; err = __ifsock_getsockaddr (file, &aport); @@ -54,7 +59,7 @@ __connect (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len) else err = EIEIO; - err = HURD_DPORT_USE (fd, + err = HURD_DPORT_USE_CANCEL (fd, ({ if (err) err = __socket_create_address (port, @@ -63,7 +68,9 @@ __connect (int fd, __CONST_SOCKADDR_ARG addrarg, socklen_t len) &aport); if (! err) { + cancel_oldtype = LIBC_CANCEL_ASYNC(); err = __socket_connect (port, aport); + LIBC_CANCEL_RESET (cancel_oldtype); __mach_port_deallocate (__mach_task_self (), aport); } diff --git a/sysdeps/mach/hurd/fdatasync.c b/sysdeps/mach/hurd/fdatasync.c index 797fcf6..8ccda0a 100644 --- a/sysdeps/mach/hurd/fdatasync.c +++ b/sysdeps/mach/hurd/fdatasync.c @@ -19,12 +19,18 @@ #include #include #include +#include /* 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)); + error_t err; + int cancel_oldtype; + + cancel_oldtype = LIBC_CANCEL_ASYNC(); + err = HURD_DPORT_USE_CANCEL (fd, __file_sync (port, 1, 1)); + LIBC_CANCEL_RESET (cancel_oldtype); if (err) { if (err == EOPNOTSUPP) diff --git a/sysdeps/mach/hurd/fsync.c b/sysdeps/mach/hurd/fsync.c index 85aa992..0b2a09d 100644 --- a/sysdeps/mach/hurd/fsync.c +++ b/sysdeps/mach/hurd/fsync.c @@ -19,12 +19,18 @@ #include #include #include +#include /* 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)); + error_t err; + int cancel_oldtype; + + cancel_oldtype = LIBC_CANCEL_ASYNC(); + err = HURD_DPORT_USE_CANCEL (fd, __file_sync (port, 1, 0)); + LIBC_CANCEL_RESET (cancel_oldtype); if (err) { if (err == EOPNOTSUPP) diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c index a9a148f..4c0e54b 100644 --- a/sysdeps/mach/hurd/ioctl.c +++ b/sysdeps/mach/hurd/ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -269,7 +270,15 @@ __ioctl (int fd, unsigned long int request, ...) /* 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)); + if (request == TIOCDRAIN) + { + /* This is a cancellation point. */ + int cancel_oldtype = LIBC_CANCEL_ASYNC(); + err = HURD_DPORT_USE_CANCEL (fd, _hurd_ctty_output (port, ctty, send_rpc)); + LIBC_CANCEL_RESET (cancel_oldtype); + } + else + err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc)); #ifdef MACH_MSG_TYPE_BIT t = (mach_msg_type_t *) msg.data; diff --git a/sysdeps/mach/hurd/msync.c b/sysdeps/mach/hurd/msync.c index cec467e..1820190 100644 --- a/sysdeps/mach/hurd/msync.c +++ b/sysdeps/mach/hurd/msync.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -44,6 +45,7 @@ msync (void *addr, size_t length, int flags) vm_offset_t offset; kern_return_t err; + int cancel_oldtype; if (flags & (MS_SYNC | MS_ASYNC) == (MS_SYNC | MS_ASYNC)) return __hurd_fail (EINVAL); @@ -77,8 +79,10 @@ msync (void *addr, size_t length, int flags) else sync_len = len; + cancel_oldtype = LIBC_CANCEL_ASYNC(); err = __vm_object_sync (obj, cur - begin + offset, sync_len, should_flush, 1, should_iosync); + LIBC_CANCEL_RESET (cancel_oldtype); __mach_port_deallocate (__mach_task_self (), obj); if (err) diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c index 38f095e..ed98104 100644 --- a/sysdeps/mach/hurd/sigsuspend.c +++ b/sysdeps/mach/hurd/sigsuspend.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Change the set of blocked signals to SET, wait until a signal arrives, and restore the set of blocked signals. */ @@ -30,6 +31,7 @@ __sigsuspend (const sigset_t *set) sigset_t newmask, oldmask, pending; mach_port_t wait; mach_msg_header_t msg; + int cancel_oldtype; if (set != NULL) /* Crash before locking. */ @@ -59,8 +61,11 @@ __sigsuspend (const sigset_t *set) __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); /* Wait for the signal thread's message. */ + + cancel_oldtype = LIBC_CANCEL_ASYNC(); __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + LIBC_CANCEL_RESET (cancel_oldtype); __mach_port_destroy (__mach_task_self (), wait); /* Restore the old mask and check for pending signals again. */ diff --git a/sysdeps/mach/hurd/sigwait.c b/sysdeps/mach/hurd/sigwait.c index 53d2110..48ccaf0 100644 --- a/sysdeps/mach/hurd/sigwait.c +++ b/sysdeps/mach/hurd/sigwait.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Select any of pending signals from SET or wait for any to arrive. */ int @@ -33,6 +34,7 @@ __sigwait (const sigset_t *set, int *sig) jmp_buf buf; mach_port_t wait; mach_msg_header_t msg; + int cancel_oldtype; sighandler_t preempt_fun (struct hurd_signal_preemptor *pe, @@ -71,6 +73,7 @@ __sigwait (const sigset_t *set, int *sig) __sigemptyset (&mask); ss = _hurd_self_sigstate (); + cancel_oldtype = LIBC_CANCEL_ASYNC(); _hurd_sigstate_lock (ss); /* See if one of these signals is currently pending. */ @@ -128,6 +131,7 @@ __sigwait (const sigset_t *set, int *sig) all_done: _hurd_sigstate_unlock (ss); + LIBC_CANCEL_RESET (cancel_oldtype); __mach_port_destroy (__mach_task_self (), wait); *sig = signo; diff --git a/sysdeps/mach/msync.c b/sysdeps/mach/msync.c index e36a564..f72222b 100644 --- a/sysdeps/mach/msync.c +++ b/sysdeps/mach/msync.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Some Mach variants have vm_msync and some don't. Those that have it define the VM_SYNC_* bits when we include . */ @@ -37,6 +38,7 @@ msync (void *addr, size_t len, int flags) { vm_sync_t sync_flags = 0; kern_return_t err; + int cancel_oldtype; if (flags & MS_SYNC) sync_flags |= VM_SYNC_SYNCHRONOUS; @@ -45,8 +47,11 @@ msync (void *addr, size_t len, int flags) 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)) + cancel_oldtype = LIBC_CANCEL_ASYNC(); + err = __vm_msync (__mach_task_self (), + (vm_address_t) addr, (vm_size_t) len, sync_flags); + LIBC_CANCEL_RESET (cancel_oldtype); + if (err) { errno = err; return -1; diff --git a/sysdeps/mach/sleep.c b/sysdeps/mach/sleep.c index de58bd1..9de9de1 100644 --- a/sysdeps/mach/sleep.c +++ b/sysdeps/mach/sleep.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Make the process sleep for SECONDS seconds, or until a signal arrives and is not ignored. The function returns the number of seconds less @@ -30,12 +31,15 @@ __sleep (unsigned int seconds) { time_t before, after; mach_port_t recv; + int cancel_oldtype; recv = __mach_reply_port (); before = time_now (); + cancel_oldtype = LIBC_CANCEL_ASYNC(); (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, 0, 0, recv, seconds * 1000, MACH_PORT_NULL); + LIBC_CANCEL_RESET (cancel_oldtype); after = time_now (); __mach_port_destroy (__mach_task_self (), recv); diff --git a/sysdeps/mach/usleep.c b/sysdeps/mach/usleep.c index d53eb04..75514b2 100644 --- a/sysdeps/mach/usleep.c +++ b/sysdeps/mach/usleep.c @@ -19,12 +19,14 @@ #include #include #include +#include /* Sleep USECONDS microseconds, or until a previously set timer goes off. */ int usleep (useconds_t useconds) { mach_port_t recv; + int cancel_oldtype; useconds_t useconds_up = useconds + 999; if (useconds_up < useconds) @@ -32,8 +34,10 @@ usleep (useconds_t useconds) recv = __mach_reply_port (); + cancel_oldtype = LIBC_CANCEL_ASYNC(); (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, 0, 0, recv, useconds_up / 1000, MACH_PORT_NULL); + LIBC_CANCEL_RESET (cancel_oldtype); __mach_port_destroy (mach_task_self (), recv); return 0; -- 2.7.4