clone.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * clone test for uClibc
  4. *
  5. * Copyright (C) 2000 by Lineo, inc. and Erik Andersen
  6. * Copyright (C) 2000-2006 by Erik Andersen <andersen@uclibc.org>
  7. * Written by Erik Andersen <andersen@uclibc.org>
  8. *
  9. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <signal.h>
  15. #include <sched.h>
  16. #include <sys/wait.h>
  17. #include "clone_cruft.h"
  18. #define GOT1 (1 << 1)
  19. #define GOT2 (1 << 2)
  20. #define GOT3 (1 << 3)
  21. #define ALLGOT (GOT1|GOT2|GOT3)
  22. void child_handler(int sig)
  23. {
  24. printf("I got a SIGCHLD\n");
  25. }
  26. int clone_main(void *arg)
  27. {
  28. unsigned long input = (unsigned long)arg;
  29. int secs = (input / 10) * 4;
  30. printf("Clone got %lu, sleeping for %i secs\n", input, secs);
  31. sleep(secs);
  32. return input + 20;
  33. }
  34. int main(void)
  35. {
  36. int clone1, clone2, clone3;
  37. char clone1_stack[8192], clone2_stack[8192], clone3_stack[8192];
  38. int status, nostatus, result, wpid;
  39. signal(SIGCHLD, child_handler);
  40. if ((clone1 = do_clone(clone_main, clone1_stack, 0, (void*)11)) == -1) {
  41. perror("Clone 1 failed");
  42. exit(-1);
  43. }
  44. if ((clone2 = do_clone(clone_main, clone2_stack, 0, (void*)22)) == -1) {
  45. perror("Clone 2 failed");
  46. exit(-2);
  47. }
  48. if ((clone3 = do_clone(clone_main, clone3_stack, 0, (void*)33)) == -1) {
  49. perror("Clone 3 failed");
  50. exit(-3);
  51. }
  52. sleep(1);
  53. printf("Parent: waiting for the clones to die.\n");
  54. nostatus = status = 0;
  55. while (1) {
  56. if ((wpid = waitpid(clone1, &result, WNOHANG|__WCLONE)) == -1)
  57. nostatus |= GOT1;
  58. if (wpid == clone1) {
  59. status |= GOT1;
  60. printf("Clone1 gave back %i\n", WEXITSTATUS(result));
  61. }
  62. if ((wpid = waitpid(clone2, &result, WNOHANG|__WCLONE)) == -1)
  63. nostatus |= GOT2;
  64. if (wpid == clone2) {
  65. status |= GOT2;
  66. printf("Clone2 gave back %i\n", WEXITSTATUS(result));
  67. }
  68. if ((wpid = waitpid(clone3, &result, WNOHANG|__WCLONE)) == -1)
  69. nostatus |= GOT3;
  70. if (wpid == clone3) {
  71. status |= GOT3;
  72. printf("Clone3 gave back %i\n", WEXITSTATUS(result));
  73. }
  74. if (status == ALLGOT || nostatus == ALLGOT)
  75. break;
  76. }
  77. if (status == ALLGOT) {
  78. printf("Clones exited.\nGoodbye.\n");
  79. return EXIT_SUCCESS;
  80. } else {
  81. perror("Waiting for clones failed");
  82. return EXIT_FAILURE;
  83. }
  84. }
  85. /*
  86. Local Variables:
  87. c-file-style: "linux"
  88. c-basic-offset: 4
  89. tab-width: 4
  90. End:
  91. */