Reputation: 1103
I want to create a named pipe and then write to it and after that I want read it. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#define FIFO "fifo0001"
int main(intargc, char *argv[]){
char input[256];
FILE *fp;
char str[50];
printf("Please write some text:\n");
scanf("%s", input);
unlink(FIFO); /* Because it already exists, unlink it before */
umask(0);
if(mkfifo(FIFO, 0666) == -1){
printf("Something went wrong");
return EXIT_FAILURE;
}
if((fp = fopen(FIFO, "a")) == NULL){
printf("Something went wrong");
return EXIT_FAILURE;
}
fprintf(fp, "%s", input);
if(fgets(str, 50, fp) != NULL){
puts(str);
}
fclose(fp);
return EXIT_SUCCESS;
}
After I write a text, nothing happen anymore. And there is no message. I have to quit the program with STRG C. Someone know what is wrong? I have to use the functions mkfifo, fopen, fprintf, fgets and fclose. So would be nice if I could keep them into the code.
Upvotes: 3
Views: 10813
Reputation: 60145
FIFO's don't work nice with just one thread. You'll get blocked on a reading open until a writing open is performed and vice versa, so you'll need to open in RDWR (non-portable) mode or with RDONLY in one thread and WRONLY in another or you'll get blocked.
E.g.:
fp = fopen(FIFO, "r+");
then you'll need to write no more than the size of the FIFO buffer (which is ulimit -p
* 512 ?) (or else you get blocked). After that, you'll need to read no more than what you've written.
All in all, this should work (although it's not the usual way to use FIFOs):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#define FIFO "fifo0001"
int main(int argc, char *argv[]){
char input[256] = "hw";
FILE *fp;
char str[50];
printf("Please write some text:\n");
scanf("%s", input); //!!!
size_t input_len = strlen(input);
unlink(FIFO); /* Because it already exists, unlink it before */
umask(0);
if(mkfifo(FIFO, 0666) == -1){
printf("Something went wrong");
return EXIT_FAILURE;
}
if((fp = fopen(FIFO, "r+")) == NULL){
printf("Something went wrong");
return EXIT_FAILURE;
}
fprintf(fp, "%s", input);
if(fgets(str, input_len+1, fp) != NULL){
puts(str);
}
fclose(fp);
return EXIT_SUCCESS;
}
Upvotes: 5