PDA

View Full Version : [SOLVED] Problem with reading and writing to FIFO pipe



Tcressy
February 21st, 2011, 09:56 AM
I'm trying to setup two simple processes (separate c files), where one writes to the respective pipe, and the other reads and displays the message in standard out. Problem is I keep on getting extra gibberish on the receiving end.
Here is my code:

Receiving end

#include "npipe.h"

int main(int argc, char** argv) {
char line[MAX_LINE];
int pipe;

// open a named pipe
pipe = open("/tmp/myFIFO", O_RDONLY);

// set the mode to blocking
int flags;
//flags &= ~O_NONBLOCK; //Default
//flags |= O_NONBLOCK;
//fcntl(pipe, F_SETFL, flags); /*Tried with and without changing the flags*/

// read the data from the pipe
read(pipe, line, MAX_LINE);

printf("Received line: %s\n", line);

// close the pipe
close(pipe);
return 0;
}Writing end

#include "npipe.h"

int main(int argc, char** argv) {
char line[MAX_LINE];
int pipe;

int stat;
if (stat = mkfifo("/tmp/myFIFO", 0600) < 0)
oops("Cannot make FIFO", stat);

// open a named pipe
pipe = open("/tmp/myFIFO", O_WRONLY);

while(1)
{
// get a line to send
printf("Enter line: ");
int i=0;
fgets(line, MAX_LINE, stdin);

if (strcmp(line, "quit\n") == 0)
break;

// actually write out the data and close the pipe
write(pipe, line, strlen(line));
}
// close the pipe
close(pipe);
return 0;
} This is the mutual header file.


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define MAX_LINE 80
#define oops(m,x) { perror(m); exit(x); }
My input to send is

~/Dev/npipe$ ./send
Enter line: hi
My output from receive is

~/Dev/npipe$ ./receive
Received line: hi
�Mp���b��fĿ�ia��_u���fĿ�0@x���fĿ�$cu��_u�p�fĿ��b�0 @x�{�I don't know how to get rid of the gibberish at the end. I don't want to use string manipulation to get rid of it, I would prefer to just have a "clean" string if you will. Any help would be appreciated.

Arndt
February 21st, 2011, 10:37 AM
I'm trying to setup two simple processes (separate c files), where one writes to the respective pipe, and the other reads and displays the message in standard out. Problem is I keep on getting extra gibberish on the receiving end.
Here is my code:

Receiving end

#include "npipe.h"

int main(int argc, char** argv) {
char line[MAX_LINE];
int pipe;

// open a named pipe
pipe = open("/tmp/myFIFO", O_RDONLY);

// set the mode to blocking
int flags;
//flags &= ~O_NONBLOCK; //Default
//flags |= O_NONBLOCK;
//fcntl(pipe, F_SETFL, flags); /*Tried with and without changing the flags*/

// read the data from the pipe
read(pipe, line, MAX_LINE);

printf("Received line: %s\n", line);

// close the pipe
close(pipe);
return 0;
}Writing end

#include "npipe.h"

int main(int argc, char** argv) {
char line[MAX_LINE];
int pipe;

int stat;
if (stat = mkfifo("/tmp/myFIFO", 0600) < 0)
oops("Cannot make FIFO", stat);

// open a named pipe
pipe = open("/tmp/myFIFO", O_WRONLY);

while(1)
{
// get a line to send
printf("Enter line: ");
int i=0;
fgets(line, MAX_LINE, stdin);

if (strcmp(line, "quit\n") == 0)
break;

// actually write out the data and close the pipe
write(pipe, line, strlen(line));
}
// close the pipe
close(pipe);
return 0;
} This is the mutual header file.


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define MAX_LINE 80
#define oops(m,x) { perror(m); exit(x); }
My input to send is
My output from receive is
I don't know how to get rid of the gibberish at the end. I don't want to use string manipulation to get rid of it, I would prefer to just have a "clean" string if you will. Any help would be appreciated.

With 'read', you read arbitrary data, possibly including Nul characters. That means it does not write a Nul to the end in order to produce a C string. Instead it returns how many bytes were received, as the return value of 'read'.

From the manual page:


RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of
file), and the file position is advanced by this number.

greenmonkeey
February 21st, 2011, 10:44 AM
i can run it..

slavik
February 21st, 2011, 11:05 AM
use fopen/fgets in reader and fopen/fprintf in writer.

Tony Flury
February 21st, 2011, 11:23 AM
With 'read', you read arbitrary data, possibly including Nul characters. That means it does not write a Nul to the end in order to produce a C string. Instead it returns how many bytes were received, as the return value of 'read'.

From the manual page:


RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of
file), and the file position is advanced by this number.


@Tcressy
In other words - you need to use the return value of the read function call to re-insert the NUL character into your received string.

Using Slaviks suggestion using fprintf, fgets will handle the Nul characters etc for you, and give you all the formatting power too - should you need it.

@greenmonkeey : The reason your run may work "properly" as it all depends on the data in the receiving buffer - if when you run your code the memory for your buffer happens to be filled with zeros (or even just have a zero in the right place) then the code will appear to work correctly, however arrays are not initialised to all zeros in C, and therefore you should not rely on it always working.

Tcressy
February 21st, 2011, 07:31 PM
@Tcressy
In other words - you need to use the return value of the read function call to re-insert the NUL character into your received string.

Using Slaviks suggestion using fprintf, fgets will handle the Nul characters etc for you, and give you all the formatting power too - should you need it.

@greenmonkeey : The reason your run may work "properly" as it all depends on the data in the receiving buffer - if when you run your code the memory for your buffer happens to be filled with zeros (or even just have a zero in the right place) then the code will appear to work correctly, however arrays are not initialised to all zeros in C, and therefore you should not rely on it always working.

Thanks a bunch, works...and better yet I understand it.

I know i could have used fprintf and family, but I needed to use the bare system calls for academic purposes.

THANKS!