I want to make an example application with libev
. I want to have a watcher on keyboard input that will parse several commands like "start" "stop" "exit". On "start" I want to create a pipe and fork the application to start some worker(like ffmpeg
with exec()
or just some loop that prints some characters) in a child and set a watcher on this pipe in a parent to print output to console. On "stop" command I want to kill a child and remove a watcher.
I have implemented this program but after the fork I always get segfault on keyboard input when the child is running.
At first I thought that because if STDIN
can be shared between child and parent. I've tried to detach child, close STDIN
in child. Then I tried dup
STDIN
and close the default STDIN
in parent at the beginning and set a watcher on duplicated STDIN
. I also tried to close STDOUT/ERR
descriptors before forking and restore them in the parent after the fork.
I stopped and start user_input
watcher in user_input
callback in case this could help.
Then I tried to execute ev_default_fork()
and ev_loop_fork()
in a child (this is not necessary because I want to exec()
just after the fork or in any case the child loop never get a control) with no success.
I also tried to use different back-ends (select
instead of epoll
).
Also I tried to ignore some signals like SIGHUP
SIGPIPE
SIGCHILD
.
I noticed also that my input after the fork()
causes segfault and bash get it as a command so if I do something like this (With ">" I denote self-hand written input and with "<" the program and system output):
> $ ./libev_example
> start
< Debug: fork data got:
< [Data got from child through pipe]
> asd
< Segmentation fault (core dumped)
< $ asd
< bash: asd: command not found...
Then I built libev
from sources and tried to debug. The segfault happens in ev.c:1698
if (expect_false (w_->pending))
pendings [pri][w_->pending - 1].events |= revents;
else
the pri
value is 4 and as I could understand it's a priority. pendings[4]
is 0x0
so the segfault happens. When program doesn't crash code goes in else
branch.
The fd that epoll
returns is 0, but I didn't use 0 as fd in any event. Moreover for 0 there is a watcher in loop->anfds
that has a callback to my user_input
callback. In previous iteration, when I enter any string there was no event for 0. I checked the pipe fds and they are also have a number grater then 0.
I can't figure whats happen here and what I'm doing wrong. I can place here some code, but there is nothing special there. This post is quite big enough so if someone asks for the code I'll post it later.
Thanks.