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