simple-ipc: preparations for supporting binary messages.
Add `command_len` argument to the Simple IPC API. In my original Simple IPC API, I assumed that the request would always be a null-terminated string of text characters. The `command` argument was just a `const char *`. I found a caller that would like to pass a binary command to the daemon, so I am amending the Simple IPC API to receive `const char *command, size_t command_len` arguments. I considered changing the `command` argument to be a `void *`, but the IPC layer simply passes it to the pkt-line layer which takes a `const char *`, so to avoid confusion I left it as is. Note, the response side has always been a `struct strbuf` which includes the buffer and length, so we already support returning a binary answer. (Yes, it feels a little weird returning a binary buffer in a `strbuf`, but it works.) Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
64bc75244b
commit
a3e2033e04
@ -168,7 +168,8 @@ void ipc_client_close_connection(struct ipc_client_connection *connection)
|
|||||||
|
|
||||||
int ipc_client_send_command_to_connection(
|
int ipc_client_send_command_to_connection(
|
||||||
struct ipc_client_connection *connection,
|
struct ipc_client_connection *connection,
|
||||||
const char *message, struct strbuf *answer)
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *answer)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -176,7 +177,7 @@ int ipc_client_send_command_to_connection(
|
|||||||
|
|
||||||
trace2_region_enter("ipc-client", "send-command", NULL);
|
trace2_region_enter("ipc-client", "send-command", NULL);
|
||||||
|
|
||||||
if (write_packetized_from_buf_no_flush(message, strlen(message),
|
if (write_packetized_from_buf_no_flush(message, message_len,
|
||||||
connection->fd) < 0 ||
|
connection->fd) < 0 ||
|
||||||
packet_flush_gently(connection->fd) < 0) {
|
packet_flush_gently(connection->fd) < 0) {
|
||||||
ret = error(_("could not send IPC command"));
|
ret = error(_("could not send IPC command"));
|
||||||
@ -197,7 +198,8 @@ done:
|
|||||||
|
|
||||||
int ipc_client_send_command(const char *path,
|
int ipc_client_send_command(const char *path,
|
||||||
const struct ipc_client_connect_options *options,
|
const struct ipc_client_connect_options *options,
|
||||||
const char *message, struct strbuf *answer)
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *answer)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
enum ipc_active_state state;
|
enum ipc_active_state state;
|
||||||
@ -208,7 +210,9 @@ int ipc_client_send_command(const char *path,
|
|||||||
if (state != IPC_STATE__LISTENING)
|
if (state != IPC_STATE__LISTENING)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = ipc_client_send_command_to_connection(connection, message, answer);
|
ret = ipc_client_send_command_to_connection(connection,
|
||||||
|
message, message_len,
|
||||||
|
answer);
|
||||||
|
|
||||||
ipc_client_close_connection(connection);
|
ipc_client_close_connection(connection);
|
||||||
|
|
||||||
@ -503,7 +507,7 @@ static int worker_thread__do_io(
|
|||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
ret = worker_thread_data->server_data->application_cb(
|
ret = worker_thread_data->server_data->application_cb(
|
||||||
worker_thread_data->server_data->application_data,
|
worker_thread_data->server_data->application_data,
|
||||||
buf.buf, do_io_reply_callback, &reply_data);
|
buf.buf, buf.len, do_io_reply_callback, &reply_data);
|
||||||
|
|
||||||
packet_flush_gently(reply_data.fd);
|
packet_flush_gently(reply_data.fd);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,8 @@ void ipc_client_close_connection(struct ipc_client_connection *connection)
|
|||||||
|
|
||||||
int ipc_client_send_command_to_connection(
|
int ipc_client_send_command_to_connection(
|
||||||
struct ipc_client_connection *connection,
|
struct ipc_client_connection *connection,
|
||||||
const char *message, struct strbuf *answer)
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *answer)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -216,7 +217,7 @@ int ipc_client_send_command_to_connection(
|
|||||||
|
|
||||||
trace2_region_enter("ipc-client", "send-command", NULL);
|
trace2_region_enter("ipc-client", "send-command", NULL);
|
||||||
|
|
||||||
if (write_packetized_from_buf_no_flush(message, strlen(message),
|
if (write_packetized_from_buf_no_flush(message, message_len,
|
||||||
connection->fd) < 0 ||
|
connection->fd) < 0 ||
|
||||||
packet_flush_gently(connection->fd) < 0) {
|
packet_flush_gently(connection->fd) < 0) {
|
||||||
ret = error(_("could not send IPC command"));
|
ret = error(_("could not send IPC command"));
|
||||||
@ -239,7 +240,8 @@ done:
|
|||||||
|
|
||||||
int ipc_client_send_command(const char *path,
|
int ipc_client_send_command(const char *path,
|
||||||
const struct ipc_client_connect_options *options,
|
const struct ipc_client_connect_options *options,
|
||||||
const char *message, struct strbuf *response)
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *response)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
enum ipc_active_state state;
|
enum ipc_active_state state;
|
||||||
@ -250,7 +252,9 @@ int ipc_client_send_command(const char *path,
|
|||||||
if (state != IPC_STATE__LISTENING)
|
if (state != IPC_STATE__LISTENING)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = ipc_client_send_command_to_connection(connection, message, response);
|
ret = ipc_client_send_command_to_connection(connection,
|
||||||
|
message, message_len,
|
||||||
|
response);
|
||||||
|
|
||||||
ipc_client_close_connection(connection);
|
ipc_client_close_connection(connection);
|
||||||
|
|
||||||
@ -458,7 +462,7 @@ static int do_io(struct ipc_server_thread_data *server_thread_data)
|
|||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
ret = server_thread_data->server_data->application_cb(
|
ret = server_thread_data->server_data->application_cb(
|
||||||
server_thread_data->server_data->application_data,
|
server_thread_data->server_data->application_data,
|
||||||
buf.buf, do_io_reply_callback, &reply_data);
|
buf.buf, buf.len, do_io_reply_callback, &reply_data);
|
||||||
|
|
||||||
packet_flush_gently(reply_data.fd);
|
packet_flush_gently(reply_data.fd);
|
||||||
|
|
||||||
|
@ -107,7 +107,8 @@ void ipc_client_close_connection(struct ipc_client_connection *connection);
|
|||||||
*/
|
*/
|
||||||
int ipc_client_send_command_to_connection(
|
int ipc_client_send_command_to_connection(
|
||||||
struct ipc_client_connection *connection,
|
struct ipc_client_connection *connection,
|
||||||
const char *message, struct strbuf *answer);
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *answer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used by the client to synchronously connect and send and receive a
|
* Used by the client to synchronously connect and send and receive a
|
||||||
@ -119,7 +120,8 @@ int ipc_client_send_command_to_connection(
|
|||||||
*/
|
*/
|
||||||
int ipc_client_send_command(const char *path,
|
int ipc_client_send_command(const char *path,
|
||||||
const struct ipc_client_connect_options *options,
|
const struct ipc_client_connect_options *options,
|
||||||
const char *message, struct strbuf *answer);
|
const char *message, size_t message_len,
|
||||||
|
struct strbuf *answer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple IPC Server Side API.
|
* Simple IPC Server Side API.
|
||||||
@ -144,6 +146,7 @@ typedef int (ipc_server_reply_cb)(struct ipc_server_reply_data *,
|
|||||||
*/
|
*/
|
||||||
typedef int (ipc_server_application_cb)(void *application_data,
|
typedef int (ipc_server_application_cb)(void *application_data,
|
||||||
const char *request,
|
const char *request,
|
||||||
|
size_t request_len,
|
||||||
ipc_server_reply_cb *reply_cb,
|
ipc_server_reply_cb *reply_cb,
|
||||||
struct ipc_server_reply_data *reply_data);
|
struct ipc_server_reply_data *reply_data);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ static int app__slow_command(ipc_server_reply_cb *reply_cb,
|
|||||||
/*
|
/*
|
||||||
* The client sent a command followed by a (possibly very) large buffer.
|
* The client sent a command followed by a (possibly very) large buffer.
|
||||||
*/
|
*/
|
||||||
static int app__sendbytes_command(const char *received,
|
static int app__sendbytes_command(const char *received, size_t received_len,
|
||||||
ipc_server_reply_cb *reply_cb,
|
ipc_server_reply_cb *reply_cb,
|
||||||
struct ipc_server_reply_data *reply_data)
|
struct ipc_server_reply_data *reply_data)
|
||||||
{
|
{
|
||||||
@ -123,6 +123,13 @@ static int app__sendbytes_command(const char *received,
|
|||||||
int errs = 0;
|
int errs = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The test is setup to send:
|
||||||
|
* "sendbytes" SP <n * char>
|
||||||
|
*/
|
||||||
|
if (received_len < strlen("sendbytes "))
|
||||||
|
BUG("received_len is short in app__sendbytes_command");
|
||||||
|
|
||||||
if (skip_prefix(received, "sendbytes ", &p))
|
if (skip_prefix(received, "sendbytes ", &p))
|
||||||
len_ballast = strlen(p);
|
len_ballast = strlen(p);
|
||||||
|
|
||||||
@ -160,7 +167,7 @@ static ipc_server_application_cb test_app_cb;
|
|||||||
* by this application.
|
* by this application.
|
||||||
*/
|
*/
|
||||||
static int test_app_cb(void *application_data,
|
static int test_app_cb(void *application_data,
|
||||||
const char *command,
|
const char *command, size_t command_len,
|
||||||
ipc_server_reply_cb *reply_cb,
|
ipc_server_reply_cb *reply_cb,
|
||||||
struct ipc_server_reply_data *reply_data)
|
struct ipc_server_reply_data *reply_data)
|
||||||
{
|
{
|
||||||
@ -173,7 +180,7 @@ static int test_app_cb(void *application_data,
|
|||||||
if (application_data != (void*)&my_app_data)
|
if (application_data != (void*)&my_app_data)
|
||||||
BUG("application_cb: application_data pointer wrong");
|
BUG("application_cb: application_data pointer wrong");
|
||||||
|
|
||||||
if (!strcmp(command, "quit")) {
|
if (command_len == 4 && !strncmp(command, "quit", 4)) {
|
||||||
/*
|
/*
|
||||||
* The client sent a "quit" command. This is an async
|
* The client sent a "quit" command. This is an async
|
||||||
* request for the server to shutdown.
|
* request for the server to shutdown.
|
||||||
@ -193,22 +200,23 @@ static int test_app_cb(void *application_data,
|
|||||||
return SIMPLE_IPC_QUIT;
|
return SIMPLE_IPC_QUIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(command, "ping")) {
|
if (command_len == 4 && !strncmp(command, "ping", 4)) {
|
||||||
const char *answer = "pong";
|
const char *answer = "pong";
|
||||||
return reply_cb(reply_data, answer, strlen(answer));
|
return reply_cb(reply_data, answer, strlen(answer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(command, "big"))
|
if (command_len == 3 && !strncmp(command, "big", 3))
|
||||||
return app__big_command(reply_cb, reply_data);
|
return app__big_command(reply_cb, reply_data);
|
||||||
|
|
||||||
if (!strcmp(command, "chunk"))
|
if (command_len == 5 && !strncmp(command, "chunk", 5))
|
||||||
return app__chunk_command(reply_cb, reply_data);
|
return app__chunk_command(reply_cb, reply_data);
|
||||||
|
|
||||||
if (!strcmp(command, "slow"))
|
if (command_len == 4 && !strncmp(command, "slow", 4))
|
||||||
return app__slow_command(reply_cb, reply_data);
|
return app__slow_command(reply_cb, reply_data);
|
||||||
|
|
||||||
if (starts_with(command, "sendbytes "))
|
if (command_len >= 10 && starts_with(command, "sendbytes "))
|
||||||
return app__sendbytes_command(command, reply_cb, reply_data);
|
return app__sendbytes_command(command, command_len,
|
||||||
|
reply_cb, reply_data);
|
||||||
|
|
||||||
return app__unhandled_command(command, reply_cb, reply_data);
|
return app__unhandled_command(command, reply_cb, reply_data);
|
||||||
}
|
}
|
||||||
@ -488,7 +496,9 @@ static int client__send_ipc(void)
|
|||||||
options.wait_if_busy = 1;
|
options.wait_if_busy = 1;
|
||||||
options.wait_if_not_found = 0;
|
options.wait_if_not_found = 0;
|
||||||
|
|
||||||
if (!ipc_client_send_command(cl_args.path, &options, command, &buf)) {
|
if (!ipc_client_send_command(cl_args.path, &options,
|
||||||
|
command, strlen(command),
|
||||||
|
&buf)) {
|
||||||
if (buf.len) {
|
if (buf.len) {
|
||||||
printf("%s\n", buf.buf);
|
printf("%s\n", buf.buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -556,7 +566,9 @@ static int do_sendbytes(int bytecount, char byte, const char *path,
|
|||||||
strbuf_addstr(&buf_send, "sendbytes ");
|
strbuf_addstr(&buf_send, "sendbytes ");
|
||||||
strbuf_addchars(&buf_send, byte, bytecount);
|
strbuf_addchars(&buf_send, byte, bytecount);
|
||||||
|
|
||||||
if (!ipc_client_send_command(path, options, buf_send.buf, &buf_resp)) {
|
if (!ipc_client_send_command(path, options,
|
||||||
|
buf_send.buf, buf_send.len,
|
||||||
|
&buf_resp)) {
|
||||||
strbuf_rtrim(&buf_resp);
|
strbuf_rtrim(&buf_resp);
|
||||||
printf("sent:%c%08d %s\n", byte, bytecount, buf_resp.buf);
|
printf("sent:%c%08d %s\n", byte, bytecount, buf_resp.buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
Loading…
Reference in New Issue
Block a user