12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390 |
- /* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
- /* NOTE: this tests functionality beyond POSIX. POSIX does not allow
- exit to be called more than once. */
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <pthread.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <termios.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <sys/msg.h>
- #include <sys/poll.h>
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <sys/uio.h>
- #include <sys/un.h>
- #include <sys/wait.h>
- #include "pthreadP.h"
- /* Since STREAMS are not supported in the standard Linux kernel and
- there we don't advertise STREAMS as supported is no need to test
- the STREAMS related functions. This affects
- getmsg() getpmsg() putmsg()
- putpmsg()
- lockf() and fcntl() are tested in tst-cancel16.
- pthread_join() is tested in tst-join5.
- pthread_testcancel()'s only purpose is to allow cancellation. This
- is tested in several places.
- sem_wait() and sem_timedwait() are checked in tst-cancel1[2345] tests.
- mq_send(), mq_timedsend(), mq_receive() and mq_timedreceive() are checked
- in tst-mqueue8{,x} tests.
- aio_suspend() is tested in tst-cancel17.
- clock_nanosleep() is tested in tst-cancel18.
- */
- /* Pipe descriptors. */
- static int fds[2];
- /* Temporary file descriptor, to be closed after each round. */
- static int tempfd = -1;
- static int tempfd2 = -1;
- /* Name of temporary file to be removed after each round. */
- static char *tempfname;
- /* Temporary message queue. */
- static int tempmsg = -1;
- /* Often used barrier for two threads. */
- static pthread_barrier_t b2;
- #ifndef IPC_ADDVAL
- # define IPC_ADDVAL 0
- #endif
- #define WRITE_BUFFER_SIZE 4096
- /* Cleanup handling test. */
- static int cl_called;
- static void
- cl (void *arg)
- {
- ++cl_called;
- }
- static void *
- tf_read (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- ssize_t s;
- pthread_cleanup_push (cl, NULL);
- char buf[100];
- s = read (fd, buf, sizeof (buf));
- pthread_cleanup_pop (0);
- printf ("%s: read returns with %zd\n", __FUNCTION__, s);
- exit (1);
- }
- static void *
- tf_readv (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- ssize_t s;
- pthread_cleanup_push (cl, NULL);
- char buf[100];
- struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
- s = readv (fd, iov, 1);
- pthread_cleanup_pop (0);
- printf ("%s: readv returns with %zd\n", __FUNCTION__, s);
- exit (1);
- }
- static void *
- tf_write (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[1];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- ssize_t s;
- pthread_cleanup_push (cl, NULL);
- char buf[WRITE_BUFFER_SIZE];
- memset (buf, '\0', sizeof (buf));
- s = write (fd, buf, sizeof (buf));
- pthread_cleanup_pop (0);
- printf ("%s: write returns with %zd\n", __FUNCTION__, s);
- exit (1);
- }
- static void *
- tf_writev (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[1];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- ssize_t s;
- pthread_cleanup_push (cl, NULL);
- char buf[WRITE_BUFFER_SIZE];
- memset (buf, '\0', sizeof (buf));
- struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
- s = writev (fd, iov, 1);
- pthread_cleanup_pop (0);
- printf ("%s: writev returns with %zd\n", __FUNCTION__, s);
- exit (1);
- }
- static void *
- tf_sleep (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- pthread_cleanup_push (cl, NULL);
- sleep (arg == NULL ? 1000000 : 0);
- pthread_cleanup_pop (0);
- printf ("%s: sleep returns\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_usleep (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);
- pthread_cleanup_pop (0);
- printf ("%s: usleep returns\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_nanosleep (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- pthread_cleanup_push (cl, NULL);
- struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
- TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
- pthread_cleanup_pop (0);
- printf ("%s: nanosleep returns\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_select (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- fd_set rfs;
- FD_ZERO (&rfs);
- FD_SET (fd, &rfs);
- int s;
- pthread_cleanup_push (cl, NULL);
- s = select (fd + 1, &rfs, NULL, NULL, NULL);
- pthread_cleanup_pop (0);
- printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_pselect (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- fd_set rfs;
- FD_ZERO (&rfs);
- FD_SET (fd, &rfs);
- int s;
- pthread_cleanup_push (cl, NULL);
- s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);
- pthread_cleanup_pop (0);
- printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_poll (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
- int s;
- pthread_cleanup_push (cl, NULL);
- s = poll (rfs, 1, -1);
- pthread_cleanup_pop (0);
- printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_ppoll (void *arg)
- {
- int fd;
- int r;
- if (arg == NULL)
- fd = fds[0];
- else
- {
- char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
- tempfd = fd = mkstemp (fname);
- if (fd == -1)
- printf ("%s: mkstemp failed\n", __FUNCTION__);
- unlink (fname);
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };
- int s;
- pthread_cleanup_push (cl, NULL);
- s = ppoll (rfs, 1, NULL, NULL);
- pthread_cleanup_pop (0);
- printf ("%s: ppoll returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_wait (void *arg)
- {
- pid_t pid = fork ();
- if (pid == -1)
- {
- puts ("fork failed");
- exit (1);
- }
- if (pid == 0)
- {
- /* Make the program disappear after a while. */
- if (arg == NULL)
- sleep (10);
- exit (0);
- }
- int r;
- if (arg != NULL)
- {
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
- while (nanosleep (&ts, &ts) != 0)
- continue;
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- int s;
- pthread_cleanup_push (cl, NULL);
- s = wait (NULL);
- pthread_cleanup_pop (0);
- printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_waitpid (void *arg)
- {
- pid_t pid = fork ();
- if (pid == -1)
- {
- puts ("fork failed");
- exit (1);
- }
- if (pid == 0)
- {
- /* Make the program disappear after a while. */
- if (arg == NULL)
- sleep (10);
- exit (0);
- }
- int r;
- if (arg != NULL)
- {
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
- while (nanosleep (&ts, &ts) != 0)
- continue;
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- int s;
- pthread_cleanup_push (cl, NULL);
- s = waitpid (-1, NULL, 0);
- pthread_cleanup_pop (0);
- printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_waitid (void *arg)
- {
- pid_t pid = fork ();
- if (pid == -1)
- {
- puts ("fork failed");
- exit (1);
- }
- if (pid == 0)
- {
- /* Make the program disappear after a while. */
- if (arg == NULL)
- sleep (10);
- exit (0);
- }
- int r;
- if (arg != NULL)
- {
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
- while (nanosleep (&ts, &ts) != 0)
- continue;
- 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: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- int s;
- pthread_cleanup_push (cl, NULL);
- #ifndef WEXITED
- # define WEXITED 0
- #endif
- siginfo_t si;
- s = waitid (P_PID, pid, &si, WEXITED);
- pthread_cleanup_pop (0);
- printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
- strerror (errno));
- exit (1);
- }
- static void *
- tf_sigpause (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- /* Just for fun block the cancellation signal. We need to use
- __xpg_sigpause since otherwise we will get the BSD version. */
- //__xpg_sigpause (SIGCANCEL);
- __sigpause (SIGCANCEL, 1);
- pthread_cleanup_pop (0);
- printf ("%s: sigpause returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_sigsuspend (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- /* Just for fun block all signals. */
- sigset_t mask;
- sigfillset (&mask);
- sigsuspend (&mask);
- pthread_cleanup_pop (0);
- printf ("%s: sigsuspend returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_sigwait (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- /* Block SIGUSR1. */
- sigset_t mask;
- sigemptyset (&mask);
- sigaddset (&mask, SIGUSR1);
- if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
- {
- printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
- exit (1);
- }
- int sig;
- pthread_cleanup_push (cl, NULL);
- /* Wait for SIGUSR1. */
- sigwait (&mask, &sig);
- pthread_cleanup_pop (0);
- printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);
- exit (1);
- }
- static void *
- tf_sigwaitinfo (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- /* Block SIGUSR1. */
- sigset_t mask;
- sigemptyset (&mask);
- sigaddset (&mask, SIGUSR1);
- if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
- {
- printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
- exit (1);
- }
- siginfo_t info;
- pthread_cleanup_push (cl, NULL);
- /* Wait for SIGUSR1. */
- sigwaitinfo (&mask, &info);
- pthread_cleanup_pop (0);
- printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
- info.si_signo);
- exit (1);
- }
- static void *
- tf_sigtimedwait (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- /* Block SIGUSR1. */
- sigset_t mask;
- sigemptyset (&mask);
- sigaddset (&mask, SIGUSR1);
- if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
- {
- printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
- exit (1);
- }
- /* Wait for SIGUSR1. */
- siginfo_t info;
- struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
- pthread_cleanup_push (cl, NULL);
- sigtimedwait (&mask, &info, &ts);
- pthread_cleanup_pop (0);
- printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
- info.si_signo);
- exit (1);
- }
- static void *
- tf_pause (void *arg)
- {
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- pause ();
- pthread_cleanup_pop (0);
- printf ("%s: pause returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_accept (void *arg)
- {
- int tfd;
- struct sockaddr_un sun;
- /* To test a non-blocking accept call we make the call file by using
- a datagrame socket. */
- int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;
- tempfd = socket (AF_UNIX, pf, 0);
- if (tempfd == -1)
- {
- printf ("%s: socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- unlink (sun.sun_path);
- listen (tempfd, 5);
- socklen_t len = sizeof (sun);
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- accept (tempfd, (struct sockaddr *) &sun, &len);
- pthread_cleanup_pop (0);
- printf ("%s: accept returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_send (void *arg)
- {
- int tfd;
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- listen (tempfd, 5);
- tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\n", __FUNCTION__);
- exit (1);
- }
- if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
- {
- printf ("%s: connect failed\n", __FUNCTION__);
- exit(1);
- }
- unlink (sun.sun_path);
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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);
- /* Very large block, so that the send call blocks. */
- char mem[700000];
- send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);
- pthread_cleanup_pop (0);
- printf ("%s: send returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_recv (void *arg)
- {
- int tfd;
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- listen (tempfd, 5);
- tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\n", __FUNCTION__);
- exit (1);
- }
- if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
- {
- printf ("%s: connect failed\n", __FUNCTION__);
- exit(1);
- }
- unlink (sun.sun_path);
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- if (arg != NULL)
- {
- 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[70];
- recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);
- pthread_cleanup_pop (0);
- printf ("%s: recv returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_recvfrom (void *arg)
- {
- int tfd;
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- tempfname = strdup (sun.sun_path);
- tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\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);
- }
- if (arg != NULL)
- {
- 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[70];
- socklen_t len = sizeof (sun);
- recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
- (struct sockaddr *) &sun, &len);
- pthread_cleanup_pop (0);
- printf ("%s: recvfrom returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_recvmsg (void *arg)
- {
- int tfd;
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- tempfname = strdup (sun.sun_path);
- tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\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);
- }
- if (arg != NULL)
- {
- 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[70];
- struct iovec iov[1];
- iov[0].iov_base = mem;
- iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;
- struct msghdr m;
- m.msg_name = &sun;
- m.msg_namelen = sizeof (sun);
- m.msg_iov = iov;
- m.msg_iovlen = 1;
- m.msg_control = NULL;
- m.msg_controllen = 0;
- recvmsg (tempfd2, &m, 0);
- pthread_cleanup_pop (0);
- printf ("%s: recvmsg returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_open (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);
- open ("Makefile", O_RDONLY);
- pthread_cleanup_pop (0);
- printf ("%s: open returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_close (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which close()
- // blocks we can enable this test to run in both rounds.
- abort ();
- char fname[] = "/tmp/tst-cancel-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);
- close (tempfd);
- pthread_cleanup_pop (0);
- printf ("%s: close returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_pread (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 = open ("Makefile", O_RDONLY);
- if (tempfd == -1)
- {
- printf ("%s: cannot open 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];
- pread (tempfd, mem, sizeof (mem), 0);
- pthread_cleanup_pop (0);
- printf ("%s: pread returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_pwrite (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];
- pwrite (tempfd, mem, sizeof (mem), 0);
- pthread_cleanup_pop (0);
- printf ("%s: pwrite returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_fsync (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which fsync()
- // blocks we can enable this test to run in both rounds.
- abort ();
- tempfd = open ("Makefile", O_RDONLY);
- if (tempfd == -1)
- {
- printf ("%s: cannot open 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);
- fsync (tempfd);
- pthread_cleanup_pop (0);
- printf ("%s: fsync returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_fdatasync (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which fdatasync()
- // blocks we can enable this test to run in both rounds.
- abort ();
- tempfd = open ("Makefile", O_RDONLY);
- if (tempfd == -1)
- {
- printf ("%s: cannot open 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);
- fdatasync (tempfd);
- pthread_cleanup_pop (0);
- printf ("%s: fdatasync returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_msync (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which msync()
- // blocks we can enable this test to run in both rounds.
- abort ();
- tempfd = open ("Makefile", O_RDONLY);
- if (tempfd == -1)
- {
- printf ("%s: cannot open Makefile\n", __FUNCTION__);
- exit (1);
- }
- void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
- if (p == MAP_FAILED)
- {
- printf ("%s: mmap failed\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);
- msync (p, 10, 0);
- pthread_cleanup_pop (0);
- printf ("%s: msync returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_sendto (void *arg)
- {
- int tfd;
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which sendto()
- // blocks we can enable this test to run in both rounds.
- abort ();
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- tempfname = strdup (sun.sun_path);
- tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\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[1];
- sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
- (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);
- pthread_cleanup_pop (0);
- printf ("%s: sendto returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_sendmsg (void *arg)
- {
- int tfd;
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which sendmsg()
- // blocks we can enable this test to run in both rounds.
- abort ();
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- tempfname = strdup (sun.sun_path);
- tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\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[1];
- struct iovec iov[1];
- iov[0].iov_base = mem;
- iov[0].iov_len = 1;
- struct msghdr m;
- m.msg_name = &sun;
- m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1);
- m.msg_iov = iov;
- m.msg_iovlen = 1;
- m.msg_control = NULL;
- m.msg_controllen = 0;
- sendmsg (tempfd2, &m, 0);
- pthread_cleanup_pop (0);
- printf ("%s: sendmsg returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_creat (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which sendmsg()
- // 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);
- creat ("tmp/tst-cancel-4-should-not-exist", 0666);
- pthread_cleanup_pop (0);
- printf ("%s: creat returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_connect (void *arg)
- {
- int tfd;
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which connect()
- // blocks we can enable this test to run in both rounds.
- abort ();
- struct sockaddr_un sun;
- tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd == -1)
- {
- printf ("%s: first socket call failed\n", __FUNCTION__);
- exit (1);
- }
- int tries = 0;
- do
- {
- if (++tries > 10)
- {
- printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
- }
- strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
- tfd = mkstemp(sun.sun_path);
- if (tfd < 0)
- {
- printf ("%s: cannot generate temp file name\n", __FUNCTION__);
- exit (1);
- }
- close(tfd);
- sun.sun_family = AF_UNIX;
- }
- while (bind (tempfd, (struct sockaddr *) &sun,
- offsetof (struct sockaddr_un, sun_path)
- + strlen (sun.sun_path) + 1) != 0);
- tempfname = strdup (sun.sun_path);
- listen (tempfd, 5);
- tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
- if (tempfd2 == -1)
- {
- printf ("%s: second socket call failed\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);
- }
- if (arg != NULL)
- {
- 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);
- connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));
- pthread_cleanup_pop (0);
- printf ("%s: connect returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_tcdrain (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which tcdrain()
- // 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);
- }
- if (arg != NULL)
- {
- 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);
- /* Regardless of stderr being a terminal, the tcdrain call should be
- canceled. */
- tcdrain (STDERR_FILENO);
- pthread_cleanup_pop (0);
- printf ("%s: tcdrain returned\n", __FUNCTION__);
- exit (1);
- }
- static void *
- tf_msgrcv (void *arg)
- {
- tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
- if (tempmsg == -1)
- {
- printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
- 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);
- }
- if (arg != NULL)
- {
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
- exit (1);
- }
- }
- ssize_t s;
- pthread_cleanup_push (cl, NULL);
- struct
- {
- long int type;
- char mem[10];
- } m;
- int randnr;
- /* We need a positive random number. */
- do
- randnr = random () % 64000;
- while (randnr <= 0);
- do
- {
- errno = 0;
- s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
- }
- while (errno == EIDRM || errno == EINTR);
- pthread_cleanup_pop (0);
- printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);
- msgctl (tempmsg, IPC_RMID, NULL);
- exit (1);
- }
- static void *
- tf_msgsnd (void *arg)
- {
- if (arg == NULL)
- // XXX If somebody can provide a portable test case in which msgsnd()
- // blocks we can enable this test to run in both rounds.
- abort ();
- tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
- if (tempmsg == -1)
- {
- printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
- 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);
- struct
- {
- long int type;
- char mem[1];
- } m;
- /* We need a positive random number. */
- do
- m.type = random () % 64000;
- while (m.type <= 0);
- msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);
- pthread_cleanup_pop (0);
- printf ("%s: msgsnd returned\n", __FUNCTION__);
- msgctl (tempmsg, IPC_RMID, NULL);
- exit (1);
- }
- static struct
- {
- const char *name;
- void *(*tf) (void *);
- int nb;
- int only_early;
- } tests[] =
- {
- #define ADD_TEST(name, nbar, early) { #name, tf_##name, nbar, early }
- ADD_TEST (read, 2, 0),
- ADD_TEST (readv, 2, 0),
- ADD_TEST (select, 2, 0),
- ADD_TEST (pselect, 2, 0),
- ADD_TEST (poll, 2, 0),
- ADD_TEST (ppoll, 2, 0),
- ADD_TEST (write, 2, 0),
- ADD_TEST (writev, 2, 0),
- ADD_TEST (sleep, 2, 0),
- ADD_TEST (usleep, 2, 0),
- ADD_TEST (nanosleep, 2, 0),
- ADD_TEST (wait, 2, 0),
- ADD_TEST (waitid, 2, 0),
- ADD_TEST (waitpid, 2, 0),
- ADD_TEST (sigpause, 2, 0),
- ADD_TEST (sigsuspend, 2, 0),
- ADD_TEST (sigwait, 2, 0),
- ADD_TEST (sigwaitinfo, 2, 0),
- ADD_TEST (sigtimedwait, 2, 0),
- ADD_TEST (pause, 2, 0),
- ADD_TEST (accept, 2, 0),
- ADD_TEST (send, 2, 0),
- ADD_TEST (recv, 2, 0),
- ADD_TEST (recvfrom, 2, 0),
- ADD_TEST (recvmsg, 2, 0),
- ADD_TEST (open, 2, 1),
- ADD_TEST (close, 2, 1),
- ADD_TEST (pread, 2, 1),
- ADD_TEST (pwrite, 2, 1),
- ADD_TEST (fsync, 2, 1),
- ADD_TEST (fdatasync, 2, 1),
- ADD_TEST (msync, 2, 1),
- ADD_TEST (sendto, 2, 1),
- ADD_TEST (sendmsg, 2, 1),
- ADD_TEST (creat, 2, 1),
- ADD_TEST (connect, 2, 1),
- ADD_TEST (tcdrain, 2, 1),
- ADD_TEST (msgrcv, 2, 0),
- ADD_TEST (msgsnd, 2, 1),
- };
- #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
- static int
- do_test (void)
- {
- int val;
- socklen_t len;
- if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
- {
- perror ("socketpair");
- exit (1);
- }
- val = 1;
- len = sizeof(val);
- setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
- if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
- {
- perror ("getsockopt");
- exit (1);
- }
- if (val >= WRITE_BUFFER_SIZE)
- {
- puts ("minimum write buffer size too large");
- exit (1);
- }
- setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
- int result = 0;
- size_t cnt;
- for (cnt = 0; cnt < ntest_tf; ++cnt)
- {
- if (tests[cnt].only_early)
- continue;
- if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
- {
- puts ("b2 init failed");
- exit (1);
- }
- /* Reset the counter for the cleanup handler. */
- cl_called = 0;
- pthread_t th;
- if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
- {
- printf ("create for '%s' test failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- result = 1;
- continue;
- }
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 };
- while (nanosleep (&ts, &ts) != 0)
- continue;
- if (pthread_cancel (th) != 0)
- {
- printf ("cancel for '%s' failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- void *status;
- if (pthread_join (th, &status) != 0)
- {
- printf ("join for '%s' failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (status != PTHREAD_CANCELED)
- {
- printf ("thread for '%s' not canceled\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (pthread_barrier_destroy (&b2) != 0)
- {
- puts ("barrier_destroy failed");
- result = 1;
- continue;
- }
- if (cl_called == 0)
- {
- printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (cl_called > 1)
- {
- printf ("cleanup handler called more than once for '%s'\n",
- tests[cnt].name);
- result = 1;
- continue;
- }
- printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);
- if (tempfd != -1)
- {
- close (tempfd);
- tempfd = -1;
- }
- if (tempfd2 != -1)
- {
- close (tempfd2);
- tempfd2 = -1;
- }
- if (tempfname != NULL)
- {
- unlink (tempfname);
- free (tempfname);
- tempfname = NULL;
- }
- if (tempmsg != -1)
- {
- msgctl (tempmsg, IPC_RMID, NULL);
- tempmsg = -1;
- }
- }
- for (cnt = 0; cnt < ntest_tf; ++cnt)
- {
- if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
- {
- puts ("b2 init failed");
- exit (1);
- }
- /* Reset the counter for the cleanup handler. */
- cl_called = 0;
- pthread_t th;
- if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
- {
- printf ("create for '%s' test failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- int r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- result = 1;
- continue;
- }
- if (pthread_cancel (th) != 0)
- {
- printf ("cancel for '%s' failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- r = pthread_barrier_wait (&b2);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
- {
- printf ("%s: barrier_wait failed\n", __FUNCTION__);
- result = 1;
- continue;
- }
- void *status;
- if (pthread_join (th, &status) != 0)
- {
- printf ("join for '%s' failed\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (status != PTHREAD_CANCELED)
- {
- printf ("thread for '%s' not canceled\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (pthread_barrier_destroy (&b2) != 0)
- {
- puts ("barrier_destroy failed");
- result = 1;
- continue;
- }
- if (cl_called == 0)
- {
- printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
- result = 1;
- continue;
- }
- if (cl_called > 1)
- {
- printf ("cleanup handler called more than once for '%s'\n",
- tests[cnt].name);
- result = 1;
- continue;
- }
- printf ("early cancel test of '%s' successful\n", tests[cnt].name);
- if (tempfd != -1)
- {
- close (tempfd);
- tempfd = -1;
- }
- if (tempfd2 != -1)
- {
- close (tempfd2);
- tempfd2 = -1;
- }
- if (tempfname != NULL)
- {
- unlink (tempfname);
- free (tempfname);
- tempfname = NULL;
- }
- if (tempmsg != -1)
- {
- msgctl (tempmsg, IPC_RMID, NULL);
- tempmsg = -1;
- }
- }
- return result;
- }
- #define TIMEOUT 60
- #define TEST_FUNCTION do_test ()
- #include "../test-skeleton.c"
|