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