9.4. File Descriptor ExampleΒΆ

/*
*  process 1 reads from stdin and writes to a pipe to process 2.
*  process 2 reads from pipe from process 1, converts to caps and
*            writes to pipe to process 3
*  process 3 reads from pipe from process 2 and writes to stdout.
*/
#define STDIN 0
#define STDOUT 1
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
   char *process="./cat";       /* process to exec */
   char *caps="caps";
   int fd[2];                     /* pipe file desc. */

   pipe(fd);
   if( fork() != 0 ) {/* process 1, parent */
      close(fd[0]);   /* parent does not read from pipe */
      close(STDOUT);  /* prepare to redirect stdout     */
      dup(fd[1]);     /* stdout now writes to the pipe  */
      close(fd[1]);   /* extra file descriptor          */
      execl( process, process, 0 ); /* call cat         */
   } else {           /* process 2, child */
      /*
       * First deal with pipe between proc. 1 & 2.
      */
      close(fd[1]);   /* child does not write to pipe   */
      close(STDIN);   /* prepare to redirect stdin      */
      dup(fd[0]);     /* stdin now reads from the pipe  */
      close(fd[0]);   /* extra file descriptor          */
      /*
       * now for process 3. and pipe between 2 & 3.
      */
      pipe(fd);
      if( fork() != 0 ) {/* process 2, parent of second fork  */
         close(fd[0]);   /* parent does not read from pipe */
         close(STDOUT);  /* prepare to redirect stdout     */
         dup(fd[1]);     /* stdout now writes to the pipe  */
         close(fd[1]);   /* extra file descriptor          */
         execl( process, process, caps, 0 ); /* call cat   */
      } else {           /* process 3, child of second fork */
         close(fd[1]);   /* child does not write to pipe   */
         close(STDIN);   /* prepare to redirect stdin      */
         dup(fd[0]);     /* stdin now reads from the pipe  */
         close(fd[0]);   /* extra file descriptor          */
         execl( process, process, 0 ); /* call cat         */
     }
   }
   return 0;
}
/*
 * This program just reads from stdin and prints to stdout
 * If the word 'caps' is used as an argument, it converts to caps.
*/

#include <stdio.h>
#include <string.h>

int makecap( int );

int main(int argc, char **argv)
{
   int c;

   if( (argc == 2 ) && ( strcmp(argv[1], "caps")  == 0  ) ) {
      while( (c=getchar()) !=EOF )
         putchar(makecap(c));
   } else {
      while( (c=getchar()) !=EOF )
         putchar(c);
   }
   fflush(stdout);
   return 0;
}

int makecap( int c )
{
   if( ( c >= 'a' ) && ( c <= 'z' ) )
      return( c - 'a' + 'A' );
   else
      return( c );
}

/*
 * Send a signal from a child process to the parent.
 * Parent will catch the signal.
*/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

void sighandler(int);

int FLAG=0;

int main(void)
{
   int pid;
   struct sigaction act;

   pid = getpid();
   /*  set up the act data structure  */
   act.sa_handler = sighandler;      /* function to call on signal      */
   sigemptyset(&act.sa_mask);        /* start with an empty signal mask */
   act.sa_flags = 0;                 /* no special flags */
   /* set signal handling, discard old mask */
   sigaction( SIGUSR1, &act, NULL );
   if( fork() != 0 ) {
      /* parent */
      while( FLAG == 0 );
      printf("sigtest terminates\n");
   } else {
      /* child */
      sleep(5);
      kill( pid, SIGUSR1);    /* send the SIGUSR1 signal to parent */
   }
   return 0;
}

void sighandler(int sig)
{
   if( sig == SIGUSR1 ) {
    printf("SIGNAL: SIGUSR1 is caught\n");
    FLAG = 1;
   } else {
    printf("SIGNAL: %d is caught\n",sig);
   }
}