how to read and write on pipes to communicate with each other?
Create two named pipes with mkfifo("pipename", 0660);
Open them with
int readfd=open("pipename", O_RDONLY);
int writefd=open("pipename", O_WRONLY);
Be sure to open them in the same order in both processes. When you open the pipe for read in one, it will wait for the other process to open it for write before finishing.
Write to it with write(fd, buffer, size), read from it with read(fd, buffer, size)
Thank you for the help. But i have another issue now.
I open a FIFO to write
mkfifo ("pipe1", 0777);
int writefd = open ("pipe1", O_WRONLY);
now how do I write argv[1] to pipe1?
I did:
write (writefd, argv[1], BUF_PIPE);
when I run my program with an argument, it doesnt do anything. I have to hit ctrl+C to stop.
Any help!!
0777 gives the entire world read, write, and execute permissions to your fifo, and it doesn't even make sense to execute a fifo. I suggest you try the permissions I suggested, 0660, a better generic number than 777.
What in the world is BUF_PIPE? I can't find it in any include files.
argv[1] can vary in length, yes? If you don't have BUF_PIPE bytes in argv[1], you shouldn't use BUF_PIPE bytes from it. That would go beyond the end of the string and either send garbage or crash. (Or if BUF_PIPE is less, it'd only send part of the string.)
Since it's an ordinary NULL-terminated string, we can use strlen() to measure how long it is.
// for strlen
#include <string.h>
...
if(argc < 2)
{
fprintf(stderr, "Not enough arguments");
return(1);
}
char c='\n';
write(writefd, argv[1], strlen(argv[1]));
// You might need a newline for the pipe to flush
write(writefd, &c, 1);
Also remember that, like I said, named pipes wait for the other side to open them. If the other half of your program isn't going, it will wait for it. This is normal.
Also remember that, because of that, if you open the pipes in the wrong order, they will still wait for each other forever even when you run both. If they both try to open their own write-ends without the other process opening the read-end first, they'll be stuck.
All of this is only a guess because you didn't actually post your program, please do.
I am sorry, I meant to write PIPE_BUF instead of BUF_PIPE. and PIPE_BUF is in limits.h
Anyway, I am still not getting it. Here is all my scratch work
This is progA.c. progA gets an integer from argv[1] and writes it to pipe1. That progB reads.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char* argv [])
{
int readfd, writefd;
char buffer [100];
if (argc != 2)
printf ("Invalid number of argument. Enter an integer\n");
else
{
if (access ("pipe1", F_OK) == -1) //if pipe1 cannot be accessed
{
int res = mkfifo ("pipe1", 0660);
if (res != 0)
printf ("ERROR: Pipe cannot be created\n");
else;
}
}
writefd = open ("pipe1", O_WRONLY);
write (writefd, &argv[1], PIPE_BUF);
close (writefd);
return (0);
}
And here is progB that reads integer from pipe1, if positive integer then adds 10 to it and writes it to pipe2. And progA has to read pipe2.
ProgB
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
int main ()
{
int readfd;
char buffer [100];
//mkfifo ("pipe2", 0660);
readfd = open ("pipe1", O_RDONLY);
read (readfd, buffer, PIPE_BUF);
printf ("Buffer has %d\n", buffer);
return 0;
}
In my scratch work all I am trying to do is progA reads integer from argv[1], write it to pipe1 and pipe1 is read by progB and prints. So that I can understand the concept better.
I am looking at a lot of resources online and in my book but I cant put everything together. And how do I execute my programs?
thank you so much for all your help!
Both programs have to run at the same time.
./writer & # Run script1 in the background
./reader # Run reader in the foreground
wait # wait for writer to finish
Lots of errors in your code that I'll get to in a minute.
---------- Post updated at 11:30 AM ---------- Previous update was at 11:14 AM ----------
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // For strlen
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char* argv [])
{
int readfd, writefd;
// If you're going to read PIPE_BUF bytes, you might as well have
// a buffer big enough to hold PIPE_BUF bytes.
// Otherwise, if you ever read more than 100, it'll crash!
char buffer [PIPE_BUF];
if(argc != 2)
{
// Error messages belong on standard error.
fprintf (stderr, "Invalid number of argument. Enter an integer\n");
// Instead of chaining if/else 99 deep,
// quit the program early.
return(1);
}
// Good idea!
if (access ("pipe1", F_OK) == -1) //if pipe1 cannot be accessed
{
int res = mkfifo ("pipe1", 0660);
if (res != 0)
{
Error messages belong on standard error.
fprintf (stderr, "ERROR: Pipe cannot be created\n");
// Instead of chaining if/else 99 deep,
// quit the program early.
return(1);
}
}
writefd = open ("pipe1", O_WRONLY);
//argv[1] is already a pointer, no need to take its address.
// Don't write PIPE_BUF bytes unless you actually have PIPE_BUF bytes!
// The string is exactly strlen() bytes long.
//write (writefd, &argv[1], PIPE_BUF);
write(writefd, argv[1], strlen(argv[1]));
close (writefd);
return (0);
}
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
int main ()
{
int readfd, value;
ssize_t bytes;
// If you're going to read PIPE_BUF bytes, you might as well have
// a buffer big enough to hold PIPE_BUF bytes.
// Otherwise, if you ever read more than 100, it'll crash!
char buffer [PIPE_BUF];
//mkfifo ("pipe2", 0660);
readfd = open ("pipe1", O_RDONLY);
bytes=read (readfd, buffer, PIPE_BUF);
fprintf(stderr, "Read %d bytes\n", (int)bytes);
// Put a NULL terminator on the end so printf/strlen/etc won't crash.
buffer[bytes]='\0';
// buffer is a character array, not an integer.
// You can't do math on it until you convert it.
printf ("Buffer has %s\n", buffer);
if(sscanf(buffer, "%d", &value) != 1)
{
fprintf(stderr, "string '%s' is not a number\n", buffer);
return(1);
}
printf("value is %d\n", value);
// convert back into a string
sprintf(buffer, "%d", value+10);
printf("buffer is now %s\n", buffer);
close(readfd);
return 0;
}