named fifo error - C programming - c

I'm trying to write and read from a named fifo with some methods... Apparently when I run it gets stuck on write_fifo(0) for no reason... So my question is am I using named fifo in the right way? Or does the unlink method mess with my program? When and where can I unlink a named fifo.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
void write_fifo(int s)
{
printf("write_fifo");
int writing, n;
writing = open("myFIFO",O_WRONLY);
n = write(writing, &s, sizeof(s));
printf("write: %i byte.\n", n);
close(writing);
unlink("myFIFO");
}
int read_fifo()
{
printf("read_fifo");
int reading, n, s;
reading = open("myFIFO", O_RDONLY);
n = read(reading , &s, sizeof(s));
printf("read: %i byte: %d\n", n, s);
close(reading);
unlink("myFIFO");
return s;
}
int main()
{
printf("beginning");
printf("removing myFIFO");
if (mkfifo("myFIFO", FILE_MODE) == -1)
{
perror("myFIFO");
exit(1);
}
write_fifo(0);
printf("\n\n\n\n\n\n\nReading %d",read_fifo());
return 0;
}

Related

How to send properly data in fifo server

I am trying to create a simple fifo client/server. Whenever I compile the program and try to type some data in client, in server I am getting weird outputs such as:
How can I fix this?
server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
mkfifo("/tmp/my_fifo", 0666);
for(;;){
fd = open("/tmp/my_fifo", O_RDONLY);
int d;
char buf[64];
read(fd, buf, sizeof(buf));
sscanf(buf, "%d", &d);
close(fd);
}
return 0;
}
client:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(){
int fd;
fd = open("/tmp/my_fifo", O_WRONLY);
int d;
scanf("%d", &d);
char buf[32];
sprintf(buf, "%d", d);
write(fd, buf,strlen(buf));
close(fd);
return 0;
}

fifo linux - write() function terminates the program abruptly

I'm implementing a pipe in C, where multiples producer programs (9 in my case) write data to one single consumer program.
The problem is that some producers (some times one or two) exit the program abruptly when calling the write() function.
The code is simple, here is the producer code:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
void send(unsigned int * msg){
int fd, msg_size;
int r;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
fd = open(myfifo, O_WRONLY);
if(fd == -1){
perror("error open SEND to fifo");
}
r = write(fd, msg, MSG_SIZE_BYTES);
if(r == -1){
perror("error writing to fifo");
}
close(fd);
printf("Message send\n");
}
int main(int argc, char *argv[]){
int cluster_id = atoi(argv[1]);
unsigned int msg[1];
msg[0] = cluster_id;
while(1){
printf("Press a key to continue...\n");
getchar();
send(msg);
}
}
And here is the consumer code
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int receive(unsigned int * received_msg){
int fd, msg_size;
int ret_code;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
fd = open(myfifo, O_RDONLY);
if(fd == -1)
perror("error open RECV to fifo");
ret_code = read(fd, received_msg, MSG_SIZE_BYTES);
close(fd);
if (ret_code == -1){
printf("\nERROR\n");
return 0;
}
return 1;
}
void main(){
mkfifo("/tmp/myfifo", 0666);
unsigned int msg[1];
while(1){
receive(msg);
printf("receive msg from id %d\n", msg[0]);
}
}
I'm compiling the producers and consumer with the following command: gcc -o my_progam my_program.c
To reproduce the problem, you need to open 9 terminals to run each producer and 1 terminal to run the consumer.
Execute the consumer: ./consumer
Execute the producer in all terminals simultaneously, passing to each execution an associated ID passed by command line. Ex: ./producer 0, ./producer 1.
After the producer send messages some times (10 in average), one arbitrary producer will abruptly stop its execution, showing the problem.
The following image depicts the execution:
Terminals ready to execute
The following image depicts the error on producer ID 3
Error on producer 3
Thanks in advance
It looks like the consumer program closes the reading end of the pipe after reading data:
fd = open(myfifo, O_RDONLY);
if(fd == -1){
perror("error open RECV to fifo");
}
ret_code = read(fd, received_msg, MSG_SIZE_BYTES);
close(fd);
All other writers, which are currently trying to write() data (i.e. are blocked in the write()-syscall) now receive a SIGPIPE, which leads to program termination (if no other signal handling is specified).
Your consumer program may not close the filedescriptor while producers are writing. Just read the next datum without closing.
Problem SOLVED:
The problem is that I was opening and closing the FIFO at each message, generating a Broken pipe in some write attempts. Removing the close() and inserting the open() function for BOTH producer and consumer at the begging of the code instead inside the loop solved the problem.
Here is the code of producer with the bug fixed:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int my_fd;
void send(unsigned int * msg){
int fd, msg_size;
int r;
char buffer [5];
char myfifo[50] = "/tmp/myfifo"
if(fd == -1){
perror("error open SEND to fifo");
}
r = write(my_fd, msg, MSG_SIZE_BYTES);
if(r == -1){
perror("error writing to fifo");
}
//close(fd);
printf("Message send\n");
}
int main(int argc, char *argv[]){
int cluster_id = atoi(argv[1]);
unsigned int msg[1];
msg[0] = cluster_id;
my_fd = open("/tmp/myfifo", O_WRONLY);
while(1){
printf("Press a key to continue...\n");
getchar();
send(msg);
}
}
And here is the consumer code:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int my_fd;
int receive(unsigned int * received_msg){
int fd, msg_size;
int ret_code;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
if(fd == -1)
perror("error open RECV to fifo");
ret_code = read(my_fd, received_msg, MSG_SIZE_BYTES);
//close(fd);
if (ret_code == -1){
printf("\nERROR\n");
return 0;
}
return 1;
}
void main(){
mkfifo("/tmp/myfifo", 0666);
my_fd = open("/tmp/myfifo", O_RDONLY);
unsigned int msg[1];
while(1){
receive(msg);
printf("receive msg from id %d\n", msg[0]);
}
}
Thank you all!!

C - Scanf not blocking for named pipe / FIFO

Usually when a program call a scanf it waits until something is available in stdin to read from it. I am currently making a fifo for input and another one for output that will be used by another process to write an read from a background proccess. But, the background process seem not to wait for any scanf in it, does anyone know why?
Here is the code:
Background:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in, err;
char *cFifo = "/tmp/out";
char *cInFifo = "/tmp/in";
mkfifo(cFifo, S_IRUSR|S_IWUSR);
mkfifo(cInFifo, S_IRUSR|S_IWUSR);
out = open(cFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
in = open(cInFifo, O_RDWR|O_TRUNC|O_NONBLOCK);
dup2(out, STDOUT_FILENO);
dup2(out, STDERR_FILENO);
dup2(in, STDIN_FILENO);
scanf("%*c");
while(1)
{
scanf("%*c");
printf("Hello\n");
fflush(stdout);
}
return 0;
}
Foreground:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
int main()
{
int out, in;
size_t i = 0;
char bufOut[1024];
char *cFifo = "/tmp/out";
char *cFifoIn = "/tmp/in";
out = open(cFifo, O_RDONLY);
in = open(cFifoIn, O_WRONLY);
while(1)
{
i =0;
while(!i)
{
i = read(out, bufOut, 1024);
}
if(i)
write(STDOUT_FILENO, bufOut, i);
}
return 0;
}
I have already tried to force write on the new input fifo but the result is the same.
I already checked for errors, and everything return the expected values, no -1 or any other errors associated with each function

Reading and writng with named pipes C

I'm writing a program that should run indefinitely maintaining the value of a variable. Two other programs could change the value of the variable. I use named pipes to receive and send the variable value to external programs.
Here is my code for the manager of the variable.
manager.c:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
char a = 'a';
void *editTask(void *dummy)
{
int fd;
char* editor = "editor";
mkfifo(editor, 0666);
while(1)
{
fd = open(editor, O_RDONLY);
read(fd, &a, 1);
close(fd);
}
}
void *readTask(void *dummy)
{
int fd;
char* reader = "reader";
mkfifo(reader, 0666);
while(1)
{
fd = open(reader, O_WRONLY);
write(fd,&a,1);
close(fd);
}
}
int main()
{
pthread_t editor_thread, reader_thread;
pthread_create(&editor_thread, NULL, editTask, NULL);
pthread_create(&reader_thread, NULL, readTask, NULL);
pthread_join (editor_thread, NULL);
pthread_join (reader_thread, NULL);
return 0;
}
This program uses pthreads to separately get external values for the variable and to communicate the current value of the variable to external programs.
The program that is able to write values to the variable is:
writer.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv)
{
if(argc != 2)
{
printf("Need an argument!\n");
return 0;
}
int fd;
char * myfifo = "editor";
fd = open(myfifo, O_WRONLY);
write(fd, argv[0], 1);
close(fd);
return 0;
}
The program that could read the current value is:
reader.c:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd;
char * myfifo = "reader";
fd = open(myfifo, O_RDONLY);
char value = 'z';
read(fd, &value, 1);
printf("The current value of the variable is:%c\n",value);
close(fd);
return 0;
}
I ran these programs in my Ubuntu system as follows:
$ ./manager &
[1] 5226
$ ./writer k
$ ./reader
bash: ./reader: Text file busy
Why doesn't my system allow me to run this program?
Thank you.
You are trying to call both the FIFO and the reader program "reader".
Also, you have no error checking. You have no idea whether those calls to mkfifo and open succeeded or not. Adding this is critical before you attempt to do any troubleshooting.

problem with fifos linux

I am having problem debugging why n_bytes in read_from_fifo function in client.c doesn't correspond to the value written to the fifo. It should only write 25 bytes but it tries to read a lot more (1836020505 bytes (!) to be exact). Any idea why this is happening?
server.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <sys/stat.h>
typedef enum { false, true } bool;
//first read the int with the number of bytes the data will have
//then read that number of bytes
bool read_from_fifo(int fd, char* var)
{
int n_bytes;
if (read(fd, &n_bytes, sizeof(int)))
{
printf("going to read %d bytes\n", n_bytes);
if (read(fd, var, n_bytes))
printf("read var\n");
else {
printf("error in read var. errno: %d\n", errno);
exit(-1);
}
}
return true;
}
int main()
{
mkfifo("/tmp/foo", 0660);
int fd = open("/tmp/foo", O_RDONLY);
char var[100];
read_from_fifo(fd, var);
printf("var: %s\n", var);
return 0;
}
client.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
typedef enum { false, true } bool;
//first write to fd a int with the number of bytes that will be written afterwards
bool write_to_fifo(int fd, char* data)
{
int n_bytes = (strlen(data)) * sizeof(char);
printf("going to write %d bytes\n", n_bytes);
if (write(fd, &n_bytes, sizeof(int) != -1))
if (write(fd, data, n_bytes) != -1)
return true;
return false;
}
int main()
{
int fd = open("/tmp/foo", O_WRONLY);
char data[] = "some random string abcdef";
write_to_fifo(fd, data);
return 0;
}
Help is greatly appreciated. Thanks in advance.
The return value for an error from read(2) is -1, not 0. So your if statement for the first 4-byte read, at least, is wrong.
Did you verify if nbytes printed by read_from_fifo() function displayed the correct value ?
Just notice that on write(fd, data, n_bytes) you did not write the end of string char '\0', and whenever you read it by read(fd, var, n_bytes), you did not added a '\0' to the end of string just read, so the printf("var: %s\n", var); could display a not \0 ended string resulting unpredicted results.
I have found the solution myself.
The problem is a ')' believe it or not. The n_bytes variable is correct, the problem is that I am not writing that to the fifo.
this (write(fd, &n_bytes, sizeof(int) != -1))
should be this (write(fd, &n_bytes, sizeof(int)) != -1)
Thanks anyway for your answers.

Resources