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