2 * Pager: Routines to create a "more" running out of a particular file
5 * Copyright 1987, 1988 by MIT Student Information Processing Board
7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose is hereby granted, provided that
9 * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. M.I.T. and the
12 * M.I.T. S.I.P.B. make no representations about the suitability of
13 * this software for any purpose. It is provided "as is" without
14 * express or implied warranty.
18 #if HAVE_SECURE_GETENV
30 #include "ss_internal.h"
32 #include <sys/types.h>
35 #ifdef HAVE_SYS_PRCTL_H
36 #include <sys/prctl.h>
38 #define PR_GET_DUMPABLE 3
40 #if (!defined(HAVE_PRCTL) && defined(linux))
41 #include <sys/syscall.h>
44 static char MORE[] = "more";
45 extern char *_ss_pager_name;
46 extern char *getenv PROTOTYPE((const char *));
48 char *ss_safe_getenv(const char *arg)
50 if ((getuid() != geteuid()) || (getgid() != getegid()))
53 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
56 #if (defined(linux) && defined(SYS_prctl))
57 if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
62 #if defined(HAVE_SECURE_GETENV)
63 return secure_getenv(arg);
64 #elif defined(HAVE___SECURE_GETENV)
65 return __secure_getenv(arg);
72 * this needs a *lot* of work....
75 * handle SIGINT sensibly
76 * allow finer control -- put-page-break-here
80 int ss_pager_create(void)
84 if (pipe(filedes) != 0)
92 * Child; dup read half to 0, close all but 0, 1, and 2
94 if (dup2(filedes[0], 0) == -1)
99 * Parent: close "read" side of pipe, return
102 (void) close(filedes[0]);
106 #else /* don't fork */
107 int ss_pager_create()
110 fd = open("/dev/tty", O_WRONLY, 0);
115 static int write_all(int fd, char *buf, size_t count)
121 ret = write(fd, buf, count);
123 if ((errno == EAGAIN) || (errno == EINTR))
139 for (i = 3; i < 32; i++)
141 (void) signal(SIGINT, SIG_DFL);
142 sigprocmask(SIG_BLOCK, 0, &mask);
143 sigdelset(&mask, SIGINT);
144 sigprocmask(SIG_SETMASK, &mask, 0);
145 if (_ss_pager_name == (char *)NULL) {
146 if ((_ss_pager_name = ss_safe_getenv("PAGER")) == (char *)NULL)
147 _ss_pager_name = MORE;
149 (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
151 /* minimal recovery if pager program isn't found */
154 while ((n = read(0, buf, 80)) > 0)
155 write_all(1, buf, n);