I am trying to write 2 programs that will talk to each other using fifo pipe. I used the example here (section 5.2), but I changed the mknod there to mkfifo and tried to change gets to fgets. This is the code (of one program which writes into the fifo):
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h> /*mkfifo, open */
#include <sys/wait.h>
#include <sys/stat.h> /* mkfifo, open */
#include <fcntl.h> /*open */
#define FIFO_PATH "/home/hana/Desktop"
#define BUFFER_SIZE 300
int main()
{
char buffer[BUFFER_SIZE];
int fd;
int wStatus;
mkfifo(FIFO_PATH, 666);
printf("waiting for readers\n");
fd = open(FIFO_PATH, O_RDWR);
while (fgets(buffer, BUFFER_SIZE, fd), !feof(stdin))
{
if ((wStatus = write(fd, buffer, strlen(buffer))) == -1)
perror("write");
else
printf("speak: wrote %d bytes\n", wStatus);
}
return 0;
}
I get a compilation error: passing argument 3 of fgets makes pointer from integer. So fgets is expecting FILE* and not file descriptor. What should I do? change something so that fgets works? use another function?
I am compiling with gcc (ansi, pedantic).
Thanks
mkfifo()
just creates special node in filesystem. And you are free to open it in any way. Actually there are two alternatives - POSIX "non-buffered" I/O: open()/write()/read()
or standard buffered I/O: fopen()/fread()/fwrite()
. First family operates on file descriptors while second one uses so called file streams: FILE
. You can not mix these APIs freely. Just choose one and stick to it.
Standard I/O library offers some useful extra capabilities comparing to low-level non-buffered I/O. Like fgets()
that you're trying to use. In this situation would be reasonable to use standard streams and replace open()
with:
FILE* stream = fopen(FIFO_PATH, "r+");
Thus program will use FILE*
instead of plain file descriptors. Also write()
need to be changed to fwrite()
immediately followed by fflush()
to guarantee that written data are passed to FIFO.
P.S. In case of necessity it is possible to "wrap" low-level descriptors returned by open()
(or something other) with standard FILE*
. See fdopen()
. But it is much like a workaround to use standard I/O API with special file objects that can not be opened with fopen()
.