xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/pager.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2018 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include <errno.h>
7*61046927SAndroid Build Coastguard Worker #include <signal.h>
8*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
9*61046927SAndroid Build Coastguard Worker #include <stdio.h>
10*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
11*61046927SAndroid Build Coastguard Worker #include <string.h>
12*61046927SAndroid Build Coastguard Worker #include <unistd.h>
13*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
14*61046927SAndroid Build Coastguard Worker #include <sys/wait.h>
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker #include "pager.h"
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker static pid_t pager_pid;
19*61046927SAndroid Build Coastguard Worker 
20*61046927SAndroid Build Coastguard Worker static void
pager_death(int n)21*61046927SAndroid Build Coastguard Worker pager_death(int n)
22*61046927SAndroid Build Coastguard Worker {
23*61046927SAndroid Build Coastguard Worker    exit(0);
24*61046927SAndroid Build Coastguard Worker }
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker void
pager_open(void)27*61046927SAndroid Build Coastguard Worker pager_open(void)
28*61046927SAndroid Build Coastguard Worker {
29*61046927SAndroid Build Coastguard Worker    int fd[2];
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker    if (pipe(fd) < 0) {
32*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Failed to create pager pipe: %m\n");
33*61046927SAndroid Build Coastguard Worker       exit(-1);
34*61046927SAndroid Build Coastguard Worker    }
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker    pager_pid = fork();
37*61046927SAndroid Build Coastguard Worker    if (pager_pid < 0) {
38*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "Failed to fork pager: %m\n");
39*61046927SAndroid Build Coastguard Worker       exit(-1);
40*61046927SAndroid Build Coastguard Worker    }
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker    if (pager_pid == 0) {
43*61046927SAndroid Build Coastguard Worker       const char *less_opts;
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker       dup2(fd[0], STDIN_FILENO);
46*61046927SAndroid Build Coastguard Worker       close(fd[0]);
47*61046927SAndroid Build Coastguard Worker       close(fd[1]);
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker       less_opts = "FRSMKX";
50*61046927SAndroid Build Coastguard Worker       setenv("LESS", less_opts, 1);
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker       execlp("less", "less", NULL);
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker    } else {
55*61046927SAndroid Build Coastguard Worker       /* we want to kill the parent process when pager exits: */
56*61046927SAndroid Build Coastguard Worker       signal(SIGCHLD, pager_death);
57*61046927SAndroid Build Coastguard Worker       dup2(fd[1], STDOUT_FILENO);
58*61046927SAndroid Build Coastguard Worker       close(fd[0]);
59*61046927SAndroid Build Coastguard Worker       close(fd[1]);
60*61046927SAndroid Build Coastguard Worker    }
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker int
pager_close(void)64*61046927SAndroid Build Coastguard Worker pager_close(void)
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker    siginfo_t status;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    close(STDOUT_FILENO);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    while (true) {
71*61046927SAndroid Build Coastguard Worker       memset(&status, 0, sizeof(status));
72*61046927SAndroid Build Coastguard Worker       if (waitid(P_PID, pager_pid, &status, WEXITED) < 0) {
73*61046927SAndroid Build Coastguard Worker          if (errno == EINTR)
74*61046927SAndroid Build Coastguard Worker             continue;
75*61046927SAndroid Build Coastguard Worker          return -errno;
76*61046927SAndroid Build Coastguard Worker       }
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker       return 0;
79*61046927SAndroid Build Coastguard Worker    }
80*61046927SAndroid Build Coastguard Worker }
81