C pipe to write / read sequence of doubles fails

mimmo970

For this C project I am trying to use a pipe to get a parent process to communicate with a child. The child is supposed to read lines (one each second) from a txt file (containing real numbers) and use a pipe to supply the parent, which in turn should read from the pipe and write the numbers into a log file. However the parent process only reads a sequence of 0.000000. Here is my code:

#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <wait.h>
#define MAX_I 5
#define delay 1
void read_input(FILE *fp);

FILE *file_log;
int status;
pid_t pid;
int pipeFD[2];

int main(int argc, char **argv) {
//initialize
    FILE *fp;

    if (argc != 2){
    if ((fp = fopen("input.txt", "r")) == NULL) {
        printf("Error! opening file");
        exit(1);}
    }
    else{
        fp = fopen(argv[1], "r");
        }

    if (pipe(pipeFD) == -1){    /* creates a pipe */
    fprintf(stderr, "\nERROR: pipe() failed\n");
    exit(1);}

    file_log=fopen("file.log","w+"); /*open the log file*/

    pid=fork();
    if(pid==0) {//child process
    printf ("%d starts \n", getpid());
    close(pipeFD[0]);//close read end for child
    read_input(fp);
    return 0;
    exit(status);
    }else{//parent 
    double speed_read;
    close(pipeFD[1]);//close write end for parent
    while(1){
        if (read(pipeFD[0], &speed_read, sizeof(speed_read)) >0){
        if (speed_read<0)
        break;
        fprintf(file_log, "%f \n", speed_read); 
        printf("process %d received %f from child \n",getpid(),speed_read);
        }else
            printf("Nothing there to read \n");  
        }
    printf("parent ended \n");
    wait(&status);
    fclose(fp);
    fclose(file_log);
    }
    return 0;
}

void read_input(FILE *fp){
    char *line = NULL;
    double speed;
    int i=0; size_t len = 0; double exit_sign =-10.0;
    while(getline(&line, &len, fp) != -1) { 
        speed=atof(line);
        i++;
        if(i>MAX_I){//reads up to MAX_I rows of input
                        printf("I'll send the exit sign to parent now\n");
                        write(pipeFD[1], &exit_sign, sizeof(double));
                        free(line);
                        break;      
                    }
        if(write(pipeFD[1], &speed, sizeof(double)>0)){
            printf("%d at %d wrote that speed is %f\n",getpid(), i,speed);
        }else{printf("Write on pipe failed\n");}
        sleep(delay);
        }
    free(line);
}

Here is what is printed:


15032 starts

15032 at 1 wrote that speed is 0.345670

process 15031 received 0.000000 from child

15032 at 2 wrote that speed is 12.678890

process 15031 received 0.000000 from child

15032 at 3 wrote that speed is 34.789870

process 15031 received 0.000000 from child

15032 at 4 wrote that speed is 0.000000

process 15031 received 0.000000 from child

15032 at 5 wrote that speed is 12.009288

process 15031 received 0.000000 from child

I'll send the exit sign to parent now

parent ended


Likewise the log file consists in the following:

0.000000

0.000000

0.000000

0.000000

0.000000

bruno

in read_input the line :

if(write(pipeFD[1], &speed, sizeof(double)>0)){

must be

if(write(pipeFD[1], &speed, sizeof(double))>0){

in your case you do not write sizeof(double) bytes but only 1

Note read_input does two times free(line); with an undefined behavior, you must remove the one when if(i>MAX_I){

After the corrections, compilation and execution :

pi@raspberrypi:/tmp $ gcc -g -Wall p.c
pi@raspberrypi:/tmp $ cat input.txt 
1.2
2.3
3.45
7.8
9.12
12.345
pi@raspberrypi:/tmp $ ./a.out
15121 starts 
15121 at 1 wrote that speed is 1.200000
process 15120 received 1.200000 from child 
15121 at 2 wrote that speed is 2.300000
process 15120 received 2.300000 from child 
15121 at 3 wrote that speed is 3.450000
process 15120 received 3.450000 from child 
15121 at 4 wrote that speed is 7.800000
process 15120 received 7.800000 from child 
15121 at 5 wrote that speed is 9.120000
process 15120 received 9.120000 from child 
I'll send the exit sign to parent now
parent ended 
pi@raspberrypi:/tmp $ cat file.log
1.200000 
2.300000 
3.450000 
7.800000 
9.120000 
pi@raspberrypi:/tmp $ 

Out of that when you detect the EOF and do printf("Nothing there to read \n"); to also do a break; to finish the while seems better. Note you can also send exit_sign when you reach the end of the input file in read_input. If you don't the parent never ends writing Nothing there to read if the input file has less than MAX_I lines


A pipe is a stream but reading or writing pipe data is atomic if the size of data written is not greater than PIPE_BUF where PIPE_BUF is at least 512 bytes, and 4096 under Linux

So in your case where in main you read as fast as possible and the read_input function sleeps, while you read and write the same small amount of bytes, you have no risk. Else as in general when you read in a stream you need to loop until you get the expected amount of bytes, for instance replacing the use of read by a call to a function like :

int read_block(int f, char * p, size_t sz)
{
  ssize_t n;

  while ((n = read(f, p, sz)) > 0) {
    if ((sz -= (size_t) n) == 0)
      return 1;
    p += n;
  }

  return -1;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to write and read from a named pipe in C?

From Dev

C read and write from named pipe

From Dev

Multiple read and write in a single pipe

From Dev

write on pipe in C

From Dev

Read an entire pipe - c

From Dev

GATTTool fails to read/write characteristics

From Dev

Write and read on pipe a list of unknown size

From Dev

What is the simplest way to pipe from a Read to a Write

From Dev

Read integer or doubles from JsonArray in C#

From Linux

Problem with C++ pipes when doing a read and write on the same pipe in a process

From Dev

How to fix data write or read using pipe in c program is giving wrong output?

From Dev

Angular Pipe to remove doubles

From Dev

c pipe read string is empty

From Dev

Continuously read from a pipe in C

From Dev

Hadoop MapReduce read and write Sequence File

From

How can I properly write the `Read` and `Write` the `net.Pipe()`

From Dev

Why read_JPEG_file() fails to write image (libjpeg/jpeg-turbo) in C?

From Dev

Understanding read + write in c

From Dev

write Error: Broken Pipe in C using execlp

From Dev

how to wait an exec finishes to write in pipe in C

From Dev

How to write an array of doubles to a file very fast in C#?

From Dev

C++ How to write full precision of doubles into a .dat file

From Java

Can I use asyncio to read from and write to a multiprocessing.Pipe?

From Dev

Can I use pipe as read at parent and write in child?

From Linux

Why does read block on a pipe until the write end is closed?

From

How do the io.Pipe Write() and Read() functions work?

From

Download a zip file using io.Pipe() read/write golang

From Dev

Does a read() in parent process wait for a child write() in a pipe?

From Dev

Execute a console program, write to standard input and read result with pipe

Related Related

  1. 1

    How to write and read from a named pipe in C?

  2. 2

    C read and write from named pipe

  3. 3

    Multiple read and write in a single pipe

  4. 4

    write on pipe in C

  5. 5

    Read an entire pipe - c

  6. 6

    GATTTool fails to read/write characteristics

  7. 7

    Write and read on pipe a list of unknown size

  8. 8

    What is the simplest way to pipe from a Read to a Write

  9. 9

    Read integer or doubles from JsonArray in C#

  10. 10

    Problem with C++ pipes when doing a read and write on the same pipe in a process

  11. 11

    How to fix data write or read using pipe in c program is giving wrong output?

  12. 12

    Angular Pipe to remove doubles

  13. 13

    c pipe read string is empty

  14. 14

    Continuously read from a pipe in C

  15. 15

    Hadoop MapReduce read and write Sequence File

  16. 16

    How can I properly write the `Read` and `Write` the `net.Pipe()`

  17. 17

    Why read_JPEG_file() fails to write image (libjpeg/jpeg-turbo) in C?

  18. 18

    Understanding read + write in c

  19. 19

    write Error: Broken Pipe in C using execlp

  20. 20

    how to wait an exec finishes to write in pipe in C

  21. 21

    How to write an array of doubles to a file very fast in C#?

  22. 22

    C++ How to write full precision of doubles into a .dat file

  23. 23

    Can I use asyncio to read from and write to a multiprocessing.Pipe?

  24. 24

    Can I use pipe as read at parent and write in child?

  25. 25

    Why does read block on a pipe until the write end is closed?

  26. 26

    How do the io.Pipe Write() and Read() functions work?

  27. 27

    Download a zip file using io.Pipe() read/write golang

  28. 28

    Does a read() in parent process wait for a child write() in a pipe?

  29. 29

    Execute a console program, write to standard input and read result with pipe

HotTag

Archive