我需要在Linux下使用C模拟以下bash命令(使用fork,exec,kill,signal,wait,waitpid,dup2,open,sleep,pipe等)。
[0] echo 'tail-f $1' > /tmp/rtail
[1]/tmp/rtail ~/.bash_history >> /tmp/1.txt &
PID of process [1] should be saved.
[2] Expect termination of the command started on step [1]. After termination print on the screen: "Program 1 terminated."
到目前为止,我有这段代码:
#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;
}
问题是当我使用保存在/ tmp / pidprog1中的PID手动终止进程时,父进程不会停止等待,也不会打印“程序1终止”行。
答案 0 :(得分:1)
父母很可能将垃圾值读入pidc。你没有做任何事情来确保孙在父母试图读它之前实际上已经写了pid。您需要使用wait来确保有效的pid在文件中。 (或者,只需从fork的返回值跟踪pids。)
您没有做足够的错误检查:如果任何打开失败会发生什么? (例如,当你尝试 打开/tmp/1.txt进行追加但它还不存在?)
为什么使用fgets将40个字符读入20的缓冲区?
为什么要重复使用fput而不是只写入fd?
为什么要将错误消息打印到stdout而不是stderr(使用perror)。