readline hangs on manual pipe()
up vote
3
down vote
favorite
I'm trying to dispel the magic fork variant of open:
# magic-fork.pl
if (open my $fh, '-|') { # fork self, make new fd for reading, attach child STDOUT to it
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $fh->fileno: ', $fh->fileno);
while (my $line = $fh->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
STDOUT->say('child getpid: ', $$);
STDOUT->say('child STDOUT->fileno: ', STDOUT->fileno);
}
It runs and finishes.
# plain-fork.pl
pipe my $r, my $w;
if (fork) {
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $r->fileno: ', $r->fileno);
STDOUT->say('parent $w->fileno: ', $w->fileno);
while (my $line = $r->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
$w->say('child getpid: ', $$);
$w->say('child $r->fileno: ', $r->fileno);
$w->say('child $w->fileno: ', $w->fileno);
$w->say('child STDOUT->fileno: ', STDOUT->fileno);
}
This program unexpectedly hangs in the loop.
I tried to no avail:
- calling $w->autoflush(1)
- explicit close on handles
- explicit exit
- POSIX::dup2 $w onto STDOUT
- checking strace -ff to see whether I missed a crucial syscall
What's the problem?
perl posix
add a comment |
up vote
3
down vote
favorite
I'm trying to dispel the magic fork variant of open:
# magic-fork.pl
if (open my $fh, '-|') { # fork self, make new fd for reading, attach child STDOUT to it
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $fh->fileno: ', $fh->fileno);
while (my $line = $fh->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
STDOUT->say('child getpid: ', $$);
STDOUT->say('child STDOUT->fileno: ', STDOUT->fileno);
}
It runs and finishes.
# plain-fork.pl
pipe my $r, my $w;
if (fork) {
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $r->fileno: ', $r->fileno);
STDOUT->say('parent $w->fileno: ', $w->fileno);
while (my $line = $r->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
$w->say('child getpid: ', $$);
$w->say('child $r->fileno: ', $r->fileno);
$w->say('child $w->fileno: ', $w->fileno);
$w->say('child STDOUT->fileno: ', STDOUT->fileno);
}
This program unexpectedly hangs in the loop.
I tried to no avail:
- calling $w->autoflush(1)
- explicit close on handles
- explicit exit
- POSIX::dup2 $w onto STDOUT
- checking strace -ff to see whether I missed a crucial syscall
What's the problem?
perl posix
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I'm trying to dispel the magic fork variant of open:
# magic-fork.pl
if (open my $fh, '-|') { # fork self, make new fd for reading, attach child STDOUT to it
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $fh->fileno: ', $fh->fileno);
while (my $line = $fh->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
STDOUT->say('child getpid: ', $$);
STDOUT->say('child STDOUT->fileno: ', STDOUT->fileno);
}
It runs and finishes.
# plain-fork.pl
pipe my $r, my $w;
if (fork) {
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $r->fileno: ', $r->fileno);
STDOUT->say('parent $w->fileno: ', $w->fileno);
while (my $line = $r->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
$w->say('child getpid: ', $$);
$w->say('child $r->fileno: ', $r->fileno);
$w->say('child $w->fileno: ', $w->fileno);
$w->say('child STDOUT->fileno: ', STDOUT->fileno);
}
This program unexpectedly hangs in the loop.
I tried to no avail:
- calling $w->autoflush(1)
- explicit close on handles
- explicit exit
- POSIX::dup2 $w onto STDOUT
- checking strace -ff to see whether I missed a crucial syscall
What's the problem?
perl posix
I'm trying to dispel the magic fork variant of open:
# magic-fork.pl
if (open my $fh, '-|') { # fork self, make new fd for reading, attach child STDOUT to it
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $fh->fileno: ', $fh->fileno);
while (my $line = $fh->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
STDOUT->say('child getpid: ', $$);
STDOUT->say('child STDOUT->fileno: ', STDOUT->fileno);
}
It runs and finishes.
# plain-fork.pl
pipe my $r, my $w;
if (fork) {
STDOUT->say('parent getpid: ', $$);
STDOUT->say('parent STDOUT->fileno: ', STDOUT->fileno);
STDOUT->say('parent $r->fileno: ', $r->fileno);
STDOUT->say('parent $w->fileno: ', $w->fileno);
while (my $line = $r->getline) {
STDOUT->print('parent readline from child: ', $line);
}
} else {
$w->say('child getpid: ', $$);
$w->say('child $r->fileno: ', $r->fileno);
$w->say('child $w->fileno: ', $w->fileno);
$w->say('child STDOUT->fileno: ', STDOUT->fileno);
}
This program unexpectedly hangs in the loop.
I tried to no avail:
- calling $w->autoflush(1)
- explicit close on handles
- explicit exit
- POSIX::dup2 $w onto STDOUT
- checking strace -ff to see whether I missed a crucial syscall
What's the problem?
perl posix
perl posix
asked 2 days ago
daxim
35.8k449112
35.8k449112
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago
add a comment |
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
You pipe
before fork
ing (Like usual for this sort of IPC), so both processes have open copies of both the read and write file descriptors, so the read loop in the parent will just block waiting for more input which never comes from the still-open write end.
The child process needs to close $r;
, the parent process needs to close $w;
at the start of their respective blocks (Or after you print out the file descriptors for those handles).
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
You pipe
before fork
ing (Like usual for this sort of IPC), so both processes have open copies of both the read and write file descriptors, so the read loop in the parent will just block waiting for more input which never comes from the still-open write end.
The child process needs to close $r;
, the parent process needs to close $w;
at the start of their respective blocks (Or after you print out the file descriptors for those handles).
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
add a comment |
up vote
3
down vote
accepted
You pipe
before fork
ing (Like usual for this sort of IPC), so both processes have open copies of both the read and write file descriptors, so the read loop in the parent will just block waiting for more input which never comes from the still-open write end.
The child process needs to close $r;
, the parent process needs to close $w;
at the start of their respective blocks (Or after you print out the file descriptors for those handles).
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
You pipe
before fork
ing (Like usual for this sort of IPC), so both processes have open copies of both the read and write file descriptors, so the read loop in the parent will just block waiting for more input which never comes from the still-open write end.
The child process needs to close $r;
, the parent process needs to close $w;
at the start of their respective blocks (Or after you print out the file descriptors for those handles).
You pipe
before fork
ing (Like usual for this sort of IPC), so both processes have open copies of both the read and write file descriptors, so the read loop in the parent will just block waiting for more input which never comes from the still-open write end.
The child process needs to close $r;
, the parent process needs to close $w;
at the start of their respective blocks (Or after you print out the file descriptors for those handles).
answered 2 days ago
Shawn
3,0441513
3,0441513
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
add a comment |
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
Key piece of missing info: The pipe will only return EOF once there are no open handles to the write end of the pipe.
– ikegami
22 hours ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372637%2freadline-hangs-on-manual-pipe%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I believe Shawn's answer is correct; reading continues to block because the pipe is still open for writing (by the parent). But you do say you tried explicitly closing handles; did you try closing the write handle in the parent (before the getline)?
– ysth
2 days ago