summaryrefslogtreecommitdiff
path: root/src/include/skalibs/unixmessage.h
blob: 4c98ed6df09e30d074a1377060b613c8abff190d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* ISC license. */

#ifndef UNIXMESSAGE_H
#define UNIXMESSAGE_H

#include <sys/types.h>
#include <sys/uio.h>
#include <stdint.h>
#include <skalibs/gccattributes.h>
#include <skalibs/buffer.h>
#include <skalibs/cbuffer.h>
#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
#include <skalibs/tai.h>


 /* Message */

typedef struct unixmessage_s unixmessage_t, *unixmessage_t_ref ;
struct unixmessage_s
{
  char *s ;
  size_t 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
{
  struct iovec *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 (1U << 28)
#define UNIXMESSAGE_MAXFDS 255
#define UNIXMESSAGE_BUFSIZE 2048
#define UNIXMESSAGE_AUXBUFSIZE (sizeof(int) * UNIXMESSAGE_MAXFDS + 1)
#define UNIXMESSAGE_MAXREADS 32


 /* Sender */

typedef void unixmessage_sender_closecb_func_t (int, void *) ;
typedef unixmessage_sender_closecb_func_t *unixmessage_sender_closecb_func_t_ref ;

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 ; /* disize */
  size_t head ;
  size_t shorty ;
  unixmessage_sender_closecb_func_t_ref closecb ;
  void *closecbdata ;
} ;
#define UNIXMESSAGE_SENDER_ZERO UNIXMESSAGE_SENDER_INIT(-1)
#define UNIXMESSAGE_SENDER_INIT(s) UNIXMESSAGE_SENDER_INIT_WITHCLOSECB((s), &unixmessage_sender_closecb, 0)
#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) }

extern unixmessage_sender_t const unixmessage_sender_zero ;
extern unixmessage_sender_closecb_func_t unixmessage_sender_closecb ;
extern void unixmessage_sender_init (unixmessage_sender_t *, int) ;
extern void unixmessage_sender_init_withclosecb (unixmessage_sender_t *, int, unixmessage_sender_closecb_func_t_ref, void *) ;
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_t mainlen ;
  uint16_t 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 *, size_t, char *, size_t) ;
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_ref, void *) ;
extern int unixmessage_timed_handle (unixmessage_receiver_t *, unixmessage_handler_func_t_ref, 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