I
I
Ilya Podshivalov2015-04-27 10:19:48
linux
Ilya Podshivalov, 2015-04-27 10:19:48

How to properly organize a bidirectional connection between processes?

Hello. Wrote a simple program to organize a bidirectional connection between streams, guided by Sean Walton (Chapter 7, Figure 7.3). Before starting the program, 2 terminal windows open, where you can see the interaction process. The program consists of 2 processes: The parent owns the terminal /dev/pts/2, the child owns the terminal /dev/pts/1. An ancestor and a child, using the inotify mechanism, monitor pinp and dinp files, respectively. As soon as any of these files has been written, the data is written to the pipe (pipe) and sent to the neighboring process for output to its terminal. However, the program does not work correctly, namely, as soon as the parent inotify has worked, poll starts to work constantly ., as if writing to a file (which is not happening). When you try to send something to the channel from a neighbor, nothing happens. Why? Help me please.

#include <unistd.h>
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <fcntl.h>

#include <sys/inotify.h>

int main(int argc, char **argv)
{
    int fd1[2];
    int fd2[2];

    pipe(fd1);
    pipe(fd2);

    int pid;
    if( (pid = fork()) < 0 ){
        perror("Error while calling fork()");
        return 1;
    }
    else if(pid == 0){
        // CHILD
        close(fd1[0]);
        close(fd2[1]);

        dup2(fd2[0], 0);
        close(fd2[0]);

        dup2(fd1[1], 1);
        close(fd1[1]);

        int fileInp = open("./dinp.txt",  O_RDONLY);
        int fileOut = open("/dev/pts/1",  O_WRONLY);

        int dinp;
        dinp = inotify_init();
        if(dinp == -1){
            perror("inotify not init");
            exit(EXIT_FAILURE);
        }
        int wdinp;
        wdinp = inotify_add_watch(dinp, "./dinp.txt", IN_MODIFY);
        if(wdinp == -1){
            perror("inotify_add_watch");
            exit(EXIT_FAILURE);
        }

        lseek(fileInp, 0, SEEK_END);

        struct pollfd fds[2];
        fds[0].fd = dinp;
        fds[0].events = POLLIN;
        fds[1].fd = 0;
        fds[1].events = POLLIN;

        while(true){
            int ret = poll(fds, 2, -1);
            if(ret == -1){
                perror("poll error");
                return 1;
            }
            if(fds[0].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fileInp, c, BUFSIZ)) != 0)
                    write(1, c, len);
            }
            if(fds[1].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fds[1].fd, c, BUFSIZ)) != 0)
                    write(fileOut, c, len);
            }
        }
    }
    else{
        // PARENT
        close(fd1[1]);
        close(fd2[0]);

        fd1[1] = fd2[1];

        int fileInp = open("./pinp.txt",  O_RDONLY);
        int fileOut = open("/dev/pts/2",  O_WRONLY);

        int pinp;
        pinp = inotify_init();
        if(pinp == -1){
            perror("inotify not init");
            exit(EXIT_FAILURE);
        }
        int wpinp;
        wpinp = inotify_add_watch(pinp, "./pinp.txt", IN_MODIFY);
        if(wpinp == -1){
            perror("inotify_add_watch");
            exit(EXIT_FAILURE);
        }

        lseek(fileInp, 0, SEEK_END);

        struct pollfd fds[2];
        fds[0].fd = pinp;
        fds[0].events = POLLIN;
        fds[1].fd = fd1[0];
        fds[1].events = POLLIN;

        while(true){
            int ret = poll(fds, 2, -1);

            if(ret == -1){
                perror("poll error");
                return 1;
            }
            if(fds[0].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fileInp, c, BUFSIZ)) != 0){
                    write(fd1[1], c, len);
                }
            }
            if(fds[1].revents & POLLIN){
                char c[BUFSIZ];
                int len = 0;
                while((len = read(fds[1].fd, c, BUFSIZ)) != 0){
                    write(fileOut, c, len);
                }
            }
        }
    }
    return 0;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2015-04-27
@Harrowmont

as soon as the parent inotify has worked, it starts polling all the time

You don't read from the pinp file anywhere, so after the first time the poll fires non-stop.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question