2013-12-10 91 views
4

我想使用fork()來產生我的程序中的新進程。新進程只有一項任務:將鼠標輸入重定向到串行端口。我已經在終端窗口中成功測試了以下命令:hexdump/dev/input/mice>/dev/ttyS0使用fork()和execl()輸出重定向

到目前爲止,我設法使用fork來創建子進程,但是我的問題是我似乎無法讓我的EXECL()方法才能正常工作:

execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice > /dev/ttyS0", (char*) NULL); 

我已經試過其他變體也,就像這樣:

execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice", ">", "/dev/ttyS0", (char*) NULL); 

但總是以相同的結果,出口值1(一般錯誤)。

還值得一提的是,我已經設法使用popen()方法工作,您可以在其中完全按照您在終端中所做的那樣鍵入命令。 popen()的問題是我沒有找到終止這個過程的好方法。 叉()我得到的PID,並可以通過終止進程:

kill(pid, SIGKILL); 

這是一個要求,因爲我必須能夠停止和重新啓動輸出重定向爲所需的程序運行時。

回答

8

您不能以這種方式執行重定向。

如果要將stdout重定向到一個進程exec,則需要將open路徑和dup2轉換爲適當的文件描述符。

實施例:

if (!(pid = fork()) 
{ 
    int fd = open("/dev/ttyS0", O_WRONLY); 
    dup2(fd, 1); // redirect stdout 
    execl("/usr/bin/hexdump", "hexdump", "/dev/input/mice", NULL); 
} 
+0

就像一個魅力。非常感謝你!只是一個簡短的問題:在殺死進程之前是否需要關閉文件描述符,還是在進程被終止時自動關閉? – Hippo

+0

當孩子死亡時,向孩子開放的文件描述符會關閉,就像任何進程一樣。如果你注意到上面的內容,我會在'if'的主體中打開'/ dev/ttyS0',這樣只有孩子有'/ dev/ttyS0'的打開文件描述符。所以,當你殺死孩子時,該fd關閉。 –

1

這個問題似乎是 「>」 的說法。這個符號是特定於shell(在你的情況下是bash或破折號)。但execl()調用不會調用shell並傳遞參數給hexdump

作爲一種可能的解決方案,我可以建議使用system()通話

system("hexdump /dev/input/mice > /dev/ttyS0")

這將模擬命令行實驗的行爲。

而且讓你的進程的PID,你可以繼續做fork(),只需調用system()代替execl()

+0

這可能也會起作用,但使用exec()更安全嗎?如所建議的[這裏](http://stackoverflow.com/questions/14830611/to-system-or-fork-exec)? – Hippo

+1

當然不是 - exec()不會因爲「>」參數而做這個工作。你確實需要這個shell。或者在接受的答案中使用dup2()。 – LiMar

+0

是的,我明白了。感謝您指出「>」不在exec()調用中的問題。 – Hippo