run-read_all.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* FIXME: Do something tricky to ensure we really do loop in read_all. */
  2. #include <ccan/read_write_all/read_write_all.h>
  3. #include <ccan/read_write_all/read_write_all.c>
  4. #include <ccan/tap/tap.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <signal.h>
  8. #include <sys/wait.h>
  9. #include <limits.h>
  10. #include <err.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. static volatile int sigcount;
  14. static int p2c[2], c2p[2];
  15. static void got_signal(int sig)
  16. {
  17. char c = 0;
  18. (void)sig;
  19. if (write(p2c[1], &c, 1) == 1)
  20. sigcount++;
  21. }
  22. /* < PIPE_BUF *will* be atomic. But > PIPE_BUF only *might* be non-atomic. */
  23. #define BUFSZ (1024*1024)
  24. int main(void)
  25. {
  26. char *buffer;
  27. char c = 0;
  28. int status;
  29. pid_t child;
  30. buffer = calloc(BUFSZ, 2);
  31. plan_tests(6);
  32. /* We fork and torture parent. */
  33. if (pipe(p2c) != 0 || pipe(c2p) != 0)
  34. err(1, "pipe");
  35. child = fork();
  36. if (!child) {
  37. close(p2c[1]);
  38. close(c2p[0]);
  39. /* Child. Make sure parent ready, then write in two parts. */
  40. if (read(p2c[0], &c, 1) != 1)
  41. exit(1);
  42. memset(buffer, 0xff, BUFSZ*2);
  43. if (!write_all(c2p[1], buffer, BUFSZ))
  44. exit(2);
  45. if (kill(getppid(), SIGUSR1) != 0)
  46. exit(3);
  47. /* Make sure they get signal. */
  48. if (read(p2c[0], &c, 1) != 1)
  49. exit(4);
  50. if (write(c2p[1], buffer, BUFSZ) != BUFSZ)
  51. exit(5);
  52. exit(0);
  53. }
  54. if (child == -1)
  55. err(1, "forking");
  56. close(p2c[0]);
  57. close(c2p[1]);
  58. signal(SIGUSR1, got_signal);
  59. ok1(write(p2c[1], &c, 1) == 1);
  60. ok1(read_all(c2p[0], buffer, BUFSZ*2));
  61. ok1(memchr(buffer, 0, BUFSZ*2) == NULL);
  62. ok1(sigcount == 1);
  63. ok1(wait(&status) == child);
  64. ok(WIFEXITED(status) && WEXITSTATUS(status) == 0,
  65. "WIFEXITED(status) = %u, WEXITSTATUS(status) = %u",
  66. WIFEXITED(status), WEXITSTATUS(status));
  67. free(buffer);
  68. return exit_status();
  69. }