blob: 97e025fdc0cc68e179616fa6ecd8150553904226 [file] [log] [blame]
/*
* Copyright 2021 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "proxy_client.h"
#include <unistd.h>
#include "server/render_protocol.h"
#include "proxy_server.h"
bool
proxy_client_destroy_context(struct proxy_client *client, uint32_t ctx_id)
{
const struct render_client_op_destroy_context_request req = {
.header.op = RENDER_CLIENT_OP_DESTROY_CONTEXT,
.ctx_id = ctx_id,
};
return proxy_socket_send_request(&client->socket, &req, sizeof(req));
}
bool
proxy_client_create_context(struct proxy_client *client,
uint32_t ctx_id,
size_t ctx_name_len,
const char *ctx_name,
int *out_ctx_fd)
{
struct render_client_op_create_context_request req = {
.header.op = RENDER_CLIENT_OP_CREATE_CONTEXT,
.ctx_id = ctx_id,
};
const size_t len = MIN2(ctx_name_len, sizeof(req.ctx_name) - 1);
memcpy(req.ctx_name, ctx_name, len);
if (!proxy_socket_send_request(&client->socket, &req, sizeof(req)))
return false;
struct render_client_op_create_context_reply reply;
int fd_count;
int ctx_fd;
if (!proxy_socket_receive_reply_with_fds(&client->socket, &reply, sizeof(reply),
&ctx_fd, 1, &fd_count))
return false;
if (reply.ok != fd_count) {
if (fd_count)
close(ctx_fd);
return false;
} else if (!reply.ok) {
return false;
}
if (!proxy_socket_is_seqpacket(ctx_fd)) {
close(ctx_fd);
return false;
}
*out_ctx_fd = ctx_fd;
return true;
}
bool
proxy_client_reset(struct proxy_client *client)
{
const struct render_client_op_reset_request req = {
.header.op = RENDER_CLIENT_OP_RESET,
};
return proxy_socket_send_request(&client->socket, &req, sizeof(req));
}
void
proxy_client_destroy(struct proxy_client *client)
{
proxy_socket_fini(&client->socket);
free(client);
}
static bool
proxy_client_init(struct proxy_client *client, uint32_t flags)
{
const struct render_client_op_init_request req = {
.header.op = RENDER_CLIENT_OP_INIT,
.flags = flags,
};
return proxy_socket_send_request(&client->socket, &req, sizeof(req));
}
struct proxy_client *
proxy_client_create(struct proxy_server *srv, uint32_t flags)
{
struct proxy_client *client = calloc(1, sizeof(*client));
if (!client)
return NULL;
const int client_fd = proxy_server_connect(srv);
if (client_fd < 0) {
free(client);
return NULL;
}
proxy_socket_init(&client->socket, client_fd);
if (!proxy_client_init(client, flags)) {
proxy_socket_fini(&client->socket);
free(client);
return NULL;
}
return client;
}