C 进程终止不';不影响waitpid()
我需要在Linux下使用C模拟以下bash命令(使用fork、exec、kill、signal、wait、waitpid、dup2、open、sleep、pipe等) 到目前为止,我有以下代码:C 进程终止不';不影响waitpid(),c,linux,operating-system,system-calls,C,Linux,Operating System,System Calls,我需要在Linux下使用C模拟以下bash命令(使用fork、exec、kill、signal、wait、waitpid、dup2、open、sleep、pipe等) 到目前为止,我有以下代码: #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> int main(int argc,
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
pid_t pID = fork();
if (pID == 0) // child
{
int file = open("/tmp/rtail", O_CREAT | O_WRONLY);
//Now we redirect standard output to the file using dup2
dup2(file, 1);
puts("tail -f $1");
close(file);
system("chmod 777 /tmp/rtail");
exit(0);
} else if (pID < 0) // failed to fork
{
printf("Failed to fork");
exit(1);
// Throw exception
} else // parent
{
pid_t pID2 = fork();
if (pID2 == 0) {
char tmp1[20];
sprintf(tmp1, "echo %i > /tmp/pidprog1", getpid());
system(tmp1);
int file = open("/tmp/1.txt", O_APPEND | O_WRONLY);
//Now we redirect standard output to the file using dup2
dup2(file, 1);
FILE* proc = popen("sh /tmp/rtail ~/.bash_history", "r");
char tmp[20];
while (fgets(tmp, 40, proc) != NULL) {
printf(tmp);
}
fclose(proc);
exit(0);
}
else if (pID2 < 0) // failed to fork
{
printf("Failed to fork");
exit(1);
// Throw exception
} else {
FILE* fl = fopen("/tmp/pidprog1", "r");
char buff[10];
fgets(buff, 10, fl);
int pidc = atoi(buff);
fclose(fl);
int status;
waitpid(pidc, &status, 0);
printf("Program 1 terminated\n");
}
}
// Code executed by both parent and child.
return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
pid_t pid=fork();
if(pID==0)//子级
{
int file=open(“/tmp/rtail”,O|u CREAT | O|u WRONLY);
//现在,我们使用dup2将标准输出重定向到文件
dup2(文件,1);
看跌期权(“尾价-1美元”);
关闭(文件);
系统(“chmod 777/tmp/rtail”);
出口(0);
}else if(pID<0)//分叉失败
{
printf(“未能分叉”);
出口(1);
//抛出异常
}else//parent
{
pid_t pID2=fork();
如果(pID2==0){
char-tmp1[20];
sprintf(tmp1,“echo%i>/tmp/pidprog1”,getpid());
系统(tmp1);
int file=open(“/tmp/1.txt”,O_APPEND | O_WRONLY);
//现在,我们使用dup2将标准输出重定向到文件
dup2(文件,1);
文件*proc=popen(“sh/tmp/rtail~/.bash_history”,“r”);
char-tmp[20];
while(fgets(tmp,40,proc)!=NULL){
printf(tmp);
}
fclose(proc);
出口(0);
}
else if(pID2<0)//分叉失败
{
printf(“未能分叉”);
出口(1);
//抛出异常
}否则{
文件*fl=fopen(“/tmp/pidprog1”,“r”);
字符buff[10];
fgets(浅黄色,10,fl);
int-pidc=atoi(buff);
fclose(fl);
智力状态;
waitpid(pid,状态为0);
printf(“程序1已终止\n”);
}
}
//由父级和子级执行的代码。
返回0;
}
问题是,当我使用保存到/tmp/pidprog1中的PID手动终止进程时,父进程不会停止等待,也不会打印“程序1已终止”行。父进程很可能正在将垃圾值读入pidc。您没有做任何事情来确保在父对象尝试读取pid之前,孙辈已经实际编写了pid。您需要使用wait来确保文件中存在有效的PID。(或者,只需从fork的返回值跟踪PID即可。) 您没有进行足够的错误检查:如果任何打开失败会发生什么?(例如,当你尝试时 要打开/tmp/1.txt进行追加,但它还不存在?) 为什么要使用FGET将40个字符读入大小为20的缓冲区 为什么您要复制和使用FPUT,而不仅仅是向fd写入
为什么要将错误消息打印到stdout而不是stderr(使用peror)。如果写入文件的全部目的是保存孙子的PID,那么如何等待孙子呢?大多数错误都是由于代码的草稿阶段造成的。我使用dup而不是直接写入文件,因为我认为任务明确表示我更喜欢这种方法。@bvk256使用wait来等待,直到子项完成。但你为什么要从文件中获取pid?它由fork()返回。将外子代的pid传递给父代需要做更多的工作,通常通过管道而不是文件系统完成。你需要某种同步。使用wait,或者打开管道,或者使用其他形式的IPC。您的家庭作业是否指定pid应保存在文件中,或者只是说“pid…应保存”。根本不需要保存它,因为它是由wait返回的,并且将它保存在文件中是非常不寻常的。将其存储在变量中。调用wait并使用返回值,忽略存储值。还有第二部分赋值,应创建第二个程序,并在一段时间后使用保存的PID杀死第一个程序。因此,第二个程序需要写入文件才能知道第一个程序的PID。
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
pid_t pID = fork();
if (pID == 0) // child
{
int file = open("/tmp/rtail", O_CREAT | O_WRONLY);
//Now we redirect standard output to the file using dup2
dup2(file, 1);
puts("tail -f $1");
close(file);
system("chmod 777 /tmp/rtail");
exit(0);
} else if (pID < 0) // failed to fork
{
printf("Failed to fork");
exit(1);
// Throw exception
} else // parent
{
pid_t pID2 = fork();
if (pID2 == 0) {
char tmp1[20];
sprintf(tmp1, "echo %i > /tmp/pidprog1", getpid());
system(tmp1);
int file = open("/tmp/1.txt", O_APPEND | O_WRONLY);
//Now we redirect standard output to the file using dup2
dup2(file, 1);
FILE* proc = popen("sh /tmp/rtail ~/.bash_history", "r");
char tmp[20];
while (fgets(tmp, 40, proc) != NULL) {
printf(tmp);
}
fclose(proc);
exit(0);
}
else if (pID2 < 0) // failed to fork
{
printf("Failed to fork");
exit(1);
// Throw exception
} else {
FILE* fl = fopen("/tmp/pidprog1", "r");
char buff[10];
fgets(buff, 10, fl);
int pidc = atoi(buff);
fclose(fl);
int status;
waitpid(pidc, &status, 0);
printf("Program 1 terminated\n");
}
}
// Code executed by both parent and child.
return 0;
}