xref: /aosp_15_r20/external/virglrenderer/src/proxy/proxy_server.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /*
2*bbecb9d1SAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
3*bbecb9d1SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*bbecb9d1SAndroid Build Coastguard Worker  */
5*bbecb9d1SAndroid Build Coastguard Worker 
6*bbecb9d1SAndroid Build Coastguard Worker #include "proxy_server.h"
7*bbecb9d1SAndroid Build Coastguard Worker 
8*bbecb9d1SAndroid Build Coastguard Worker #include <signal.h>
9*bbecb9d1SAndroid Build Coastguard Worker #include <sys/wait.h>
10*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
11*bbecb9d1SAndroid Build Coastguard Worker 
12*bbecb9d1SAndroid Build Coastguard Worker #include "server/render_protocol.h"
13*bbecb9d1SAndroid Build Coastguard Worker 
14*bbecb9d1SAndroid Build Coastguard Worker int
proxy_server_connect(struct proxy_server * srv)15*bbecb9d1SAndroid Build Coastguard Worker proxy_server_connect(struct proxy_server *srv)
16*bbecb9d1SAndroid Build Coastguard Worker {
17*bbecb9d1SAndroid Build Coastguard Worker    int client_fd = srv->client_fd;
18*bbecb9d1SAndroid Build Coastguard Worker    /* transfer ownership */
19*bbecb9d1SAndroid Build Coastguard Worker    srv->client_fd = -1;
20*bbecb9d1SAndroid Build Coastguard Worker    return client_fd;
21*bbecb9d1SAndroid Build Coastguard Worker }
22*bbecb9d1SAndroid Build Coastguard Worker 
23*bbecb9d1SAndroid Build Coastguard Worker void
proxy_server_destroy(struct proxy_server * srv)24*bbecb9d1SAndroid Build Coastguard Worker proxy_server_destroy(struct proxy_server *srv)
25*bbecb9d1SAndroid Build Coastguard Worker {
26*bbecb9d1SAndroid Build Coastguard Worker    if (srv->pid >= 0) {
27*bbecb9d1SAndroid Build Coastguard Worker       kill(srv->pid, SIGKILL);
28*bbecb9d1SAndroid Build Coastguard Worker 
29*bbecb9d1SAndroid Build Coastguard Worker       siginfo_t siginfo = { 0 };
30*bbecb9d1SAndroid Build Coastguard Worker       waitid(P_PID, srv->pid, &siginfo, WEXITED);
31*bbecb9d1SAndroid Build Coastguard Worker    }
32*bbecb9d1SAndroid Build Coastguard Worker 
33*bbecb9d1SAndroid Build Coastguard Worker    if (srv->client_fd >= 0)
34*bbecb9d1SAndroid Build Coastguard Worker       close(srv->client_fd);
35*bbecb9d1SAndroid Build Coastguard Worker 
36*bbecb9d1SAndroid Build Coastguard Worker    free(srv);
37*bbecb9d1SAndroid Build Coastguard Worker }
38*bbecb9d1SAndroid Build Coastguard Worker 
39*bbecb9d1SAndroid Build Coastguard Worker static bool
proxy_server_fork(struct proxy_server * srv)40*bbecb9d1SAndroid Build Coastguard Worker proxy_server_fork(struct proxy_server *srv)
41*bbecb9d1SAndroid Build Coastguard Worker {
42*bbecb9d1SAndroid Build Coastguard Worker    int socket_fds[2];
43*bbecb9d1SAndroid Build Coastguard Worker    if (!proxy_socket_pair(socket_fds))
44*bbecb9d1SAndroid Build Coastguard Worker       return false;
45*bbecb9d1SAndroid Build Coastguard Worker    const int client_fd = socket_fds[0];
46*bbecb9d1SAndroid Build Coastguard Worker    const int remote_fd = socket_fds[1];
47*bbecb9d1SAndroid Build Coastguard Worker 
48*bbecb9d1SAndroid Build Coastguard Worker    pid_t pid = fork();
49*bbecb9d1SAndroid Build Coastguard Worker    if (pid < 0) {
50*bbecb9d1SAndroid Build Coastguard Worker       proxy_log("failed to fork proxy server");
51*bbecb9d1SAndroid Build Coastguard Worker       close(client_fd);
52*bbecb9d1SAndroid Build Coastguard Worker       close(remote_fd);
53*bbecb9d1SAndroid Build Coastguard Worker       return false;
54*bbecb9d1SAndroid Build Coastguard Worker    }
55*bbecb9d1SAndroid Build Coastguard Worker 
56*bbecb9d1SAndroid Build Coastguard Worker    if (pid > 0) {
57*bbecb9d1SAndroid Build Coastguard Worker       srv->pid = pid;
58*bbecb9d1SAndroid Build Coastguard Worker       srv->client_fd = client_fd;
59*bbecb9d1SAndroid Build Coastguard Worker       close(remote_fd);
60*bbecb9d1SAndroid Build Coastguard Worker    } else {
61*bbecb9d1SAndroid Build Coastguard Worker       close(client_fd);
62*bbecb9d1SAndroid Build Coastguard Worker 
63*bbecb9d1SAndroid Build Coastguard Worker       /* do not receive signals from terminal */
64*bbecb9d1SAndroid Build Coastguard Worker       setpgid(0, 0);
65*bbecb9d1SAndroid Build Coastguard Worker 
66*bbecb9d1SAndroid Build Coastguard Worker       char fd_str[16];
67*bbecb9d1SAndroid Build Coastguard Worker       snprintf(fd_str, sizeof(fd_str), "%d", remote_fd);
68*bbecb9d1SAndroid Build Coastguard Worker 
69*bbecb9d1SAndroid Build Coastguard Worker       char *const argv[] = {
70*bbecb9d1SAndroid Build Coastguard Worker          RENDER_SERVER_EXEC_PATH,
71*bbecb9d1SAndroid Build Coastguard Worker          "--socket-fd",
72*bbecb9d1SAndroid Build Coastguard Worker          fd_str,
73*bbecb9d1SAndroid Build Coastguard Worker          NULL,
74*bbecb9d1SAndroid Build Coastguard Worker       };
75*bbecb9d1SAndroid Build Coastguard Worker       execv(argv[0], argv);
76*bbecb9d1SAndroid Build Coastguard Worker 
77*bbecb9d1SAndroid Build Coastguard Worker       proxy_log("failed to exec %s: %s", argv[0], strerror(errno));
78*bbecb9d1SAndroid Build Coastguard Worker       close(remote_fd);
79*bbecb9d1SAndroid Build Coastguard Worker       exit(-1);
80*bbecb9d1SAndroid Build Coastguard Worker    }
81*bbecb9d1SAndroid Build Coastguard Worker 
82*bbecb9d1SAndroid Build Coastguard Worker    return true;
83*bbecb9d1SAndroid Build Coastguard Worker }
84*bbecb9d1SAndroid Build Coastguard Worker 
85*bbecb9d1SAndroid Build Coastguard Worker static bool
proxy_server_init_fd(struct proxy_server * srv)86*bbecb9d1SAndroid Build Coastguard Worker proxy_server_init_fd(struct proxy_server *srv)
87*bbecb9d1SAndroid Build Coastguard Worker {
88*bbecb9d1SAndroid Build Coastguard Worker    /* the fd represents a connection to the server */
89*bbecb9d1SAndroid Build Coastguard Worker    srv->client_fd = proxy_renderer.cbs->get_server_fd(RENDER_SERVER_VERSION);
90*bbecb9d1SAndroid Build Coastguard Worker    if (srv->client_fd < 0)
91*bbecb9d1SAndroid Build Coastguard Worker       return false;
92*bbecb9d1SAndroid Build Coastguard Worker 
93*bbecb9d1SAndroid Build Coastguard Worker    return true;
94*bbecb9d1SAndroid Build Coastguard Worker }
95*bbecb9d1SAndroid Build Coastguard Worker 
96*bbecb9d1SAndroid Build Coastguard Worker struct proxy_server *
proxy_server_create(void)97*bbecb9d1SAndroid Build Coastguard Worker proxy_server_create(void)
98*bbecb9d1SAndroid Build Coastguard Worker {
99*bbecb9d1SAndroid Build Coastguard Worker    struct proxy_server *srv = calloc(1, sizeof(*srv));
100*bbecb9d1SAndroid Build Coastguard Worker    if (!srv)
101*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
102*bbecb9d1SAndroid Build Coastguard Worker 
103*bbecb9d1SAndroid Build Coastguard Worker    srv->pid = -1;
104*bbecb9d1SAndroid Build Coastguard Worker 
105*bbecb9d1SAndroid Build Coastguard Worker    if (!proxy_server_init_fd(srv)) {
106*bbecb9d1SAndroid Build Coastguard Worker       /* start the render server on demand when the client does not provide a
107*bbecb9d1SAndroid Build Coastguard Worker        * server fd
108*bbecb9d1SAndroid Build Coastguard Worker        */
109*bbecb9d1SAndroid Build Coastguard Worker       if (!proxy_server_fork(srv)) {
110*bbecb9d1SAndroid Build Coastguard Worker          free(srv);
111*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
112*bbecb9d1SAndroid Build Coastguard Worker       }
113*bbecb9d1SAndroid Build Coastguard Worker    }
114*bbecb9d1SAndroid Build Coastguard Worker 
115*bbecb9d1SAndroid Build Coastguard Worker    if (!proxy_socket_is_seqpacket(srv->client_fd)) {
116*bbecb9d1SAndroid Build Coastguard Worker       proxy_log("invalid client fd type");
117*bbecb9d1SAndroid Build Coastguard Worker       close(srv->client_fd);
118*bbecb9d1SAndroid Build Coastguard Worker       free(srv);
119*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
120*bbecb9d1SAndroid Build Coastguard Worker    }
121*bbecb9d1SAndroid Build Coastguard Worker 
122*bbecb9d1SAndroid Build Coastguard Worker    proxy_log("proxy server with pid %d", srv->pid);
123*bbecb9d1SAndroid Build Coastguard Worker 
124*bbecb9d1SAndroid Build Coastguard Worker    return srv;
125*bbecb9d1SAndroid Build Coastguard Worker }
126