1 /* ISC license. */ 2 3 #ifndef UNIXMESSAGE_H 4 #define UNIXMESSAGE_H 5 6 #include <sys/uio.h> 7 #include <stdint.h> 8 #include <skalibs/gccattributes.h> 9 #include <skalibs/buffer.h> 10 #include <skalibs/cbuffer.h> 11 #include <skalibs/stralloc.h> 12 #include <skalibs/genalloc.h> 13 #include <skalibs/tai.h> 14 15 16 /* Message */ 17 18 typedef struct unixmessage_s unixmessage_t, *unixmessage_t_ref ; 19 struct unixmessage_s 20 { 21 char *s ; 22 size_t len ; 23 int *fds ; 24 unsigned int nfds ; 25 } ; 26 #define UNIXMESSAGE_ZERO { .s = 0, .len = 0, .fds = 0, .nfds = 0 } 27 extern unixmessage_t const unixmessage_zero ; 28 29 extern void unixmessage_drop (unixmessage_t const *) ; 30 31 typedef struct unixmessage_v_s unixmessage_v_t, *unixmessage_v_t_ref ; 32 struct unixmessage_v_s 33 { 34 struct iovec *v ; 35 unsigned int vlen ; 36 int *fds ; 37 unsigned int nfds ; 38 } ; 39 #define UNIXMESSAGE_V_ZERO { .v = 0, .vlen = 0, .fds = 0, .nfds = 0 } 40 extern unixmessage_v_t const unixmessage_v_zero ; 41 42 #define UNIXMESSAGE_MAXSIZE (1U << 28) 43 #define UNIXMESSAGE_MAXFDS 255 44 #define UNIXMESSAGE_BUFSIZE 2048 45 #define UNIXMESSAGE_AUXBUFSIZE (sizeof(int) * UNIXMESSAGE_MAXFDS + 1) 46 #define UNIXMESSAGE_MAXREADS 128 47 48 49 /* Sender */ 50 51 typedef void unixmessage_sender_closecb_func_t (int, void *) ; 52 typedef unixmessage_sender_closecb_func_t *unixmessage_sender_closecb_func_t_ref ; 53 54 typedef struct unixmessage_sender_s unixmessage_sender_t, *unixmessage_sender_t_ref ; 55 struct unixmessage_sender_s 56 { 57 int fd ; 58 stralloc data ; 59 genalloc fds ; /* int */ 60 genalloc offsets ; /* disize */ 61 size_t head ; 62 size_t shorty ; 63 unixmessage_sender_closecb_func_t_ref closecb ; 64 void *closecbdata ; 65 } ; 66 #define UNIXMESSAGE_SENDER_ZERO UNIXMESSAGE_SENDER_INIT(-1) 67 #define UNIXMESSAGE_SENDER_INIT(s) UNIXMESSAGE_SENDER_INIT_WITHCLOSECB((s), &unixmessage_sender_closecb, 0) 68 #define UNIXMESSAGE_SENDER_INIT_WITHCLOSECB(s, f, p) { .fd = (s), .data = STRALLOC_ZERO, .fds = GENALLOC_ZERO, .offsets = GENALLOC_ZERO, .head = 0, .shorty = 0, .closecb = (f), .closecbdata = (p) } 69 70 extern unixmessage_sender_t const unixmessage_sender_zero ; 71 extern unixmessage_sender_closecb_func_t unixmessage_sender_closecb ; 72 extern void unixmessage_sender_init (unixmessage_sender_t *, int) ; 73 extern void unixmessage_sender_init_withclosecb (unixmessage_sender_t *, int, unixmessage_sender_closecb_func_t_ref, void *) ; 74 extern void unixmessage_sender_free (unixmessage_sender_t *) ; 75 #define unixmessage_sender_fd(b) ((b)->fd) 76 extern int unixmessage_sender_getfd (unixmessage_sender_t const *) gccattr_pure ; 77 #define unixmessage_sender_isempty(b) (!genalloc_len(unsigned int, &(b)->offsets)) 78 79 extern int unixmessage_put_and_close (unixmessage_sender_t *, unixmessage_t const *, unsigned char const *) ; 80 #define unixmessage_put(b, m) unixmessage_put_and_close(b, m, unixmessage_bits_closenone) 81 extern int unixmessage_putv_and_close (unixmessage_sender_t *, unixmessage_v_t const *, unsigned char const *) ; 82 #define unixmessage_putv(b, m) unixmessage_putv_and_close(b, m, unixmessage_bits_closenone) 83 84 extern int unixmessage_unput_and_maybe_drop (unixmessage_sender_t *, int) ; 85 #define unixmessage_unput(b) unixmessage_unput_and_maybe_drop((b), 0) 86 #define unixmessage_unput_and_drop(b) unixmessage_unput_and_maybe_drop((b), 1) 87 88 extern unsigned char const *const unixmessage_bits_closenone ; 89 extern unsigned char const *const unixmessage_bits_closeall ; 90 91 extern int unixmessage_sender_flush (unixmessage_sender_t *) ; 92 extern int unixmessage_sender_timed_flush (unixmessage_sender_t *, tain_t const *, tain_t *) ; 93 #define unixmessage_sender_timed_flush_g(sender, deadline) unixmessage_sender_timed_flush(sender, (deadline), &STAMP) 94 95 96 /* Receiver */ 97 98 typedef struct unixmessage_receiver_s unixmessage_receiver_t, *unixmessage_receiver_t_ref ; 99 struct unixmessage_receiver_s 100 { 101 int fd ; 102 cbuffer_t mainb ; 103 cbuffer_t auxb ; 104 stralloc maindata ; 105 stralloc auxdata ; 106 uint32_t mainlen ; 107 uint16_t auxlen ; 108 unsigned int fds_ok : 2 ; 109 } ; 110 #define UNIXMESSAGE_RECEIVER_ZERO { .fd = -1, .mainb = CBUFFER_ZERO, .auxb = CBUFFER_ZERO, .maindata = STRALLOC_ZERO, .auxdata = STRALLOC_ZERO, .mainlen = 0, .auxlen = 0, .fds_ok = 3 } 111 #define UNIXMESSAGE_RECEIVER_INIT(d, mains, mainn, auxs, auxn) \ 112 { \ 113 .fd = d, \ 114 .mainb = CBUFFER_INIT(mains, mainn), \ 115 .auxb = CBUFFER_INIT(auxs, auxn), \ 116 .maindata = STRALLOC_ZERO, \ 117 .auxdata = STRALLOC_ZERO, \ 118 .mainlen = 0, \ 119 .auxlen = 0, \ 120 .fds_ok = 3 \ 121 } 122 extern int unixmessage_receiver_init (unixmessage_receiver_t *, int, char *, size_t, char *, size_t) ; 123 extern void unixmessage_receiver_free (unixmessage_receiver_t *) ; 124 #define unixmessage_receiver_fd(b) ((b)->fd) 125 #define unixmessage_receiver_isempty(b) (cbuffer_isempty(&(b)->mainb) && cbuffer_isempty(&(b)->auxb)) 126 #define unixmessage_receiver_isfull(b) (cbuffer_isfull(&(b)->mainb) || cbuffer_isfull(&(b)->auxb)) 127 128 extern int unixmessage_receiver_hasmsginbuf (unixmessage_receiver_t const *) ; 129 130 extern int unixmessage_receive (unixmessage_receiver_t *, unixmessage_t *) ; 131 extern int unixmessage_timed_receive (unixmessage_receiver_t *, unixmessage_t *, tain_t const *, tain_t *) ; 132 #define unixmessage_timed_receive_g(receiver, msg, deadline) unixmessage_timed_receive(receiver, msg, (deadline), &STAMP) 133 134 #define unixmessage_receiver_accept_fds(b) ((b)->fds_ok = 3) 135 #define unixmessage_receiver_refuse_fds(b) ((b)->fds_ok = 1) 136 #define unixmessage_receiver_ignore_fds(b) ((b)->fds_ok = 0) 137 138 typedef int unixmessage_handler_func_t (unixmessage_t const *, void *) ; 139 typedef unixmessage_handler_func_t *unixmessage_handler_func_t_ref ; 140 141 extern int unixmessage_handle (unixmessage_receiver_t *, unixmessage_handler_func_t_ref, void *) ; 142 extern int unixmessage_timed_handle (unixmessage_receiver_t *, unixmessage_handler_func_t_ref, void *, tain_t const *, tain_t *) ; 143 #define unixmessage_timed_handle_g(b, f, p, deadline) unixmessage_timed_handle(b, f, p, (deadline), &STAMP) 144 145 146 147 /* Globals */ 148 149 extern unixmessage_receiver_t unixmessage_receiver_0_ ; 150 #define unixmessage_receiver_0 (&unixmessage_receiver_0_) 151 152 extern unixmessage_sender_t unixmessage_sender_1_ ; 153 #define unixmessage_sender_1 (&unixmessage_sender_1_) 154 155 extern unixmessage_sender_t unixmessage_sender_x_ ; 156 #define unixmessage_sender_x (&unixmessage_sender_x_) 157 158 #endif 159