Output redirection using fork() and execl()
I want to use fork() to spawn off a new process in my program. The new process will have only one task: To redirect the mouse input to a serial port. I have tested the following command with success in a terminal window: hexdump /dev/input/mice > /dev/ttyS0
So far I have managed to use fork to create a child process, but my problem is that I can't seem to get my execl() method to work properly:
execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice > /dev/ttyS0", (char*) NULL);
I have tried other variants also, like this:
execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice", ">", "/dev/ttyS0", (char*) NULL);
But always with the same result, an exit value of 1 (general error).
It's also worth mentioning that I have managed to make it work by using the popen() method, where you can type the command exactly like you would have done in a terminal. The problem with popen() is that I have not found a good way for terminating the process. With fork() I get the PID, and can terminate the process by using:
kill(pid, SIGKILL);
This is a requirement, as I have to be able to stop and restart the output redirection as desired while the program is running.
Solution 1:
You cannot perform redirection in this way.
If you want to redirect stdout
for a process you're about to exec
, you need to open
the path and dup2
it onto the appropriate file descriptor.
Example:
if (!(pid = fork())
{
int fd = open("/dev/ttyS0", O_WRONLY);
dup2(fd, 1); // redirect stdout
execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice", NULL);
}
Solution 2:
The problem seems to be the ">" argument. This symbol is specific to the shell (bash or dash in your case). But execl()
call does not invoke the shell and passes the arguments to the hexdump
As a possible solution I can propose using of system()
call
Like system("hexdump /dev/input/mice > /dev/ttyS0")
This will simulate the behaviour of your command line experiment.
And to get the pid of your process you can continue doing fork()
, just call the system()
in place of execl()