diff options
author | Denis Doria <denisdoria@gmail.com> | 2016-05-31 16:04:15 +0200 |
---|---|---|
committer | Denis Doria <denisdoria@gmail.com> | 2016-05-31 16:04:15 +0200 |
commit | 3c4c62301290991b790b90c840d18b398e0522c8 (patch) | |
tree | 9665fbaac9e2f7d099d7c54715404032ea406551 | |
parent | Initial work for floating view with sane values (diff) | |
parent | Merge pull request #637 from 1ace/fix/ipc-leak (diff) | |
download | sway-3c4c62301290991b790b90c840d18b398e0522c8.tar.gz sway-3c4c62301290991b790b90c840d18b398e0522c8.tar.zst sway-3c4c62301290991b790b90c840d18b398e0522c8.zip |
Merge branch 'master' into floating_size
-rw-r--r-- | sway/ipc-server.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 05041ec1..13e1837a 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -292,6 +292,11 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
292 | } | 292 | } |
293 | 293 | ||
294 | char *buf = malloc(client->payload_length + 1); | 294 | char *buf = malloc(client->payload_length + 1); |
295 | if (!buf) { | ||
296 | sway_log_errno(L_INFO, "Out of memory"); | ||
297 | ipc_client_disconnect(client); | ||
298 | return; | ||
299 | } | ||
295 | if (client->payload_length > 0) | 300 | if (client->payload_length > 0) |
296 | { | 301 | { |
297 | ssize_t received = recv(client->fd, buf, client->payload_length, 0); | 302 | ssize_t received = recv(client->fd, buf, client->payload_length, 0); |
@@ -303,28 +308,27 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
303 | return; | 308 | return; |
304 | } | 309 | } |
305 | } | 310 | } |
311 | buf[client->payload_length] = '\0'; | ||
306 | 312 | ||
307 | switch (client->current_command) { | 313 | switch (client->current_command) { |
308 | case IPC_COMMAND: | 314 | case IPC_COMMAND: |
309 | { | 315 | { |
310 | buf[client->payload_length] = '\0'; | ||
311 | struct cmd_results *results = handle_command(buf); | 316 | struct cmd_results *results = handle_command(buf); |
312 | const char *json = cmd_results_to_json(results); | 317 | const char *json = cmd_results_to_json(results); |
313 | char reply[256]; | 318 | char reply[256]; |
314 | int length = snprintf(reply, sizeof(reply), "%s", json); | 319 | int length = snprintf(reply, sizeof(reply), "%s", json); |
315 | ipc_send_reply(client, reply, (uint32_t) length); | 320 | ipc_send_reply(client, reply, (uint32_t) length); |
316 | free_cmd_results(results); | 321 | free_cmd_results(results); |
317 | break; | 322 | goto exit_cleanup; |
318 | } | 323 | } |
324 | |||
319 | case IPC_SUBSCRIBE: | 325 | case IPC_SUBSCRIBE: |
320 | { | 326 | { |
321 | buf[client->payload_length] = '\0'; | ||
322 | struct json_object *request = json_tokener_parse(buf); | 327 | struct json_object *request = json_tokener_parse(buf); |
323 | if (request == NULL) { | 328 | if (request == NULL) { |
324 | ipc_send_reply(client, "{\"success\": false}", 18); | 329 | ipc_send_reply(client, "{\"success\": false}", 18); |
325 | ipc_client_disconnect(client); | 330 | sway_log_errno(L_INFO, "Failed to read request"); |
326 | free(buf); | 331 | goto exit_cleanup; |
327 | return; | ||
328 | } | 332 | } |
329 | 333 | ||
330 | // parse requested event types | 334 | // parse requested event types |
@@ -344,18 +348,18 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
344 | #endif | 348 | #endif |
345 | } else { | 349 | } else { |
346 | ipc_send_reply(client, "{\"success\": false}", 18); | 350 | ipc_send_reply(client, "{\"success\": false}", 18); |
347 | ipc_client_disconnect(client); | ||
348 | json_object_put(request); | 351 | json_object_put(request); |
349 | free(buf); | 352 | sway_log_errno(L_INFO, "Failed to parse request"); |
350 | return; | 353 | goto exit_cleanup; |
351 | } | 354 | } |
352 | } | 355 | } |
353 | 356 | ||
354 | json_object_put(request); | 357 | json_object_put(request); |
355 | 358 | ||
356 | ipc_send_reply(client, "{\"success\": true}", 17); | 359 | ipc_send_reply(client, "{\"success\": true}", 17); |
357 | break; | 360 | goto exit_cleanup; |
358 | } | 361 | } |
362 | |||
359 | case IPC_GET_WORKSPACES: | 363 | case IPC_GET_WORKSPACES: |
360 | { | 364 | { |
361 | json_object *workspaces = json_object_new_array(); | 365 | json_object *workspaces = json_object_new_array(); |
@@ -363,8 +367,9 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
363 | const char *json_string = json_object_to_json_string(workspaces); | 367 | const char *json_string = json_object_to_json_string(workspaces); |
364 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); | 368 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); |
365 | json_object_put(workspaces); // free | 369 | json_object_put(workspaces); // free |
366 | break; | 370 | goto exit_cleanup; |
367 | } | 371 | } |
372 | |||
368 | case IPC_GET_INPUTS: | 373 | case IPC_GET_INPUTS: |
369 | { | 374 | { |
370 | json_object *inputs = json_object_new_array(); | 375 | json_object *inputs = json_object_new_array(); |
@@ -381,8 +386,9 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
381 | const char *json_string = json_object_to_json_string(inputs); | 386 | const char *json_string = json_object_to_json_string(inputs); |
382 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); | 387 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); |
383 | json_object_put(inputs); | 388 | json_object_put(inputs); |
384 | break; | 389 | goto exit_cleanup; |
385 | } | 390 | } |
391 | |||
386 | case IPC_GET_OUTPUTS: | 392 | case IPC_GET_OUTPUTS: |
387 | { | 393 | { |
388 | json_object *outputs = json_object_new_array(); | 394 | json_object *outputs = json_object_new_array(); |
@@ -390,8 +396,9 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
390 | const char *json_string = json_object_to_json_string(outputs); | 396 | const char *json_string = json_object_to_json_string(outputs); |
391 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); | 397 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); |
392 | json_object_put(outputs); // free | 398 | json_object_put(outputs); // free |
393 | break; | 399 | goto exit_cleanup; |
394 | } | 400 | } |
401 | |||
395 | case IPC_GET_VERSION: | 402 | case IPC_GET_VERSION: |
396 | { | 403 | { |
397 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE | 404 | #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE |
@@ -419,29 +426,29 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
419 | ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); | 426 | ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); |
420 | json_object_put(json); // free | 427 | json_object_put(json); // free |
421 | free(full_version); | 428 | free(full_version); |
422 | break; | 429 | goto exit_cleanup; |
423 | } | 430 | } |
431 | |||
424 | case IPC_SWAY_GET_PIXELS: | 432 | case IPC_SWAY_GET_PIXELS: |
425 | { | 433 | { |
426 | char response_header[9]; | 434 | char response_header[9]; |
427 | memset(response_header, 0, sizeof(response_header)); | 435 | memset(response_header, 0, sizeof(response_header)); |
428 | buf[client->payload_length] = '\0'; | ||
429 | swayc_t *output = swayc_by_test(&root_container, output_by_name_test, buf); | 436 | swayc_t *output = swayc_by_test(&root_container, output_by_name_test, buf); |
430 | if (!output) { | 437 | if (!output) { |
431 | sway_log(L_ERROR, "IPC GET_PIXELS request with unknown output name"); | 438 | sway_log(L_ERROR, "IPC GET_PIXELS request with unknown output name"); |
432 | ipc_send_reply(client, response_header, sizeof(response_header)); | 439 | ipc_send_reply(client, response_header, sizeof(response_header)); |
433 | break; | 440 | goto exit_cleanup; |
434 | } | 441 | } |
435 | struct get_pixels_request *req = malloc(sizeof(struct get_pixels_request)); | 442 | struct get_pixels_request *req = malloc(sizeof(struct get_pixels_request)); |
436 | req->client = client; | 443 | req->client = client; |
437 | req->output = output->handle; | 444 | req->output = output->handle; |
438 | list_add(ipc_get_pixel_requests, req); | 445 | list_add(ipc_get_pixel_requests, req); |
439 | wlc_output_schedule_render(output->handle); | 446 | wlc_output_schedule_render(output->handle); |
440 | break; | 447 | goto exit_cleanup; |
441 | } | 448 | } |
449 | |||
442 | case IPC_GET_BAR_CONFIG: | 450 | case IPC_GET_BAR_CONFIG: |
443 | { | 451 | { |
444 | buf[client->payload_length] = '\0'; | ||
445 | if (!buf[0]) { | 452 | if (!buf[0]) { |
446 | // Send list of configured bar IDs | 453 | // Send list of configured bar IDs |
447 | json_object *bars = json_object_new_array(); | 454 | json_object *bars = json_object_new_array(); |
@@ -455,7 +462,6 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
455 | json_object_put(bars); // free | 462 | json_object_put(bars); // free |
456 | } else { | 463 | } else { |
457 | // Send particular bar's details | 464 | // Send particular bar's details |
458 | buf[client->payload_length] = '\0'; | ||
459 | struct bar_config *bar = NULL; | 465 | struct bar_config *bar = NULL; |
460 | int i; | 466 | int i; |
461 | for (i = 0; i < config->bars->length; ++i) { | 467 | for (i = 0; i < config->bars->length; ++i) { |
@@ -468,23 +474,24 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
468 | if (!bar) { | 474 | if (!bar) { |
469 | const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }"; | 475 | const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }"; |
470 | ipc_send_reply(client, error, (uint32_t)strlen(error)); | 476 | ipc_send_reply(client, error, (uint32_t)strlen(error)); |
471 | break; | 477 | goto exit_cleanup; |
472 | } | 478 | } |
473 | json_object *json = ipc_json_describe_bar_config(bar); | 479 | json_object *json = ipc_json_describe_bar_config(bar); |
474 | const char *json_string = json_object_to_json_string(json); | 480 | const char *json_string = json_object_to_json_string(json); |
475 | ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); | 481 | ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); |
476 | json_object_put(json); // free | 482 | json_object_put(json); // free |
477 | break; | ||
478 | } | 483 | } |
484 | goto exit_cleanup; | ||
479 | } | 485 | } |
486 | |||
480 | default: | 487 | default: |
481 | sway_log(L_INFO, "Unknown IPC command type %i", client->current_command); | 488 | sway_log(L_INFO, "Unknown IPC command type %i", client->current_command); |
482 | ipc_client_disconnect(client); | 489 | goto exit_cleanup; |
483 | return; | ||
484 | } | 490 | } |
485 | 491 | ||
486 | client->payload_length = 0; | 492 | exit_cleanup: |
487 | free(buf); | 493 | free(buf); |
494 | return; | ||
488 | } | 495 | } |
489 | 496 | ||
490 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length) { | 497 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length) { |
@@ -499,13 +506,11 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay | |||
499 | 506 | ||
500 | if (write(client->fd, data, ipc_header_size) == -1) { | 507 | if (write(client->fd, data, ipc_header_size) == -1) { |
501 | sway_log_errno(L_INFO, "Unable to send header to IPC client"); | 508 | sway_log_errno(L_INFO, "Unable to send header to IPC client"); |
502 | ipc_client_disconnect(client); | ||
503 | return false; | 509 | return false; |
504 | } | 510 | } |
505 | 511 | ||
506 | if (write(client->fd, payload, payload_length) == -1) { | 512 | if (write(client->fd, payload, payload_length) == -1) { |
507 | sway_log_errno(L_INFO, "Unable to send payload to IPC client"); | 513 | sway_log_errno(L_INFO, "Unable to send payload to IPC client"); |
508 | ipc_client_disconnect(client); | ||
509 | return false; | 514 | return false; |
510 | } | 515 | } |
511 | 516 | ||
@@ -654,7 +659,10 @@ void ipc_send_event(const char *json_string, enum ipc_command_type event) { | |||
654 | continue; | 659 | continue; |
655 | } | 660 | } |
656 | client->current_command = event; | 661 | client->current_command = event; |
657 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); | 662 | if (!ipc_send_reply(client, json_string, (uint32_t) strlen(json_string))) { |
663 | sway_log_errno(L_INFO, "Unable to send reply to IPC client"); | ||
664 | ipc_client_disconnect(client); | ||
665 | } | ||
658 | } | 666 | } |
659 | } | 667 | } |
660 | 668 | ||