C-内部带有fork()/pipe()的WHILE循环
我有一个问题,我必须实现一个键盘记录器到我们在课堂上制作的shell中。在创建子进程并运行execlp()后,在while循环中使程序流继续循环时遇到问题 这是一个简单的程序,我已经做了工作的一部分,我有麻烦。。我的主程序pipe.c包含一个带有while循环的父/子进程,该循环“应该”使用fgets()继续从用户处获取输入,创建一个子进程,使用dup2(),写入stdout,然后子进程调用receive.c可执行文件,该可执行文件将从stdin获取输入并显示它C-内部带有fork()/pipe()的WHILE循环,c,exec,fork,pipe,parent-child,C,Exec,Fork,Pipe,Parent Child,我有一个问题,我必须实现一个键盘记录器到我们在课堂上制作的shell中。在创建子进程并运行execlp()后,在while循环中使程序流继续循环时遇到问题 这是一个简单的程序,我已经做了工作的一部分,我有麻烦。。我的主程序pipe.c包含一个带有while循环的父/子进程,该循环“应该”使用fgets()继续从用户处获取输入,创建一个子进程,使用dup2(),写入stdout,然后子进程调用receive.c可执行文件,该可执行文件将从stdin获取输入并显示它 /* file: pipe.c
/* file: pipe.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int key_logger_on = 0;
int p[2];
pid_t pid;
char str[256];
char input[1024];
int status;
char * file = "test.txt";
printf("Input :: ");
while(fgets(input, sizeof(input), stdin)) {
if (pipe(p)==-1) {
perror("Pipe create error");
exit(1);
}
if ((pid=fork())==-1) {
perror("Fork create error");
exit(1);
}
if (pid==0) {
close(p[1]); // Close write
dup2(p[0],0);
close(p[0]);
execlp("receive",file,NULL);
}
else {
close(p[0]); // Close read
fflush(stdout);
dup2(p[1],1);
close(p[1]);
write(1, input, strlen(input)+1);
waitpid(pid, NULL, 0);
}
printf("Input :: ");
}
}
/*文件:pipe.c*/
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
int key_logger_on=0;
int p[2];
pid_t pid;
char-str[256];
字符输入[1024];
智力状态;
char*file=“test.txt”;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
如果(管道(p)=-1){
perror(“管道创建错误”);
出口(1);
}
如果((pid=fork())=-1){
perror(“Fork创建错误”);
出口(1);
}
如果(pid==0){
关闭(p[1]);//关闭写入
dup2(p[0],0);
接近(p[0]);
execlp(“接收”,文件,空);
}
否则{
关闭(p[0]);//关闭读取
fflush(stdout);
dup2(p[1],1);
关闭(p[1]);
写入(1,输入,strlen(输入)+1);
waitpid(pid,NULL,0);
}
printf(“输入::”);
}
}
下面是简单的receive.c,它获取输入的stdin并显示它。该文件只是传递参数的测试
/* file: receive.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char input[256];
fgets(input, sizeof(input), stdin);
printf("FILE: %s RECEIVE: %s", argv[0],input);
return 0;
}
/*文件:receive.c*/
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
字符输入[256];
fgets(输入,sizeof(输入),标准输入);
printf(“文件:%s接收:%s”,argv[0],输入);
返回0;
}
现在,所有这些对我来说都是第一次运行时,它获取输入,将其发送到stdout,子调用receive,打印出输入,然后整个父程序退出,while循环被忽略,一切都结束了。我对叉子和管子很陌生,所以处理这件事很令人沮丧!甚至让我第一次在这里发帖!事先非常感谢 今天做这件事是作为我的重复任务。检查此代码。我也用你的接收机测试过:
#define PREAD 0
#define PWRITE 1
/*
*
*/
int main(int argc, char** argv) {
int key_logger_on = 0;
int pIn[2];
int pOut[2];
pid_t pid;
char str[256];
char input[1024] = "";
int status;
char file[] = "test.txt";
char buf;
printf("Input :: ");
while (fgets(input,sizeof(input),stdin)) {
char nChar;
int nResult;
if (pipe(pIn) < 0) {
perror("allocating pipe for child input redirect");
return -1;
}
if (pipe(pOut) < 0) {
close(pIn[PREAD]);
close(pIn[PWRITE]);
perror("allocating pipe for child output redirect");
return -1;
}
pid = fork();
if ( pid==0) {
// child continues here
// redirect stdin
if (dup2(pIn[PREAD], 0) == -1) {
perror("stdin");
return -1;
}
// redirect stdout
if (dup2(pOut[PWRITE], 1) == -1) {
perror("stdout");
return -1;
}
// redirect stderr
if (dup2(pOut[PWRITE], 2) == -1) {
perror("stderr");
return -1;
}
// all these are for use by parent only
close(pIn[PREAD]);
close(pIn[PWRITE]);
close(pOut[PREAD]);
close(pOut[PWRITE]);
// run child process image
nResult = execl("receive",file,NULL);
exit(nResult);
} else if (pid > 0) {
// parent continues here
// close unused file descriptors, these are for child only
close(pIn[PREAD]);
close(pOut[PWRITE]);
write(pIn[PWRITE], input, strlen(input));
// char by char reading
while (read(pOut[PREAD], &nChar, 1) == 1) {
write(STDOUT_FILENO, &nChar, 1);
}
// close we done
close(pIn[PWRITE]);
close(pOut[PREAD]);
}
printf("Input :: ");
}
}
#定义序言0
#定义PWRITE 1
/*
*
*/
int main(int argc,字符**argv){
int key_logger_on=0;
int引脚[2];
int pOut[2];
pid_t pid;
char-str[256];
字符输入[1024]=“”;
智力状态;
字符文件[]=“test.txt”;
焦炉;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
查恩查尔;
结果;
如果(管道(销)<0){
perror(“为子输入重定向分配管道”);
返回-1;
}
如果(管道(撅嘴)<0){
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
perror(“为子输出重定向分配管道”);
返回-1;
}
pid=fork();
如果(pid==0){
//孩子继续在这里
//重定向标准
如果(dup2(引脚[PREAD],0)=-1){
佩罗尔(“标准数据”);
返回-1;
}
//重定向标准输出
if(dup2(pOut[PWRITE],1)=-1){
佩罗尔(“stdout”);
返回-1;
}
//重定向标准
if(dup2(pOut[PWRITE],2)=-1){
佩罗尔(“stderr”);
返回-1;
}
//所有这些仅供家长使用
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
关闭(撅嘴[前置]);
关闭(撅嘴[PWRITE]);
//运行子进程映像
nResult=execl(“接收”,文件,空);
退出(nResult);
}否则,如果(pid>0){
//家长继续在这里
//关闭未使用的文件描述符,这些描述符仅适用于儿童
关闭(引脚[PREAD]);
关闭(撅嘴[PWRITE]);
写入(引脚[PWRITE],输入,strlen(输入));
//逐字符读取
while(读取(pOut[PREAD],&nChar,1)==1){
写入(标准文件号和nChar,1);
}
//接近完成
关闭(引脚[PWRITE]);
关闭(撅嘴[前置]);
}
printf(“输入::”);
}
}
今天我把它作为重复任务来做。检查此代码。我也用你的接收机测试过:
#define PREAD 0
#define PWRITE 1
/*
*
*/
int main(int argc, char** argv) {
int key_logger_on = 0;
int pIn[2];
int pOut[2];
pid_t pid;
char str[256];
char input[1024] = "";
int status;
char file[] = "test.txt";
char buf;
printf("Input :: ");
while (fgets(input,sizeof(input),stdin)) {
char nChar;
int nResult;
if (pipe(pIn) < 0) {
perror("allocating pipe for child input redirect");
return -1;
}
if (pipe(pOut) < 0) {
close(pIn[PREAD]);
close(pIn[PWRITE]);
perror("allocating pipe for child output redirect");
return -1;
}
pid = fork();
if ( pid==0) {
// child continues here
// redirect stdin
if (dup2(pIn[PREAD], 0) == -1) {
perror("stdin");
return -1;
}
// redirect stdout
if (dup2(pOut[PWRITE], 1) == -1) {
perror("stdout");
return -1;
}
// redirect stderr
if (dup2(pOut[PWRITE], 2) == -1) {
perror("stderr");
return -1;
}
// all these are for use by parent only
close(pIn[PREAD]);
close(pIn[PWRITE]);
close(pOut[PREAD]);
close(pOut[PWRITE]);
// run child process image
nResult = execl("receive",file,NULL);
exit(nResult);
} else if (pid > 0) {
// parent continues here
// close unused file descriptors, these are for child only
close(pIn[PREAD]);
close(pOut[PWRITE]);
write(pIn[PWRITE], input, strlen(input));
// char by char reading
while (read(pOut[PREAD], &nChar, 1) == 1) {
write(STDOUT_FILENO, &nChar, 1);
}
// close we done
close(pIn[PWRITE]);
close(pOut[PREAD]);
}
printf("Input :: ");
}
}
#定义序言0
#定义PWRITE 1
/*
*
*/
int main(int argc,字符**argv){
int key_logger_on=0;
int引脚[2];
int pOut[2];
pid_t pid;
char-str[256];
字符输入[1024]=“”;
智力状态;
字符文件[]=“test.txt”;
焦炉;
printf(“输入::”);
while(fgets(input,sizeof(input),stdin)){
查恩查尔;
结果;
如果(管道(销)<0){
perror(“为子输入重定向分配管道”);
返回-1;
}
如果(管道(撅嘴)<0){
关闭(引脚[PREAD]);
关闭(引脚[PWRITE]);
perror(“为子输出重定向分配管道”);
返回-1;
}
pid=fork();
如果(pid==0){
//孩子继续在这里
//重定向标准
如果(dup2(引脚[PREAD],0)=-1){
佩罗尔(“标准数据”);
返回-1;
}
//重定向标准输出
if(dup2(pOut[PWRITE],1)=-1){
佩罗尔(“stdout”