1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * Pager: Routines to create a "more" running out of a particular file 10 * descriptor. 11 * 12 * Copyright 1987, 1988 by MIT Student Information Processing Board 13 * 14 * For copyright information, see copyright.h. 15 */ 16 17 #include "ss_internal.h" 18 #include "copyright.h" 19 #include <stdio.h> 20 #include <sys/types.h> 21 #include <sys/file.h> 22 #include <signal.h> 23 #include <errno.h> 24 25 static char MORE[] = "more"; 26 extern char *_ss_pager_name; 27 extern char *getenv(); 28 29 /* 30 * this needs a *lot* of work.... 31 * 32 * run in same process 33 * handle SIGINT sensibly 34 * allow finer control -- put-page-break-here 35 */ 36 void ss_page_stdin(); 37 38 #ifndef NO_FORK 39 int ss_pager_create() 40 { 41 int filedes[2]; 42 43 if (pipe(filedes) != 0) 44 return(-1); 45 46 switch(fork()) { 47 case -1: 48 return(-1); 49 case 0: 50 /* 51 * Child; dup read half to 0, close all but 0, 1, and 2 52 */ 53 if (dup2(filedes[0], 0) == -1) 54 exit(1); 55 ss_page_stdin(); 56 default: 57 /* 58 * Parent: close "read" side of pipe, return 59 * "write" side. 60 */ 61 (void) close(filedes[0]); 62 return(filedes[1]); 63 } 64 } 65 #else /* don't fork */ 66 int ss_pager_create() 67 { 68 int fd; 69 fd = open("/dev/tty", O_WRONLY, 0); 70 return fd; 71 } 72 #endif 73 74 void ss_page_stdin() 75 { 76 int i; 77 #ifdef POSIX_SIGNALS 78 struct sigaction sa; 79 sigset_t mask; 80 #endif 81 /* 82 * Close all fd's, excepting stdin/stdout/stderr 83 */ 84 closefrom(3); 85 86 #ifdef POSIX_SIGNALS 87 sa.sa_handler = SIG_DFL; 88 sigemptyset(&sa.sa_mask); 89 sa.sa_flags = 0; 90 sigaction(SIGINT, &sa, (struct sigaction *)0); 91 #else 92 (void) signal(SIGINT, SIG_DFL); 93 #endif 94 { 95 #ifdef POSIX_SIGNALS 96 sigemptyset(&mask); 97 sigaddset(&mask, SIGINT); 98 sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)0); 99 #else 100 int mask = sigblock(0); 101 mask &= ~sigmask(SIGINT); 102 sigsetmask(mask); 103 #endif 104 } 105 if (_ss_pager_name == (char *)NULL) { 106 if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL) 107 _ss_pager_name = MORE; 108 } 109 (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL); 110 { 111 /* minimal recovery if pager program isn't found */ 112 char buf[80]; 113 register int n; 114 while ((n = read(0, buf, 80)) > 0) 115 write(1, buf, n); 116 } 117 exit(errno); 118 } 119