PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/t/io/pipe.t

https://github.com/schacon/perl
Perl | 243 lines | 215 code | 17 blank | 11 comment | 11 complexity | bf07748bf96c9d92ce6d4b74b0e101dc MD5 | raw file
Possible License(s): AGPL-1.0
  1. #!./perl
  2. BEGIN {
  3. chdir 't' if -d 't';
  4. @INC = '../lib';
  5. require Config; import Config;
  6. require './test.pl';
  7. if (!$Config{'d_fork'}) {
  8. skip_all("fork required to pipe");
  9. }
  10. else {
  11. plan(tests => 24);
  12. }
  13. }
  14. my $Perl = which_perl();
  15. $| = 1;
  16. open(PIPE, "|-") || exec $Perl, '-pe', 'tr/YX/ko/';
  17. printf PIPE "Xk %d - open |- || exec\n", curr_test();
  18. next_test();
  19. printf PIPE "oY %d - again\n", curr_test();
  20. next_test();
  21. close PIPE;
  22. SKIP: {
  23. # Technically this should be TODO. Someone try it if you happen to
  24. # have a vmesa machine.
  25. skip "Doesn't work here yet", 6 if $^O eq 'vmesa';
  26. if (open(PIPE, "-|")) {
  27. while(<PIPE>) {
  28. s/^not //;
  29. print;
  30. }
  31. close PIPE; # avoid zombies
  32. }
  33. else {
  34. printf STDOUT "not ok %d - open -|\n", curr_test();
  35. next_test();
  36. my $tnum = curr_test;
  37. next_test();
  38. exec $Perl, '-le', "print q{not ok $tnum - again}";
  39. }
  40. # This has to be *outside* the fork
  41. next_test() for 1..2;
  42. my $raw = "abc\nrst\rxyz\r\nfoo\n";
  43. if (open(PIPE, "-|")) {
  44. $_ = join '', <PIPE>;
  45. (my $raw1 = $_) =~ s/not ok \d+ - //;
  46. my @r = map ord, split //, $raw;
  47. my @r1 = map ord, split //, $raw1;
  48. if ($raw1 eq $raw) {
  49. s/^not (ok \d+ -) .*/$1 '@r1' passes through '-|'\n/s;
  50. } else {
  51. s/^(not ok \d+ -) .*/$1 expect '@r', got '@r1'\n/s;
  52. }
  53. print;
  54. close PIPE; # avoid zombies
  55. }
  56. else {
  57. printf STDOUT "not ok %d - $raw", curr_test();
  58. exec $Perl, '-e0'; # Do not run END()...
  59. }
  60. # This has to be *outside* the fork
  61. next_test();
  62. if (open(PIPE, "|-")) {
  63. printf PIPE "not ok %d - $raw", curr_test();
  64. close PIPE; # avoid zombies
  65. }
  66. else {
  67. $_ = join '', <STDIN>;
  68. (my $raw1 = $_) =~ s/not ok \d+ - //;
  69. my @r = map ord, split //, $raw;
  70. my @r1 = map ord, split //, $raw1;
  71. if ($raw1 eq $raw) {
  72. s/^not (ok \d+ -) .*/$1 '@r1' passes through '|-'\n/s;
  73. } else {
  74. s/^(not ok \d+ -) .*/$1 expect '@r', got '@r1'\n/s;
  75. }
  76. print;
  77. exec $Perl, '-e0'; # Do not run END()...
  78. }
  79. # This has to be *outside* the fork
  80. next_test();
  81. SKIP: {
  82. skip "fork required", 2 unless $Config{d_fork};
  83. pipe(READER,WRITER) || die "Can't open pipe";
  84. if ($pid = fork) {
  85. close WRITER;
  86. while(<READER>) {
  87. s/^not //;
  88. y/A-Z/a-z/;
  89. print;
  90. }
  91. close READER; # avoid zombies
  92. }
  93. else {
  94. die "Couldn't fork" unless defined $pid;
  95. close READER;
  96. printf WRITER "not ok %d - pipe & fork\n", curr_test;
  97. next_test;
  98. open(STDOUT,">&WRITER") || die "Can't dup WRITER to STDOUT";
  99. close WRITER;
  100. my $tnum = curr_test;
  101. next_test;
  102. exec $Perl, '-le', "print q{not ok $tnum - with fh dup }";
  103. }
  104. # This has to be done *outside* the fork.
  105. next_test() for 1..2;
  106. }
  107. }
  108. wait; # Collect from $pid
  109. pipe(READER,WRITER) || die "Can't open pipe";
  110. close READER;
  111. $SIG{'PIPE'} = 'broken_pipe';
  112. sub broken_pipe {
  113. $SIG{'PIPE'} = 'IGNORE'; # loop preventer
  114. printf "ok %d - SIGPIPE\n", curr_test;
  115. }
  116. printf WRITER "not ok %d - SIGPIPE\n", curr_test;
  117. close WRITER;
  118. sleep 1;
  119. next_test;
  120. pass();
  121. # VMS doesn't like spawning subprocesses that are still connected to
  122. # STDOUT. Someone should modify these tests to work with VMS.
  123. SKIP: {
  124. skip "doesn't like spawning subprocesses that are still connected", 10
  125. if $^O eq 'VMS';
  126. SKIP: {
  127. # Sfio doesn't report failure when closing a broken pipe
  128. # that has pending output. Go figure. MachTen doesn't either,
  129. # but won't write to broken pipes, so nothing's pending at close.
  130. # BeOS will not write to broken pipes, either.
  131. # Nor does POSIX-BC.
  132. skip "Won't report failure on broken pipe", 1
  133. if $Config{d_sfio} || $^O eq 'machten' || $^O eq 'beos' ||
  134. $^O eq 'posix-bc';
  135. local $SIG{PIPE} = 'IGNORE';
  136. open NIL, qq{|$Perl -e "exit 0"} or die "open failed: $!";
  137. sleep 5;
  138. if (print NIL 'foo') {
  139. # If print was allowed we had better get an error on close
  140. ok( !close NIL, 'close error on broken pipe' );
  141. }
  142. else {
  143. ok(close NIL, 'print failed on broken pipe');
  144. }
  145. }
  146. SKIP: {
  147. skip "Don't work yet", 9 if $^O eq 'vmesa';
  148. # check that errno gets forced to 0 if the piped program exited
  149. # non-zero
  150. open NIL, qq{|$Perl -e "exit 23";} or die "fork failed: $!";
  151. $! = 1;
  152. ok(!close NIL, 'close failure on non-zero piped exit');
  153. is($!, '', ' errno');
  154. isnt($?, 0, ' status');
  155. SKIP: {
  156. skip "Don't work yet", 6 if $^O eq 'mpeix';
  157. # check that status for the correct process is collected
  158. my $zombie;
  159. unless( $zombie = fork ) {
  160. $NO_ENDING=1;
  161. exit 37;
  162. }
  163. my $pipe = open *FH, "sleep 2;exit 13|" or die "Open: $!\n";
  164. $SIG{ALRM} = sub { return };
  165. alarm(1);
  166. is( close FH, '', 'close failure for... umm, something' );
  167. is( $?, 13*256, ' status' );
  168. is( $!, '', ' errno');
  169. my $wait = wait;
  170. is( $?, 37*256, 'status correct after wait' );
  171. is( $wait, $zombie, ' wait pid' );
  172. is( $!, '', ' errno');
  173. }
  174. }
  175. }
  176. # Test new semantics for missing command in piped open
  177. # 19990114 M-J. Dominus mjd@plover.com
  178. { local *P;
  179. no warnings 'pipe';
  180. ok( !open(P, "| "), 'missing command in piped open input' );
  181. ok( !open(P, " |"), ' output');
  182. }
  183. # check that status is unaffected by implicit close
  184. {
  185. local(*NIL);
  186. open NIL, qq{|$Perl -e "exit 23"} or die "fork failed: $!";
  187. $? = 42;
  188. # NIL implicitly closed here
  189. }
  190. is($?, 42, 'status unaffected by implicit close');
  191. $? = 0;
  192. # check that child is reaped if the piped program can't be executed
  193. SKIP: {
  194. skip "/no_such_process exists", 1 if -e "/no_such_process";
  195. open NIL, '/no_such_process |';
  196. close NIL;
  197. my $child = 0;
  198. eval {
  199. local $SIG{ALRM} = sub { die; };
  200. alarm 2;
  201. $child = wait;
  202. alarm 0;
  203. };
  204. is($child, -1, 'child reaped if piped program cannot be executed');
  205. }