interactive.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <faux/faux.h>
  7. #include <faux/eloop.h>
  8. #include <klish/ktp.h>
  9. #include <klish/ktp_session.h>
  10. #include <tinyrl/tinyrl.h>
  11. // Context for main loop
  12. typedef struct ctx_s {
  13. ktp_session_t *ktp;
  14. tinyrl_t *tinyrl;
  15. } ctx_t;
  16. bool_t cmd_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata);
  17. static bool_t stdin_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
  18. void *associated_data, void *user_data);
  19. int klish_interactive_shell(ktp_session_t *ktp)
  20. {
  21. ctx_t ctx = {};
  22. faux_eloop_t *eloop = NULL;
  23. tinyrl_t *tinyrl = NULL;
  24. int stdin_flags = 0;
  25. assert(ktp);
  26. if (!ktp)
  27. return -1;
  28. // Set stdin to O_NONBLOCK mode
  29. stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
  30. fcntl(STDIN_FILENO, F_SETFL, stdin_flags | O_NONBLOCK);
  31. tinyrl = tinyrl_new(stdin, stdout, NULL, 0);
  32. ctx.ktp = ktp;
  33. ctx.tinyrl = tinyrl;
  34. // Don't stop interactive loop on each answer
  35. ktp_session_set_stop_on_answer(ktp, BOOL_FALSE);
  36. ktp_session_set_cb(ktp, KTP_SESSION_CB_CMD_ACK, cmd_ack_cb, &ctx);
  37. eloop = ktp_session_eloop(ktp);
  38. faux_eloop_add_fd(eloop, STDIN_FILENO, POLLIN, stdin_cb, &ctx);
  39. faux_eloop_loop(eloop);
  40. // Cleanup
  41. tinyrl_free(tinyrl);
  42. // Restore stdin mode
  43. fcntl(STDIN_FILENO, F_SETFL, stdin_flags);
  44. return 0;
  45. }
  46. bool_t cmd_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
  47. {
  48. printf("CMD ACK CB\n");
  49. // Happy compiler
  50. ktp = ktp;
  51. msg = msg;
  52. udata = udata;
  53. ktp_session_set_done(ktp, BOOL_TRUE);
  54. return BOOL_TRUE;
  55. }
  56. static bool_t stdin_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
  57. void *associated_data, void *udata)
  58. {
  59. ctx_t *ctx = (ctx_t *)udata;
  60. tinyrl_read(ctx->tinyrl);
  61. // ktp_session_cmd(ctx->ktp, "cmd", NULL, BOOL_FALSE);
  62. return BOOL_TRUE;
  63. }