[英]System function doesn't output anything
I've been tinkering around pipes and parent-child communication, only now I used a system
function call to pass something from the child to the parent.我一直在修补管道和父子通信,直到现在我才使用
system
函数调用将某些东西从子进程传递给父进程。 Problem is I believe system
doesn't really have any output in my example.问题是我相信
system
在我的例子中没有任何输出。
The parent reads input and sends it to the child to check if the string is of "sorted letters".父级读取输入并将其发送给子级以检查字符串是否为“已排序的字母”。 Characters would have to be in lexicographic order.
字符必须按字典顺序排列。 I used
system
to combine echo
and grep
and send that result back into the pipe.我使用
system
将echo
和grep
结合起来,并将结果发送回管道。 I was able to narrow it down to the parent's read-end of the the pipe;我能够将其缩小到管道的父母读取端; it blocks.
它阻止。 I'm guessing that's because there is nothing in the pipe to be read and the write end isn't closed.
我猜这是因为管道中没有任何东西可供读取,并且写入端没有关闭。 I understand that would be the cause of the problem, for that to make sense,
system
would not have to output anything.我知道这将是问题的原因,为此,
system
不必输出任何内容。
/*
$ ./grep
AeIoU
Yes.
blah
No.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ctype.h>
#define STRING_SIZE 128
static void fatalError(char* message);
int checkIfAlpha(char *string, int length); //f-ja koja proverava da li se string sastroji samo od slova
int main(int argc, char const *argv[])
{
pid_t pid;
char input[STRING_SIZE]; //cuvamo input string ovde
char command[100 + STRING_SIZE];
int pipeToParent[2], pipeToChild[2];
int n;
char tmp[50];
int count;
if (pipe(pipeToParent) < 0)
fatalError("pipe error");
if (pipe(pipeToChild) < 0)
fatalError("pipe error");
if ((pid = fork()) < 0)
fatalError("fork error");
else if (pid == 0) {
//child
if (close(pipeToChild[1]) < 0)
fatalError("close error");
if (close(pipeToParent[0]) < 0)
fatalError("close error");
if (dup2(pipeToParent[1], STDOUT_FILENO) < 0)
fatalError("dup2 error");
while (1) {
if ((count = read(pipeToChild[0], tmp, 50)) < 0)
fatalError("read error");
fprintf(stderr, "2\n");
if (count == 0)
break;
sprintf(command, "echo '%s' | grep -i ^a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*$", tmp);
if (system(command) < 0)
fatalError("system error");
fprintf(stderr, "3\n");
}
exit(EXIT_SUCCESS);
}
//parent
if (close(pipeToParent[1]) < 0)
fatalError("close rror");
if (close(pipeToChild[0]) < 0)
fatalError("close error");
while(fgets(input, STRING_SIZE, stdin) != NULL) {
input[strlen(input)-1] = '\0';
if (checkIfAlpha(input, strlen(input)) == -1) {
fprintf(stderr, "Samo slova\n");
continue;
}
if (write(pipeToChild[1], input, strlen(input)) != strlen(input))
fatalError("write error");
printf("1\n");
if ((n = read(pipeToParent[0], input, STRING_SIZE)) < 0)
fatalError("fatal error");
printf("4\n");
if (n == 0)
printf("No\n");
else if (n > 0)
printf("Yes\n");
}
exit(EXIT_SUCCESS);
}
static void fatalError(char *message) {
perror(message);
exit(EXIT_FAILURE);
}
int checkIfAlpha(char *string , int length) {
int c = 1;
for (int i = 0; i < length; i++)
if (!isalpha(string[i])) {
c = -1;
break;
}
return c;
}
EDIT: I would've posted the outputs if I thought they would be that significant, but by all means.编辑:如果我认为它们会那么重要,我会发布输出,但无论如何。
Here's the output (with the right input):这是输出(具有正确的输入):
./grep
abcde
1
2
3
Here's GDB:这是 GDB:
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe058) at grep.c:23
23 {
(gdb) next
34 if (pipe(pipeToParent) < 0)
(gdb)
37 if (pipe(pipeToChild) < 0)
(gdb)
40 if ((pid = fork()) < 0)
(gdb)
42 else if (pid == 0) {
(gdb)
76 if (close(pipeToParent[1]) < 0)
(gdb)
80 if (close(pipeToChild[0]) < 0)
(gdb)
83 while(fgets(input, STRING_SIZE, stdin) != NULL) {
(gdb)
85 input[strlen(input)-1] = '\0';
(gdb)
88 if (checkIfAlpha(input, strlen(input)) == -1) {
(gdb)
92 if (write(pipeToChild[1], input, strlen(input)) != strlen(input))
(gdb)
94 printf("1\n");
(gdb)
1
96 if ((n = read(pipeToParent[0], input, STRING_SIZE)) < 0)
(gdb)
read
does not write a terminating null character. read
不写入终止空字符。 After if ((count = read(pipeToChild[0], tmp, 50)) < 0)
, the program passes tmp
, without writing a null charactering into it, to sprintf
.在
if ((count = read(pipeToChild[0], tmp, 50)) < 0)
,程序将tmp
传递给sprintf
,而不向其中写入空字符。
This results in the echo
command being passed additional garbage data from tmp
beyond what was read from the pipe, which in turn causes grep
not to find a matching string.这导致
echo
命令从tmp
传递额外的垃圾数据,超出了从管道读取的内容,进而导致grep
找不到匹配的字符串。
One fix would be to change the read
to read(pipeToChild[0], tmp, sizeof tmp - 1)
and insert tmp[count] = 0;
一种解决方法是将
read
更改为read(pipeToChild[0], tmp, sizeof tmp - 1)
并插入tmp[count] = 0;
. .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.