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