Skip to content

Commit a3e2033

Browse files
jeffhostetlergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 64bc752 commit a3e2033

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

compat/simple-ipc/ipc-unix-socket.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,16 @@ void ipc_client_close_connection(struct ipc_client_connection *connection)
168168

169169
int ipc_client_send_command_to_connection(
170170
struct ipc_client_connection *connection,
171-
const char *message, struct strbuf *answer)
171+
const char *message, size_t message_len,
172+
struct strbuf *answer)
172173
{
173174
int ret = 0;
174175

175176
strbuf_setlen(answer, 0);
176177

177178
trace2_region_enter("ipc-client", "send-command", NULL);
178179

179-
if (write_packetized_from_buf_no_flush(message, strlen(message),
180+
if (write_packetized_from_buf_no_flush(message, message_len,
180181
connection->fd) < 0 ||
181182
packet_flush_gently(connection->fd) < 0) {
182183
ret = error(_("could not send IPC command"));
@@ -197,7 +198,8 @@ int ipc_client_send_command_to_connection(
197198

198199
int ipc_client_send_command(const char *path,
199200
const struct ipc_client_connect_options *options,
200-
const char *message, struct strbuf *answer)
201+
const char *message, size_t message_len,
202+
struct strbuf *answer)
201203
{
202204
int ret = -1;
203205
enum ipc_active_state state;
@@ -208,7 +210,9 @@ int ipc_client_send_command(const char *path,
208210
if (state != IPC_STATE__LISTENING)
209211
return ret;
210212

211-
ret = ipc_client_send_command_to_connection(connection, message, answer);
213+
ret = ipc_client_send_command_to_connection(connection,
214+
message, message_len,
215+
answer);
212216

213217
ipc_client_close_connection(connection);
214218

@@ -503,7 +507,7 @@ static int worker_thread__do_io(
503507
if (ret >= 0) {
504508
ret = worker_thread_data->server_data->application_cb(
505509
worker_thread_data->server_data->application_data,
506-
buf.buf, do_io_reply_callback, &reply_data);
510+
buf.buf, buf.len, do_io_reply_callback, &reply_data);
507511

508512
packet_flush_gently(reply_data.fd);
509513
}

compat/simple-ipc/ipc-win32.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,16 @@ void ipc_client_close_connection(struct ipc_client_connection *connection)
208208

209209
int ipc_client_send_command_to_connection(
210210
struct ipc_client_connection *connection,
211-
const char *message, struct strbuf *answer)
211+
const char *message, size_t message_len,
212+
struct strbuf *answer)
212213
{
213214
int ret = 0;
214215

215216
strbuf_setlen(answer, 0);
216217

217218
trace2_region_enter("ipc-client", "send-command", NULL);
218219

219-
if (write_packetized_from_buf_no_flush(message, strlen(message),
220+
if (write_packetized_from_buf_no_flush(message, message_len,
220221
connection->fd) < 0 ||
221222
packet_flush_gently(connection->fd) < 0) {
222223
ret = error(_("could not send IPC command"));
@@ -239,7 +240,8 @@ int ipc_client_send_command_to_connection(
239240

240241
int ipc_client_send_command(const char *path,
241242
const struct ipc_client_connect_options *options,
242-
const char *message, struct strbuf *response)
243+
const char *message, size_t message_len,
244+
struct strbuf *response)
243245
{
244246
int ret = -1;
245247
enum ipc_active_state state;
@@ -250,7 +252,9 @@ int ipc_client_send_command(const char *path,
250252
if (state != IPC_STATE__LISTENING)
251253
return ret;
252254

253-
ret = ipc_client_send_command_to_connection(connection, message, response);
255+
ret = ipc_client_send_command_to_connection(connection,
256+
message, message_len,
257+
response);
254258

255259
ipc_client_close_connection(connection);
256260

@@ -458,7 +462,7 @@ static int do_io(struct ipc_server_thread_data *server_thread_data)
458462
if (ret >= 0) {
459463
ret = server_thread_data->server_data->application_cb(
460464
server_thread_data->server_data->application_data,
461-
buf.buf, do_io_reply_callback, &reply_data);
465+
buf.buf, buf.len, do_io_reply_callback, &reply_data);
462466

463467
packet_flush_gently(reply_data.fd);
464468

simple-ipc.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ void ipc_client_close_connection(struct ipc_client_connection *connection);
107107
*/
108108
int ipc_client_send_command_to_connection(
109109
struct ipc_client_connection *connection,
110-
const char *message, struct strbuf *answer);
110+
const char *message, size_t message_len,
111+
struct strbuf *answer);
111112

112113
/*
113114
* Used by the client to synchronously connect and send and receive a
@@ -119,7 +120,8 @@ int ipc_client_send_command_to_connection(
119120
*/
120121
int ipc_client_send_command(const char *path,
121122
const struct ipc_client_connect_options *options,
122-
const char *message, struct strbuf *answer);
123+
const char *message, size_t message_len,
124+
struct strbuf *answer);
123125

124126
/*
125127
* Simple IPC Server Side API.
@@ -144,6 +146,7 @@ typedef int (ipc_server_reply_cb)(struct ipc_server_reply_data *,
144146
*/
145147
typedef int (ipc_server_application_cb)(void *application_data,
146148
const char *request,
149+
size_t request_len,
147150
ipc_server_reply_cb *reply_cb,
148151
struct ipc_server_reply_data *reply_data);
149152

t/helper/test-simple-ipc.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static int app__slow_command(ipc_server_reply_cb *reply_cb,
112112
/*
113113
* The client sent a command followed by a (possibly very) large buffer.
114114
*/
115-
static int app__sendbytes_command(const char *received,
115+
static int app__sendbytes_command(const char *received, size_t received_len,
116116
ipc_server_reply_cb *reply_cb,
117117
struct ipc_server_reply_data *reply_data)
118118
{
@@ -123,6 +123,13 @@ static int app__sendbytes_command(const char *received,
123123
int errs = 0;
124124
int ret;
125125

126+
/*
127+
* The test is setup to send:
128+
* "sendbytes" SP <n * char>
129+
*/
130+
if (received_len < strlen("sendbytes "))
131+
BUG("received_len is short in app__sendbytes_command");
132+
126133
if (skip_prefix(received, "sendbytes ", &p))
127134
len_ballast = strlen(p);
128135

@@ -160,7 +167,7 @@ static ipc_server_application_cb test_app_cb;
160167
* by this application.
161168
*/
162169
static int test_app_cb(void *application_data,
163-
const char *command,
170+
const char *command, size_t command_len,
164171
ipc_server_reply_cb *reply_cb,
165172
struct ipc_server_reply_data *reply_data)
166173
{
@@ -173,7 +180,7 @@ static int test_app_cb(void *application_data,
173180
if (application_data != (void*)&my_app_data)
174181
BUG("application_cb: application_data pointer wrong");
175182

176-
if (!strcmp(command, "quit")) {
183+
if (command_len == 4 && !strncmp(command, "quit", 4)) {
177184
/*
178185
* The client sent a "quit" command. This is an async
179186
* request for the server to shutdown.
@@ -193,22 +200,23 @@ static int test_app_cb(void *application_data,
193200
return SIMPLE_IPC_QUIT;
194201
}
195202

196-
if (!strcmp(command, "ping")) {
203+
if (command_len == 4 && !strncmp(command, "ping", 4)) {
197204
const char *answer = "pong";
198205
return reply_cb(reply_data, answer, strlen(answer));
199206
}
200207

201-
if (!strcmp(command, "big"))
208+
if (command_len == 3 && !strncmp(command, "big", 3))
202209
return app__big_command(reply_cb, reply_data);
203210

204-
if (!strcmp(command, "chunk"))
211+
if (command_len == 5 && !strncmp(command, "chunk", 5))
205212
return app__chunk_command(reply_cb, reply_data);
206213

207-
if (!strcmp(command, "slow"))
214+
if (command_len == 4 && !strncmp(command, "slow", 4))
208215
return app__slow_command(reply_cb, reply_data);
209216

210-
if (starts_with(command, "sendbytes "))
211-
return app__sendbytes_command(command, reply_cb, reply_data);
217+
if (command_len >= 10 && starts_with(command, "sendbytes "))
218+
return app__sendbytes_command(command, command_len,
219+
reply_cb, reply_data);
212220

213221
return app__unhandled_command(command, reply_cb, reply_data);
214222
}
@@ -488,7 +496,9 @@ static int client__send_ipc(void)
488496
options.wait_if_busy = 1;
489497
options.wait_if_not_found = 0;
490498

491-
if (!ipc_client_send_command(cl_args.path, &options, command, &buf)) {
499+
if (!ipc_client_send_command(cl_args.path, &options,
500+
command, strlen(command),
501+
&buf)) {
492502
if (buf.len) {
493503
printf("%s\n", buf.buf);
494504
fflush(stdout);
@@ -556,7 +566,9 @@ static int do_sendbytes(int bytecount, char byte, const char *path,
556566
strbuf_addstr(&buf_send, "sendbytes ");
557567
strbuf_addchars(&buf_send, byte, bytecount);
558568

559-
if (!ipc_client_send_command(path, options, buf_send.buf, &buf_resp)) {
569+
if (!ipc_client_send_command(path, options,
570+
buf_send.buf, buf_send.len,
571+
&buf_resp)) {
560572
strbuf_rtrim(&buf_resp);
561573
printf("sent:%c%08d %s\n", byte, bytecount, buf_resp.buf);
562574
fflush(stdout);

0 commit comments

Comments
 (0)