xref: /titanic_50/usr/src/lib/krb5/ss/pager.c (revision 56a424cca6b3f91f31bdab72a4626c48c779fe8b)
17c478bd9Sstevel@tonic-gate /*
2*56a424ccSmp153739  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate  * Pager: Routines to create a "more" running out of a particular file
107c478bd9Sstevel@tonic-gate  * descriptor.
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * Copyright 1987, 1988 by MIT Student Information Processing Board
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * For copyright information, see copyright.h.
157c478bd9Sstevel@tonic-gate  */
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "ss_internal.h"
187c478bd9Sstevel@tonic-gate #include "copyright.h"
19*56a424ccSmp153739 #include <errno.h>
207c478bd9Sstevel@tonic-gate #include <stdio.h>
217c478bd9Sstevel@tonic-gate #include <sys/types.h>
227c478bd9Sstevel@tonic-gate #include <sys/file.h>
237c478bd9Sstevel@tonic-gate #include <signal.h>
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate static char MORE[] = "more";
267c478bd9Sstevel@tonic-gate extern char *_ss_pager_name;
277c478bd9Sstevel@tonic-gate extern char *getenv();
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * this needs a *lot* of work....
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * run in same process
337c478bd9Sstevel@tonic-gate  * handle SIGINT sensibly
347c478bd9Sstevel@tonic-gate  * allow finer control -- put-page-break-here
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate void ss_page_stdin();
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #ifndef NO_FORK
ss_pager_create()397c478bd9Sstevel@tonic-gate int ss_pager_create()
407c478bd9Sstevel@tonic-gate {
417c478bd9Sstevel@tonic-gate 	int filedes[2];
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	if (pipe(filedes) != 0)
447c478bd9Sstevel@tonic-gate 		return(-1);
457c478bd9Sstevel@tonic-gate 
46*56a424ccSmp153739 	switch((int) fork()) {
477c478bd9Sstevel@tonic-gate 	case -1:
487c478bd9Sstevel@tonic-gate 		return(-1);
497c478bd9Sstevel@tonic-gate 	case 0:
507c478bd9Sstevel@tonic-gate 		/*
517c478bd9Sstevel@tonic-gate 		 * Child; dup read half to 0, close all but 0, 1, and 2
527c478bd9Sstevel@tonic-gate 		 */
537c478bd9Sstevel@tonic-gate 		if (dup2(filedes[0], 0) == -1)
547c478bd9Sstevel@tonic-gate 			exit(1);
557c478bd9Sstevel@tonic-gate 		ss_page_stdin();
567c478bd9Sstevel@tonic-gate 	default:
577c478bd9Sstevel@tonic-gate 		/*
587c478bd9Sstevel@tonic-gate 		 * Parent:  close "read" side of pipe, return
597c478bd9Sstevel@tonic-gate 		 * "write" side.
607c478bd9Sstevel@tonic-gate 		 */
617c478bd9Sstevel@tonic-gate 		(void) close(filedes[0]);
627c478bd9Sstevel@tonic-gate 		return(filedes[1]);
637c478bd9Sstevel@tonic-gate 	}
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate #else /* don't fork */
ss_pager_create()667c478bd9Sstevel@tonic-gate int ss_pager_create()
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate     int fd;
697c478bd9Sstevel@tonic-gate     fd = open("/dev/tty", O_WRONLY, 0);
707c478bd9Sstevel@tonic-gate     return fd;
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate #endif
737c478bd9Sstevel@tonic-gate 
ss_page_stdin()747c478bd9Sstevel@tonic-gate void ss_page_stdin()
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate 	int i;
777c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
787c478bd9Sstevel@tonic-gate 	struct sigaction sa;
797c478bd9Sstevel@tonic-gate 	sigset_t mask;
807c478bd9Sstevel@tonic-gate #endif
817c478bd9Sstevel@tonic-gate 	/*
827c478bd9Sstevel@tonic-gate 	 * Close all fd's, excepting stdin/stdout/stderr
837c478bd9Sstevel@tonic-gate 	 */
847c478bd9Sstevel@tonic-gate 	closefrom(3);
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
877c478bd9Sstevel@tonic-gate 	sa.sa_handler = SIG_DFL;
887c478bd9Sstevel@tonic-gate 	sigemptyset(&sa.sa_mask);
897c478bd9Sstevel@tonic-gate 	sa.sa_flags = 0;
907c478bd9Sstevel@tonic-gate 	sigaction(SIGINT, &sa, (struct sigaction *)0);
917c478bd9Sstevel@tonic-gate #else
927c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, SIG_DFL);
937c478bd9Sstevel@tonic-gate #endif
947c478bd9Sstevel@tonic-gate 	{
957c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
967c478bd9Sstevel@tonic-gate 		sigemptyset(&mask);
977c478bd9Sstevel@tonic-gate 		sigaddset(&mask, SIGINT);
987c478bd9Sstevel@tonic-gate 		sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)0);
997c478bd9Sstevel@tonic-gate #else
1007c478bd9Sstevel@tonic-gate 		int mask = sigblock(0);
1017c478bd9Sstevel@tonic-gate 		mask &= ~sigmask(SIGINT);
1027c478bd9Sstevel@tonic-gate 		sigsetmask(mask);
1037c478bd9Sstevel@tonic-gate #endif
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 	if (_ss_pager_name == (char *)NULL) {
1067c478bd9Sstevel@tonic-gate 		if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL)
1077c478bd9Sstevel@tonic-gate 			_ss_pager_name = MORE;
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 	(void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
1107c478bd9Sstevel@tonic-gate 	{
1117c478bd9Sstevel@tonic-gate 		/* minimal recovery if pager program isn't found */
1127c478bd9Sstevel@tonic-gate 		char buf[80];
1137c478bd9Sstevel@tonic-gate 		register int n;
1147c478bd9Sstevel@tonic-gate 		while ((n = read(0, buf, 80)) > 0)
115*56a424ccSmp153739 			write(1, buf, (unsigned) n);
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate 	exit(errno);
1187c478bd9Sstevel@tonic-gate }
119