Thread: Passing functions via UNIX FIFO, is it possible?

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    121

    Passing functions via UNIX FIFO, is it possible?

    Hello,
    I am playing with the linx FIFO and mknod. As simple example as opening two programs "sender" and "receiver", and a FIFO between them, it seems that they can exchange buffers. However the interesting thing is, can they exchange function calls. Let`s say we have that struct:
    Code:
    struct msg {
         char message[64];
         int count;
         void (*pfoo)(void);
    };
    and we assume that sender and receiver know about that struct, is it possible to make a something like that:

    sender.c
    Code:
    static void _p(void) { printf("AAAAAAAAAAAAAAAA"); }
    
    int main(int argc, char *argv[])
    {
        (void) argc;
        (void) argv;
    
    
        struct  msg buff;
        strcpy(msg.message, "sender message");
        buff.count = 1;
        msg.pfoo = _p;
    
        int num = 0, fd = 0;
    
    
        mknod(FIFO_NAME, S_IFIFO|0666, 0);
        
        fd = open(FIFO_NAME, O_WRONLY);
        while (1)  {
            sleep(2);
            if ((num = write(fd,
                             (struct test_call*)&msg,
                            sizeof(struct msg))) == -1) {
                perror("write");
            } else {
                printf("sending %d data\n", num);
            }
        }
    
    
        return 0;
    }
    and the receiver.c
    Code:
    int main(int argc, char *argv[])
    {
        int num, fd;
        mknod(FIFO_NAME, S_IFIFO|0666, 0);
        printf("waiting for writers\n");
        fd = open(FIFO_NAME, O_RDONLY);
    
    
        printf("Got a writer!\n");
        char buff[sizeof(struct msg)] = {0};
    
    
        do {
            if ((num = read(fd, buff, sizeof(struct msg)))==-1) {
                perror("read");
            } else {
                struct msg *m = (struct msg*)&ubuff.tc;
                printf("[%s][%d]\n", m->msg, m->count);
                if (tc->pfoo) {
                    tc->pfoo();
                }
            }
    
    
        } while (num > 0);
    
    
        return 0;
    }
    Is that possible, or I have to compile in a separate file msg and give it`s own translation unit with the function ptr to a specific callback?

  2. #2
    Registered User taazz's Avatar
    Join Date
    May 2016
    Posts
    50
    As far as I understand how virtual memory works, no. The memory address you pass from sender does not have the same content in the receiver ee both processes have a memory address of 1000 when you try to call it from the receiver it will access the receiver's memory space at adress 1000 not the sender's. So no, you can request a procedure to be executed from the receiver and pass back the results to the sender but you can't execute what ever it is in the sender's memory directly unless the sender is a DLL/SO and it is already loaded to the receivers memory space.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    121
    That is bad Ok what if I made an auxilary .o file that is passed to both sender and receiver?

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    If you want two processes to call the same procedure, one way you can is separate the code into a shared object (.so) - calling dlopen/dlsym/dlclose - and FIFO has nothing to do with it.
    Linux Tutorial - Static, Shared Dynamic and Loadable Linux Libraries

    This is much more involved than static linking, but it makes smaller executables at least.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    You'd be better off implementing some sort of RPC protocol. SOAP is common, and works really well, but has tons of overhead. JSON/RPC is lighter weight, but just like SOAP, it requires an HTTP server. There are other RPC protocols out there. You just need to look and do some research to determine what's best for you.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  6. #6
    Registered User taazz's Avatar
    Join Date
    May 2016
    Posts
    50
    Quote Originally Posted by heatblazer View Post
    That is bad Ok what if I made an auxilary .o file that is passed to both sender and receiver?
    I'm sorry, how is that going to help? What exactly are you trying to do? In short modern systems have protections in place to make sure that one process can not access or corrupt the memory of an other process, that is why a badly written application does not crash the OS or any other executing application.

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by heatblazer View Post
    However the interesting thing is, can they exchange function calls.
    If you just want your reader to run a particular function on commands from the writer then you can just compile the functions into the reader and have the writer send the function names as strings. The reader can translate these into function calls.

  8. #8
    Registered User
    Join Date
    Sep 2014
    Posts
    121
    I was thinking of 3rd program which is the bridge between the two. The sender sends some data, the bridge has the function to work on it, let`s say it populates a struct with char data and return value, then the bridge writes back so the receiver reads the result and the data. The bridge returns the written result back to writer so he knows if it`s OK. However my implementation is not OK yet. It`s partially working but I have to implement a locking mechanism between the three. Also if you have info how to lock the data so reader can read only when bridge has worked it`s stuff that would be awesome, because now reader reads form bridge and writer which is bad.
    Passing functions via UNIX FIFO, is it possible?-ipc-jpg

  9. #9
    Registered User
    Join Date
    Sep 2014
    Posts
    121
    Also my repo is here
    GitHub - heatblazer/unix-ipc: inter proc communication
    anyone who wish to give me a hand is welcome.

  10. #10
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    If you really want to do this then you could use a System V semaphore. See semget, semop, semctl, etc.

    Note that you don't need to call mknod (or the more modern mkfifo) in every process. The actual fifo only needs to be created once, e.g., in sender. If you checked the return values of your mknod calls you would see that they are failing if the fifo already exists. You might want to delete (unlink) it at the end of sender, too.

  11. #11
    Registered User
    Join Date
    Sep 2014
    Posts
    121
    Thanks, I`ll consider it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C unix program to call remote procedures with FIFO?
    By heatblazer in forum C Programming
    Replies: 1
    Last Post: 04-26-2016, 03:45 AM
  2. passing variable to UNIX command
    By sje0606 in forum C Programming
    Replies: 1
    Last Post: 10-21-2009, 07:48 PM
  3. Replies: 5
    Last Post: 11-11-2006, 09:52 AM
  4. exec functions under unix
    By v3dant in forum C++ Programming
    Replies: 3
    Last Post: 09-10-2004, 01:08 PM
  5. Need help with FIFO's in Unix programming
    By Brackus in forum Linux Programming
    Replies: 1
    Last Post: 02-01-2003, 03:53 AM

Tags for this Thread