@@ -259,6 +259,7 @@ tests = tst-typesizes \
tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
+ tst-cancel26 tst-cancel27 \
tst-cancel-self tst-cancel-self-cancelstate \
tst-cancel-self-canceltype tst-cancel-self-testcancel \
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
@@ -397,8 +398,7 @@ tests-reverse += tst-cancel5 tst-cancel23 tst-vfork1x tst-vfork2x
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-stack3-mem.out $(objpfx)tst-oddstacklimit.out
ifeq ($(build-shared),yes)
-tests-special += $(objpfx)tst-tls6.out $(objpfx)tst-cleanup0-cmp.out \
- $(objpfx)tst-cancel-wrappers.out
+tests-special += $(objpfx)tst-tls6.out $(objpfx)tst-cleanup0-cmp.out
endif
endif
@@ -614,7 +614,7 @@ $(objpfx)$(multidir)/crtn.o: $(objpfx)crtn.o $(objpfx)$(multidir)/
endif
generated += libpthread_nonshared.a \
- multidir.mk tst-atfork2.mtrace tst-cancel-wrappers.out \
+ multidir.mk tst-atfork2.mtrace \
tst-tls6.out
generated += $(objpfx)tst-atfork2.mtrace \
@@ -631,18 +631,6 @@ LDFLAGS-pthread.so += -e __nptl_main
$(objpfx)pt-interp.os: $(common-objpfx)runtime-linker.h
endif
-ifeq ($(run-built-tests),yes)
-ifeq (yes,$(build-shared))
-$(objpfx)tst-cancel-wrappers.out: tst-cancel-wrappers.sh
- $(SHELL) $< '$(NM)' \
- $(common-objpfx)libc_pic.a \
- $(common-objpfx)libc.a \
- $(objpfx)libpthread_pic.a \
- $(objpfx)libpthread.a > $@; \
- $(evaluate-test)
-endif
-endif
-
tst-exec4-ARGS = $(host-test-program-cmd)
$(objpfx)tst-execstack: $(libdl)
deleted file mode 100644
@@ -1,92 +0,0 @@
-#! /bin/sh
-# Test whether all cancelable functions are cancelable.
-# Copyright (C) 2002-2015 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-# Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
-
-# The GNU C Library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-
-# The GNU C Library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-
-# You should have received a copy of the GNU Lesser General Public
-# License along with the GNU C Library; if not, see
-# <http://www.gnu.org/licenses/>.
-
-NM="$1"; shift
-while [ $# -gt 0 ]; do
- ( $NM -P $1; echo 'end[end]:' ) | gawk ' BEGIN {
-C["accept"]=1
-C["close"]=1
-C["connect"]=1
-C["creat"]=1
-C["fcntl"]=1
-C["fdatasync"]=1
-C["fsync"]=1
-C["msgrcv"]=1
-C["msgsnd"]=1
-C["msync"]=1
-C["nanosleep"]=1
-C["open"]=1
-C["open64"]=1
-C["pause"]=1
-C["poll"]=1
-C["pread"]=1
-C["pread64"]=1
-C["pselect"]=1
-C["pwrite"]=1
-C["pwrite64"]=1
-C["read"]=1
-C["readv"]=1
-C["recv"]=1
-C["recvfrom"]=1
-C["recvmsg"]=1
-C["select"]=1
-C["send"]=1
-C["sendmsg"]=1
-C["sendto"]=1
-C["sigpause"]=1
-C["sigsuspend"]=1
-C["sigwait"]=1
-C["sigwaitinfo"]=1
-C["tcdrain"]=1
-C["wait"]=1
-C["waitid"]=1
-C["waitpid"]=1
-C["write"]=1
-C["writev"]=1
-C["__xpg_sigpause"]=1
-}
-/:$/ {
- if (seen)
- {
- if (!seen_enable || !seen_disable)
- {
- printf "in '$1'(%s) %s'\''s cancellation missing\n", object, seen
- ret = 1
- }
- }
- seen=""
- seen_enable=""
- seen_disable=""
- object=gensub(/^.*\[(.*)\]:$/, "\\1", 1, $0)
- next
-}
-{
- if (C[$1] && $2 ~ /^[TW]$/)
- seen=$1
- else if ($1 ~ /^([.]|)__(libc|pthread)_enable_asynccancel$/ && $2 == "U")
- seen_enable=1
- else if ($1 ~ /^([.]|)__(libc|pthread)_disable_asynccancel$/ && $2 == "U")
- seen_disable=1
-}
-END {
- exit ret
-}' || exit
- shift
-done
@@ -33,6 +33,9 @@ tf (void *arg)
char buf[100000];
while (write (fd[1], buf, sizeof (buf)) > 0);
+ /* The write can return a value higher than 0 (meaning partial write)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
return (void *) 42l;
}
@@ -49,6 +49,9 @@ sh_body (void)
puts ("read succeeded");
exit (1);
}
+ /* The read can return a value higher than 0 (meaning partial reads)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
}
@@ -84,7 +87,8 @@ tf_body (void)
puts ("read succeeded");
exit (1);
}
-
+ /* Check for partial read. */
+ pthread_testcancel ();
read (fd[0], &c, 1);
pthread_cleanup_pop (0);
@@ -50,6 +50,9 @@ sh_body (void)
puts ("read succeeded");
exit (1);
}
+ /* The write can return a value higher than 0 (meaning partial write)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
}
@@ -85,6 +88,8 @@ tf_body (void)
puts ("read succeeded");
exit (1);
}
+ /* Check partial read. */
+ pthread_testcancel ();
read (fd[0], &c, 1);
@@ -38,8 +38,10 @@
#include <sys/un.h>
#include <sys/wait.h>
-#include "pthreadP.h"
-
+/* The signal used for asynchronous cancelation. */
+#ifndef SIGCANCEL
+# define SIGCANCEL __SIGRTMIN
+#endif
/* Since STREAMS are not supported in the standard Linux kernel and
there we don't advertise STREAMS as supported is no need to test
@@ -247,6 +249,9 @@ tf_write (void *arg)
char buf[WRITE_BUFFER_SIZE];
memset (buf, '\0', sizeof (buf));
s = write (fd, buf, sizeof (buf));
+ /* The write can return a value higher than 0 (meaning partial write)
+ due the SIGCANCEL, but the thread may still pending cancellation. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
@@ -1143,6 +1148,8 @@ tf_send (void *arg)
char mem[700000];
send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
+ /* Check for partial send. */
+ pthread_testcancel ();
pthread_cleanup_pop (0);
@@ -1425,6 +1432,38 @@ tf_open (void *arg)
exit (1);
}
+static void *
+tf_open64 (void *arg)
+{
+ if (arg == NULL)
+ // XXX If somebody can provide a portable test case in which open()
+ // blocks we can enable this test to run in both rounds.
+ abort ();
+
+ int r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ pthread_cleanup_push (cl, NULL);
+
+ open64 ("Makefile", O_RDONLY);
+
+ pthread_cleanup_pop (0);
+
+ printf ("%s: open returned\n", __FUNCTION__);
+
+ exit (1);
+}
static void *
tf_close (void *arg)
@@ -1510,6 +1549,46 @@ tf_pread (void *arg)
exit (1);
}
+static void *
+tf_pread64 (void *arg)
+{
+ if (arg == NULL)
+ // XXX If somebody can provide a portable test case in which pread()
+ // blocks we can enable this test to run in both rounds.
+ abort ();
+
+ tempfd = open64 ("Makefile", O_RDONLY);
+ if (tempfd == -1)
+ {
+ printf ("%s: cannot open64 Makefile\n", __FUNCTION__);
+ exit (1);
+ }
+
+ int r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ pthread_cleanup_push (cl, NULL);
+
+ char mem[10];
+ pread64 (tempfd, mem, sizeof (mem), 0);
+
+ pthread_cleanup_pop (0);
+
+ printf ("%s: pread64 returned\n", __FUNCTION__);
+
+ exit (1);
+}
static void *
tf_pwrite (void *arg)
@@ -1554,6 +1633,48 @@ tf_pwrite (void *arg)
exit (1);
}
+static void *
+tf_pwrite64 (void *arg)
+{
+ if (arg == NULL)
+ // XXX If somebody can provide a portable test case in which pwrite()
+ // blocks we can enable this test to run in both rounds.
+ abort ();
+
+ char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
+ tempfd = mkstemp (fname);
+ if (tempfd == -1)
+ {
+ printf ("%s: mkstemp failed\n", __FUNCTION__);
+ exit (1);
+ }
+ unlink (fname);
+
+ int r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ r = pthread_barrier_wait (&b2);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+ exit (1);
+ }
+
+ pthread_cleanup_push (cl, NULL);
+
+ char mem[10];
+ pwrite64 (tempfd, mem, sizeof (mem), 0);
+
+ pthread_cleanup_pop (0);
+
+ printf ("%s: pwrite64 returned\n", __FUNCTION__);
+
+ exit (1);
+}
static void *
tf_fsync (void *arg)
@@ -2141,9 +2262,12 @@ static struct
ADD_TEST (recvfrom, 2, 0),
ADD_TEST (recvmsg, 2, 0),
ADD_TEST (open, 2, 1),
+ ADD_TEST (open64, 2, 1),
ADD_TEST (close, 2, 1),
ADD_TEST (pread, 2, 1),
+ ADD_TEST (pread64, 2, 1),
ADD_TEST (pwrite, 2, 1),
+ ADD_TEST (pwrite64, 2, 1),
ADD_TEST (fsync, 2, 1),
ADD_TEST (fdatasync, 2, 1),
ADD_TEST (msync, 2, 1),