Read / Write through a pipe in C

Today I started working with pipe () and fork () and exec () in C and now I have a problem:

The main program creates two pipes and forks. The child process exec () in another program, which is now just a test program that reads from stdin, communicates with its parent, and writes data to stdout ther. The main program should receive data, communicate with a SQLite 3 database, and return data using pipes. This part of the problem is solved, the pipes are open and closed correctly and there is a connection.

Then the problem is that in the child process (the one called with exec ()) at a certain point, I have this:

printf("Strid sent: %s\n", strid);
write(4,strid,sizeof(strid));

printf("Str sent: %s\n", str);
write(4,str,sizeof(str));

      

And the parent should read this part correctly:

read(select[0],strid, sizeof(strid));
printf("Strid recived: %s\n",strid);
int id = atoi(strid);
printf("Id recived: %d\n",id);

read(select[0],buffer, sizeof(buffer));
printf("Buffer recived: %s\n",buffer);

      

But what I get from these printf:

Strid sent: 1
Str sent: start
Strid recived: 1
Id recived: 1
Buffer recived: 7  (and other strange characters)

      

As you can see, the problem is getting the second command (and this part is copied as is, there is no other code there).

I must also say that the variable "buffer" that returns str is declared as a buffer char [20] and was not used until read ()

Thank you in advance!

+3


source to share


2 answers


After reading, you need to add a trailing 0

byte at the end, before printing, something like

int len = read(select[0], buffer, sizeof(buffer) - 1);
if (len < 0) {
    perror("read error");
} else {
    buffer[len] = 0;
    printf("Buffer recived: %s\n", buffer);
}

      



So, the important thing, read the man pageread

or actually the man page of any function before using it ...

Alternatively use some stdio.h function that appends a string terminating 0

itself, perhaps fgets

if reading line by line is ok.

+3


source


Pipes

do not track "boundaries" between recording modes. Therefore, if you have multiple records on a pipe, all data from those records can be returned in response to one read. So if you send a string (for example) followed by an integer and you try to read the string in the buffer, it will receive both the string and the next integer integer in the buffer, similar to garbage at the end of the string, and the size returned by the read , there will be more.

Also, if the pipe fills up, the record might not write all the data you asked for it - it can only write as much as it can now, and you'll have to write the rest later.



so ALWAYS check the return values ​​of your calls read

and write

and be prepared to receive less (or more for read

) than you expect.

0


source







All Articles