The UNIX and Linux Forums  


Go Back   The UNIX and Linux Forums > Top Forums > UNIX for Advanced & Expert Users
.
google unix.com




View Single Post in the UNIX and Linux Forums - Click on the Thread or Permalink to View Entire Thread -->
  #2 (permalink)  
Old 06-30-2009
mgessner mgessner is offline
Registered User
  
 

Join Date: Oct 2007
Posts: 50
Well, you could devise a test pretty simply.

Create the FIFO w/ mkfifo. Create two processes, a writer and a reader.

Open the FIFO for write, which will block because there's no reader. When it unblocks, write to stderr that it's awake, and then periodically write some bytes to it, and log each write.

Run a reader process, have it sleep a bit, and have it read, say, 10 times, dumping what it reads. Then it should close the fifo and terminate.

What you SHOULD see, according to Stevens APUE, is that the write should cause SIGPIPE to be generated.

Here's an example:
Code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

int sigpipe_caught = 0;

#define TESTLOG(s) testlog(__FUNCTION__, s)

void testlog (const char *who, const char *msg)
{
  fprintf (stderr, "%s: %s\n", who, msg);
}

void writer (void)
{
  int f;
  int value = 0;
  int err;
  int done = 0;

  TESTLOG ("starting");
  if ((f = open ("fifo", O_WRONLY)) != -1)
  {
    TESTLOG ("opened fifo");

    while (done <= 0)
    {
      char buf[64];
      err = write (f, &value, sizeof value);

      if (sizeof value == err)
      {
        sprintf (buf, "wrote %d", value);
        TESTLOG (buf);
        value++;
      }
      else
      {
        sprintf (buf, "err = %d", err);
        TESTLOG (buf);
        sprintf (buf, "sigpipe_caught = %d", sigpipe_caught);
        TESTLOG (buf);
        done++;
      }

      TESTLOG ("sleeping");
      sleep (1);
    }

    close (f);
    TESTLOG ("closed fifo");
  }
}

void reader (void)
{
  int f;
  int i;
  int value;
  int err;

  TESTLOG ("sleeping 2");
  sleep (2);
  TESTLOG ("awake");

  if ((f = open ("fifo", O_RDONLY)) != -1)
  {
    TESTLOG ("opened fifo");

    for (i = 0; i < 10; i++)
    {
      char buf[64];

      err = read (f, &value, sizeof value);
      if (sizeof value == err)
      {
        sprintf (buf, "read %d", value);
        TESTLOG (buf);
      }
      else
      {
        sprintf (buf, "err = %d", err);
        TESTLOG (buf);
      }
    }

    TESTLOG ("closing fifo");
    close (f);
  }
  else
  {
    TESTLOG ("failed to open fifo");
  }
}

void sigpipe (int a)
{
  TESTLOG ("caught SIGPIPE");
  sigpipe_caught = 1;
}

int main (void)
{
  signal (SIGPIPE, sigpipe);

  if (fork())
    writer();
  else
    reader();

  return 0;
}
I've run this on a couple of systems, and I'm sure there are issues with it (for example, one shouldn't use fprintf from a signal handler...).

But I think it illustrates the point.