]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - lib/ss/pager.c
Clean up sparse warnings
[thirdparty/e2fsprogs.git] / lib / ss / pager.c
CommitLineData
3839e657
TT
1/*
2 * Pager: Routines to create a "more" running out of a particular file
3 * descriptor.
4 *
5 * Copyright 1987, 1988 by MIT Student Information Processing Board
6 *
06cefee5
TT
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.
3839e657
TT
15 */
16
d1154eb4 17#include "config.h"
1ad3174a
TT
18#if HAVE_SECURE_GETENV
19#define _GNU_SOURCE
20#endif
50e1e10f 21#ifdef HAVE_UNISTD_H
f3db3566
TT
22#include <unistd.h>
23#endif
50e1e10f
TT
24#ifdef HAVE_ERRNO_H
25#include <errno.h>
19c78dc0
TT
26#else
27extern int errno;
50e1e10f 28#endif
f3db3566 29
3839e657 30#include "ss_internal.h"
3839e657
TT
31#include <stdio.h>
32#include <sys/types.h>
33#include <sys/file.h>
34#include <signal.h>
762c7c65
TT
35#ifdef HAVE_SYS_PRCTL_H
36#include <sys/prctl.h>
37#else
38#define PR_GET_DUMPABLE 3
39#endif
40#if (!defined(HAVE_PRCTL) && defined(linux))
41#include <sys/syscall.h>
42#endif
3839e657
TT
43
44static char MORE[] = "more";
546a1ff1 45extern char *getenv PROTOTYPE((const char *));
3839e657 46
762c7c65
TT
47char *ss_safe_getenv(const char *arg)
48{
09f3eba2 49 if ((getuid() != geteuid()) || (getgid() != getegid()))
762c7c65
TT
50 return NULL;
51#if HAVE_PRCTL
583d1f83 52 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
762c7c65
TT
53 return NULL;
54#else
55#if (defined(linux) && defined(SYS_prctl))
583d1f83 56 if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
762c7c65
TT
57 return NULL;
58#endif
59#endif
60
1ad3174a
TT
61#if defined(HAVE_SECURE_GETENV)
62 return secure_getenv(arg);
63#elif defined(HAVE___SECURE_GETENV)
3af0a456 64 return __secure_getenv(arg);
762c7c65 65#else
3af0a456 66 return getenv(arg);
762c7c65
TT
67#endif
68}
69
3839e657
TT
70/*
71 * this needs a *lot* of work....
72 *
73 * run in same process
74 * handle SIGINT sensibly
75 * allow finer control -- put-page-break-here
76 */
3839e657
TT
77
78#ifndef NO_FORK
efc6f628 79int ss_pager_create(void)
3839e657
TT
80{
81 int filedes[2];
efc6f628 82
3839e657
TT
83 if (pipe(filedes) != 0)
84 return(-1);
85
86 switch(fork()) {
87 case -1:
88 return(-1);
89 case 0:
90 /*
91 * Child; dup read half to 0, close all but 0, 1, and 2
92 */
93 if (dup2(filedes[0], 0) == -1)
94 exit(1);
95 ss_page_stdin();
96 default:
97 /*
98 * Parent: close "read" side of pipe, return
99 * "write" side.
100 */
101 (void) close(filedes[0]);
102 return(filedes[1]);
103 }
104}
105#else /* don't fork */
106int ss_pager_create()
107{
108 int fd;
109 fd = open("/dev/tty", O_WRONLY, 0);
110 return fd;
111}
112#endif
113
935a123f
TT
114static int write_all(int fd, char *buf, size_t count)
115{
116 ssize_t ret;
117 int c = 0;
118
119 while (count > 0) {
120 ret = write(fd, buf, count);
121 if (ret < 0) {
122 if ((errno == EAGAIN) || (errno == EINTR))
123 continue;
124 return -1;
125 }
126 count -= ret;
127 buf += ret;
128 c += ret;
129 }
130 return c;
131}
132
f404167d 133void ss_page_stdin(void)
3839e657
TT
134{
135 int i;
91835c15 136 sigset_t mask;
efc6f628 137
3839e657
TT
138 for (i = 3; i < 32; i++)
139 (void) close(i);
140 (void) signal(SIGINT, SIG_DFL);
91835c15
TT
141 sigprocmask(SIG_BLOCK, 0, &mask);
142 sigdelset(&mask, SIGINT);
143 sigprocmask(SIG_SETMASK, &mask, 0);
3839e657 144 if (_ss_pager_name == (char *)NULL) {
762c7c65 145 if ((_ss_pager_name = ss_safe_getenv("PAGER")) == (char *)NULL)
3839e657
TT
146 _ss_pager_name = MORE;
147 }
148 (void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
149 {
150 /* minimal recovery if pager program isn't found */
151 char buf[80];
152 register int n;
153 while ((n = read(0, buf, 80)) > 0)
935a123f 154 write_all(1, buf, n);
3839e657
TT
155 }
156 exit(errno);
157}