Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/ss/pager.c
34907 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* util/ss/pager.c - create a "more" running out of a file descriptor */
3
/*
4
* Copyright 1987, 1988 by MIT Student Information Processing Board
5
*
6
* For copyright information, see copyright.h.
7
*/
8
9
#include "ss_internal.h"
10
#include "copyright.h"
11
#include <errno.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <sys/types.h>
15
#include <sys/file.h>
16
#include <signal.h>
17
18
static char MORE[] = "more";
19
extern char *_ss_pager_name;
20
21
/*
22
* this needs a *lot* of work....
23
*
24
* run in same process
25
* handle SIGINT sensibly
26
* allow finer control -- put-page-break-here
27
*/
28
void ss_page_stdin(void);
29
30
#ifndef NO_FORK
31
int ss_pager_create(void)
32
{
33
int filedes[2];
34
35
if (pipe(filedes) != 0)
36
return(-1);
37
38
switch((int) fork()) {
39
case -1:
40
return(-1);
41
case 0:
42
/*
43
* Child; dup read half to 0, close all but 0, 1, and 2
44
*/
45
if (dup2(filedes[0], 0) == -1)
46
exit(1);
47
ss_page_stdin();
48
default:
49
/*
50
* Parent: close "read" side of pipe, return
51
* "write" side.
52
*/
53
(void) close(filedes[0]);
54
set_cloexec_fd(filedes[1]);
55
return(filedes[1]);
56
}
57
}
58
#else /* don't fork */
59
int ss_pager_create(void)
60
{
61
int fd;
62
fd = open("/dev/tty", O_WRONLY, 0);
63
if (fd >= 0)
64
set_cloexec_fd(fd);
65
return fd;
66
}
67
#endif
68
69
void ss_page_stdin(void)
70
{
71
int i;
72
#ifdef POSIX_SIGNALS
73
struct sigaction sa;
74
sigset_t mask;
75
#endif
76
for (i = 3; i < 32; i++)
77
(void) close(i);
78
#ifdef POSIX_SIGNALS
79
sa.sa_handler = SIG_DFL;
80
sigemptyset(&sa.sa_mask);
81
sa.sa_flags = 0;
82
sigaction(SIGINT, &sa, (struct sigaction *)0);
83
#else
84
(void) signal(SIGINT, SIG_DFL);
85
#endif
86
{
87
#ifdef POSIX_SIGNALS
88
sigemptyset(&mask);
89
sigaddset(&mask, SIGINT);
90
sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)0);
91
#else
92
int mask = sigblock(0);
93
mask &= ~sigmask(SIGINT);
94
sigsetmask(mask);
95
#endif
96
}
97
if (_ss_pager_name == (char *)NULL) {
98
if ((_ss_pager_name = getenv("PAGER")) == (char *)NULL)
99
_ss_pager_name = MORE;
100
}
101
(void) execlp(_ss_pager_name, _ss_pager_name, (char *) NULL);
102
{
103
/* minimal recovery if pager program isn't found */
104
char buf[80];
105
int n;
106
while ((n = read(0, buf, 80)) > 0)
107
write(1, buf, (unsigned) n);
108
}
109
exit(errno);
110
}
111
112