0

I want to search a character in stream and push back in stream without consuming any data. I am using fgetc but program is stuck on callling fgetc.

below is my test program.

int main(void)
{
  int     fd[2], nbytes;
  pid_t   childpid;
  char    string[] = "Hello, world!\n";
  char    readbuffer[80];

  pipe(fd);

  if((childpid = fork()) == -1)
    {
      perror("fork");
      exit(1);
    }

  if(childpid == 0)
    {
      /* Child process closes up input side of pipe */
      close(fd[0]);

      /* Send "string" through the output side of pipe */
      write(fd[1], string, (strlen(string)+1));
      exit(0);
    }
  else
    {
      /* Parent process closes up output side of pipe */
      close(fd[1]);
      int dummy;
      fd_set set;
      struct timeval timeout;
      FD_ZERO (&set);
      FD_SET (fd[0], &set);
      timeout.tv_sec = 1;
      timeout.tv_usec = 0;
      if (select (fd[0]+1, &set, NULL, NULL, &timeout))
        {
          dummy = fgetc (stdin);
          ungetc (dummy, stdin);
          // Search for character
          if (dummy == 0x03)
               // Todo  
        }
    }

  return(0);
}

So, what is wrong with code why program stuck on fgetc.

LPs
  • 16,045
  • 8
  • 30
  • 61

2 Answers2

0

You're trying to fgetc from stdin (which is your terminal), not the pipe. You're not using the pipe anywhere. Try to understand what your code is actually doing.

I think you intended to dup2 the pipe fd to 0, the stdin fd. There are thousands of examples of this.

Without Libc's buffering, or implementing it youself, you can't do what you ask - once a byte is read from the pipe, it's yours and gone from the pipe.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • thanks for point out that I'm using terminal input from stdin not pipes that save my lot of time. –  Jan 31 '17 at 14:10
  • are you saying that the function: `ungetc()` will not push back a character on a pipe? – user3629249 Feb 01 '17 at 16:17
  • No, I'm saying [`ungetc`](https://linux.die.net/man/3/ungetc) is a libc function, which works on `FILE*` streams - a libc abstraction on top of the *actual* file descriptors (like your pipes). – Jonathon Reinhart Feb 01 '17 at 16:30
0

I think there are two issues. The one is that once a byte is consumed from the stream, you cannot push it back. Second, fgetc is a blocking function such that it will wait until data is available, and you cannot tell fgetc to return if not (or even to return once a timeout has been reached).

For the first issue, you could wrap the relevant stream by a buffer, which has then to be used throughout your program and where prefetching would work.

For the second issue, see, for example, this (or similar) posts on non blocking I/O (please don't forget to upvote the referenced answer if helpful).

Community
  • 1
  • 1
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58