因此,对于这个程序,我被要求输入将在每个子进程中使用的几个程序的名称,这些程序将链接到管道
创建管道,创建子节点,父节点关闭管道末端并等待子节点完成
我确信fork,child和pipe很有趣,但如果你想批评继续进行,但主要关注的是exec。
然而,这只是我的代码的一小部分,我在创建更多的子节点和修改管道之前遇到了问题。在我继续
之前,我遇到了我想要解决的错误myParent
int main(int argc, char* argv[]){
int i = 0;
int max_line_length = 101;
char * catprog = (char*) malloc(sizeof(char*));;
char * datafile = (char*) malloc(sizeof(char*));
char * numstrings = (char*) malloc(sizeof(char*));
int nstrings;
if(argc != 1){
printf("%s \n", "This takes no command line arguments");
exit(EXIT_FAILURE);
}
printf("%s ","Filename of spliter program:");
fgets(catprog, max_line_length, stdin);
printf("%s ","File name of data file:");
fgets(datafile, max_line_length, stdin);
printf("%s ","Number of strings to sort:");
fgets(numstrings, max_line_length, stdin);
if(!(nstrings = atoi(numstrings))){
printf("%s \n","This is an invalid number.");
exit(EXIT_FAILURE);}
int halfnstrings = nstrings/2;
pid_t pid1 = fork();
if(pid1 < 0){ //failed fork1
fprintf(stderr, "Fork 1 failed\n");
exit(EXIT_FAILURE);
}
else if(pid1 == 0){//child 1
char start[max_line_length];
char end[max_line_length];
sprintf(start, "%d", 1);
sprintf(end, "%d", halfnstrings);
printf("%s",catprog); //checking if catprog is correct
printf("%s",datafile); //checlomg of datafile
if((execlp(catprog, catprog, datafile, start, end, NULL)) == -1){
printf("%s \n","Cannot exec");
exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
}
else{
wait(NULL);
exit(EXIT_SUCCESS);
}
return 0;
}
myCat
int main(int argc, char * argv[]){
int startline;
int endline;
int max_line_length = 101;
if(argc != 4){
printf("%s \n", "Format is: myCat <data_file> <start_line> <end_line>");
exit(EXIT_FAILURE);
}
if(!(startline = atoi(argv[2]))){
printf("%s \n","Invalid Number");
exit(EXIT_FAILURE);
}
endline=atoi(argv[3]);
if(!(endline) || endline<startline){
printf("%s \n","Invalid Number");
exit(EXIT_FAILURE);
}
path = argv[1];
if(NULL == (pdata=fopen(path,"r"))){
printf("%s \n", "Cannot open file.");
exit(EXIT_FAILURE);
}
因此,当我编译并运行它时,打印输出不能执行,因此我相信我没有正确输入exec。
输入是:
拆分程序是:myCat
合并程序是:myMerge
数据文件:data.txt
num个字符串:无论要排序的字符串数是多少
myCat通过获取数据文件,起始行和结束行来工作: myCat data.txt 2 7
myCat获取数据文件并从起始行读取它直到到达结束行并输出字符串行读取
所以我的问题是空格是否会影响execl?
答案 0 :(得分:1)
有很多问题,其中大部分都在我的评论中列出。这是可行的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int max_line_length = 101;
char *catprog = (char *)malloc(max_line_length);
char *datafile = (char *)malloc(max_line_length);
char *numstrings = (char *)malloc(max_line_length);
int nstrings;
if (argc != 1)
{
fprintf(stderr, "%s: %s\n", argv[0], "this command takes no command line arguments");
exit(EXIT_FAILURE);
}
printf("%s ", "Filename of splitter program:");
fgets(catprog, max_line_length, stdin);
printf("%s ", "File name of data file:");
fgets(datafile, max_line_length, stdin);
printf("%s ", "Number of strings to sort:");
fgets(numstrings, max_line_length, stdin);
catprog[strcspn(catprog, "\n")] = '\0';
datafile[strcspn(datafile, "\n")] = '\0';
if (!(nstrings = atoi(numstrings)))
{
fprintf(stderr, "%s: %s %s\n", argv[0], numstrings, "is an invalid number.");
exit(EXIT_FAILURE);
}
int halfnstrings = nstrings / 2;
pid_t pid1 = fork();
if (pid1 < 0)
{
fprintf(stderr, "%s: fork failed\n", argv[0]);
exit(EXIT_FAILURE);
}
else if (pid1 == 0)
{
char start[max_line_length];
char end[max_line_length];
sprintf(start, "%d", 1);
sprintf(end, "%d", halfnstrings);
printf("catprog: [%s]\n", catprog);
printf("datafile: [%s]\n", datafile);
printf("start: [%s]\n", start);
printf("end: [%s]\n", end);
execlp(catprog, catprog, datafile, start, end, NULL);
fprintf(stderr, "%s: %s %s\n", argv[0], "Cannot exec", catprog);
exit(EXIT_FAILURE);
}
else
{
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("PID %d exited 0x%.4X\n", corpse, status);
exit(EXIT_SUCCESS);
}
return 0;
}
请注意,错误消息应写入标准错误而不是标准输出。他们的错误;这是stderr
的用途!此外,消息应标识创建它们的程序的名称;这就是为什么它们都包含argv[0]
作为消息的第一部分的原因。换行前的空格是草率编码。
请注意,删除fgets()
小心保留的换行符至关重要。另请注意,您应该错误地检查对fgets()
的调用(实际上是对malloc()
的调用 - 使用常规数组的另一个原因是您不必添加该错误检查)。您可以在文件stderr.h
和stderr.c
中的GitHub(https://github.com/jleffler/soq/tree/master/src/libsoq)上找到我首选的错误报告机制。该代码将每个错误报告减少到一行而不是四行,这使得它不那么繁重,因此不太可能被跳过。
请注意在打印的字符串周围使用方括号。它们可以更容易地发现数据中的问题(换行符,回车符等)。
在我的机器上,al
是一个回应其参数的命令,每行一个。因此,样本运行(exec37
)是:
$ ./exec37
Filename of splitter program: al
File name of data file: apocalypse-now.score
Number of strings to sort: 23
catprog: [al]
datafile: [apocalypse-now.score]
start: [1]
end: [11]
apocalypse-now.score
1
11
PID 93352 exited 0x0000
$
对阵列使用内存分配并不是特别明智;您可以编写char catprog[max_line_length];
等(如果您将max_line_length
转换为编译时整数常量 - enum { max_line_length = 101 };
,它们将不会是可变长度数组(VLA)。