- I've a program which
popen()
to another and alsodup()
stdout - When called from another process (like the PHP example) or via SSH, the process does not exit.
process_test.c
:
#include <stdio.h>
#include <unistd.h>
int main() {
int out;
out = dup(STDOUT_FILENO);
// close(out);
popen("sleep 10\0", "r");
}
Compile with gcc process_test.c
, run with:
./a.out
-> exits normallyruby -e 'system("./a.out");'
-> exits normallyphp -r passthry("./a.out");
-> hangsssh remotehost ./a.out
-> hangs- when I don't
dup
stdout or close the dup, it doesn't hang
This is the shortest reproducible code I could find which shows me a behavior I'd like to better understand.
It took hours to extract this from multiple PHP applications/frameworks using fork/pcntl/etc. to instrument their relations, i.e. I didn't wrote this or made this up; but obviously the whole sense of it got lost due me stripping everything apart.
Questions
- Why do some invocations hang (php, ssh) and other not (ruby) ?
- Even when I close the fd after the popen, my program hangs; why?
Because when calling the program via ssh a dup on stdoud is made by ssh, so when ssh try to end it cannot because the stdout has also another channel opened.
I try to give you a better answer: stdout is the channel number 1 if i remember correctly. Making the dup we have also the new channel 3 that is pointing to stdout. When ssh try to close the channel 2 togheter to channel 0 and 2 (stdinput and stderr) ssh cannot close itself because there is another resource that occupies the channel 3 or better the stdout.
I hope that's enough clear gaetano
If I run your demo as it is and I get errno = 15 or it could be 16 as described at the end of this answer. But, if I run it in different way:
I don't get any more the error. To check the error under bash I use: echo $?
That means you have to realease all allocated resources before to exit the c program.
I hope that's all.
Best reagards gaetano