CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/monitor/display.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2011-2012 Intel Corporation
6
* Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
7
*
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
*
23
*/
24
25
#ifdef HAVE_CONFIG_H
26
#include <config.h>
27
#endif
28
29
#include <stdio.h>
30
#include <errno.h>
31
#include <unistd.h>
32
#include <stdlib.h>
33
#include <string.h>
34
#include <signal.h>
35
#include <sys/wait.h>
36
#include <sys/prctl.h>
37
#include <sys/ioctl.h>
38
#include <termios.h>
39
40
#include "display.h"
41
42
static pid_t pager_pid = 0;
43
44
bool use_color(void)
45
{
46
static int cached_use_color = -1;
47
48
if (__builtin_expect(!!(cached_use_color < 0), 0))
49
cached_use_color = isatty(STDOUT_FILENO) > 0 || pager_pid > 0;
50
51
return cached_use_color;
52
}
53
54
int num_columns(void)
55
{
56
static int cached_num_columns = -1;
57
58
if (__builtin_expect(!!(cached_num_columns < 0), 0)) {
59
struct winsize ws;
60
61
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
62
return -1;
63
64
if (ws.ws_col > 0)
65
cached_num_columns = ws.ws_col;
66
}
67
68
return cached_num_columns;
69
}
70
71
static void close_pipe(int p[])
72
{
73
if (p[0] >= 0)
74
close(p[0]);
75
if (p[1] >= 0)
76
close(p[1]);
77
}
78
79
static void wait_for_terminate(pid_t pid)
80
{
81
siginfo_t dummy;
82
83
for (;;) {
84
memset(&dummy, 0, sizeof(dummy));
85
86
if (waitid(P_PID, pid, &dummy, WEXITED) < 0) {
87
if (errno == EINTR)
88
continue;
89
return;
90
}
91
92
return;
93
}
94
}
95
96
void open_pager(void)
97
{
98
const char *pager;
99
pid_t parent_pid;
100
int fd[2];
101
102
if (pager_pid > 0)
103
return;
104
105
pager = getenv("PAGER");
106
if (pager) {
107
if (!*pager || strcmp(pager, "cat") == 0)
108
return;
109
}
110
111
if (!(isatty(STDOUT_FILENO) > 0))
112
return;
113
114
num_columns();
115
116
if (pipe(fd) < 0) {
117
perror("Failed to create pager pipe");
118
return;
119
}
120
121
parent_pid = getpid();
122
123
pager_pid = fork();
124
if (pager_pid < 0) {
125
perror("Failed to fork pager");
126
close_pipe(fd);
127
return;
128
}
129
130
if (pager_pid == 0) {
131
dup2(fd[0], STDIN_FILENO);
132
close_pipe(fd);
133
134
setenv("LESS", "FRSX", 0);
135
136
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
137
_exit(EXIT_FAILURE);
138
139
if (getppid() != parent_pid)
140
_exit(EXIT_SUCCESS);
141
142
if (pager) {
143
execlp(pager, pager, NULL);
144
execl("/bin/sh", "sh", "-c", pager, NULL);
145
}
146
147
execlp("pager", "pager", NULL);
148
execlp("less", "less", NULL);
149
execlp("more", "more", NULL);
150
151
_exit(EXIT_FAILURE);
152
}
153
154
if (dup2(fd[1], STDOUT_FILENO) < 0) {
155
perror("Failed to duplicate pager pipe");
156
return;
157
}
158
159
close_pipe(fd);
160
}
161
162
void close_pager(void)
163
{
164
if (pager_pid <= 0)
165
return;
166
167
fclose(stdout);
168
kill(pager_pid, SIGCONT);
169
wait_for_terminate(pager_pid);
170
pager_pid = 0;
171
}
172
173