使用pipe()时,可以退出叉()
我正在重新创建一个完整的外壳。为此,我必须模拟“ |”。为此,我必须使用dup2(),fork()和pipe()函数。
我最成功的代码是:
int exec_pipe(global *glob, char *commande)
{
int pipefd[2];
char **pipe_commandes = my_split(commande, '|');
char **left = my_str_to_word_array(pipe_commandes[0]);
char **right = my_str_to_word_array(pipe_commandes[1]);
int pid = 0;
int status;
pipe(pipefd);
pid = fork();
if (pid == 0) {
close(pipefd[1]);
dup2(pipefd[0], 0);
close(pipefd[0]);
glob->commande = right;
distribe_commande(glob);
glob->commande = NULL;
} else {
close(pipefd[0]);
dup2(pipefd[1], 1);
close(pipefd[1]);
glob->commande = left;
distribe_commande(glob);
glob->commande = NULL;
}
}
函数distribe_commande()导致命令的格式,以便在此函数中使用execve()执行
void exec_path_commande(char *path, global *glob)
{
int pid;
int status;
pid = fork();
if (pid == 0) {
dup2(glob->fd, glob->origine);
if (execve(path, glob->commande, glob->env) == -1)
exit(0);
} else
while (waitpid(pid, &status, 0) != -1 && !WIFEXITED(status))
error_execve(status);
}
char *path *path *path
是正确的格式命令。
我的问题是,当我发送命令ls |时cat -e
命令工作:
$~> ls | cat -e
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
但是,如果我将另一个命令发送到程序| cat -e
效果即使在提示下仍保持效果,我也不明白为什么:
$~> ls | cat -e
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
^[[0;31m^[[1m$^[[0;36m^[[1m~^[[0;32m^[[1m> ^[[0;37m^[[0mls
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
^[[0;31m^[[1m$^[[0;36m^[[1m~^[[0;32m^[[1m> ^[[0;37m^[[0m
谢谢您的答案。
I am recreating a complete shell. For that I must simulate "|". To do this, I have to use the dup2(), fork() and pipe() functions.
The code I've had the most success with is this:
int exec_pipe(global *glob, char *commande)
{
int pipefd[2];
char **pipe_commandes = my_split(commande, '|');
char **left = my_str_to_word_array(pipe_commandes[0]);
char **right = my_str_to_word_array(pipe_commandes[1]);
int pid = 0;
int status;
pipe(pipefd);
pid = fork();
if (pid == 0) {
close(pipefd[1]);
dup2(pipefd[0], 0);
close(pipefd[0]);
glob->commande = right;
distribe_commande(glob);
glob->commande = NULL;
} else {
close(pipefd[0]);
dup2(pipefd[1], 1);
close(pipefd[1]);
glob->commande = left;
distribe_commande(glob);
glob->commande = NULL;
}
}
The function distribe_commande() leads to a formatting of the command so that it is executed with execve() in this function:
void exec_path_commande(char *path, global *glob)
{
int pid;
int status;
pid = fork();
if (pid == 0) {
dup2(glob->fd, glob->origine);
if (execve(path, glob->commande, glob->env) == -1)
exit(0);
} else
while (waitpid(pid, &status, 0) != -1 && !WIFEXITED(status))
error_execve(status);
}
Where char *path
is the correct formated command.
My probleme is that when I send the commande ls | cat -e
the command work :
$~> ls | cat -e
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
But if I send another command to the programme the | cat -e
effect remain even on the prompt and I don't understand why:
$~> ls | cat -e
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
^[[0;31m^[[1m$^[[0;36m^[[1m~^[[0;32m^[[1m> ^[[0;37m^[[0mls
^[[0$
42sh$
build$
CMakeLists.txt$
hello$
include$
Jenkinsfile$
lib$
main.c$
Makefile$
src$
^[[0;31m^[[1m$^[[0;36m^[[1m~^[[0;32m^[[1m> ^[[0;37m^[[0m
Thanks in advance for your answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在错误的地方进行
dup2
。您也有一个fork
太多。a 重定向应该看起来像这样(概述/伪代码,而不是真实的C代码):
注意,
dup2
andclose
在fork之后
和exec
之前。A Pipeline 是通过管道协调的两个(或更多)重定向,因此:
请注意,这两个
wait
s均在两个exec
s之后。如果您以另一种方式(exec-wait-exec等)进行操作,则命令是yes |头
将行不通。因此,您需要重构
exec_path_commande
很多。You are doing
dup2
in a wrong place. You also have onefork
too many.A redirect should look like this (outline/pseudocode, not real C code):
Note,
dup2
andclose
are after thefork
and before theexec
.A pipeline is two (or more) redirects coordinated via a pipe, so:
Note also both
wait
s are after bothexec
s. If you do it the other way (exec-wait-exec-wait), commands likeyes | head
will not work.So you need to refactor
exec_path_commande
quite a bit.