I want to set timeout for a process, this is my shell. I use expect to do it, in order to avoid other packages dependencies.
test.sh
#!/bin/bash
# $1 timeout in seconds
# $2 command
timeout() {
time=$1
shift
# start the command in a subshell to avoid problem with pipes
# (spawn accepts one command) -noecho
command="/bin/sh -c \"$*\""
expect -c "set echo \"-noecho\";set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"
if [ $? = 1 ] ; then
echo "timeout after ${time} seconds"
exit 1
fi
}
timeout 120 ./test
test.c
#include <stdlib.h>
int main() {
sleep(120);
}
And I run a program to fork&exec shell, and I use pipe to catch the shell output.
But I found the facts:
I find shell dup parent pipe to STDOUT, STDERR, this works fine.
lrwx------ 1 root root 64 Sep 13 17:07 0 -> /dev/pts/1
l-wx------ 1 root root 64 Sep 13 17:07 1 -> pipe:[14070157]
l-wx------ 1 root root 64 Sep 13 17:07 2 -> pipe:[14070158]
lr-x------ 1 root root 64 Sep 13 17:07 255 -> /path/to/my/shell
This is expect, it inherits parent (my shell) pipes, and opens 14070167 pipe to catch sleeping program test.c (I guess it pipes child's STDOUT).
lrwx------ 1 root root 64 Sep 13 17:08 0 -> /dev/pts/1
l-wx------ 1 root root 64 Sep 13 17:08 1 -> pipe:[14070157]
l-wx------ 1 root root 64 Sep 13 17:07 2 -> pipe:[14070158]
lr-x------ 1 root root 64 Sep 13 17:08 3 -> pipe:[14070167]
l-wx------ 1 root root 64 Sep 13 17:08 4 -> pipe:[14070167]
lrwx------ 1 root root 64 Sep 13 17:08 5 -> /dev/tty
lrwx------ 1 root root 64 Sep 13 17:08 6 -> /dev/ptmx
But what makes me confused is that test.c does not dup 1 to pipe[140167]. Until now it works fine. ( while, this is not the point causing problem)
But I have a BUG, if the test.c is a daemon program, it gets fd 5 which is pipe 14070158, (this is test.sh STDERR dupped before). And after expect exits. If I poll STDERR for the test.sh, it will block, because the sender port is a daemon program. ( assuming test.c is that daemon program).
lrwx------ 1 root root 64 Sep 13 17:07 0 -> /dev/pts/2
lrwx------ 1 root root 64 Sep 13 17:07 1 -> /dev/pts/2
lrwx------ 1 root root 64 Sep 13 17:07 2 -> /dev/pts/2
lr-x------ 1 root root 64 Sep 13 17:07 3 -> pipe:[14070167]
l-wx------ 1 root root 64 Sep 13 17:07 4 -> pipe:[14070167]
l-wx------ 1 root root 64 Sep 13 17:07 5 -> pipe:[14070158]
My question is how does expect work? Can I let it not give the pipe [14070158] to test.c so that I can fix my BUG?
My expect version is 5.43