简体   繁体   中英

Script bash write in a fifo and c program read from it

I have a bash script that writes to a fifo. And I have a C program that reads from the same fifo.

I am sure the script works because I've tried to read from the fifo with another script and everything worked. But something does not work in C program. When I run my script and when I run the C program it's like they await each other. Here's the code.

The script is (the writer):

#!/bin/bash

fifo_name="myfifo";

# Se non esiste, crea la fifo;
[ -p $fifo_name ] || mkfifo $fifo_name;

echo "3" > $fifo_name;
echo "6" > $fifo_name;

And here the c program (the reader) :

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX_BUF 1024

int main(int argc, char *argv[])
{
    int fd, i;
    char * myfifo = argv[1];
    char buf[MAX_BUF];

    fd = open(myfifo, O_RDONLY);

    while (1) {
        if(read(fd, buf, MAX_BUF) > 0)
        {
            printf("Received: %s\n", buf);      
        }
    }

    close(fd);

    return 0;
}

Where am I going wrong?

Thank you.

It works fine, provided you do the following.

  • Ensure that, when you run the C program, you provide an argument with the correct pathname to the FIFO file.

  • Run the shell program first since it's the one that will create the FIFO file if it doesn't yet exist.

You can alleviatethe second problem by having the C program exit if the FIFO isn't already there, with something like:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX_BUF 1024

int main(int argc, char *argv[])
{
    int fd, i;
    char * myfifo = argv[1];
    char buf[MAX_BUF];

    fd = open(myfifo, O_RDONLY);

    if (fd == -1) {
        perror("opening fifo");
        return 1;
    }
    *buf = '0';
    while (strchr (buf,'x') ==NULL) {
        if((i = read(fd, buf, MAX_BUF)) > 0)
        {
            buf[i] = '\0';
            printf("Received: [%s]\n", buf);
        }
    }

    close(fd);

    return 0;
}

You'll notice I've also allowed the shell script to terminate it if it sends through an x and I've also ensured the buffer is properly terminated for printing it as a string.

The (minor) changes to the shell script are:

#!/bin/bash

fifo_name="myfifo";

# Se non esiste, crea la fifo;
[ -p $fifo_name ] || mkfifo $fifo_name;

echo "3" > $fifo_name;
echo "6" > $fifo_name;
echo "x" > $fifo_name;

The output I see at the C end is then:

Received: [3
]
Received: [6
x
]

and you can see it's not always what you expect. The read call may pick up multiple sends in one hit since there's no real protocol layered on top. If you want to avoid that, you'll need to add your own protocol.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM