ktp_session.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <sys/socket.h>
  11. #include <sys/un.h>
  12. #include <faux/str.h>
  13. #include <klish/ktp_session.h>
  14. #include "private.h"
  15. #define USOCK_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
  16. ktp_session_t *ktp_session_new(const char *sun_path)
  17. {
  18. ktp_session_t *session = NULL;
  19. assert(sun_path);
  20. if (!sun_path)
  21. return NULL;
  22. session = faux_zmalloc(sizeof(*session));
  23. assert(session);
  24. if (!session)
  25. return NULL;
  26. // Init
  27. session->state = KTP_SESSION_STATE_DISCONNECTED;
  28. session->sun_path = faux_str_dup(sun_path);
  29. assert(session->sun_path);
  30. session->net = faux_net_new();
  31. assert(session->net);
  32. return session;
  33. }
  34. void ktp_session_free(ktp_session_t *session)
  35. {
  36. if (!session)
  37. return;
  38. ktp_session_disconnect(session);
  39. faux_net_free(session->net);
  40. faux_str_free(session->sun_path);
  41. faux_free(session);
  42. }
  43. int ktp_session_connect(ktp_session_t *session)
  44. {
  45. int sock = -1;
  46. int opt = 1;
  47. struct sockaddr_un laddr = {};
  48. assert(session);
  49. if (!session)
  50. return -1;
  51. if (session->state != KTP_SESSION_STATE_DISCONNECTED)
  52. return faux_net_get_fd(session->net); // Already connected
  53. // Create socket
  54. if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
  55. return -1;
  56. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
  57. close(sock);
  58. return -1;
  59. }
  60. laddr.sun_family = AF_UNIX;
  61. strncpy(laddr.sun_path, session->sun_path, USOCK_PATH_MAX);
  62. laddr.sun_path[USOCK_PATH_MAX - 1] = '\0';
  63. // Connect to server
  64. if (connect(sock, (struct sockaddr *)&laddr, sizeof(laddr))) {
  65. close(sock);
  66. return -1;
  67. }
  68. // Update session state
  69. faux_net_set_fd(session->net, sock);
  70. session->state = KTP_SESSION_STATE_IDLE;
  71. return sock;
  72. }
  73. int ktp_session_disconnect(ktp_session_t *session)
  74. {
  75. int fd = -1;
  76. assert(session);
  77. if (!session)
  78. return -1;
  79. if (KTP_SESSION_STATE_DISCONNECTED == session->state)
  80. return -1; // Already disconnected
  81. session->state = KTP_SESSION_STATE_DISCONNECTED;
  82. fd = faux_net_get_fd(session->net);
  83. if (fd < 0)
  84. return fd; // Strange - already disconnected
  85. close(fd);
  86. faux_net_unset_fd(session->net);
  87. return fd;
  88. }