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