All pastes #32590 Raw Edit

pager.c

public c v1 · immutable
#32590 ·published 2005-12-05 23:40 UTC
rendered paste body
#include <string.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include "main.h"#include <sys/wait.h>#include <signal.h>int file_exists(char *file) {  struct stat foo;              /* throw away argument for stat */  /* null files don't exist */  if (file == NULL) {    return 0;                  }    /* on success 0 is returned */  if (stat(file, &foo) == 0) {  /* this is you checking whether the return value of stat is 1 */    return 1;                   /* true, happy, passed */  }  return 0;}/* find out if $PAGER is set */char* get_pager(){  char *pager;    pager = getenv("PAGER");  /* set pager to $PAGER environment variable */    if (pager == NULL) {  /* if pager is NULL (the enviroment variable is unset) */     /*     printf("PAGER is unset\n"); */    if ( file_exists("/usr/bin/less") ) { /* if /usr/bin/less exists as a file */      pager = "/usr/bin/less";  /* set pager to /usr/bin/less */    }   }  if (pager == NULL) {        /* if pager is NULL (the enviroment variable is unset) */    if ( file_exists("/bin/more") ) { /* if /bin/more exists as a file */      pager = "/bin/more";         }  }  if (pager == NULL) {    pager = "cat";  }  return pager;}/* this function displays each file to the user */int display_file(char *filename){  gzFile *file_ptr;  char *pager;  int wait_status;       /* wait stores the exit status of the child here  */  pid_t fork_result;  int file_pipes[2] = {0};  char gzbuffer[2048] = {0};  int data_processed;    /* leave curses mode to display the file */  kill_curses();        /* get the $PAGER env variable */  pager = get_pager();  /* first we create a pipe this will pass data between two processes */  if (pipe(file_pipes) != 0) {    perror("pipe error");    exit(EXIT_FAILURE);  }    /* next the new process is created with fork() */  fork_result = fork();  /* check if fork() works */  if (fork_result == (pid_t)-1) {    perror("fork error");    exit(EXIT_FAILURE);  }  /* now we have both parent and child processes */  switch (fork_result) {    case -1: {      perror("fork failed");      exit(1);    }          case 0: {      /* we are in the childs thread of execution */      /* set stdin to a copy of the readable fd of the pipe */      close(file_pipes[1]); /* not using the write end of the pipe */      close(0); /* redirecting standard input */      dup(file_pipes[0]); /* duplicate the pipe, setting stdin */	      /* close the pipes read and write fd's because we made a copy */      close(file_pipes[0]); /* stdin should be a copy now, so don't need */      /* call the external program */      (void)execlp(pager, pager, "-", (char *)NULL);      /* DEBUG printf("should never get here...\n"); */      break;    }    default: {      /* we are in the parents thread of execution */      close(file_pipes[0]); /* not using the read end of the pipe */            /*  open the file for reading */      if ((file_ptr = gzopen(filename, "r")) == NULL) {	perror("Cannot open file for reading");	return 1;      }      /* read the file line by line or until EOF */      while (gzgets(file_ptr, gzbuffer, 256) != Z_NULL) {        /* user might quit before scrolling to EOF */        signal(SIGPIPE, SIG_IGN);	/* send all the data to the child */	data_processed = write(file_pipes[1], gzbuffer, strlen(gzbuffer));	if (data_processed == -1) {                    perror("write error");          exit(EXIT_FAILURE);	}	if (data_processed != strlen(gzbuffer)) {          /* data_processed is short .. should be rare */	  exit(EXIT_FAILURE);	}	/* make sure we're not done with the file before continuing */	if (gzeof(file_ptr)) {	  break;	}      }      close(file_pipes[1]);  /* done with the writing end of the pipe */      /*  close the file  */      gzclose(file_ptr);      /*  wait for the child to finish */      wait(&wait_status);	/* returns the PID of child */      /*  continue with the main program */      break;    } /* end default case */  } /* end switch */  return 0;}