reading a value from a pipe isn't working

lecardo

I have a program where two child processes are created belonging to the same father. Now the program starts by hitting control C and then works by pressing control Z each time.

Aim is for child 1 to write two numbers to child 2 and child two divides the numbers and writes the result back to child 1 that displays it. As a result two pipes are needed (fd and sd).

I got the first pipe working fine, so the numbers are sending over...in child 2(for debugging) it displays the correct number so if it had 8 and 2....the right answer of 4 is displayed in child 2. Now I can't seem to get this "4" or whatever the result is back to child 1.

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>


void handleSignal(int sig)
{
  if (sig == SIGTSTP)
    {
      return;
    }
}

int main()
{
    int fd[2];
    int sd[2];
    int pipe1 = 0;
    int pipe2 = 0;
    pid_t fork1 = 0;
    pid_t fork2 = 0;
    int num1, num2, result;
    int myJump = 0; 
    int returnResult = 99;

    signal(SIGINT, handleSignal);
    printf("Waiting for interrupt\n");
    pause();
    signal(SIGINT, SIG_IGN);
    pipe1 = pipe(fd);
    pipe2 = pipe(sd);
    //pipe checks been omitted...for simplicity

    fork1 = fork();
    //fork check been omited..for simplicity

    signal(SIGTSTP, handleSignal); //wait till control Z is pressed

    if (fork1 == 0)
    {

        dup2(fd[1], 1);
    dup2(sd[0], 0);
        close(fd[0]);
    close(sd[1]);

    while(1)
      {
            pause();
            int randNum1 = rand() % 9 + 1;
            fprintf(stderr, "Child 1: %d\n", randNum1);
            printf("%d\n", randNum1);
            fflush(stdout);
        scanf("%d", &returnResult);
        fprintf(stderr, "result in A :%d \n", returnResult);
      }

    }
    else if (fork1 > 0)
    {
      fork2 = fork();

      if (fork2 == 0)
        {
      signal(SIGTSTP, handleSignal);
      dup2(fd[0], 0);
      dup2(sd[1], 1);
      close(fd[1]);
      close(sd[0]);

      if (myJump == 0)
        {
          pause();
          scanf("%d", &num1);
          printf("CHild 2: %d\n", num1);
          myJump = 1;
        }
      if (myJump == 1)
        {
          while (1)
        {
          pause();
          scanf("%d", &num2);
          result = num2 / num1;
          fprintf(stderr, "result from B: %d \n", result);
          num1 = num2;
          printf("%d \n", result);
        }
        }

    }
      else
    {
      wait();
    }
    }
    else
      {
    printf("errror \n");
      }

    return 0;
}

If anyone could see whats wrong, if you was to run it...it works by hitting control C first then you have to keep hitting control Z. You can then see that the result from child A doesn't match that of B as shown below

Waiting for interrupt
^C^ZChild 1: 2
result in A :99 
^ZChild 1: 8
result in A :99 
result from B: 4 
^ZChild 1: 1
result in A :99 
result from B: 0 
Dmitri

The pipes are actually working fine... it's scanf() that's failing. When your second child process starts, it calls:

  if (myJump == 0)
    {
      pause();
      scanf("%d", &num1);
      printf("CHild 2: %d\n", num1); /* <== problem here */
      myJump = 1;
    }

...and the printf() there leaves "CHild 2: " as the next data in the sd[] pipe. Because of that, when your first child process calls scanf() to read the result from the second, scanf() fails and leaves returnResult unchanged. Since scanf() failed, the data is left on the stream, and future attempts to scanf() the result fail the same way.

How to fix it depends on what you want. If you want your second child process to just return the number it read as the result for the first pass, then just modify the offending printf() to write just the number without the text:

  if (myJump == 0)
    {
      pause();
      scanf("%d", &num1);
      printf("%d\n", num1); /* <== Changed: number only, no text */
      myJump = 1;
    }

I should add that although the change mentioned above will fix the problem, you should generally check the return from scanf() to see whether it succeeds and take appropriate action if it doesn't.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Reading resource from jar isn't working as expected

From Dev

PHP/MySQL reading color,names from tables isn't working

From Dev

Reading resource from jar isn't working as expected

From Dev

Pipe in C - scanf seems to be not working when reading from pipe

From Dev

Pipe in C - scanf seems to be not working when reading from pipe

From Dev

Linux pipe(): Reading from a pipe doesn't always unblock writers

From Dev

Removing " \ " from String isn't working for me

From Dev

Receiving object from Firebase isn´t working

From Dev

Daemon won't kill children that are reading from a named pipe

From Dev

Daemon won't kill children that are reading from a named pipe

From Dev

Why isn't sqlalchemy's default column value working

From Dev

parseInt isn't working and treating value like a string

From Dev

Posting value using Auto Submit isn't working

From Dev

Paste N Times Based on Column Value Isn't Working

From Dev

Using nested hash and a hash as default value isn't working as expected

From Dev

Why isn't margin-bottom:[value]% working?

From Dev

Posting value using Auto Submit isn't working

From Dev

Paste N Times Based on Column Value Isn't Working

From Dev

Flask-SQLAlchemy - Backref isn't working, value is None

From Dev

GetProcessesByName isn't working

From Dev

INSERT isn't working

From Dev

didSelectRowAtIndexPath isn't working

From Dev

MediaPlayer isn't working

From Dev

Why isn't & working?

From Dev

Toast isn't working

From Dev

Script isn't working

From Dev

GetProcessesByName isn't working

From Dev

Delegate isn't working

From Dev

CSS isn't working?