简体   繁体   English

系统函数不输出任何东西

[英]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.我使用systemechogrep结合起来,并将结果发送回管道。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM