xref: /illumos-gate/usr/src/lib/krb5/ss/pager.c (revision 55fea89d)
17c478bd9Sstevel@tonic-gate /*
256a424ccSmp  * 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 /*
77c478bd9Sstevel@tonic-gate  * Pager: Routines to create a "more" running out of a particular file
87c478bd9Sstevel@tonic-gate  * descriptor.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * Copyright 1987, 1988 by MIT Student Information Processing Board
117c478bd9Sstevel@tonic-gate  *
127c478bd9Sstevel@tonic-gate  * For copyright information, see copyright.h.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #include "ss_internal.h"
167c478bd9Sstevel@tonic-gate #include "copyright.h"
1756a424ccSmp #include <errno.h>
187c478bd9Sstevel@tonic-gate #include <stdio.h>
197c478bd9Sstevel@tonic-gate #include <sys/types.h>
207c478bd9Sstevel@tonic-gate #include <sys/file.h>
217c478bd9Sstevel@tonic-gate #include <signal.h>
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate static char MORE[] = "more";
247c478bd9Sstevel@tonic-gate extern char *_ss_pager_name;
257c478bd9Sstevel@tonic-gate extern char *getenv();
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * this needs a *lot* of work....
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * run in same process
317c478bd9Sstevel@tonic-gate  * handle SIGINT sensibly
327c478bd9Sstevel@tonic-gate  * allow finer control -- put-page-break-here
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifndef NO_FORK
ss_pager_create(void)360b16192fSToomas Soome int ss_pager_create(void)
377c478bd9Sstevel@tonic-gate {
387c478bd9Sstevel@tonic-gate 	int filedes[2];
39*55fea89dSDan Cross 
407c478bd9Sstevel@tonic-gate 	if (pipe(filedes) != 0)
417c478bd9Sstevel@tonic-gate 		return(-1);
427c478bd9Sstevel@tonic-gate 
4356a424ccSmp 	switch((int) fork()) {
447c478bd9Sstevel@tonic-gate 	case -1:
457c478bd9Sstevel@tonic-gate 		return(-1);
467c478bd9Sstevel@tonic-gate 	case 0:
477c478bd9Sstevel@tonic-gate 		/*
487c478bd9Sstevel@tonic-gate 		 * Child; dup read half to 0, close all but 0, 1, and 2
497c478bd9Sstevel@tonic-gate 		 */
507c478bd9Sstevel@tonic-gate 		if (dup2(filedes[0], 0) == -1)
517c478bd9Sstevel@tonic-gate 			exit(1);
527c478bd9Sstevel@tonic-gate 		ss_page_stdin();
537c478bd9Sstevel@tonic-gate 	default:
547c478bd9Sstevel@tonic-gate 		/*
557c478bd9Sstevel@tonic-gate 		 * Parent:  close "read" side of pipe, return
567c478bd9Sstevel@tonic-gate 		 * "write" side.
577c478bd9Sstevel@tonic-gate 		 */
587c478bd9Sstevel@tonic-gate 		(void) close(filedes[0]);
597c478bd9Sstevel@tonic-gate 		return(filedes[1]);
607c478bd9Sstevel@tonic-gate 	}
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate #else /* don't fork */
ss_pager_create(void)630b16192fSToomas Soome int ss_pager_create(void)
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate     int fd;
667c478bd9Sstevel@tonic-gate     fd = open("/dev/tty", O_WRONLY, 0);
677c478bd9Sstevel@tonic-gate     return fd;
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate #endif
707c478bd9Sstevel@tonic-gate 
ss_page_stdin(void)710b16192fSToomas Soome void ss_page_stdin(void)
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate 	int i;
747c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
757c478bd9Sstevel@tonic-gate 	struct sigaction sa;
767c478bd9Sstevel@tonic-gate 	sigset_t mask;
777c478bd9Sstevel@tonic-gate #endif
787c478bd9Sstevel@tonic-gate 	/*
797c478bd9Sstevel@tonic-gate 	 * Close all fd's, excepting stdin/stdout/stderr
807c478bd9Sstevel@tonic-gate 	 */
817c478bd9Sstevel@tonic-gate 	closefrom(3);
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
847c478bd9Sstevel@tonic-gate 	sa.sa_handler = SIG_DFL;
857c478bd9Sstevel@tonic-gate 	sigemptyset(&sa.sa_mask);
867c478bd9Sstevel@tonic-gate 	sa.sa_flags = 0;
870b16192fSToomas Soome 	sigaction(SIGINT, &sa, NULL);
887c478bd9Sstevel@tonic-gate #else
897c478bd9Sstevel@tonic-gate 	(void) signal(SIGINT, SIG_DFL);
907c478bd9Sstevel@tonic-gate #endif
917c478bd9Sstevel@tonic-gate 	{
927c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
937c478bd9Sstevel@tonic-gate 		sigemptyset(&mask);
947c478bd9Sstevel@tonic-gate 		sigaddset(&mask, SIGINT);
950b16192fSToomas Soome 		sigprocmask(SIG_UNBLOCK, &mask, NULL);
967c478bd9Sstevel@tonic-gate #else
977c478bd9Sstevel@tonic-gate 		int mask = sigblock(0);
987c478bd9Sstevel@tonic-gate 		mask &= ~sigmask(SIGINT);
997c478bd9Sstevel@tonic-gate 		sigsetmask(mask);
1007c478bd9Sstevel@tonic-gate #endif
1017c478bd9Sstevel@tonic-gate 	}
1020b16192fSToomas Soome 	if (_ss_pager_name == NULL) {
1030b16192fSToomas Soome 		if ((_ss_pager_name = getenv("PAGER")) == NULL)
1047c478bd9Sstevel@tonic-gate 			_ss_pager_name = MORE;
1057c478bd9Sstevel@tonic-gate 	}
1060b16192fSToomas Soome 	(void) execlp(_ss_pager_name, _ss_pager_name, NULL);
1077c478bd9Sstevel@tonic-gate 	{
1087c478bd9Sstevel@tonic-gate 		/* minimal recovery if pager program isn't found */
1097c478bd9Sstevel@tonic-gate 		char buf[80];
1107c478bd9Sstevel@tonic-gate 		register int n;
1117c478bd9Sstevel@tonic-gate 		while ((n = read(0, buf, 80)) > 0)
11256a424ccSmp 			write(1, buf, (unsigned) n);
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	exit(errno);
1157c478bd9Sstevel@tonic-gate }
116