Avoid cancellable I/O primitives in ld.so.

Neither the <dlfcn.h> entry points, nor lazy symbol resolution, nor
initial shared library load-up, are cancellation points, so ld.so
should exclusively use I/O primitives that are not cancellable.  We
currently achieve this by having the cancellation hooks compile as
no-ops when IS_IN(rtld); this patch changes to using exclusively
_nocancel primitives in the source code instead, which makes the
intent clearer and significantly reduces the amount of code compiled
under IS_IN(rtld) as well as IS_IN(libc) -- in particular,
elf/Makefile no longer thinks we require a copy of unwind.c in
rtld-libc.a.  (The older mechanism is preserved as a backstop.)

The bulk of the change is splitting up the files that define the
_nocancel I/O functions, so they don't also define the variants that
*are* cancellation points; after which, the existing logic for picking
out the bits of libc that need to be recompiled as part of ld.so Just
Works.  I did this for all of the _nocancel functions, not just the
ones used by ld.so, for consistency.

fcntl was a little tricky because it's only a cancellation point for
certain opcodes (F_SETLKW(64), which can block), and the existing
__fcntl_nocancel wasn't applying the FCNTL_ADJUST_CMD hook, which
strikes me as asking for trouble, especially as the only nontrivial
definition of FCNTL_ADJUST_CMD (for powerpc64) changes F_*LK* opcodes.
To fix this, fcntl_common moves to fcntl_nocancel.c along with
__fcntl_nocancel, and changes its name to the extern (but hidden)
symbol __fcntl_nocancel_adjusted, so that regular fcntl can continue
calling it.  __fcntl_nocancel now applies FCNTL_ADJUST_CMD; so that
both both fcntl.c and fcntl_nocancel.c can see it, the only nontrivial
definition moves from sysdeps/u/s/l/powerpc/powerpc64/fcntl.c to
.../powerpc64/sysdep.h and becomes entirely a macro, instead of a macro
that calls an inline function.

The nptl version of libpthread also changes a little, because its
"compat-routines" formerly included files that defined all the
_nocancel functions it uses; instead of continuing to duplicate them,
I exported the relevant ones from libc.so as GLIBC_PRIVATE.  Since the
Linux fcntl.c calls a function defined by fcntl_nocancel.c, it can no
longer be used from libpthread.so; instead, introduce a custom
forwarder, pt-fcntl.c, and export __libc_fcntl from libc.so as
GLIBC_PRIVATE.  The nios2-linux ABI doesn't include a copy of vfork()
in libpthread, and it was handling that by manipulating
libpthread-routines in .../linux/nios2/Makefile; it is cleaner to do
what other such ports do, and have a pt-vfork.S that defines no symbols.

Right now, it appears that Hurd does not implement _nocancel I/O, so
sysdeps/generic/not-cancel.h will forward everything back to the
regular functions.  This changed the names of some of the functions
that sysdeps/mach/hurd/dl-sysdep.c needs to interpose.

	* elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c
	* sysdeps/unix/sysv/linux/dl-sysdep.c
	Include not-cancel.h.  Use __close_nocancel instead of __close,
	__open64_nocancel instead of __open, __read_nocancel instead of
	__libc_read, and __write_nocancel instead of __libc_write.

	* csu/check_fds.c (check_one_fd)
	* sysdeps/posix/fdopendir.c (__fdopendir)
	* sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel
        instead of __fcntl and/or __libc_fcntl.

	* sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np)
	* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np)
        * sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system):
	Use __open64_nocancel instead of __open_nocancel.

	* sysdeps/unix/sysv/linux/not-cancel.h: Move all of the
	hidden_proto declarations to the end and issue them if either
	IS_IN(libc) or IS_IN(rtld).
	* sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines):
	Add close_nocancel, fcntl_nocancel, nanosleep_nocancel,
	open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel,
	read_nocancel, waitpid_nocancel, write_nocancel.

        * io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl,
        __fcntl_nocancel, __open64_nocancel, __write_nocancel.
        * posix/Versions: Add __nanosleep_nocancel, __pause_nocancel.

        * nptl/pt-fcntl.c: New file.
        * nptl/Makefile (pthread-compat-wrappers): Remove fcntl.
        (libpthread-routines): Add pt-fcntl.
        * include/fcntl.h (__fcntl_nocancel_adjusted): New function.
        (__libc_fcntl): Remove attribute_hidden.
	* sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call
	__fcntl_nocancel_adjusted, not fcntl_common.
        (__fcntl_nocancel): Move to new file fcntl_nocancel.c.
	(fcntl_common): Rename to __fcntl_nocancel_adjusted; also move
	to fcntl_nocancel.c.
	* sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h:
	Define FCNTL_ADJUST_CMD here, as a self-contained macro.

	* sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to...
	* sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to...
	* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to...
	* sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to...
	* sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to...
	* sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to...
	* sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to...
	* sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to...
	* sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to...
	* sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to...
	* sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file.

        * sysdeps/unix/sysv/linux/nios2/Makefile: Don't override
        libpthread-routines.
        * sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which
        defines nothing.

        * sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of
        __libc_read, and __write instead of __libc_write.  Define
        __open64 in addition to __open.
This commit is contained in:
Zack Weinberg 2018-04-03 18:26:44 -04:00
parent 0221ce2a90
commit 329ea513b4
45 changed files with 647 additions and 279 deletions

View File

@ -1,3 +1,78 @@
2018-06-12 Zack Weinberg <zackw@panix.com>
* elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c
* sysdeps/unix/sysv/linux/dl-sysdep.c
Include not-cancel.h. Use __close_nocancel instead of __close,
__open64_nocancel instead of __open, __read_nocancel instead of
__libc_read, and __write_nocancel instead of __libc_write.
* csu/check_fds.c (check_one_fd)
* sysdeps/posix/fdopendir.c (__fdopendir)
* sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel
instead of __fcntl and/or __libc_fcntl.
* sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np)
* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np)
* sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system):
Use __open64_nocancel instead of __open_nocancel.
* sysdeps/unix/sysv/linux/not-cancel.h: Move all of the
hidden_proto declarations to the end and issue them if either
IS_IN(libc) or IS_IN(rtld).
* sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines):
Add close_nocancel, fcntl_nocancel, nanosleep_nocancel,
open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel,
read_nocancel, waitpid_nocancel, write_nocancel.
* io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl,
__fcntl_nocancel, __open64_nocancel, __write_nocancel.
* posix/Versions: Add __nanosleep_nocancel, __pause_nocancel.
* nptl/pt-fcntl.c: New file.
* nptl/Makefile (pthread-compat-wrappers): Remove fcntl.
(libpthread-routines): Add pt-fcntl.
* include/fcntl.h (__fcntl_nocancel_adjusted): New function.
(__libc_fcntl): Remove attribute_hidden.
* sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call
__fcntl_nocancel_adjusted, not fcntl_common.
(__fcntl_nocancel): Move to new file fcntl_nocancel.c.
(fcntl_common): Rename to __fcntl_nocancel_adjusted; also move
to fcntl_nocancel.c.
* sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h:
Define FCNTL_ADJUST_CMD here, as a self-contained macro.
* sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to...
* sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to...
* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to...
* sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to...
* sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to...
* sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to...
* sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to...
* sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to...
* sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to...
* sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to...
* sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file.
* sysdeps/unix/sysv/linux/nios2/Makefile: Don't override
libpthread-routines.
* sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which
defines nothing.
* sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of
__libc_read, and __write instead of __libc_write. Define
__open64 in addition to __open.
2018-06-12 H.J. Lu <hongjiu.lu@intel.com> 2018-06-12 H.J. Lu <hongjiu.lu@intel.com>
[BZ #23250] [BZ #23250]

View File

@ -39,8 +39,7 @@
static void static void
check_one_fd (int fd, int mode) check_one_fd (int fd, int mode)
{ {
/* Note that fcntl() with this parameter is not a cancellation point. */ if (__builtin_expect (__fcntl_nocancel (fd, F_GETFD), 0) == -1
if (__builtin_expect (__libc_fcntl (fd, F_GETFD), 0) == -1
&& errno == EBADF) && errno == EBADF)
{ {
const char *name; const char *name;

View File

@ -44,7 +44,7 @@
#include <dl-unmap-segments.h> #include <dl-unmap-segments.h>
#include <dl-machine-reject-phdr.h> #include <dl-machine-reject-phdr.h>
#include <dl-sysdep-open.h> #include <dl-sysdep-open.h>
#include <not-cancel.h>
#include <endian.h> #include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
@ -776,7 +776,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
{ {
/* The file might already be closed. */ /* The file might already be closed. */
if (fd != -1) if (fd != -1)
(void) __close (fd); (void) __close_nocancel (fd);
if (l != NULL && l->l_origin != (char *) -1l) if (l != NULL && l->l_origin != (char *) -1l)
free ((char *) l->l_origin); free ((char *) l->l_origin);
free (l); free (l);
@ -835,7 +835,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
{ {
/* The object is already loaded. /* The object is already loaded.
Just bump its reference count and return it. */ Just bump its reference count and return it. */
__close (fd); __close_nocancel (fd);
/* If the name is not in the list of names for this object add /* If the name is not in the list of names for this object add
it. */ it. */
@ -863,7 +863,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
/* No need to bump the refcount of the real object, ld.so will /* No need to bump the refcount of the real object, ld.so will
never be unloaded. */ never be unloaded. */
__close (fd); __close_nocancel (fd);
/* Add the map for the mirrored object to the object list. */ /* Add the map for the mirrored object to the object list. */
_dl_add_to_namespace_list (l, nsid); _dl_add_to_namespace_list (l, nsid);
@ -877,7 +877,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
/* We are not supposed to load the object unless it is already /* We are not supposed to load the object unless it is already
loaded. So return now. */ loaded. So return now. */
free (realname); free (realname);
__close (fd); __close_nocancel (fd);
return NULL; return NULL;
} }
@ -896,7 +896,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
if (_dl_zerofd == -1) if (_dl_zerofd == -1)
{ {
free (realname); free (realname);
__close (fd); __close_nocancel (fd);
_dl_signal_error (errno, NULL, NULL, _dl_signal_error (errno, NULL, NULL,
N_("cannot open zero fill device")); N_("cannot open zero fill device"));
} }
@ -962,7 +962,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
{ {
phdr = alloca (maplength); phdr = alloca (maplength);
__lseek (fd, header->e_phoff, SEEK_SET); __lseek (fd, header->e_phoff, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength) if ((size_t) __read_nocancel (fd, (void *) phdr, maplength) != maplength)
{ {
errstring = N_("cannot read file data"); errstring = N_("cannot read file data");
goto call_lose_errno; goto call_lose_errno;
@ -1232,7 +1232,7 @@ cannot enable executable stack as shared object requires");
l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr; l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
/* We are done mapping in the file. We no longer need the descriptor. */ /* We are done mapping in the file. We no longer need the descriptor. */
if (__glibc_unlikely (__close (fd) != 0)) if (__glibc_unlikely (__close_nocancel (fd) != 0))
{ {
errstring = N_("cannot close file descriptor"); errstring = N_("cannot close file descriptor");
goto call_lose_errno; goto call_lose_errno;
@ -1447,7 +1447,7 @@ open_verify (const char *name, int fd,
{ {
/* An audit library changed what we're supposed to open, /* An audit library changed what we're supposed to open,
so FD no longer matches it. */ so FD no longer matches it. */
__close (fd); __close_nocancel (fd);
fd = -1; fd = -1;
} }
} }
@ -1455,7 +1455,7 @@ open_verify (const char *name, int fd,
if (fd == -1) if (fd == -1)
/* Open the file. We always open files read-only. */ /* Open the file. We always open files read-only. */
fd = __open (name, O_RDONLY | O_CLOEXEC); fd = __open64_nocancel (name, O_RDONLY | O_CLOEXEC);
if (fd != -1) if (fd != -1)
{ {
@ -1474,8 +1474,8 @@ open_verify (const char *name, int fd,
/* Read in the header. */ /* Read in the header. */
do do
{ {
ssize_t retlen = __libc_read (fd, fbp->buf + fbp->len, ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len,
sizeof (fbp->buf) - fbp->len); sizeof (fbp->buf) - fbp->len);
if (retlen <= 0) if (retlen <= 0)
break; break;
fbp->len += retlen; fbp->len += retlen;
@ -1598,7 +1598,8 @@ open_verify (const char *name, int fd,
{ {
phdr = alloca (maplength); phdr = alloca (maplength);
__lseek (fd, ehdr->e_phoff, SEEK_SET); __lseek (fd, ehdr->e_phoff, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength) if ((size_t) __read_nocancel (fd, (void *) phdr, maplength)
!= maplength)
{ {
read_error: read_error:
errval = errno; errval = errno;
@ -1648,7 +1649,7 @@ open_verify (const char *name, int fd,
abi_note = abi_note_malloced; abi_note = abi_note_malloced;
} }
__lseek (fd, ph->p_offset, SEEK_SET); __lseek (fd, ph->p_offset, SEEK_SET);
if (__libc_read (fd, (void *) abi_note, size) != size) if (__read_nocancel (fd, (void *) abi_note, size) != size)
{ {
free (abi_note_malloced); free (abi_note_malloced);
goto read_error; goto read_error;
@ -1680,7 +1681,7 @@ open_verify (const char *name, int fd,
|| (GLRO(dl_osversion) && GLRO(dl_osversion) < osversion)) || (GLRO(dl_osversion) && GLRO(dl_osversion) < osversion))
{ {
close_and_out: close_and_out:
__close (fd); __close_nocancel (fd);
__set_errno (ENOENT); __set_errno (ENOENT);
fd = -1; fd = -1;
} }
@ -1797,7 +1798,7 @@ open_path (const char *name, size_t namelen, int mode,
/* The shared object cannot be tested for being SUID /* The shared object cannot be tested for being SUID
or this bit is not set. In this case we must not or this bit is not set. In this case we must not
use this object. */ use this object. */
__close (fd); __close_nocancel (fd);
fd = -1; fd = -1;
/* We simply ignore the file, signal this by setting /* We simply ignore the file, signal this by setting
the error value which would have been set by `open'. */ the error value which would have been set by `open'. */
@ -1818,7 +1819,7 @@ open_path (const char *name, size_t namelen, int mode,
{ {
/* No memory for the name, we certainly won't be able /* No memory for the name, we certainly won't be able
to load and link it. */ to load and link it. */
__close (fd); __close_nocancel (fd);
return -1; return -1;
} }
} }

View File

@ -33,7 +33,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <_itoa.h> #include <_itoa.h>
#include <dl-writev.h> #include <dl-writev.h>
#include <not-cancel.h>
/* Read the whole contents of FILE into new mmap'd space with given /* Read the whole contents of FILE into new mmap'd space with given
protections. *SIZEP gets the size of the file. On error MAP_FAILED protections. *SIZEP gets the size of the file. On error MAP_FAILED
@ -44,7 +44,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
{ {
void *result = MAP_FAILED; void *result = MAP_FAILED;
struct stat64 st; struct stat64 st;
int fd = __open (file, O_RDONLY | O_CLOEXEC); int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
if (fd >= 0) if (fd >= 0)
{ {
if (__fxstat64 (_STAT_VER, fd, &st) >= 0) if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
@ -65,7 +65,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
#endif #endif
, fd, 0); , fd, 0);
} }
__close (fd); __close_nocancel (fd);
} }
return result; return result;
} }

View File

@ -35,6 +35,7 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <atomic.h> #include <atomic.h>
#include <not-cancel.h>
/* The LD_PROFILE feature has to be implemented different to the /* The LD_PROFILE feature has to be implemented different to the
normal profiling using the gmon/ functions. The problem is that an normal profiling using the gmon/ functions. The problem is that an
@ -324,7 +325,7 @@ _dl_start_profile (void)
*cp++ = '/'; *cp++ = '/';
__stpcpy (__stpcpy (cp, GLRO(dl_profile)), ".profile"); __stpcpy (__stpcpy (cp, GLRO(dl_profile)), ".profile");
fd = __open (filename, O_RDWR | O_CREAT | O_NOFOLLOW, DEFFILEMODE); fd = __open64_nocancel (filename, O_RDWR|O_CREAT|O_NOFOLLOW, DEFFILEMODE);
if (fd == -1) if (fd == -1)
{ {
char buf[400]; char buf[400];
@ -335,7 +336,7 @@ _dl_start_profile (void)
print_error: print_error:
errnum = errno; errnum = errno;
if (fd != -1) if (fd != -1)
__close (fd); __close_nocancel (fd);
_dl_error_printf (errstr, filename, _dl_error_printf (errstr, filename,
__strerror_r (errnum, buf, sizeof buf)); __strerror_r (errnum, buf, sizeof buf));
return; return;
@ -364,15 +365,14 @@ _dl_start_profile (void)
goto print_error; goto print_error;
} }
if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size if (TEMP_FAILURE_RETRY
& (GLRO(dl_pagesize) (__write_nocancel (fd, buf, (expected_size & (GLRO(dl_pagesize) - 1))))
- 1))))
< 0) < 0)
goto cannot_create; goto cannot_create;
} }
else if (st.st_size != expected_size) else if (st.st_size != expected_size)
{ {
__close (fd); __close_nocancel (fd);
wrong_format: wrong_format:
if (addr != NULL) if (addr != NULL)
@ -392,7 +392,7 @@ _dl_start_profile (void)
} }
/* We don't need the file descriptor anymore. */ /* We don't need the file descriptor anymore. */
__close (fd); __close_nocancel (fd);
/* Pointer to data after the header. */ /* Pointer to data after the header. */
hist = (char *) (addr + 1); hist = (char *) (addr + 1);

View File

@ -41,6 +41,7 @@
#include <tls.h> #include <tls.h>
#include <stap-probe.h> #include <stap-probe.h>
#include <stackinfo.h> #include <stackinfo.h>
#include <not-cancel.h>
#include <assert.h> #include <assert.h>
@ -2673,7 +2674,7 @@ process_envvars (enum mode *modep)
*--startp = '.'; *--startp = '.';
startp = memcpy (startp - name_len, debug_output, name_len); startp = memcpy (startp - name_len, debug_output, name_len);
GLRO(dl_debug_fd) = __open (startp, flags, DEFFILEMODE); GLRO(dl_debug_fd) = __open64_nocancel (startp, flags, DEFFILEMODE);
if (GLRO(dl_debug_fd) == -1) if (GLRO(dl_debug_fd) == -1)
/* We use standard output if opening the file failed. */ /* We use standard output if opening the file failed. */
GLRO(dl_debug_fd) = STDOUT_FILENO; GLRO(dl_debug_fd) = STDOUT_FILENO;

View File

@ -8,8 +8,9 @@ libc_hidden_proto (__open64)
extern int __libc_open64 (const char *file, int oflag, ...); extern int __libc_open64 (const char *file, int oflag, ...);
extern int __libc_open (const char *file, int oflag, ...); extern int __libc_open (const char *file, int oflag, ...);
libc_hidden_proto (__libc_open) libc_hidden_proto (__libc_open)
extern int __libc_fcntl (int fd, int cmd, ...) attribute_hidden; extern int __libc_fcntl (int fd, int cmd, ...);
libc_hidden_proto (__libc_fcntl) libc_hidden_proto (__libc_fcntl)
extern int __fcntl_nocancel_adjusted (int fd, int cmd, void *arg) attribute_hidden;
extern int __open (const char *__file, int __oflag, ...); extern int __open (const char *__file, int __oflag, ...);
libc_hidden_proto (__open) libc_hidden_proto (__open)
extern int __fcntl (int __fd, int __cmd, ...); extern int __fcntl (int __fd, int __cmd, ...);

View File

@ -128,4 +128,10 @@ libc {
GLIBC_2.27 { GLIBC_2.27 {
copy_file_range; copy_file_range;
} }
GLIBC_PRIVATE {
__libc_fcntl;
__fcntl_nocancel;
__open64_nocancel;
__write_nocancel;
}
} }

View File

@ -36,7 +36,7 @@ static-only-routines = pthread_atfork
# We need to provide certain routines for compatibility with existing # We need to provide certain routines for compatibility with existing
# binaries. # binaries.
pthread-compat-wrappers = \ pthread-compat-wrappers = \
write read close fcntl accept \ write read close accept \
connect recv recvfrom send \ connect recv recvfrom send \
sendto fsync lseek lseek64 \ sendto fsync lseek lseek64 \
msync nanosleep open open64 pause \ msync nanosleep open open64 pause \
@ -120,7 +120,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
cancellation \ cancellation \
lowlevellock \ lowlevellock \
lll_timedlock_wait lll_timedwait_tid \ lll_timedlock_wait lll_timedwait_tid \
pt-fork pt-vfork \ pt-fork pt-vfork pt-fcntl \
$(pthread-compat-wrappers) \ $(pthread-compat-wrappers) \
pt-raise pt-system \ pt-raise pt-system \
flockfile ftrylockfile funlockfile \ flockfile ftrylockfile funlockfile \

View File

@ -139,5 +139,6 @@ libc {
} }
GLIBC_PRIVATE { GLIBC_PRIVATE {
__libc_fork; __libc_pread; __libc_pwrite; __libc_fork; __libc_pread; __libc_pwrite;
__nanosleep_nocancel; __pause_nocancel;
} }
} }

View File

@ -339,6 +339,7 @@ open_file (const char *file_name, int flags,
} }
check_no_hidden(__open); check_no_hidden(__open);
check_no_hidden (__open64);
int weak_function int weak_function
__open (const char *file_name, int mode, ...) __open (const char *file_name, int mode, ...)
{ {
@ -349,6 +350,7 @@ __open (const char *file_name, int mode, ...)
else else
return (int)port; return (int)port;
} }
weak_alias (__open, __open64)
check_no_hidden(__close); check_no_hidden(__close);
int weak_function int weak_function
@ -359,9 +361,9 @@ __close (int fd)
return 0; return 0;
} }
check_no_hidden(__libc_read); check_no_hidden(__read);
__ssize_t weak_function __ssize_t weak_function
__libc_read (int fd, void *buf, size_t nbytes) __read (int fd, void *buf, size_t nbytes)
{ {
error_t err; error_t err;
char *data; char *data;
@ -381,11 +383,11 @@ __libc_read (int fd, void *buf, size_t nbytes)
return nread; return nread;
} }
libc_hidden_weak (__libc_read) libc_hidden_weak (__read)
check_no_hidden(__libc_write); check_no_hidden(__write);
__ssize_t weak_function __ssize_t weak_function
__libc_write (int fd, const void *buf, size_t nbytes) __write (int fd, const void *buf, size_t nbytes)
{ {
error_t err; error_t err;
mach_msg_type_number_t nwrote; mach_msg_type_number_t nwrote;
@ -398,7 +400,7 @@ __libc_write (int fd, const void *buf, size_t nbytes)
return nwrote; return nwrote;
} }
libc_hidden_weak (__libc_write) libc_hidden_weak (__write)
/* This is only used for printing messages (see dl-misc.c). */ /* This is only used for printing messages (see dl-misc.c). */
check_no_hidden(__writev); check_no_hidden(__writev);

View File

@ -38,7 +38,7 @@ __fdopendir (int fd)
} }
/* Make sure the descriptor allows for reading. */ /* Make sure the descriptor allows for reading. */
int flags = __fcntl (fd, F_GETFL); int flags = __fcntl_nocancel (fd, F_GETFL);
if (__glibc_unlikely (flags == -1)) if (__glibc_unlikely (flags == -1))
return NULL; return NULL;
if (__glibc_unlikely ((flags & O_ACCMODE) == O_WRONLY)) if (__glibc_unlikely ((flags & O_ACCMODE) == O_WRONLY))

View File

@ -99,7 +99,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
/* We have to set the close-on-exit flag if the user provided the /* We have to set the close-on-exit flag if the user provided the
file descriptor. */ file descriptor. */
if (!close_fd if (!close_fd
&& __builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) && __glibc_unlikely (__fcntl_nocancel (fd, F_SETFD, FD_CLOEXEC) < 0))
goto lose; goto lose;
const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64) const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64)

49
sysdeps/unix/pt-fcntl.c Normal file
View File

@ -0,0 +1,49 @@
/* ABI compatibility for 'fcntl' symbol in libpthread ABI.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <stdarg.h>
#include <shlib-compat.h>
/* libpthread once had its own fcntl, though there was no apparent reason
for it. There is no use in having a separate symbol in libpthread, but
the historical ABI requires it. For static linking, there is no need to
provide anything here--the libc version will be linked in. For shared
library ABI compatibility, there must be __fcntl and fcntl symbols in
libpthread.so. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_28)
static int
fcntl_compat (int fd, int cmd, ...)
{
void *arg;
va_list ap;
va_start (ap, cmd);
arg = va_arg (ap, void *);
va_end (ap);
return __libc_fcntl (fd, cmd, arg);
}
weak_alias (fcntl_compat, fcntl_alias)
compat_symbol (libpthread, fcntl_alias, fcntl, GLIBC_2_0);
weak_alias (fcntl_compat, __fcntl_alias)
compat_symbol (libpthread, __fcntl_alias, __fcntl, GLIBC_2_0);
#endif

View File

@ -167,7 +167,12 @@ endif
ifeq ($(subdir),io) ifeq ($(subdir),io)
sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
sync_file_range fallocate fallocate64 sync_file_range fallocate fallocate64 \
close_nocancel fcntl_nocancel nanosleep_nocancel \
open_nocancel open64_nocancel \
openat_nocancel openat64_nocancel \
pause_nocancel read_nocancel waitpid_nocancel write_nocancel
sysdep_headers += bits/fcntl-linux.h sysdep_headers += bits/fcntl-linux.h
tests += tst-fallocate tst-fallocate64 tests += tst-fallocate tst-fallocate64

View File

@ -29,14 +29,3 @@ __close (int fd)
libc_hidden_def (__close) libc_hidden_def (__close)
strong_alias (__close, __libc_close) strong_alias (__close, __libc_close)
weak_alias (__close, close) weak_alias (__close, close)
# if !IS_IN (rtld)
int
__close_nocancel (int fd)
{
return INLINE_SYSCALL_CALL (close, fd);
}
#else
strong_alias (__libc_close, __close_nocancel)
#endif
libc_hidden_def (__close_nocancel)

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2000-2018 Free Software Foundation, Inc. /* Linux close syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -16,17 +17,12 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
static inline int int
fcntl_adjust_cmd (int cmd) __close_nocancel (int fd)
{ {
if (cmd >= F_GETLK64 && cmd <= F_SETLKW64) return INLINE_SYSCALL_CALL (close, fd);
cmd -= F_GETLK64 - F_GETLK;
return cmd;
} }
libc_hidden_def (__close_nocancel)
#define FCNTL_ADJUST_CMD(__cmd) \
fcntl_adjust_cmd (__cmd)
#include <sysdeps/unix/sysv/linux/fcntl.c>

View File

@ -25,6 +25,7 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <ldsodefs.h> #include <ldsodefs.h>
#include <not-cancel.h>
#ifdef SHARED #ifdef SHARED
# define DL_SYSDEP_INIT frob_brk () # define DL_SYSDEP_INIT frob_brk ()
@ -87,11 +88,11 @@ _dl_discover_osversion (void)
if (__uname (&uts)) if (__uname (&uts))
{ {
/* This was not successful. Now try reading the /proc filesystem. */ /* This was not successful. Now try reading the /proc filesystem. */
int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); int fd = __open64_nocancel ("/proc/sys/kernel/osrelease", O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
ssize_t reslen = __read (fd, bufmem, sizeof (bufmem)); ssize_t reslen = __read_nocancel (fd, bufmem, sizeof (bufmem));
__close (fd); __close_nocancel (fd);
if (reslen <= 0) if (reslen <= 0)
/* This also didn't work. We give up since we cannot /* This also didn't work. We give up since we cannot
make sure the library can actually work. */ make sure the library can actually work. */

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2000-2018 Free Software Foundation, Inc. /* Linux fcntl syscall implementation.
Copyright (C) 2000-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -29,24 +30,6 @@
# define FCNTL_ADJUST_CMD(__cmd) __cmd # define FCNTL_ADJUST_CMD(__cmd) __cmd
#endif #endif
static int
fcntl_common (int fd, int cmd, void *arg)
{
if (cmd == F_GETOWN)
{
INTERNAL_SYSCALL_DECL (err);
struct f_owner_ex fex;
int res = INTERNAL_SYSCALL_CALL (fcntl64, err, fd, F_GETOWN_EX, &fex);
if (!INTERNAL_SYSCALL_ERROR_P (res, err))
return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (res,
err));
}
return INLINE_SYSCALL_CALL (fcntl64, fd, cmd, (void *) arg);
}
int int
__libc_fcntl (int fd, int cmd, ...) __libc_fcntl (int fd, int cmd, ...)
{ {
@ -62,28 +45,10 @@ __libc_fcntl (int fd, int cmd, ...)
if (cmd == F_SETLKW || cmd == F_SETLKW64) if (cmd == F_SETLKW || cmd == F_SETLKW64)
return SYSCALL_CANCEL (fcntl64, fd, cmd, (void *) arg); return SYSCALL_CANCEL (fcntl64, fd, cmd, (void *) arg);
return fcntl_common (fd, cmd, arg); return __fcntl_nocancel_adjusted (fd, cmd, arg);
} }
libc_hidden_def (__libc_fcntl) libc_hidden_def (__libc_fcntl)
#if !IS_IN (rtld)
int
__fcntl_nocancel (int fd, int cmd, ...)
{
va_list ap;
void *arg;
va_start (ap, cmd);
arg = va_arg (ap, void *);
va_end (ap);
return fcntl_common (fd, cmd, arg);
}
#else
strong_alias (__libc_fcntl, __fcntl_nocancel)
#endif
libc_hidden_def (__fcntl_nocancel)
weak_alias (__libc_fcntl, __fcntl) weak_alias (__libc_fcntl, __fcntl)
libc_hidden_weak (__fcntl) libc_hidden_weak (__fcntl)
weak_alias (__libc_fcntl, fcntl) weak_alias (__libc_fcntl, fcntl)

View File

@ -0,0 +1,65 @@
/* Linux fcntl syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <stdarg.h>
#include <errno.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
#ifndef __NR_fcntl64
# define __NR_fcntl64 __NR_fcntl
#endif
#ifndef FCNTL_ADJUST_CMD
# define FCNTL_ADJUST_CMD(__cmd) __cmd
#endif
int
__fcntl_nocancel (int fd, int cmd, ...)
{
va_list ap;
void *arg;
va_start (ap, cmd);
arg = va_arg (ap, void *);
va_end (ap);
cmd = FCNTL_ADJUST_CMD (cmd);
return __fcntl_nocancel_adjusted (fd, cmd, arg);
}
hidden_def (__fcntl_nocancel)
int
__fcntl_nocancel_adjusted (int fd, int cmd, void *arg)
{
if (cmd == F_GETOWN)
{
INTERNAL_SYSCALL_DECL (err);
struct f_owner_ex fex;
int res = INTERNAL_SYSCALL_CALL (fcntl64, err, fd, F_GETOWN_EX, &fex);
if (!INTERNAL_SYSCALL_ERROR_P (res, err))
return fex.type == F_OWNER_GID ? -fex.pid : fex.pid;
return INLINE_SYSCALL_ERROR_RETURN_VALUE
(INTERNAL_SYSCALL_ERRNO (res, err));
}
return INLINE_SYSCALL_CALL (fcntl64, fd, cmd, (void *) arg);
}

View File

@ -41,7 +41,7 @@ is_smp_system (void)
else else
{ {
/* This was not successful. Now try reading the /proc filesystem. */ /* This was not successful. Now try reading the /proc filesystem. */
int fd = __open_nocancel ("/proc/sys/kernel/version", O_RDONLY); int fd = __open64_nocancel ("/proc/sys/kernel/version", O_RDONLY);
if (__builtin_expect (fd, 0) == -1 if (__builtin_expect (fd, 0) == -1
|| __read_nocancel (fd, u.buf, sizeof (u.buf)) <= 0) || __read_nocancel (fd, u.buf, sizeof (u.buf)) <= 0)
/* This also didn't work. We give up and say it's a UP machine. */ /* This also didn't work. We give up and say it's a UP machine. */

View File

@ -1,4 +1,4 @@
/* Linux high resolution nanosleep implementation. /* Linux nanosleep syscall implementation.
Copyright (C) 2017-2018 Free Software Foundation, Inc. Copyright (C) 2017-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -29,11 +29,3 @@ __nanosleep (const struct timespec *requested_time,
} }
hidden_def (__nanosleep) hidden_def (__nanosleep)
weak_alias (__nanosleep, nanosleep) weak_alias (__nanosleep, nanosleep)
int
__nanosleep_nocancel (const struct timespec *requested_time,
struct timespec *remaining)
{
return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining);
}
hidden_def (__nanosleep_nocancel)

View File

@ -0,0 +1,29 @@
/* Linux nanosleep syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <sysdep-cancel.h>
#include <not-cancel.h>
int
__nanosleep_nocancel (const struct timespec *requested_time,
struct timespec *remaining)
{
return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining);
}
hidden_def (__nanosleep_nocancel)

View File

@ -7,7 +7,3 @@ ifeq ($(subdir),misc)
sysdep_headers += sys/cachectl.h sysdep_headers += sys/cachectl.h
sysdep_routines += cacheflush sysdep_routines += cacheflush
endif endif
ifeq ($(subdir),nptl)
libpthread-routines := $(filter-out pt-vfork,$(libpthread-routines))
endif

View File

@ -0,0 +1 @@
# Nios2 does not require a stub for vfork in libpthread.

View File

@ -30,31 +30,24 @@
/* Non cancellable open syscall. */ /* Non cancellable open syscall. */
__typeof (open) __open_nocancel; __typeof (open) __open_nocancel;
libc_hidden_proto (__open_nocancel)
/* Non cancellable open syscall (LFS version). */ /* Non cancellable open syscall (LFS version). */
__typeof (open64) __open64_nocancel; __typeof (open64) __open64_nocancel;
libc_hidden_proto (__open64_nocancel)
/* Non cancellable openat syscall. */ /* Non cancellable openat syscall. */
__typeof (openat) __openat_nocancel; __typeof (openat) __openat_nocancel;
libc_hidden_proto (__openat_nocancel)
/* Non cacellable openat syscall (LFS version). */ /* Non cacellable openat syscall (LFS version). */
__typeof (openat64) __openat64_nocancel; __typeof (openat64) __openat64_nocancel;
libc_hidden_proto (__openat64_nocancel)
/* Non cancellable read syscall. */ /* Non cancellable read syscall. */
__typeof (__read) __read_nocancel; __typeof (__read) __read_nocancel;
libc_hidden_proto (__read_nocancel)
/* Uncancelable write. */ /* Uncancelable write. */
__typeof (__write) __write_nocancel; __typeof (__write) __write_nocancel;
libc_hidden_proto (__write_nocancel)
/* Uncancelable close. */ /* Uncancelable close. */
__typeof (__close) __close_nocancel; __typeof (__close) __close_nocancel;
libc_hidden_proto (__close_nocancel)
/* Non cancellable close syscall that does not also set errno in case of /* Non cancellable close syscall that does not also set errno in case of
failure. */ failure. */
@ -75,18 +68,28 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt)
/* Uncancelable waitpid. */ /* Uncancelable waitpid. */
__typeof (waitpid) __waitpid_nocancel; __typeof (waitpid) __waitpid_nocancel;
libc_hidden_proto (__waitpid_nocancel)
/* Uncancelable pause. */ /* Uncancelable pause. */
__typeof (pause) __pause_nocancel; __typeof (pause) __pause_nocancel;
libc_hidden_proto (__pause_nocancel)
/* Uncancelable nanosleep. */ /* Uncancelable nanosleep. */
__typeof (__nanosleep) __nanosleep_nocancel; __typeof (__nanosleep) __nanosleep_nocancel;
hidden_proto (__nanosleep_nocancel)
/* Uncancelable fcntl. */ /* Uncancelable fcntl. */
__typeof (__fcntl) __fcntl_nocancel; __typeof (__fcntl) __fcntl_nocancel;
libc_hidden_proto (__fcntl_nocancel)
#if IS_IN (libc) || IS_IN (rtld)
hidden_proto (__open_nocancel)
hidden_proto (__open64_nocancel)
hidden_proto (__openat_nocancel)
hidden_proto (__openat64_nocancel)
hidden_proto (__read_nocancel)
hidden_proto (__write_nocancel)
hidden_proto (__close_nocancel)
hidden_proto (__waitpid_nocancel)
hidden_proto (__pause_nocancel)
hidden_proto (__nanosleep_nocancel)
hidden_proto (__fcntl_nocancel)
#endif
#endif /* NOT_CANCEL_H */ #endif /* NOT_CANCEL_H */

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2017-2018 Free Software Foundation, Inc. /* Linux open syscall implementation, non-LFS.
Copyright (C) 2017-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011. Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
@ -22,7 +23,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
#ifndef __OFF_T_MATCHES_OFF64_T #ifndef __OFF_T_MATCHES_OFF64_T
@ -48,25 +48,4 @@ libc_hidden_def (__libc_open)
weak_alias (__libc_open, __open) weak_alias (__libc_open, __open)
libc_hidden_weak (__open) libc_hidden_weak (__open)
weak_alias (__libc_open, open) weak_alias (__libc_open, open)
# if !IS_IN (rtld)
int
__open_nocancel (const char *file, int oflag, ...)
{
int mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, int);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag, mode);
}
# else
strong_alias (__libc_open, __open_nocancel)
# endif
libc_hidden_def (__open_nocancel)
#endif #endif

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991-2018 Free Software Foundation, Inc. /* Linux open syscall implementation, LFS.
Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -21,7 +22,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
#ifdef __OFF_T_MATCHES_OFF64_T #ifdef __OFF_T_MATCHES_OFF64_T
# define EXTRA_OPEN_FLAGS 0 # define EXTRA_OPEN_FLAGS 0
@ -52,34 +53,9 @@ strong_alias (__libc_open64, __open64)
libc_hidden_weak (__open64) libc_hidden_weak (__open64)
weak_alias (__libc_open64, open64) weak_alias (__libc_open64, open64)
# if !IS_IN (rtld)
int
__open64_nocancel (const char *file, int oflag, ...)
{
int mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, int);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag | EXTRA_OPEN_FLAGS,
mode);
}
#else
strong_alias (__libc_open64, __open64_nocancel)
#endif
libc_hidden_def (__open64_nocancel)
#ifdef __OFF_T_MATCHES_OFF64_T #ifdef __OFF_T_MATCHES_OFF64_T
strong_alias (__libc_open64, __libc_open) strong_alias (__libc_open64, __libc_open)
strong_alias (__libc_open64, __open) strong_alias (__libc_open64, __open)
libc_hidden_weak (__open) libc_hidden_weak (__open)
weak_alias (__libc_open64, open) weak_alias (__libc_open64, open)
strong_alias (__open64_nocancel, __open_nocancel)
libc_hidden_weak (__open_nocancel)
#endif #endif

View File

@ -0,0 +1,54 @@
/* Linux open syscall implementation, LFS, non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <not-cancel.h>
#ifdef __OFF_T_MATCHES_OFF64_T
# define EXTRA_OPEN_FLAGS 0
#else
# define EXTRA_OPEN_FLAGS O_LARGEFILE
#endif
int
__open64_nocancel (const char *file, int oflag, ...)
{
int mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, int);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag | EXTRA_OPEN_FLAGS,
mode);
}
hidden_def (__open64_nocancel)
#ifdef __OFF_T_MATCHES_OFF64_T
strong_alias (__open64_nocancel, __open_nocancel)
hidden_def (__open_nocancel)
#endif

View File

@ -0,0 +1,46 @@
/* Linux open syscall implementation, non-LFS, non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
#ifndef __OFF_T_MATCHES_OFF64_T
int
__open_nocancel (const char *file, int oflag, ...)
{
int mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, int);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag, mode);
}
hidden_def (__open_nocancel)
#endif

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2005-2018 Free Software Foundation, Inc. /* Linux openat syscall implementation, non-LFS.
Copyright (C) 2005-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -19,7 +20,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
#ifndef __OFF_T_MATCHES_OFF64_T #ifndef __OFF_T_MATCHES_OFF64_T
@ -43,24 +43,4 @@ __libc_openat (int fd, const char *file, int oflag, ...)
weak_alias (__libc_openat, __openat) weak_alias (__libc_openat, __openat)
libc_hidden_weak (__openat) libc_hidden_weak (__openat)
weak_alias (__libc_openat, openat) weak_alias (__libc_openat, openat)
# if !IS_IN (rtld)
int
__openat_nocancel (int fd, const char *file, int oflag, ...)
{
mode_t mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, fd, file, oflag, mode);
}
# else
strong_alias (__libc_openat, __openat_nocancel)
# endif
libc_hidden_weak (__openat_nocancel)
#endif #endif

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2007-2018 Free Software Foundation, Inc. /* Linux openat syscall implementation, LFS.
Copyright (C) 2007-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -19,7 +20,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
#ifdef __OFF_T_MATCHES_OFF64_T #ifdef __OFF_T_MATCHES_OFF64_T
# define EXTRA_OPEN_FLAGS 0 # define EXTRA_OPEN_FLAGS 0
@ -49,31 +49,8 @@ strong_alias (__libc_openat64, __openat64)
libc_hidden_weak (__openat64) libc_hidden_weak (__openat64)
weak_alias (__libc_openat64, openat64) weak_alias (__libc_openat64, openat64)
#if !IS_IN (rtld)
int
__openat64_nocancel (int fd, const char *file, int oflag, ...)
{
mode_t mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, fd, file, oflag | EXTRA_OPEN_FLAGS,
mode);
}
#else
strong_alias (__libc_openat64, __openat64_nocancel)
#endif
libc_hidden_def (__openat64_nocancel)
#ifdef __OFF_T_MATCHES_OFF64_T #ifdef __OFF_T_MATCHES_OFF64_T
strong_alias (__libc_openat64, __openat) strong_alias (__libc_openat64, __openat)
libc_hidden_weak (__openat) libc_hidden_weak (__openat)
weak_alias (__libc_openat64, openat) weak_alias (__libc_openat64, openat)
strong_alias (__openat64_nocancel, __openat_nocancel)
#endif #endif

View File

@ -0,0 +1,51 @@
/* Linux openat syscall implementation, LFS, non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <stdarg.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
#ifdef __OFF_T_MATCHES_OFF64_T
# define EXTRA_OPEN_FLAGS 0
#else
# define EXTRA_OPEN_FLAGS O_LARGEFILE
#endif
int
__openat64_nocancel (int fd, const char *file, int oflag, ...)
{
mode_t mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, fd, file, oflag | EXTRA_OPEN_FLAGS,
mode);
}
hidden_def (__openat64_nocancel)
#ifdef __OFF_T_MATCHES_OFF64_T
strong_alias (__openat64_nocancel, __openat_nocancel)
hidden_def (__openat_nocancel)
#endif

View File

@ -0,0 +1,43 @@
/* Linux openat syscall implementation, non-LFS, non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <stdarg.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
#ifndef __OFF_T_MATCHES_OFF64_T
int
__openat_nocancel (int fd, const char *file, int oflag, ...)
{
mode_t mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
return INLINE_SYSCALL_CALL (openat, fd, file, oflag, mode);
}
hidden_def (__openat_nocancel)
#endif

View File

@ -19,7 +19,6 @@
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
/* Suspend the process until a signal arrives. /* Suspend the process until a signal arrives.
This always returns -1 and sets errno to EINTR. */ This always returns -1 and sets errno to EINTR. */
@ -33,14 +32,3 @@ __libc_pause (void)
#endif #endif
} }
weak_alias (__libc_pause, pause) weak_alias (__libc_pause, pause)
int
__pause_nocancel (void)
{
#ifdef __NR_pause
return INLINE_SYSCALL_CALL (pause);
#else
return INLINE_SYSCALL_CALL (ppoll, NULL, 0, NULL, NULL);
#endif
}
libc_hidden_def (__pause_nocancel)

View File

@ -0,0 +1,33 @@
/* Linux pause syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <unistd.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
int
__pause_nocancel (void)
{
#ifdef __NR_pause
return INLINE_SYSCALL_CALL (pause);
#else
return INLINE_SYSCALL_CALL (ppoll, NULL, 0, NULL, NULL);
#endif
}
hidden_def (__pause_nocancel)

View File

@ -236,4 +236,13 @@
# endif # endif
#endif #endif
/* In the PowerPC64 ABI, the unadorned F_GETLK* opcodes should be used
even by largefile64 code. */
#define FCNTL_ADJUST_CMD(__cmd) \
({ int cmd_ = (__cmd); \
if (cmd_ >= F_GETLK64 && cmd_ <= F_SETLKW64) \
cmd_ -= F_GETLK64 - F_GETLK; \
cmd_; })
#endif /* linux/powerpc/powerpc64/sysdep.h */ #endif /* linux/powerpc/powerpc64/sysdep.h */

View File

@ -45,7 +45,7 @@ pthread_getname_np (pthread_t th, char *buf, size_t len)
char fname[sizeof (FMT) + 8]; char fname[sizeof (FMT) + 8];
sprintf (fname, FMT, (unsigned int) pd->tid); sprintf (fname, FMT, (unsigned int) pd->tid);
int fd = __open_nocancel (fname, O_RDONLY); int fd = __open64_nocancel (fname, O_RDONLY);
if (fd == -1) if (fd == -1)
return errno; return errno;

View File

@ -46,7 +46,7 @@ pthread_setname_np (pthread_t th, const char *name)
char fname[sizeof (FMT) + 8]; char fname[sizeof (FMT) + 8];
sprintf (fname, FMT, (unsigned int) pd->tid); sprintf (fname, FMT, (unsigned int) pd->tid);
int fd = __open_nocancel (fname, O_RDWR); int fd = __open64_nocancel (fname, O_RDWR);
if (fd == -1) if (fd == -1)
return errno; return errno;

View File

@ -18,7 +18,6 @@
#include <unistd.h> #include <unistd.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
/* Read NBYTES into BUF from FD. Return the number read or -1. */ /* Read NBYTES into BUF from FD. Return the number read or -1. */
ssize_t ssize_t
@ -32,14 +31,3 @@ libc_hidden_def (__read)
weak_alias (__libc_read, __read) weak_alias (__libc_read, __read)
libc_hidden_def (read) libc_hidden_def (read)
weak_alias (__libc_read, read) weak_alias (__libc_read, read)
#if !IS_IN (rtld)
ssize_t
__read_nocancel (int fd, void *buf, size_t nbytes)
{
return INLINE_SYSCALL_CALL (read, fd, buf, nbytes);
}
#else
strong_alias (__libc_read, __read_nocancel)
#endif
libc_hidden_def (__read_nocancel)

View File

@ -0,0 +1,28 @@
/* Linux read syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <sysdep-cancel.h>
#include <not-cancel.h>
ssize_t
__read_nocancel (int fd, void *buf, size_t nbytes)
{
return INLINE_SYSCALL_CALL (read, fd, buf, nbytes);
}
hidden_def (__read_nocancel)

View File

@ -1,4 +1,5 @@
/* Copyright (C) 1991-2018 Free Software Foundation, Inc. /* Linux waitpid syscall implementation.
Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -19,7 +20,6 @@
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <not-cancel.h>
__pid_t __pid_t
__waitpid (__pid_t pid, int *stat_loc, int options) __waitpid (__pid_t pid, int *stat_loc, int options)
@ -32,14 +32,3 @@ __waitpid (__pid_t pid, int *stat_loc, int options)
} }
libc_hidden_def (__waitpid) libc_hidden_def (__waitpid)
weak_alias (__waitpid, waitpid) weak_alias (__waitpid, waitpid)
__pid_t
__waitpid_nocancel (__pid_t pid, int *stat_loc, int options)
{
#ifdef __NR_waitpid
return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options);
#else
return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL);
#endif
}
libc_hidden_def (__waitpid_nocancel)

View File

@ -0,0 +1,34 @@
/* Linux waitpid syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <sysdep-cancel.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <not-cancel.h>
__pid_t
__waitpid_nocancel (__pid_t pid, int *stat_loc, int options)
{
#ifdef __NR_waitpid
return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options);
#else
return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL);
#endif
}
libc_hidden_def (__waitpid_nocancel)

View File

@ -18,7 +18,6 @@
#include <unistd.h> #include <unistd.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <not-cancel.h>
/* Write NBYTES of BUF to FD. Return the number written, or -1. */ /* Write NBYTES of BUF to FD. Return the number written, or -1. */
ssize_t ssize_t
@ -32,14 +31,3 @@ weak_alias (__libc_write, __write)
libc_hidden_weak (__write) libc_hidden_weak (__write)
weak_alias (__libc_write, write) weak_alias (__libc_write, write)
libc_hidden_weak (write) libc_hidden_weak (write)
#if !IS_IN (rtld)
ssize_t
__write_nocancel (int fd, const void *buf, size_t nbytes)
{
return INLINE_SYSCALL_CALL (write, fd, buf, nbytes);
}
#else
strong_alias (__libc_write, __write_nocancel)
#endif
libc_hidden_def (__write_nocancel)

View File

@ -0,0 +1,28 @@
/* Linux write syscall implementation -- non-cancellable.
Copyright (C) 2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have 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 <sysdep-cancel.h>
#include <not-cancel.h>
ssize_t
__write_nocancel (int fd, const void *buf, size_t nbytes)
{
return INLINE_SYSCALL_CALL (write, fd, buf, nbytes);
}
hidden_def (__write_nocancel)