From 3944c61bdf5d1530d0576a396eb3e2f9a4d6caff Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 7 Jun 2020 23:16:46 +0000 Subject: hurd: Make read and pread64 cancellable and add _nocancel variants. * sysdeps/mach/hurd/pread64.c (__libc_pread64): Call __pread64_nocancel surrounded by enabling async cancel, to replace implementation moved to... * sysdeps/mach/hurd/pread64_nocancel.c (__pread64_nocancel): ... here. * sysdeps/mach/hurd/read.c (__libc_read): Call __read_nocancel surrounded by enabling async cancel, to replace implementation moved to... * sysdeps/mach/hurd/read_nocancel.c (__read_nocancel): ... here. * sysdeps/mach/hurd/Makefile (sysdep_routines): Add read_nocancel and pread64_nocancel. * sysdeps/mach/hurd/not-cancel.h (__read_nocancel, __pread64_nocancel): Replace macros with prototypes with a hidden proto on libc. * sysdeps/mach/hurd/dl-sysdep.c: Include . (__pread64_nocancel): New alias, check that it is not hidden. (__read_nocancel): New alias, check that it is not hidden. * sysdeps/mach/hurd/Versions (libc.GLIBC_PRIVATE): Add __read_nocancel and __pread64_nocancel. (ld.GLIBC_2.1): Add __pread64. (ld.GLIBC_PRIVATE): Add __read_nocancel and __pread64_nocancel. * sysdeps/mach/hurd/i386/ld.abilist (__pread64): Add symbol. * sysdeps/mach/hurd/i386/localplt.data (__read_nocancel, __pread64, __pread64_nocancel): Add references. --- sysdeps/mach/hurd/Makefile | 3 ++- sysdeps/mach/hurd/Versions | 6 ++++++ sysdeps/mach/hurd/dl-sysdep.c | 5 +++++ sysdeps/mach/hurd/i386/ld.abilist | 1 + sysdeps/mach/hurd/i386/localplt.data | 5 ++++- sysdeps/mach/hurd/not-cancel.h | 14 +++++++++----- sysdeps/mach/hurd/pread64.c | 16 +++++++--------- sysdeps/mach/hurd/pread64_nocancel.c | 35 +++++++++++++++++++++++++++++++++++ sysdeps/mach/hurd/read.c | 12 +++++++----- sysdeps/mach/hurd/read_nocancel.c | 30 ++++++++++++++++++++++++++++++ 10 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 sysdeps/mach/hurd/pread64_nocancel.c create mode 100644 sysdeps/mach/hurd/read_nocancel.c diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile index 039bcfc041..bf741058f5 100644 --- a/sysdeps/mach/hurd/Makefile +++ b/sysdeps/mach/hurd/Makefile @@ -196,7 +196,8 @@ sysdep_routines += cthreads endif ifeq (io, $(subdir)) -sysdep_routines += f_setlk close_nocancel_nostatus +sysdep_routines += f_setlk close_nocancel_nostatus read_nocancel \ + pread64_nocancel endif ifeq ($(subdir),sunrpc) diff --git a/sysdeps/mach/hurd/Versions b/sysdeps/mach/hurd/Versions index 1d6633f782..ce873f33f6 100644 --- a/sysdeps/mach/hurd/Versions +++ b/sysdeps/mach/hurd/Versions @@ -10,6 +10,7 @@ libc { GLIBC_PRIVATE { # Functions shared with the dynamic linker __access; __access_noerrno; __libc_read; __libc_write; __libc_lseek64; + __read_nocancel; __pread64_nocancel; __libc_lock_self0; __getcwd; _dl_init_first; @@ -32,6 +33,10 @@ ld { _exit; _hurd_intr_rpc_mach_msg; abort; } + GLIBC_2.1 { + # functions that must be shared with libc + __pread64; + } GLIBC_2.2 { # functions that must be shared with libc __open64; @@ -45,6 +50,7 @@ ld { # functions that must be shared with libc __access; __access_noerrno; __libc_read; __libc_write; __libc_lseek64; + __read_nocancel; __pread64_nocancel; __libc_lock_self0; __getcwd; } } diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 574e252836..1626cd5928 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -47,6 +47,7 @@ #include #include +#include extern void __mach_init (void); @@ -359,6 +360,7 @@ __close (int fd) } check_no_hidden(__pread64); +check_no_hidden(__pread64_nocancel); __ssize_t weak_function __pread64 (int fd, void *buf, size_t nbytes, off64_t offset) { @@ -381,14 +383,17 @@ __pread64 (int fd, void *buf, size_t nbytes, off64_t offset) return nread; } libc_hidden_weak (__pread64) +weak_alias (__pread64, __pread64_nocancel) check_no_hidden(__read); +check_no_hidden(__read_nocancel); __ssize_t weak_function __read (int fd, void *buf, size_t nbytes) { return __pread64 (fd, buf, nbytes, -1); } libc_hidden_weak (__read) +weak_alias (__read, __read_nocancel) check_no_hidden(__write); __ssize_t weak_function diff --git a/sysdeps/mach/hurd/i386/ld.abilist b/sysdeps/mach/hurd/i386/ld.abilist index b2be75cbff..b4fce5e5f5 100644 --- a/sysdeps/mach/hurd/i386/ld.abilist +++ b/sysdeps/mach/hurd/i386/ld.abilist @@ -6,6 +6,7 @@ GLIBC_2.2.6 __libc_stack_end D 0x4 GLIBC_2.2.6 __mmap F GLIBC_2.2.6 __open F GLIBC_2.2.6 __open64 F +GLIBC_2.2.6 __pread64 F GLIBC_2.2.6 __read F GLIBC_2.2.6 __sbrk F GLIBC_2.2.6 __strtoul_internal F diff --git a/sysdeps/mach/hurd/i386/localplt.data b/sysdeps/mach/hurd/i386/localplt.data index 541c3f32ae..c9f3ca66f9 100644 --- a/sysdeps/mach/hurd/i386/localplt.data +++ b/sysdeps/mach/hurd/i386/localplt.data @@ -19,7 +19,10 @@ ld.so: _dl_catch_exception + REL R_386_GLOB_DAT ld.so: __open ? ld.so: __open64 ld.so: __close -ld.so: __read +ld.so: __read ? +ld.so: __read_nocancel +ld.so: __pread64 +ld.so: __pread64_nocancel ld.so: __write ld.so: __writev ld.so: __libc_lseek64 diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h index 15acfa3b92..8a8f5a9d3c 100644 --- a/sysdeps/mach/hurd/not-cancel.h +++ b/sysdeps/mach/hurd/not-cancel.h @@ -42,10 +42,12 @@ void __close_nocancel_nostatus (int fd); -#define __read_nocancel(fd, buf, n) \ - __read (fd, buf, n) -#define __pread64_nocancel(fd, buf, count, offset) \ - __pread64 (fd, buf, count, offset) +/* Non cancellable read syscall. */ +__typeof (__read) __read_nocancel; + +/* Non cancellable pread syscall (LFS version). */ +__typeof (__pread64) __pread64_nocancel; + #define __write_nocancel(fd, buf, n) \ __write (fd, buf, n) #define __writev_nocancel_nostatus(fd, iov, n) \ @@ -55,7 +57,9 @@ void __close_nocancel_nostatus (int fd); #define __fcntl64_nocancel(fd, cmd, ...) \ __fcntl64 (fd, cmd, __VA_ARGS__) -#if IS_IN (libc) || IS_IN (rtld) +#if IS_IN (libc) +hidden_proto (__read_nocancel) +hidden_proto (__pread64_nocancel) hidden_proto (__close_nocancel_nostatus) #endif diff --git a/sysdeps/mach/hurd/pread64.c b/sysdeps/mach/hurd/pread64.c index 7683e29c99..e14416e63a 100644 --- a/sysdeps/mach/hurd/pread64.c +++ b/sysdeps/mach/hurd/pread64.c @@ -17,19 +17,17 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include +#include +#include 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; + ssize_t ret; + int cancel_oldtype = LIBC_CANCEL_ASYNC(); + ret = __pread64_nocancel (fd, buf, nbytes, offset); + LIBC_CANCEL_RESET (cancel_oldtype); + return ret; } #ifndef __libc_pread64 diff --git a/sysdeps/mach/hurd/pread64_nocancel.c b/sysdeps/mach/hurd/pread64_nocancel.c new file mode 100644 index 0000000000..f6bc5e62b4 --- /dev/null +++ b/sysdeps/mach/hurd/pread64_nocancel.c @@ -0,0 +1,35 @@ +/* Read block from given position in file without changing file pointer. + Hurd version. + Copyright (C) 2001-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +ssize_t +__pread64_nocancel (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; +} +libc_hidden_weak (__pread64_nocancel) diff --git a/sysdeps/mach/hurd/read.c b/sysdeps/mach/hurd/read.c index 2e8f92a542..00e574e6d1 100644 --- a/sysdeps/mach/hurd/read.c +++ b/sysdeps/mach/hurd/read.c @@ -15,16 +15,18 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include +#include +#include /* 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; + ssize_t ret; + int cancel_oldtype = LIBC_CANCEL_ASYNC(); + ret = __read_nocancel (fd, buf, nbytes); + LIBC_CANCEL_RESET (cancel_oldtype); + return ret; } libc_hidden_def (__libc_read) weak_alias (__libc_read, __read) diff --git a/sysdeps/mach/hurd/read_nocancel.c b/sysdeps/mach/hurd/read_nocancel.c new file mode 100644 index 0000000000..1aeae44d41 --- /dev/null +++ b/sysdeps/mach/hurd/read_nocancel.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1993-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +/* Read NBYTES into BUF from FD. Return the number read or -1. */ +ssize_t +__read_nocancel (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_weak (__read_nocancel) -- cgit 1.4.1