Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!VAX1.CC.UAKRON.EDU!math-cs.kent.edu!news From: gorpong@math-cs.kent.edu (Gordon C. Galligher) Newsgroups: comp.lang.perl Subject: Perl 3.0 PL28 problems with pipe() Keywords: Pipe call is a problem Message-ID: <1990Sep4.205514.13088@math-cs.kent.edu> Date: 4 Sep 90 20:55:14 GMT Organization: Kent State University Lines: 100 There is some synchronization problems when dealing with pipes via the pipe() call in Perl. Below are code examples first in PERL and then one in C. The one in C works just like you would expect: IN THE PARENT: PID == ... IN THE CHILD: PID == 0 CHILD-SEND: 25 PARENT REC'd <25> PARENT-SEND: 255 CHILD REC'd <255> The Perl example, on the other hand, does this: IN THE CHILD: PID == 0 CHILD-SEND: 25 IN THE PARENT: PID == ... And just sits there. I do get some output when I change the $val = calls below to read() calls, but I need to know exactly how many bytes are coming down the pipe in order to not hang. What is so drastically different between the C program and Perl that makes it not work? Any help would be greatly appreciated. Is there a way to specially treat descriptors created with pipe() to be non-buffered? (I even tried $| = 1 on a read descriptor, and it had no effect (but it did not fail).) In order to totally emulate the effect of C, I would need to pack a variable with an integer, and force that down the pipe first, and then unpack it to get the number of bytes coming, and so on. That is a lot of work. Granted, if it needs to be done, it needs to be done, but it would make me think twice before choosing Perl as the tool to use. -- Gordon. =========================snip here--PERL--==================================== pipe(DESC1_0, DESC1_1); pipe(DESC2_0, DESC2_1); $id = fork(); $| = 1; if ( $id == 0 ) { sleep(1); close(DESC1_0); close(DESC2_1); select(DESC1_1); $| = 1; select(STDOUT); print "IN THE CHILD: PID == $id\n"; $mval = 25; print "CHILD-SEND: $mval\n"; print DESC1_1 $mval; $mval = ; print "CHILD REC'd <$mval>\n"; exit(0); } else { close(DESC1_1); close(DESC2_0); select(DESC2_1); $| = 1; select(STDOUT); print "IN THE PARENT: PID == $id\n"; $val = ; print "PARENT REC'd <$val>\n"; $val = 255; print "PARENT-SEND: $val\n"; print DESC2_1 $val; exit(0); } =========================snip here--C--======================================= #include main() { int desc1[2], desc2[2]; int pid, msg1, msg2; char buf[256]; pipe(desc1); pipe(desc2); switch(pid = fork()) { case 0: close(desc1[0]); close(desc2[1]); printf("IN THE CHILD: PID == %d\n", pid); msg1 = 25; printf("CHILD-SEND: %d\n", msg1); write(desc1[1], & msg1, sizeof(int)); read(desc2[0], & msg2, sizeof(int)); printf("CHILD REC'd <%d>\n", msg2); exit(0); default: close(desc1[1]); close(desc2[0]); printf("IN THE PARENT: PID == %d\n", pid); read(desc1[0], & msg1, sizeof(int)); printf("PARENT REC'd <%d>\n", msg1); msg2 = 255; printf("PARENT-SEND: %d\n", msg2); write(desc2[1], & msg2, sizeof(int)); exit(0); } /* SWITCH */ } /* MAIN */ ===================================done snip==============================