tst-cancel7.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <errno.h>
  16. #include <fcntl.h>
  17. #include <pthread.h>
  18. #include <signal.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. const char *command;
  24. const char *pidfile;
  25. char pidfilename[] = "/tmp/tst-cancel7-XXXXXX";
  26. static void *
  27. tf (void *arg)
  28. {
  29. const char *args = " --direct --pidfile ";
  30. char *cmd = alloca (strlen (command) + strlen (args)
  31. + strlen (pidfilename) + 1);
  32. strcpy (stpcpy (stpcpy (cmd, command), args), pidfilename);
  33. system (cmd);
  34. /* This call should never return. */
  35. return NULL;
  36. }
  37. static void
  38. sl (void)
  39. {
  40. FILE *f = fopen (pidfile, "w");
  41. if (f == NULL)
  42. exit (1);
  43. fprintf (f, "%lld\n", (long long) getpid ());
  44. fflush (f);
  45. struct flock fl =
  46. {
  47. .l_type = F_WRLCK,
  48. .l_start = 0,
  49. .l_whence = SEEK_SET,
  50. .l_len = 1
  51. };
  52. if (fcntl (fileno (f), F_SETLK, &fl) != 0)
  53. exit (1);
  54. sigset_t ss;
  55. sigfillset (&ss);
  56. sigsuspend (&ss);
  57. exit (0);
  58. }
  59. static void
  60. do_prepare (int argc, char *argv[])
  61. {
  62. if (command == NULL)
  63. command = argv[0];
  64. if (pidfile)
  65. sl ();
  66. int fd = mkstemp (pidfilename);
  67. if (fd == -1)
  68. {
  69. puts ("mkstemp failed");
  70. exit (1);
  71. }
  72. write (fd, " ", 1);
  73. close (fd);
  74. }
  75. static int
  76. do_test (void)
  77. {
  78. pthread_t th;
  79. if (pthread_create (&th, NULL, tf, NULL) != 0)
  80. {
  81. puts ("pthread_create failed");
  82. return 1;
  83. }
  84. do
  85. sleep (1);
  86. while (access (pidfilename, R_OK) != 0);
  87. if (pthread_cancel (th) != 0)
  88. {
  89. puts ("pthread_cancel failed");
  90. return 1;
  91. }
  92. void *r;
  93. if (pthread_join (th, &r) != 0)
  94. {
  95. puts ("pthread_join failed");
  96. return 1;
  97. }
  98. sleep (1);
  99. FILE *f = fopen (pidfilename, "r+");
  100. if (f == NULL)
  101. {
  102. puts ("no pidfile");
  103. return 1;
  104. }
  105. long long ll;
  106. if (fscanf (f, "%lld\n", &ll) != 1)
  107. {
  108. puts ("could not read pid");
  109. unlink (pidfilename);
  110. return 1;
  111. }
  112. struct flock fl =
  113. {
  114. .l_type = F_WRLCK,
  115. .l_start = 0,
  116. .l_whence = SEEK_SET,
  117. .l_len = 1
  118. };
  119. if (fcntl (fileno (f), F_GETLK, &fl) != 0)
  120. {
  121. puts ("F_GETLK failed");
  122. unlink (pidfilename);
  123. return 1;
  124. }
  125. if (fl.l_type != F_UNLCK)
  126. {
  127. printf ("child %lld still running\n", (long long) fl.l_pid);
  128. if (fl.l_pid == ll)
  129. kill (fl.l_pid, SIGKILL);
  130. unlink (pidfilename);
  131. return 1;
  132. }
  133. fclose (f);
  134. unlink (pidfilename);
  135. return r != PTHREAD_CANCELED;
  136. }
  137. #if 0 /* unused */
  138. static void
  139. do_cleanup (void)
  140. {
  141. FILE *f = fopen (pidfilename, "r+");
  142. long long ll;
  143. if (f != NULL && fscanf (f, "%lld\n", &ll) == 1)
  144. {
  145. struct flock fl =
  146. {
  147. .l_type = F_WRLCK,
  148. .l_start = 0,
  149. .l_whence = SEEK_SET,
  150. .l_len = 1
  151. };
  152. if (fcntl (fileno (f), F_GETLK, &fl) == 0 && fl.l_type != F_UNLCK
  153. && fl.l_pid == ll)
  154. kill (fl.l_pid, SIGKILL);
  155. fclose (f);
  156. }
  157. unlink (pidfilename);
  158. }
  159. #endif
  160. #define OPT_COMMAND 10000
  161. #define OPT_PIDFILE 10001
  162. #define CMDLINE_OPTIONS \
  163. "c:p:"
  164. /*
  165. { "command", required_argument, NULL, OPT_COMMAND }, \
  166. { "pidfile", required_argument, NULL, OPT_PIDFILE },
  167. */
  168. #define CMDLINE_PROCESS \
  169. case 'c': \
  170. command = optarg; \
  171. break; \
  172. case 'p': \
  173. pidfile = optarg; \
  174. break;
  175. // #define CLEANUP_HANDLER do_cleanup ()
  176. #define PREPARE(argc, argv) do_prepare (argc, argv)
  177. #define TEST_FUNCTION do_test ()
  178. #define TIMEOUT 5
  179. #include "../test-skeleton.c"