Solved

Named pipe read/write of a struct

Posted on 2004-10-31
754 Views
Last Modified: 2010-04-21
Hi,

Can someone please point me to a place where I can get examples of named pipes being used for sending structures ?
I am having some problems in my application and want to compare the code to a standard / sample code from somewhere
0
Question by:namityadav
    7 Comments
     
    LVL 16

    Expert Comment

    by:manav_mathur
    namityadav,

    would be better if you list your problem and code thats creating it here

    Manav
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Hi namityadav,
    You can use the mkfifo() function to create a FIFO special file (note: there is also a "mkfifo" shell command):

    int mkfifo(const char *path, mode_t mode);
    (This is a special case of the mknod() function, just in case you want to do something fancy)

    You can then open the fifo file just as a regular file, passing data between a process writing and a process reading. Beware that the buffer of a fifo is small, so you can get deadlocks if you don't watch out.

    Cheers!

    Stefan
    0
     

    Author Comment

    by:namityadav
    Okay, I guess I need to explain the problem in detail.

    Actually I am reading a structure from a pipe, but sometimes the data coming to my process isn't legit. I want my process to (the moment it finds out that the data is incorrect) clean up the pipe (maybe by reading out the pipe or something).

    Something like -

                 fn() {
                   ....
                   ....
                   ....
                    while(numread) {
                      numread = read(fd, bufMsg, MAX_BUF_SIZE);
                    }
                    continue;
                   ....
                   ....
                 }

    Is there something wrong with this?
    0
     
    LVL 16

    Expert Comment

    by:manav_mathur
    namitayadav,

    I have never practically implemented a named-pipe scheme, but If Im not wrong, your code will block in the first call to read.
    This is because the writer may not have written complete MAX_BUF characters to the pipe. In this case, if O_NONBLOCK is not specified while creation of pipe, your code will block in the read(), waiting for more data to arrive.

    As a flipcase, the data may be legit data which the writer writes in a subsequent write().

    You should use fs.eof() in your while().

    Manav
    0
     
    LVL 16

    Accepted Solution

    by:

    And the mode is a simply equivalent to the file permissions you want to set on the named pipe.

    Acually, what I believe is that instead of making an ad-hoc solution like reading the whole pipe when illegitimate data is found, you should investigate more as to why illegitimate data is coming(i.e. look more on the writer's side).
    Thays bcoz these kinds of problems tend to mutate into somethign else, and then you'll end up coding a whole lot for trapping illegit data whereas the problem was a simple glitch.

    Manav
    0
     

    Author Comment

    by:namityadav
    Hi Manav,

    Thanks for the help. Since there are more than one processes writing to the pipe, and since our QA believes in testing the read end of the pipe by sending crap through the pipe, I won't be able to assume that the data is always legit. So I need a way to clean up the pipe if something like that happens. We are okay with dropping some legit data as part of the cleaning up process too.

    So, yeah, I open the pipe in non-blocking mode only. But I don't need to check the equality of numread with 0, 0 happens when the pipe's not open for write .. I needed to check for -1 here. I guess this code should work, what say?

    fd = open(pipename, O_RDONLY|O_NONBLOCK);
    ...
    ...
    while(1) {
    numread = read(fd, bufMsg, SOMESIZE);
    if (numread == 0 || (numread==-1 && errno==EAGAIN)) {
       sleep(SLEEPTIME); // Just to save lil bit of CPU - sleep for a sec or two
       continue;
    }
    ...
    ParseNamedPipeMsg(bufMsg,someStruct); /* the pipe is used to create a struct */
    ...
             if(someStruct->someVar!=5) { /* assume if someVar ain't 5, the data is corrupt */
                /* Flushin */
                    while(numread!=-1) {
                      numread = read(fd, bufMsg, MAX_BUF_SIZE);
                    }
                    continue;
             }
    }
    0
     
    LVL 12

    Assisted Solution

    by:stefan73
    namityadav,

    You can't write to the same pipe with several processes. Not good.

    Each sender needs a separate pipe.

    Check if SysV message queues better suit your needs. With those, each queued item is clearly distinguishable - you won't end up with a useless pipe when you get a single crappy message (i.e., truncated).
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Find Ransomware Secrets With All-Source Analysis

    Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

    I promised to write further about my project, and here I am.  First, I needed to setup the Primary Server.  You can read how in this article: Setup FreeBSD Server with full HDD encryption (http://www.experts-exchange.com/OS/Unix/BSD/FreeBSD/A_3660-S…
    Using libpcap/Jpcap to capture and send packets on Solaris version (10/11) Library used: 1.      Libpcap (http://www.tcpdump.org) Version 1.2 2.      Jpcap(http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/index.html) Version 0.6 Prerequisite: 1.      GCC …
    Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
    This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    7 Experts available now in Live!

    Get 1:1 Help Now