From abd5b38c96317205b32582359713f0f3867657de Mon Sep 17 00:00:00 2001 From: ffashion Date: Wed, 17 Apr 2024 00:19:37 +0800 Subject: [PATCH] feat xdbd: support shell service --- CMakeLists.txt | 5 ++ README.md | 12 ++++ include/xdbd.h | 2 + src/adb/command.c | 12 +++- src/adb/packet.c | 20 +++++- src/adb/xdbd_adb.c | 26 ++++++- src/adb/xdbd_adb_request.c | 30 ++++++-- src/adb/xdbd_adb_request.h | 9 ++- src/connection/connection.h | 2 +- src/os/unix/xdbd_process.c | 32 +++++++-- src/os/unix/xdbd_process.h | 14 +++- src/service/shell/xdbd_shell_service.c | 94 ++++++++++++++++++++++++++ src/service/shell/xdbd_shell_service.h | 13 ++++ src/service/xdbd_service.c | 31 +++++++++ src/service/xdbd_service.h | 42 ++++++++++++ 15 files changed, 323 insertions(+), 21 deletions(-) create mode 100644 src/service/shell/xdbd_shell_service.c create mode 100644 src/service/shell/xdbd_shell_service.h create mode 100644 src/service/xdbd_service.c create mode 100644 src/service/xdbd_service.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 941efbe..15b365c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,9 @@ set(SRCS ${PROJECT_SOURCE_DIR}/src/event/select/xdbd_select.c ${PROJECT_SOURCE_DIR}/src/event/xdbd_event.c ${PROJECT_SOURCE_DIR}/src/event/xdbd_timer.c + ${PROJECT_SOURCE_DIR}/src/os/unix/xdbd_process.c + ${PROJECT_SOURCE_DIR}/src/service/xdbd_service.c + ${PROJECT_SOURCE_DIR}/src/service/shell/xdbd_shell_service.c ${PROJECT_SOURCE_DIR}/src/xdbd.c ) @@ -44,6 +47,8 @@ set( ${PROJECT_SOURCE_DIR}/src/core/ #FIXME: check platform ${PROJECT_SOURCE_DIR}/src/os/unix/ + ${PROJECT_SOURCE_DIR}/src/service/ + ${PROJECT_SOURCE_DIR}/src/service/shell/ ) include_directories(${XADB_INCLUDES}) diff --git a/README.md b/README.md index 3ff2883..90ef5eb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ # other 1. adb will recognize the shell protocol. so this xdbd version need use adb shell -x to debug for closing the recognize shell protocol. in future we will fix it +# service + ```c + struct xdbd_service_t { + xdbd_pid_t pid; + xdbd_event_t *read; + xdbd_event_t *write; + } + + xdbd_service_create(); + // xdbd_service_fetch(); + xdbd_service_destroy(); + ``` diff --git a/include/xdbd.h b/include/xdbd.h index 3c088fd..369d541 100644 --- a/include/xdbd.h +++ b/include/xdbd.h @@ -1,6 +1,7 @@ #ifndef __ADBD__H__ #define __ADBD__H__ +#include #include #include "xdbd_pool.h" @@ -24,6 +25,7 @@ #define xdbd_msec_t unsigned typedef struct xdbd_connection_s xdbd_connection_t; +typedef struct xdbd_adb_connection_s xdbd_adb_connection_t; typedef struct xdbd_listening_s xdbd_listening_t; typedef struct xdbd_event_s xdbd_event_t; typedef struct xdbd_buf_s xdbd_buf_t; diff --git a/src/adb/command.c b/src/adb/command.c index f8d642f..d693d19 100644 --- a/src/adb/command.c +++ b/src/adb/command.c @@ -7,7 +7,7 @@ #include #include #include - +#include int xdbd_process_shell_cmd(xdbd_adb_request_t *r, xdbd_adb_packet_t *p, const adb_command_t *cmd); static adb_command_t adb_cmds[] = { @@ -19,7 +19,10 @@ static adb_command_t adb_cmds[] = { int xdbd_process_shell_cmd(xdbd_adb_request_t *r, xdbd_adb_packet_t *p, const adb_command_t *cmd) { xdbd_adb_packet_t *out; + xdbd_service_t *service; + xdbd_adb_connection_t *ac; + ac = r->ac; out = xdbd_palloc(r->pool, sizeof(xdbd_adb_packet_t)); if (out == NULL) { return XDBD_ERR; @@ -30,6 +33,13 @@ int xdbd_process_shell_cmd(xdbd_adb_request_t *r, xdbd_adb_packet_t *p, const ad return XDBD_ERR; } + service = xdbd_create_service(r->pool, (xdbd_str_t)xdbd_string("shell")); + if (service == NULL) { + return XDBD_ERR; + } + + // FIXME: + ac->service = service; bfdev_log_info("shell_cmd: send okay packet\n"); xdbd_okey_packet(r, out); diff --git a/src/adb/packet.c b/src/adb/packet.c index 060ecac..8c7cdc1 100644 --- a/src/adb/packet.c +++ b/src/adb/packet.c @@ -239,7 +239,10 @@ int xdbd_process_close_packet(xdbd_adb_request_t *r, xdbd_adb_packet_t *p) { int xdbd_process_write_packet(xdbd_adb_request_t *r, xdbd_adb_packet_t *p) { xdbd_adb_packet_t *out; - xdbd_connection_t *c = r->coonection; + xdbd_adb_connection_t *ac; + xdbd_buf_t *payload; + int n = 0; + ac = r->ac; xdbd_str_t t_data = xdbd_string("helloworld\r\n"); @@ -253,6 +256,21 @@ int xdbd_process_write_packet(xdbd_adb_request_t *r, xdbd_adb_packet_t *p) { return XDBD_ERR; } + + payload = xdbd_create_buf(r->pool, ADB_MAX_PACKET_SIZE); + if (payload == NULL) { + return XDBD_ERR; + } + + // FIXME: make it can async + n = ac->service->ops->write(ac->service, r->pool, p->payload); + + n = ac->service->ops->read(ac->service, r->pool, payload); + + + t_data.data = payload->pos; + t_data.size = xdbd_buf_size(payload); + xdbd_write_packet(r, out, &t_data); xdbd_buf_append_mem(r->out, r->pool, &out->header, sizeof(xdbd_adb_header_t)); diff --git a/src/adb/xdbd_adb.c b/src/adb/xdbd_adb.c index ef7b84f..5e325e0 100644 --- a/src/adb/xdbd_adb.c +++ b/src/adb/xdbd_adb.c @@ -19,7 +19,7 @@ size_t xdbd_adb_read_adb_header(xdbd_adb_request_t *r) { int rc; xdbd_event_t *rev; - c = r->coonection; + c = r->ac->coonection; rev = c->read; n = xdbd_buf_size(r->buffer); @@ -79,7 +79,7 @@ size_t xdbd_adb_read_adb_payload(xdbd_adb_request_t *r) { int rc; xdbd_event_t *rev; - c = r->coonection; + c = r->ac->coonection; rev = c->read; n = xdbd_buf_size(r->buffer); @@ -196,6 +196,8 @@ void xdbd_adb_process_adb_payload(xdbd_event_t *rev) { return ; } } + + //destroy request } void xdbd_adb_process_adb_header(xdbd_event_t *rev) { @@ -294,6 +296,12 @@ void xdbd_adb_wait_apacket_handler(xdbd_event_t *ev) { bfdev_log_info("%s receive size %ld\n", (char *)b->start, n); + c->ac = xdbd_adb_create_adb_connection(c); + if (c->ac == NULL) { + xdbd_adb_close_connection(c); + return; + } + c->data = xdbd_adb_create_request(c); if (c->data == NULL) { xdbd_adb_close_connection(c); @@ -343,7 +351,19 @@ void xdbd_adb_close_connection(xdbd_connection_t *c) { void xdbd_adb_close_request(xdbd_adb_request_t *r) { xdbd_connection_t *c; - c = r->coonection; + c = r->ac->coonection; xdbd_adb_close_connection(c); } + + +void xdbd_adb_close_adb_connection(xdbd_adb_connection_t *ac) { + xdbd_connection_t *c; + + c = ac->coonection; + xdbd_adb_close_connection(c); +} + +void xdbd_adb_destroy_request(xdbd_adb_request_t *r) { + xdbd_destroy_pool(r->pool); +} diff --git a/src/adb/xdbd_adb_request.c b/src/adb/xdbd_adb_request.c index 7d922ee..d5eb05d 100644 --- a/src/adb/xdbd_adb_request.c +++ b/src/adb/xdbd_adb_request.c @@ -8,18 +8,18 @@ xdbd_adb_request_t *xdbd_adb_create_request(xdbd_connection_t *c) { xdbd_adb_request_t *r; xdbd_adb_packet_t *p; + xdbd_pool_t *pool; - r = xdbd_pcalloc(c->pool, sizeof(xdbd_adb_request_t)); + pool = xdbd_create_pool(); + + r = xdbd_pcalloc(pool, sizeof(xdbd_adb_request_t)); if (r == NULL) { return NULL; } - r->pool = c->pool; - r->temp_pool = c->temp_pool; - + r->pool = pool; r->buffer = c->buffer; - - r->coonection = c; + r->ac = c->ac; p = xdbd_pcalloc(r->pool, sizeof(xdbd_adb_packet_t)); if (p == NULL) { @@ -34,3 +34,21 @@ xdbd_adb_request_t *xdbd_adb_create_request(xdbd_connection_t *c) { r->p = p; return r; } + +xdbd_adb_connection_t *xdbd_adb_create_adb_connection(xdbd_connection_t *c) { + xdbd_adb_connection_t *ac; + + // FIXME: remove this + if (c->ac != NULL) { + return c->ac; + } + ac = xdbd_pcalloc(c->pool, sizeof(xdbd_adb_connection_t)); + if (ac == NULL) { + return NULL; + } + + ac->pool = c->pool; + ac->coonection = c; + + return ac; +} diff --git a/src/adb/xdbd_adb_request.h b/src/adb/xdbd_adb_request.h index a2a09b6..8c8b4f9 100644 --- a/src/adb/xdbd_adb_request.h +++ b/src/adb/xdbd_adb_request.h @@ -3,6 +3,7 @@ #include "adb.h" #include "xdbd.h" +#include "xdbd_service.h" #include #include #include @@ -10,19 +11,23 @@ struct xdbd_adb_connection_s { xdbd_connection_t *coonection; xdbd_pool_t *pool; + int state; + + // FIXME: + xdbd_service_t *service; }; struct xdbd_adb_request_s { xdbd_buf_t *buffer; xdbd_buf_t *body; xdbd_pool_t *pool; - xdbd_pool_t *temp_pool; xdbd_adb_header_t h; xdbd_adb_packet_t *p; - xdbd_connection_t *coonection; xdbd_buf_t *out; + xdbd_adb_connection_t *ac; }; xdbd_adb_request_t *xdbd_adb_create_request(xdbd_connection_t *c); +xdbd_adb_connection_t *xdbd_adb_create_adb_connection(xdbd_connection_t *c); #endif /*__XDBD_ADB_REQUEST__H__*/ diff --git a/src/connection/connection.h b/src/connection/connection.h index 3039fd7..2436dee 100644 --- a/src/connection/connection.h +++ b/src/connection/connection.h @@ -39,7 +39,7 @@ struct xdbd_connection_s { struct sockaddr *local_sockaddr; socklen_t local_socklen; - + xdbd_adb_connection_t *ac; void *data; xdbd_listening_t *listening; diff --git a/src/os/unix/xdbd_process.c b/src/os/unix/xdbd_process.c index a689e1e..d6a1042 100644 --- a/src/os/unix/xdbd_process.c +++ b/src/os/unix/xdbd_process.c @@ -1,7 +1,8 @@ +#include "xdbd.h" #include #include -static void xdbd_execute_proc(xdbd_t *cycle, void *data); +void xdbd_execute_proc(xdbd_t *xdbd, void *data); xdbd_pid_t xdbd_spawn_process(xdbd_t *xdbd, xdbd_spawn_proc_pt proc, void *data, char *name) { @@ -13,7 +14,6 @@ xdbd_pid_t xdbd_spawn_process(xdbd_t *xdbd, case -1: bfdev_log_err("fork() failed while spawning \"%s\"", name); - // xdbd_close_channel(xdbd_processes[s].channel, cycle->log); return XDBD_INVALID_PID; case 0: @@ -27,12 +27,34 @@ xdbd_pid_t xdbd_spawn_process(xdbd_t *xdbd, return pid; } -xdbd_pid_t xdbd_execute(xdbd_t *cycle, xdbd_exec_ctx_t *ctx) { - return xdbd_spawn_process(cycle, xdbd_execute_proc, ctx, ctx->name); +xdbd_pid_t xdbd_spawn_pty_process(xdbd_t *xdbd, + xdbd_spawn_proc_pt proc, void *data, char *name, xdbd_socket_t *mfd, char *ptyname, struct termios *termp, struct winsize *winp) { + xdbd_pid_t pid; + + pid = forkpty(mfd, ptyname, termp, winp); + switch (pid) { + + case -1: + bfdev_log_err("fork() failed while spawning \"%s\"", name); + return XDBD_INVALID_PID; + + case 0: + proc(xdbd, data); + break; + + default: + break; + } + + return pid; +} + +xdbd_pid_t xdbd_execute(xdbd_t *xdbd, xdbd_exec_ctx_t *ctx) { + return xdbd_spawn_process(xdbd, xdbd_execute_proc, ctx, ctx->name); } -static void xdbd_execute_proc(xdbd_t *cycle, void *data) { +void xdbd_execute_proc(xdbd_t *xdbd, void *data) { xdbd_exec_ctx_t *ctx = data; if (execve(ctx->path, ctx->argv, ctx->envp) == -1) { diff --git a/src/os/unix/xdbd_process.h b/src/os/unix/xdbd_process.h index 1ea3e18..73da244 100644 --- a/src/os/unix/xdbd_process.h +++ b/src/os/unix/xdbd_process.h @@ -2,6 +2,12 @@ #define __NGX_PROCESS__H__ #include +#if defined(XDBD_CONFIG_LINUX) + #include +#elif defined(XDBD_CONFIG_OSX) + #include +#endif + typedef pid_t xdbd_pid_t; #define XDBD_INVALID_PID -1 @@ -11,7 +17,6 @@ typedef void (*xdbd_spawn_proc_pt) (xdbd_t *xdbd, void *data); typedef struct { xdbd_pid_t pid; xdbd_spawn_proc_pt proc; - } xdbd_process_t; typedef struct { @@ -24,7 +29,12 @@ typedef struct { xdbd_pid_t xdbd_spawn_process(xdbd_t *xdbd, xdbd_spawn_proc_pt proc, void *data, char *name); -xdbd_pid_t xdbd_execute(xdbd_t *cycle, xdbd_exec_ctx_t *ctx); +xdbd_pid_t xdbd_spawn_pty_process(xdbd_t *xdbd, + xdbd_spawn_proc_pt proc, void *data, char *name, xdbd_socket_t *mfd, char *ptyname, struct termios *termp, struct winsize *winp); + +xdbd_pid_t xdbd_execute(xdbd_t *xdbd, xdbd_exec_ctx_t *ctx); + +void xdbd_execute_proc(xdbd_t *xdbd, void *data); #define ngx_getpid getpid #define ngx_getppid getppid diff --git a/src/service/shell/xdbd_shell_service.c b/src/service/shell/xdbd_shell_service.c new file mode 100644 index 0000000..08ddab6 --- /dev/null +++ b/src/service/shell/xdbd_shell_service.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(XDBD_CONFIG_LINUX) + #include +#elif defined(XDBD_CONFIG_OSX) + #include +#endif + +xdbd_service_t *create_service(xdbd_t *xdbd, xdbd_pool_t *pool); +int service_write(xdbd_service_t *service, xdbd_pool_t *pool, xdbd_buf_t *buf); +int service_read(xdbd_service_t *service, xdbd_pool_t *pool, xdbd_buf_t *out); + +static xdbd_service_ops_t shell_service_ops = { + .name = xdbd_string("shell"), + .create = create_service, + .read = service_read, + .write = service_write +}; + +static __bfdev_ctor void init() { + xdbd_register_service_ops(&shell_service_ops); +} + +xdbd_service_t *create_service(xdbd_t *xdbd, xdbd_pool_t *pool) { + xdbd_shell_service_t *sservice; + xdbd_pid_t pid; + + xdbd_exec_ctx_t ctx; + sservice = xdbd_palloc(pool, sizeof(xdbd_shell_service_t)); + if (sservice == NULL) { + return NULL; + } + + ctx.path = "/bin/zsh"; + ctx.argv = (char *[]) {ctx.path, NULL}; + ctx.envp = NULL; + ctx.name = NULL; + + pid = xdbd_spawn_pty_process(xdbd, xdbd_execute_proc, &ctx, "shell", &sservice->fd, sservice->ptyname, NULL, NULL); + if (pid == XDBD_INVALID_PID) { + return NULL; + } + + sservice->pid = pid; + + sservice->service.ops = &shell_service_ops; + + return &sservice->service; +} + +int service_write(xdbd_service_t *s, xdbd_pool_t *pool, xdbd_buf_t *buf) { + xdbd_shell_service_t *ss; + int n = 0; + + ss = bfdev_container_of(s, xdbd_shell_service_t, service); + + n = write(ss->fd, buf->pos, xdbd_buf_size(buf)); + + return n; +} + +int service_read(xdbd_service_t *s, xdbd_pool_t *pool, xdbd_buf_t *out) { + xdbd_shell_service_t *ss; + int n = 0; + ss = bfdev_container_of(s, xdbd_shell_service_t, service); + + n = read(ss->fd, out->last, out->end - out->last); + if (n == 0) { + return 0; + } + + if (n > 0) { + out->last += n; + } + + return n; +} + +void destroy_service(xdbd_t *xdbd, xdbd_service_t *s) { + xdbd_shell_service_t *ss; + ss = bfdev_container_of(s, xdbd_shell_service_t, service); + + close(ss->fd); + kill(ss->pid, SIGKILL); + + // FIXME: call destroy father's destory +} diff --git a/src/service/shell/xdbd_shell_service.h b/src/service/shell/xdbd_shell_service.h new file mode 100644 index 0000000..f562250 --- /dev/null +++ b/src/service/shell/xdbd_shell_service.h @@ -0,0 +1,13 @@ +#ifndef __XDBD_SHELL_SERVICE__H__ +#define __XDBD_SHELL_SERVICE__H__ +#include + +typedef struct { + xdbd_service_t service; + char ptyname[1024]; + xdbd_pid_t pid; + xdbd_socket_t fd; + +} xdbd_shell_service_t; + +#endif /*__XDBD_SHELL_SERVICE__H__*/ diff --git a/src/service/xdbd_service.c b/src/service/xdbd_service.c new file mode 100644 index 0000000..7a5be0a --- /dev/null +++ b/src/service/xdbd_service.c @@ -0,0 +1,31 @@ +#include +#include +#include + +static BFDEV_LIST_HEAD(services_ops); + +xdbd_service_t *xdbd_create_service(xdbd_pool_t *pool, xdbd_str_t name) { + xdbd_service_ops_t *sops; + bfdev_list_for_each_entry(sops, &services_ops, list) { + if (name.size != sops->name.size) { + continue; + } + + if (strncmp((const char *)name.data, (const char *)sops->name.data, name.size) != 0) { + continue; + } + + return sops->create(NULL, pool); + } + + return NULL; +} + + +void xdbd_register_service_ops(xdbd_service_ops_t *sops) { + bfdev_list_add(&services_ops, &sops->list); +} + +void xdbd_unregister_service(xdbd_service_ops_t *sops) { + bfdev_list_del(&sops->list); +} diff --git a/src/service/xdbd_service.h b/src/service/xdbd_service.h new file mode 100644 index 0000000..562362c --- /dev/null +++ b/src/service/xdbd_service.h @@ -0,0 +1,42 @@ +#ifndef __XDBD_SERVICE__H__ +#define __XDBD_SERVICE__H__ + +#include +#include +#include + + +#define XDBD_SERVICE_SHELL 0x1 +#define XDBD_SERVICE_PULL 0x2 + +typedef struct xdbd_service_s xdbd_service_t; + +typedef xdbd_service_t *(*xdbd_create_service_pt)(xdbd_t *xdbd, xdbd_pool_t *pool); + +typedef int (*xdbd_service_read_pt)(xdbd_service_t *service, xdbd_pool_t *pool, xdbd_buf_t *buf); +typedef int (*xdbd_service_write_pt)(xdbd_service_t *service, xdbd_pool_t *pool, xdbd_buf_t *out); + +typedef struct xdbd_service_connection_s { + xdbd_connection_t *connection; + xdbd_pid_t pid; + +} xdbd_service_connection_t; +typedef struct { + xdbd_str_t name; + bfdev_list_head_t list; + xdbd_create_service_pt create; + xdbd_service_read_pt read; + xdbd_service_write_pt write; + +} xdbd_service_ops_t; +struct xdbd_service_s{ + xdbd_service_ops_t *ops; + xdbd_service_connection_t *c; +}; + + +xdbd_service_t *xdbd_create_service(xdbd_pool_t *pool, xdbd_str_t name); + +void xdbd_register_service_ops(xdbd_service_ops_t *service); + +#endif /*__XDBD_SERVICE__H__*/