我不知道这段代码有什么问题。其输出存在多个错误。该程序应该模仿UNIX shell。只要它不包含任何管道,它就可以运行任何命令。但是,当我包含管道时,有趣的事情开始发生。
例如:当我输入sort < myshell1,c | grep main | cat > o.txt
它创建了一个额外的过程。您可以看到这一点,因为在代码中,perror(in)
被执行了4次(根据GDB):
COP4338$ sort < myshell1.c | grep main | cat > o.txt
Detaching after fork from child process 16465.
Process ID: 16465
Process ID: 0
in: Success
Detaching after fork from child process 16466.
Process ID: 16466
Process ID: 0
in: Success
Something happened in i != numcommands - 1: Success
Detaching after fork from child process 16468.
Process ID: 16468
COP4338$ Process ID: 0
in: Success
ELSE STATEMENT!
Detaching after fork from child process 17403.
in: Bad address
然后,程序转到新行,并且不打印COP4338 $:像应该这样。出现未定义的行为。我对为什么会这样的猜测是因为第4个进程还在继续,因此像父进程一样回到了main(),但是我无法查明为什么还要创建它。
当我尝试运行ls -l | cat > o.txt
这是GDB的输出:
至于要解决此问题,我还不确定是否是导致此问题的原因。我尝试使用gdb调试器通过键入“ set follow-fork-mode child”并在第3个子进程的第1行使用断点来调试第3个子进程,但没有任何反应。这样只能调试第一个子进程。
/* This code was written by Dr. Raju Rangaswami and was expanded upon as per the instructions in Assignment3, by Michael Duboc(PID: 5706538)*/
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ARGS 20
#define BUFSIZ 1024
int get_args(char* cmdline, char* args[])
{
int i = 0;
/* if no args */
if((args[0] = strtok(cmdline, "\n\t ")) == NULL)
return 0;
while((args[++i] = strtok(NULL, "\n\t ")) != NULL)
{
if(i >= MAX_ARGS)
{
printf("Too many arguments!\n");
exit(1);
}
}
/* the last one is always NULL */
return i;
}
int customStrCpy(char** line1, char* line2)
{
int strlen1 = strlen(*line1), strlen2 = strlen(line2);
if(strlen1 < strlen2)
{
//Creates a dynamically allocated array that is big enough to store the contents of line2.
*line1 = calloc(strlen2, sizeof(char));
}
strcpy(*line1, line2);
}
void adjustArray(char* args[], int args_itr, int* nargs)
{
int i, j;
for(i = 0; i < 2; i++)
{
for(j = args_itr; j < (*nargs) - 1; j++)
{
customStrCpy(&args[j],args[j+1]);
}
args[(*nargs) - 1] = 0;
(*nargs)--;
}
}
int process(int* greaterthan, int* d_greaterthan, char* args_pipe[], int*
nargs_p, int* fileno_out, int* fileno_in, int* lessthan, FILE** fout,
FILE** fin)
{
int greaterthan_strcmp = strcmp(args_pipe[args_itr], ">");
int d_greaterthan_strcmp = strcmp(args_pipe[args_itr], ">>");
if(greaterthan_strcmp == 0 || d_greaterthan_strcmp == 0)
{
if(greaterthan_strcmp == 0)
*fout = fopen(args_pipe[args_itr + 1], "w");
else
*fout = fopen(args_pipe[args_itr + 1], "a");
*fileno_out = fileno(*fout);
*greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
int print_arr;
for(print_arr = 0; print_arr
(sizeof(args_pipe)/sizeof(args_pipe[0])); print_arr++)
printf("%s ",args_pipe[print_arr]);
printf("\n");
}
else if(strcmp(args_pipe[args_itr], "<") == 0)
{
*fin = fopen(args_pipe[args_itr + 1], "r");
*fileno_in = fileno(*fin);
*lessthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
}
return 0;
}
void execute(char* cmdline)
{
int pid, async, lessthan = 0;
int greaterthan = 0, pipef = 0, d_greaterthan = 0;
int args_itr, pipe_flag = 0;
int flag_count = 0, fileno_in, fileno_out;
char* args_pipe[MAX_ARGS];/*5 and 3 are test numbers.*/
char* args[MAX_ARGS];
int nargs = get_args(cmdline, args);
if(nargs <= 0) return;
if(!strcmp(args[0], "quit") || !strcmp(args[0], "exit"))
{
exit(0);
}
/* check if async call */
if(!strcmp(args[nargs-1], "&")) { async = 1; args[--nargs] = 0; }
else async = 0;
FILE* fout = stdout;
FILE* fin = stdin;
for(args_itr = 0; args_itr < nargs; args_itr++)
{
if(!strcmp(args[args_itr], "|")) {pipe_flag = 1; flag_count++;}
}
if(pipe_flag)
{
int num_commands = flag_count + 1, i = 0, j = 0;
int fd[num_commands][2];
for(i = 0; i < flag_count; i++) {pipe(fd[i]);}
for(i = 0; i < num_commands; i++)
{
int nargs_p = 0, args_pipe_itr = 0;
while(j < nargs && strcmp(args[j], "|"))
{//Possibly make into for loop.
args_pipe[args_pipe_itr] = args[j];
args_pipe_itr++;
j++;
nargs_p++;
}
j++;
int pid = fork();
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
printf("Process ID: %d\n", pid);
if(pid < 0)
{
perror("Error forking!");
return;
}
else if(pid > 0) {continue;}
else //pid == 0
{
perror("in");
if(i == 0)
{
process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
printf("Lessthan = %d", lessthan);
if(lessthan) dup2(fileno_in, STDIN_FILENO);
dup2(fd[i][1], STDOUT_FILENO);
}
else if(i != num_commands - 1)
{
dup2(fd[i - 1][1], STDIN_FILENO);
//process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
dup2(fd[i][1], STDOUT_FILENO);
}
else
{
dup2(fd[i - 1][1], STDIN_FILENO);
process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
printf("greaterthan = %d", greaterthan);
printf("d_greaterthan = %d", d_greaterthan);
if(greaterthan || d_greaterthan) dup2(fileno_out, STDOUT_FILENO);
}
int close_pipes;
for(close_pipes = 0; close_pipes < flag_count; close_pipes++)
{
//close(fd[i][0]); close(fd[i][1]); JUST, WHY?!? THIS IS WHAT HAPPENS WHEN YOU DON'T THINK!
close(fd[close_pipes][0]);
close(fd[close_pipes][1]);
}
if(fout != stdout) fclose(fout);
if(fin != stdin) fclose(fin);
execvp(args_pipe[0], args_pipe);
perror("Something happened.");
exit(-1);
}//end child.
}
for(i = 0; i < flag_count; i++) {close(fd[i][0]); close(fd[i][1]);}
return;
}
}
int main (int argc, char* argv [])
{
for(;;)
{
printf("COP4338$ ");
if(fgets(cmdline, BUFSIZ, stdin) == NULL)
{
perror("fgets failed");
exit(1);
}
execute(cmdline);
int corpse;
int status;
while(corpse = wait(%status)) > 0)
perror(pid %d exited with status: 0x%.4X\n, corpse, status);
}
}
该程序应该将“ int main (int argc, char* argv [])
”打印到o.txt,但是o.txt完全没有改变。
对于好奇的人,函数process()扫描构成命令的一串参数,并根据程序看到的符号设置标志。
答案 0 :(得分:0)
您的代码有很多问题:
wait()
或等效电话。我认为customStrCpy()
函数和adjustArray()
函数中存在内存泄漏和不必要的内存分配问题,但是我没有解决这些问题-如果您不这样做,代码似乎可以正常工作需要担心泄漏。
我需要添加诊断信息以找出您的代码在做什么错。因此,我使用了错误报告代码,该代码在GitHub上的SOQ(堆栈溢出问题)存储库中以src/libsoq子目录中的文件stderr.c
和stderr.h
的形式提供。
此代码基于问题Revision 6中显示的代码-此后显示的问题代码已被修改。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include "stderr.h"
#define MAX_ARGS 20
#define BUFSIZ 1024
static
int get_args(char *cmdline, char *args[])
{
int i = 0;
/* if no args */
if ((args[0] = strtok(cmdline, "\n\t ")) == NULL)
return 0;
while ((args[++i] = strtok(NULL, "\n\t ")) != NULL)
{
if (i >= MAX_ARGS)
{
printf("Too many arguments!\n");
exit(1);
}
}
/* the last one is always NULL */
return i;
}
static
void customStrCpy(char **line1, char *line2)
{
int strlen1 = strlen(*line1), strlen2 = strlen(line2);
if (strlen1 < strlen2)
{
// Creates a dynamically allocated array that is big enough to store the contents of line2.
*line1 = calloc(strlen2, sizeof(char));
}
strcpy(*line1, line2);
}
static
void adjustArray(char *args[], int args_itr, int *nargs)
{
int i, j;
for (i = 0; i < 2; i++)
{
for (j = args_itr; j < (*nargs) - 1; j++)
{
customStrCpy(&args[j], args[j + 1]);
}
args[(*nargs) - 1] = 0;
(*nargs)--;
}
}
static
void process(int *greaterthan, int *d_greaterthan, char *args_pipe[],
int *nargs_p, int *fileno_out, int *fileno_in, int *lessthan,
FILE **fout, FILE **fin)
{
int args_itr;
err_remark("-->> %s():\n", __func__);
for (args_itr = 0; args_itr < *nargs_p; args_itr++)
{
if (strcmp(args_pipe[args_itr], ">") == 0)
{
err_remark("---- %s(): > %s\n", __func__, args_pipe[args_itr + 1]);
*fout = fopen(args_pipe[args_itr + 1], "w");
if (fout == NULL)
err_syserr("failed to open file '%s' for writing\n",
args_pipe[args_itr + 1]);
*fileno_out = fileno(*fout);
*greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
else if (strcmp(args_pipe[args_itr], ">>") == 0)
{
err_remark("---- %s(): >> %s\n", __func__, args_pipe[args_itr + 1]);
*fout = fopen(args_pipe[args_itr + 1], "a");
if (fout == NULL)
err_syserr("failed to open file '%s' for appending\n",
args_pipe[args_itr + 1]);
*fileno_out = fileno(*fout);
*d_greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
else if (strcmp(args_pipe[args_itr], "<") == 0)
{
err_remark("---- %s(): < %s\n", __func__, args_pipe[args_itr + 1]);
*fin = fopen(args_pipe[args_itr + 1], "r");
if (fin == NULL)
err_syserr("failed to open file '%s' for reading\n",
args_pipe[args_itr + 1]);
*fileno_in = fileno(*fin);
*lessthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
}
err_remark("<<-- %s()\n", __func__);
}
static
void execute(char *cmdline)
{
int lessthan = 0;
int greaterthan = 0, d_greaterthan = 0;
int args_itr, pipe_flag = 0;
int flag_count = 0, fileno_in, fileno_out;
char *args_pipe[MAX_ARGS];/*5 and 3 are test numbers.*/
char *args[MAX_ARGS];
int nargs = get_args(cmdline, args);
if (nargs <= 0)
return;
if (!strcmp(args[0], "quit") || !strcmp(args[0], "exit"))
{
exit(0);
}
for (int x = 0; x < nargs; x++)
err_remark("args[%d] = [%s]\n", x, args[x]);
FILE *fout = stdout;
FILE *fin = stdin;
for (args_itr = 0; args_itr < nargs; args_itr++)
{
if (!strcmp(args[args_itr], "|"))
{
pipe_flag = 1;
flag_count++;
}
}
if (pipe_flag)
{
int num_commands = flag_count + 1, i = 0, j = 0;
int fd[flag_count][2];
for (i = 0; i < flag_count; i++)
{
pipe(fd[i]);
err_remark("opened pipe - %d and %d\n", fd[i][0], fd[i][1]);
}
for (i = 0; i < num_commands; i++)
{
int nargs_p = 0, args_pipe_itr = 0;
while (j < nargs && strcmp(args[j], "|"))
{
// Possibly make into for loop.
args_pipe[args_pipe_itr] = args[j];
args_pipe_itr++;
j++;
nargs_p++;
}
args_pipe[nargs_p] = NULL; /* JL: Null-terminate argument list */
j++; /* Skip pipe argument */
int pid = fork();
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
if (pid < 0)
{
err_syserr("failed to fork a child process: ");
/*NOTREACHED*/
}
if (pid > 0)
{
err_remark("Parent launched child %d\n", pid);
continue;
}
else // if (pid == 0)
{
err_remark("child at work (i == %d)\n", i);
if (i == 0)
{
err_remark("first process in pipeline (i = %d, j = %d)\n", i, j);
process(&greaterthan, &d_greaterthan, args_pipe,
&nargs_p, &fileno_out, &fileno_in, &lessthan,
&fout, &fin);
if (lessthan)
dup2(fileno_in, STDIN_FILENO);
dup2(fd[i][1], STDOUT_FILENO);
}
else if (i != num_commands - 1)
{
err_remark("middle process in pipeline (i = %d, j = %d)\n", i, j);
dup2(fd[i - 1][0], STDIN_FILENO); /* JL */
/* Will need to process I/O redirections mid-pipeline */
/* However, they're always a bug in the shell script */
dup2(fd[i][1], STDOUT_FILENO);
}
else
{
err_remark("final process in pipeline (i = %d, j = %d)\n", i, j);
dup2(fd[i - 1][0], STDIN_FILENO); /* JL */
process(&greaterthan, &d_greaterthan, args_pipe,
&nargs_p, &fileno_out, &fileno_in, &lessthan,
&fout, &fin);
if (greaterthan || d_greaterthan)
err_remark("Redirection:\n"),
dup2(fileno_out, STDOUT_FILENO);
}
err_remark("close pipes\n");
int close_pipes;
for (close_pipes = 0; close_pipes < flag_count; close_pipes++)
{
close(fd[close_pipes][0]); /* JL */
close(fd[close_pipes][1]); /* JL */
}
if (fout != stdout)
fclose(fout);
if (fin != stdin)
fclose(fin);
err_remark("execute command [%s]\n", args_pipe[0]);
for (int i = 1; args_pipe[i] != NULL; i++)
err_remark("argument %d [%s]\n", i, args_pipe[i]);
execvp(args_pipe[0], args_pipe);
err_syserr("Failed to execute (i=%d) '%s': ", i, args_pipe[0]);
/*NOTREACHED*/
}// end child.
}
/* Parent process closes its copy of each pipe */
for (i = 0; i < flag_count; i++)
{
close(fd[i][0]);
close(fd[i][1]);
}
return;
}
else
err_remark("No pipe in input - no command executed\n");
}
int main(int argc, char **argv)
{
if (argc >= 0)
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MILLI);
for ( ; ; )
{
printf("COP4338$ ");
char cmdline[BUFSIZ];
if (fgets(cmdline, BUFSIZ, stdin) == NULL)
{
printf("EOF\n");
exit(1);
}
execute(cmdline);
int status;
int corpse;
while ((corpse = wait(&status)) > 0)
err_remark("PID %d exited with status 0x%.4X\n", corpse, status);
}
}
process()
函数不需要在参数列表中区分>
和>>
;正确处理标准输出就足够了。调用代码会更简单。我不认为您应该使用fopen()
-将open()
与适当的控制参数一起使用会更明智。
但是,这似乎至少有效。源代码为shell61.c
,已编译为程序shell61
。
$ shell61
COP4338$ sort < shell61.c | grep main | cat > o.txt
shell61: 2019-05-04 22:17:39.982 - pid=8150: args[0] = [sort]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[1] = [<]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[2] = [shell61.c]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[3] = [|]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[4] = [grep]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[5] = [main]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[6] = [|]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[7] = [cat]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[8] = [>]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[9] = [o.txt]
shell61: 2019-05-04 22:17:39.983 - pid=8150: opened pipe - 3 and 4
shell61: 2019-05-04 22:17:39.983 - pid=8150: opened pipe - 5 and 6
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8153
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8154
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8155
shell61: 2019-05-04 22:17:39.984 - pid=8154: child at work (i == 1)
shell61: 2019-05-04 22:17:39.984 - pid=8153: child at work (i == 0)
shell61: 2019-05-04 22:17:39.984 - pid=8155: child at work (i == 2)
shell61: 2019-05-04 22:17:39.985 - pid=8154: middle process in pipeline (i = 1, j = 7)
shell61: 2019-05-04 22:17:39.985 - pid=8155: final process in pipeline (i = 2, j = 11)
shell61: 2019-05-04 22:17:39.985 - pid=8153: first process in pipeline (i = 0, j = 4)
shell61: 2019-05-04 22:17:39.985 - pid=8154: close pipes
shell61: 2019-05-04 22:17:39.985 - pid=8155: -->> process():
shell61: 2019-05-04 22:17:39.985 - pid=8153: -->> process():
shell61: 2019-05-04 22:17:39.986 - pid=8154: execute command [grep]
shell61: 2019-05-04 22:17:39.986 - pid=8155: ---- process(): > o.txt
shell61: 2019-05-04 22:17:39.986 - pid=8153: ---- process(): < shell61.c
shell61: 2019-05-04 22:17:39.986 - pid=8154: argument 1 [main]
shell61: 2019-05-04 22:17:39.986 - pid=8155: <<-- process()
shell61: 2019-05-04 22:17:39.986 - pid=8153: <<-- process()
shell61: 2019-05-04 22:17:39.987 - pid=8155: Redirection:
shell61: 2019-05-04 22:17:39.987 - pid=8153: close pipes
shell61: 2019-05-04 22:17:39.987 - pid=8155: close pipes
shell61: 2019-05-04 22:17:39.987 - pid=8153: execute command [sort]
shell61: 2019-05-04 22:17:39.988 - pid=8155: execute command [cat]
shell61: 2019-05-04 22:17:39.993 - pid=8150: PID 8153 exited with status 0x0000
shell61: 2019-05-04 22:17:39.993 - pid=8150: PID 8154 exited with status 0x0000
shell61: 2019-05-04 22:17:39.994 - pid=8150: PID 8155 exited with status 0x0000
COP4338$ cat o.txt | cat
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[0] = [cat]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[1] = [o.txt]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[2] = [|]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[3] = [cat]
shell61: 2019-05-04 22:18:08.339 - pid=8150: opened pipe - 3 and 4
shell61: 2019-05-04 22:18:08.340 - pid=8150: Parent launched child 8157
shell61: 2019-05-04 22:18:08.340 - pid=8150: Parent launched child 8158
shell61: 2019-05-04 22:18:08.340 - pid=8157: child at work (i == 0)
shell61: 2019-05-04 22:18:08.340 - pid=8158: child at work (i == 1)
shell61: 2019-05-04 22:18:08.340 - pid=8157: first process in pipeline (i = 0, j = 3)
shell61: 2019-05-04 22:18:08.341 - pid=8157: -->> process():
shell61: 2019-05-04 22:18:08.341 - pid=8158: final process in pipeline (i = 1, j = 5)
shell61: 2019-05-04 22:18:08.341 - pid=8157: <<-- process()
shell61: 2019-05-04 22:18:08.341 - pid=8158: -->> process():
shell61: 2019-05-04 22:18:08.342 - pid=8157: close pipes
shell61: 2019-05-04 22:18:08.342 - pid=8158: <<-- process()
shell61: 2019-05-04 22:18:08.342 - pid=8157: execute command [cat]
shell61: 2019-05-04 22:18:08.342 - pid=8158: close pipes
shell61: 2019-05-04 22:18:08.343 - pid=8157: argument 1 [o.txt]
shell61: 2019-05-04 22:18:08.343 - pid=8158: execute command [cat]
int main(int argc, char **argv)
shell61: 2019-05-04 22:18:08.347 - pid=8150: PID 8158 exited with status 0x0000
shell61: 2019-05-04 22:18:08.347 - pid=8150: PID 8157 exited with status 0x0000
COP4338$ ls
shell61: 2019-05-04 22:18:41.516 - pid=8150: args[0] = [ls]
shell61: 2019-05-04 22:18:41.516 - pid=8150: No pipe in input - no command executed
COP4338$ exit
$
当我首先添加wait()
代码时,收到如下消息:
$ shell61
COP4338$ ls | grep shell
shell61: 2019-05-04 14:29:23.201 - pid=5181: args[0] = [ls]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[1] = [|]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[2] = [grep]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[3] = [shell]
shell61: 2019-05-04 14:29:23.202 - pid=5181: opened pipe - 3 and 4
Process ID: 5182
Process ID: 5183
Process ID: 0
Process ID: 0
shell61: 2019-05-04 14:29:23.203 - pid=5183: child at work
PID 5183 exited with status 0x000B
shell61: 2019-05-04 14:29:23.203 - pid=5182: child at work
PID 5182 exited with status 0x000D
COP4338$ exit
$
5183的退出状态为0x000B,表示“死于信号11 — SIGSEGV”; 5182的退出状态为0x000D,转换为“死亡表格信号13-SIGPIPE”。这是重要的信息。尤其是通过err_remark()
添加的印刷有助于显示出问题所在。同样重要的是,发现您使用process()
而不是&args_pipe[i]
或&args_pipe[0]
来呼叫args_pipe
。
跟踪显示如下:
$ shell61
COP4338$ ls | grep shell
shell61: 2019-05-04 16:24:24.297 - pid=6417: args[0] = [ls]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[1] = [|]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[2] = [grep]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[3] = [shell]
shell61: 2019-05-04 16:24:24.298 - pid=6417: opened pipe - 3 and 4
shell61: 2019-05-04 16:24:24.299 - pid=6417: Parent launched child 6419
shell61: 2019-05-04 16:24:24.299 - pid=6417: Parent launched child 6420
shell61: 2019-05-04 16:24:24.300 - pid=6420: child at work (i == 1)
shell61: 2019-05-04 16:24:24.299 - pid=6419: child at work (i == 0)
shell61: 2019-05-04 16:24:24.300 - pid=6420: final process in pipeline (i = 1, j = 5)
shell61: 2019-05-04 16:24:24.301 - pid=6419: first process in pipeline (i = 0, j = 2)
shell61: 2019-05-04 16:24:24.301 - pid=6420: -->> process():
shell61: 2019-05-04 16:24:24.302 - pid=6420: <<-- process()
greaterthan = 0
d_greaterthan = 0
shell61: 2019-05-04 16:24:24.302 - pid=6419: -->> process():
shell61: 2019-05-04 16:24:24.302 - pid=6420: close pipes
shell61: 2019-05-04 16:24:24.302 - pid=6419: <<-- process()
Lessthan = 0
shell61: 2019-05-04 16:24:24.303 - pid=6420: execute command [grep]
shell61: 2019-05-04 16:24:24.303 - pid=6420: argument 1 [shell]
shell61: 2019-05-04 16:24:24.303 - pid=6419: close pipes
shell61: 2019-05-04 16:24:24.304 - pid=6419: execute command [ls]
grep: (standard input): Bad file descriptor
PID 6420 exited with status 0x0100
PID 6419 exited with status 0x000D
COP4338$ exit
$
很明显,重定向存在问题-不清楚标准输入是否关闭,或者是否要求grep
从只写文件描述符中读取;代码审查显示,后者实际上是问题所在(使用fd[i][1]
,其中需要使用fd[i][0]
)。
我不能太强调拥有功能强大而简单的错误报告工具将如何提供帮助。我在大多数程序中都使用stderr.c
和stderr.h
代码-在极端情况下,我很少使用它们。您应该获取它们的副本或设计自己的副本,但要注意该代码已有30年的完善(尽管有些年我没有对其进行任何更改-2018年是最近的一年) ,但在1992年至1995年并没有改变,此后的其他年份也没有变化。我仍然拥有的最早版本是1988年。该代码实际上是在此之前启动的,但是在移动作业时我未能成功传输数据(事实证明,这是一个错误的选择)(8英寸软盘)。