typedef struct { char** cmd; int in[2]; int out[2];} cmdio;cmdio cmds[MAX_PIPE + 1];
读取管道中的命令并将其存储在cmds中.
cmdio [i] .in是pipe()返回的输入管道的文件描述符对.对于从终端输入读取的第一个命令,它只是{fileno(stdin),– 1}. cmdin [i] .out对输出管道/终端输出类似. cmdio [i] .in与cmd [i-1] .out相同.例如:
$ls -l | sort | wcCMD: ls -l IN: 0 -1OUT: 3 4CMD: sort IN: 3 4OUT: 5 6CMD: wc IN: 5 6OUT: -1 1
我们将每个命令传递给process_command,它执行许多 *** 作:
for (cmdi = 0; cmds[cmdi].cmd != NulL; cmdi++) { process_command(&cmds[cmdi]);}
现在,在process_command中:
if (!(pID_fork = fork())) { dup2(cmd->in[0],fileno(stdin)); dup2(cmd->out[1],fileno(stdout)); if (cmd->in[1] >= 0) { if (close(cmd->in[1])) { perror(NulL); } } if (cmd->out[0] >= 0) { if (close(cmd->out[0])) { perror(NulL); } } execvp(cmd->cmd[0],cmd->cmd); exit(-1);}
问题是永远从管道中读取:
COMMAND $ls | wcCreated pipe,in: 5 out: 6Foreground pID: 9042,command: ls,Exited,info: 0[blocked running read() within wc]
如果,而不是与execvp交换过程,我只是这样做:
if (!(pID_fork = fork())) { dup2(cmd->in[0],fileno(stdout)); if (cmd->in[1] >= 0) { if (close(cmd->in[1])) { perror(NulL); } } if (cmd->out[0] >= 0) { if (close(cmd->out[0])) { perror(NulL); } } char buf[6]; read(fileno(stdin),buf,5); buf[5] = 'COMMAND $cmd1 | cmd2 | cmd3 | cmd4 | cmd5 Pipe creada,in: 11 out: 12Pipe creada,in: 13 out: 14Pipe creada,in: 15 out: 16Pipe creada,in: 17 out: 18hola!Foreground pID: 9251,command: cmd1,info: 0Foreground pID: 9252,command: cmd2,info: 0Foreground pID: 9253,command: cmd3,info: 0Foreground pID: 9254,command: cmd4,info: 0hola!Foreground pID: 9255,command: cmd5,info: 0'; printf("%s\n",buf); exit(0);}
它碰巧工作:
if (!(pID_fork = fork())) { dup2(cmd->in[0],cmd->cmd); exit(-1);}
可能是什么问题呢?
解决方法 你没有足够的关闭.在代码中:if (!(pID_fork = fork())) { dup2(cmd->in[0],fileno(stdout)); if (cmd->in[1] >= 0) { if (close(cmd->in[1])) { perror(NulL); } } if (cmd->out[0] >= 0) { if (close(cmd->out[0])) { perror(NulL); } } close(cmd->in[0]); // Or your error checked version,but I'd use a function close(cmd->out[1]); execvp(cmd->cmd[0],cmd->cmd); exit(-1);}
在将管道复制到stdin和stdout(通过fileno())之后,需要关闭管道:
程序没有完成,因为文件的写入结束仍然打开.另外,不要忘记,如果父进程(shell)创建管道,它必须关闭管道的两端.在开始学习管道管道时,没有关闭足够的管道可能是最常见的错误.
总结以上是内存溢出为你收集整理的读取C块上的UNIX管道全部内容,希望文章能够帮你解决读取C块上的UNIX管道所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)