/* ISC license. */ #ifndef UNIXMESSAGE_H #define UNIXMESSAGE_H #include #include #include #include #include #include #include #include #include /* Message */ typedef struct unixmessage_s unixmessage_t, *unixmessage_t_ref ; struct unixmessage_s { char *s ; unsigned int len ; int *fds ; unsigned int nfds ; } ; #define UNIXMESSAGE_ZERO { .s = 0, .len = 0, .fds = 0, .nfds = 0 } extern unixmessage_t const unixmessage_zero ; extern void unixmessage_drop (unixmessage_t const *) ; typedef struct unixmessage_v_s unixmessage_v_t, *unixmessage_v_t_ref ; struct unixmessage_v_s { siovec_t *v ; unsigned int vlen ; int *fds ; unsigned int nfds ; } ; #define UNIXMESSAGE_V_ZERO { .v = 0, .vlen = 0, .fds = 0, .nfds = 0 } extern unixmessage_v_t const unixmessage_v_zero ; #define UNIXMESSAGE_MAXSIZE (2U << 27) #define UNIXMESSAGE_MAXFDS 255 #define UNIXMESSAGE_BUFSIZE 2048 #define UNIXMESSAGE_AUXBUFSIZE (sizeof(int) * UNIXMESSAGE_MAXFDS + 1) #define UNIXMESSAGE_MAXREADS 32 /* Sender */ typedef struct unixmessage_sender_s unixmessage_sender_t, *unixmessage_sender_t_ref ; struct unixmessage_sender_s { int fd ; stralloc data ; genalloc fds ; /* int */ genalloc offsets ; /* diuint */ unsigned int head ; unsigned int shorty ; } ; #define UNIXMESSAGE_SENDER_ZERO UNIXMESSAGE_SENDER_INIT(-1) #define UNIXMESSAGE_SENDER_INIT(s) { .fd = (s), .data = STRALLOC_ZERO, .fds = GENALLOC_ZERO, .offsets = GENALLOC_ZERO, .head = 0, .shorty = 0 } extern unixmessage_sender_t const unixmessage_sender_zero ; extern void unixmessage_sender_init (unixmessage_sender_t *, int) ; extern void unixmessage_sender_free (unixmessage_sender_t *) ; #define unixmessage_sender_fd(b) ((b)->fd) extern int unixmessage_sender_getfd (unixmessage_sender_t const *) gccattr_pure ; #define unixmessage_sender_isempty(b) (!genalloc_len(unsigned int, &(b)->offsets)) extern int unixmessage_put_and_close (unixmessage_sender_t *, unixmessage_t const *, unsigned char const *) ; #define unixmessage_put(b, m) unixmessage_put_and_close(b, m, unixmessage_bits_closenone) extern int unixmessage_putv_and_close (unixmessage_sender_t *, unixmessage_v_t const *, unsigned char const *) ; #define unixmessage_putv(b, m) unixmessage_putv_and_close(b, m, unixmessage_bits_closenone) extern int unixmessage_unput_and_maybe_drop (unixmessage_sender_t *, int) ; #define unixmessage_unput(b) unixmessage_unput_and_maybe_drop((b), 0) #define unixmessage_unput_and_drop(b) unixmessage_unput_and_maybe_drop((b), 1) extern unsigned char const *const unixmessage_bits_closenone ; extern unsigned char const *const unixmessage_bits_closeall ; extern int unixmessage_sender_flush (unixmessage_sender_t *) ; extern int unixmessage_sender_timed_flush (unixmessage_sender_t *, tain_t const *, tain_t *) ; #define unixmessage_sender_timed_flush_g(sender, deadline) unixmessage_sender_timed_flush(sender, (deadline), &STAMP) /* Receiver */ typedef struct unixmessage_receiver_s unixmessage_receiver_t, *unixmessage_receiver_t_ref ; struct unixmessage_receiver_s { int fd ; cbuffer_t mainb ; cbuffer_t auxb ; stralloc maindata ; stralloc auxdata ; uint32 mainlen ; uint16 auxlen ; unsigned int fds_ok : 2 ; } ; #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 } #define UNIXMESSAGE_RECEIVER_INIT(d, mains, mainn, auxs, auxn) \ { \ .fd = d, \ .mainb = CBUFFER_INIT(mains, mainn), \ .auxb = CBUFFER_INIT(auxs, auxn), \ .maindata = STRALLOC_ZERO, \ .auxdata = STRALLOC_ZERO, \ .mainlen = 0, \ .auxlen = 0, \ .fds_ok = 3 \ } extern int unixmessage_receiver_init (unixmessage_receiver_t *, int, char *, unsigned int, char *, unsigned int) ; extern void unixmessage_receiver_free (unixmessage_receiver_t *) ; #define unixmessage_receiver_fd(b) ((b)->fd) #define unixmessage_receiver_isempty(b) (cbuffer_isempty(&(b)->mainb) && cbuffer_isempty(&(b)->auxb)) #define unixmessage_receiver_isfull(b) (cbuffer_isfull(&(b)->mainb) || cbuffer_isfull(&(b)->auxb)) extern int unixmessage_receive (unixmessage_receiver_t *, unixmessage_t *) ; extern int unixmessage_timed_receive (unixmessage_receiver_t *, unixmessage_t *, tain_t const *, tain_t *) ; #define unixmessage_timed_receive_g(receiver, msg, deadline) unixmessage_timed_receive(receiver, msg, (deadline), &STAMP) #define unixmessage_receiver_accept_fds(b) ((b)->fds_ok = 3) #define unixmessage_receiver_refuse_fds(b) ((b)->fds_ok = 1) #define unixmessage_receiver_ignore_fds(b) ((b)->fds_ok = 0) typedef int unixmessage_handler_func_t (unixmessage_t const *, void *) ; typedef unixmessage_handler_func_t *unixmessage_handler_func_t_ref ; extern int unixmessage_handle (unixmessage_receiver_t *, unixmessage_handler_func_t *, void *) ; extern int unixmessage_timed_handle (unixmessage_receiver_t *, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; #define unixmessage_timed_handle_g(b, f, p, deadline) unixmessage_timed_handle(b, f, p, (deadline), &STAMP) /* Globals */ extern unixmessage_receiver_t unixmessage_receiver_0_ ; #define unixmessage_receiver_0 (&unixmessage_receiver_0_) extern unixmessage_sender_t unixmessage_sender_1_ ; #define unixmessage_sender_1 (&unixmessage_sender_1_) extern unixmessage_sender_t unixmessage_sender_x_ ; #define unixmessage_sender_x (&unixmessage_sender_x_) #endif