user2228135
user2228135

Reputation: 239

Program in C language using pipe and fork?

I have an assignment where i have to solve this problem...im a complete newbie to C and im still trying to learn C.

so here is the question

Write a program that creates a pipe and a child process. The parent repeatedly sets an alarm for 15 seconds. When the alarm is triggered, the parent calculates the number of seconds and microseconds elapsed since it started and sends these through the pipe to the child. On obtaining the information the child displays them on the screen. The whole continues for 2 minutes.

i have attempted this question, but i have got many errors..

here is my solution..

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>


int main(void)
{
        int     fd[2], nbytes;
    int fd2[2];
        pid_t   childpid;
        char    readbuffer1[80];
    char    readbuffer2[80];

         clock_t start, stop;
         long count;
         double time_sec, time_milli;
    const char* time1, time2;

        pipe(fd);
    pipe(fd2);
        childpid = fork();



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

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


        /* Read in a string from the pipe */
        read(fd[0], readbuffer1, sizeof(readbuffer1));
        read(fd2[0], readbuffer2, sizeof(readbuffer2));
                printf("Received string 1: %s", readbuffer1);
        printf("Received string 2: %s", readbuffer2);

        }
        else
        {
                start = clock();
                /* Parent process closes up output side of pipe */

                alarm(15);
                /* Send "string" through the output side of pipe */


                stop = clock();



                time_sec = (double)(stop-start)/CLOCKS_PER_SEC;
        time_milli = time_sec*1000;
        sprintf(&time1,"%f",time_sec);
        sprintf(&time2,"%f",time_milli);
        close(fd[0]);
        write(fd[1], time1, (strlen(time1)+1));
        write(fd2[1], time2, (strlen(time2)+1));

        }

        return(0);
}

how do i make this run for 2 mins? how can i repeatedly run the alarm for 15 seconds? please help....

Upvotes: 1

Views: 5430

Answers (3)

SpecialTrooper
SpecialTrooper

Reputation: 104

First of all, what errors do you get, if you run your code?

The first problem I see in your code is that you are creating two pipes, not one as mentioned in the question!!!

This should create a proper pipe, where you can do your stuff

Edit: I just added a simple one time communication in my code. All you have to do is wrap everything in a loop that runs 2 minutes and sends the alarm at the right time.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
        int pipefd[2];
        int rt;
        pid_t child = 0;

        // An array with some values
        char charBuffer[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        // A buffer we use to communicate over the pipe
        char outputBuffer[10];

        if( pipe(pipefd) == -1 ) // Create new pipe
        {
                fprintf(stderr, "Failed to create pipe\n");
                exit(1);
        }

        child = fork();        // Create new Child

        if( !child )
        {
                printf("child created\n");
                close(pipefd[1]); // Child is read only

                // Wait for your alarm here
                while( read(pipefd[0], (void*)&outputBuffer, 10) > 0 )
                {
                    printf("Child received something over the pipe\n");
                    // Write output direct to stdout
                    rt = write(STDOUT_FILENO, &outputBuffer, 10);
                    rt = write(STDOUT_FILENO, "\n", 1);
                }
        }
        else if( child == -1 )
        {
                fprintf(stderr, "Error on fork - no child\n");
                exit(2);
        }
        else if( child > 0 )
        {
                close(pipefd[0]); // Parent is write only

                // Write our values to the pipe
                rt = write(pipefd[1], &charBuffer, 10);

                printf("Parent finished writing\n");
                close(pipefd[1]); // Signal writing is finished
        }

        return 0;
}

Upvotes: 1

ZillGate
ZillGate

Reputation: 1183

Ok. I've corrected your code as follow. You can directly compile and run it. It should work.

Your code has several issues:

  1. You should allocate memory spaces for time1 and time2 before sprintf to them.

  2. You should use time() instead of clock(). See: clock() function always returning 0

  3. Use sleep() instead of alarm()

Hope this is helpful!

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>


int main(void){


int     fd[2];
int     nbytes;
int     fd2[2];
pid_t   childpid;
char    readbuffer1[80];
char    readbuffer2[80];

time_t start, stop;
long count;
double time_sec, time_milli;
char* time1;
char* time2;

pipe(fd);
pipe(fd2);
childpid = fork();

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

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

      /* Read in a string from the pipe */
      read(fd[0], readbuffer1, sizeof(readbuffer1));
      read(fd2[0], readbuffer2, sizeof(readbuffer2));

          printf("Received string 1: %s", readbuffer1);
      printf("Received string 2: %s", readbuffer2);
    }
    else
    {

        close(fd[0]);

        time(&start);

          sleep(15);

          time(&stop);

      time_sec = stop-start;
      time_milli = time_sec*1000;

      time1 = malloc(80);
      time2 = malloc(80);

      sprintf(time1,"%f",time_sec);
      sprintf(time2,"%f",time_milli);


      write(fd[1], time1, (strlen(time1)+1));

      write(fd2[1], time2, (strlen(time2)+1));

    }
}

Upvotes: 3

Olaf Dietsche
Olaf Dietsche

Reputation: 74098

You can just sleep for 15 seconds and wrap that into a loop

for (int i = 0; i < 8; ++i) {
    sleep(15);
    /* do something, talk to your child, ... */
}

Upvotes: 0

Related Questions