34#include <sys/socket.h>
40#include <cjson/cJSON.h>
48#define ORM_PROTO_MAGIC 0x43574F52
60} cwist_orm_worker_ctx_t;
70static int recv_all(
int fd,
void *buf,
size_t n)
73 char *
p = (
char *)buf;
76 if (r <= 0)
return -1;
86static int send_all(
int fd,
const void *buf,
size_t n)
89 const char *
p = (
const char *)buf;
92 if (
w <= 0)
return -1;
101static void free_worker_ctx(cwist_orm_worker_ctx_t *ctx)
159static const char socket_b64_table[] =
160 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
166static cJSON *socket_b64_string(
const unsigned char *data,
int n) {
167 size_t out_cap = ((
size_t)
n / 3 + 1) * 4 + 1;
168 char *out = (
char *)
malloc(out_cap);
169 if (!out)
return NULL;
172 for (;
i + 3 <=
n;
i += 3) {
174 out[
o++] = socket_b64_table[(
v >> 18) & 63];
175 out[
o++] = socket_b64_table[(
v >> 12) & 63];
176 out[
o++] = socket_b64_table[(
v >> 6) & 63];
177 out[
o++] = socket_b64_table[
v & 63];
182 out[
o++] = socket_b64_table[(
v >> 18) & 63];
183 out[
o++] = socket_b64_table[(
v >> 12) & 63];
186 }
else if (
rem == 2) {
188 out[
o++] = socket_b64_table[(
v >> 18) & 63];
189 out[
o++] = socket_b64_table[(
v >> 12) & 63];
190 out[
o++] = socket_b64_table[(
v >> 6) & 63];
254} query_accumulator_t;
268static int socket_exec_all(
sqlite3 *db,
const char *
sql, query_accumulator_t *
acc,
270 const char *tail =
sql;
273 while (tail && *tail) {
304 socket_add_legacy_cell(
row,
stmt,
i);
330static void *cwist_orm_socket_worker(
void *arg)
332 cwist_orm_worker_ctx_t *ctx = (cwist_orm_worker_ctx_t *)arg;
333 if (!ctx)
return NULL;
342 free_worker_ctx(ctx);
368 query_accumulator_t
acc;
374 if (!
acc.rows || !
acc.columns || !
acc.trows) {
424 if (send_all(ctx->fd, payload, payload_len) != 0) {
433 free_worker_ctx(ctx);
442#define SOCK_CLOEXEC 0
445static void set_cloexec(
int fd) {
456#if defined(SOCK_CLOEXEC) && SOCK_CLOEXEC != 0
487 cwist_orm_worker_ctx_t *ctx =
488 (cwist_orm_worker_ctx_t *)
calloc(1,
sizeof(*ctx));
496 ctx->db_path =
strdup(db_path);
513 free_worker_ctx(ctx);
Memory allocation wrappers backed by libttak.
void cwist_free(void *ptr)
Free memory obtained via cwist_alloc/cwist_strdup/etc.
void * cwist_alloc(size_t size)
Allocate zeroed memory tracked by libttak.
int cwist_db_transfer_sqlite_to_socket(const char *db_path)
Open a SQLite database behind an in-process SQL socket.
int cwist_orm_socketpair_cloexec(int domain, int type, int protocol, int sv[2])