aboutsummaryrefslogtreecommitdiffstats
path: root/common.h
blob: 412a45ffced24d739de75b957665ae3a3dd0435b (plain) (blame)
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
158
159
160
161
162
163
/* See LICENSE file for copyright and license details. */
#include "libaxl.h"

#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pwd.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

#if defined(__linux__)
# include "internal-linux.h"
#endif

#if !defined(NO_LIBERROR)
# include <liberror.h>
#else
struct liberror_state {int err;};
# define liberror_start(STATEP)        ((STATEP)->err = errno)
# define liberror_end(STATEP)          (errno = (STATEP)->err)
# define liberror_save_backtrace(...)  ((void) 0)
# define liberror_set_error(...)       ((void) 0)
# define liberror_set_error_errno(...) ((void) 0)
# define liberror_reset_error()        ((void) 0)
# define liberror_pop_error()          ((void) 0)
#endif

#if !defined(NO_LIBERROR) && !defined(NO_LIBERROR_LIBC)
# include <liberror-libc.h>
#else
# if defined(NO_LIBERROR)
#  define __checked_int(X, _FUN)     X
#  define __checked_ptr(X, _FUN)     X
#  define __checked_ssize_t(X, _FUN) X
# else
#  define DEFINE_CHECKED(TYPE, NAME, ERR_IF)\
	static inline TYPE\
	NAME(TYPE ret, const char *func)\
	{\
		if (ERR_IF)\
			liberror_set_error_errno(strerror(errno), func, errno);\
		return ret;\
	}
DEFINE_CHECKED(int, __checked_int, ret < 0)
DEFINE_CHECKED(void *, __checked_ptr, !ret)
DEFINE_CHECKED(ssize_t, __checked_ssize_t, ret < 0)
# endif
# define liberror_snprintf(...)           __checked_int(snprintf(__VA_ARGS__), "snprintf")
# define liberror_close(FD)               __checked_int(close(FD), "close")
# define liberror_malloc(N)               __checked_ptr(malloc(N), "malloc")
# define liberror_calloc(N, M)            __checked_ptr(calloc(N, M), "calloc")
# define liberror_realloc(P, N)           __checked_ptr(realloc(P, N), "realloc")
# define liberror_send(FD, B, N, F, _NAM) __checked_ssize_t(send(FD, B, N, F), "send")
# define liberror_recv(FD, B, N, F, _NAM) __checked_ssize_t(recv(FD, B, N, F), "recv")
# define liberror_send_failed(FD, B, N, F, _NAM) ((void) 0)
# define liberror_recv_failed(FD, B, N, F, _NAM) ((void) 0)
#endif

#define X_TCP_PORT 6000

struct id_pool {
	uint32_t        first;
	uint32_t        last;
	struct id_pool *next;
};

struct libaxl_connection {
	int                              fd;
	uint16_t                         last_seqnum;
	LIBAXL_CONNECTION_RWLOCK;
	LIBAXL_CONTEXT                  *pending_out; /* TODO can _Atomic be used instead of mutex */
	size_t                           in_progress;
	size_t                           in_buf_size;
	char                            *in_buf;
	uint32_t                         xid_base;
	uint32_t                         xid_max;
	uint32_t                         xid_shift;
	volatile _Atomic uint32_t        xid_last;
	struct id_pool *_Atomic volatile xid_pool;
	uint8_t                          request_map[1UL << 16];
	struct libaxl_display_info       info;
	char                            *info_buf;
};

struct libaxl_context {
	LIBAXL_CONNECTION *conn;
	size_t             refcount;
	LIBAXL_CONTEXT    *next_pending_out;
	size_t             out_length;
	size_t             out_progress;
	size_t             out_buf_size;
	char              *out_buf;
	size_t             in_buf_size;
	char              *in_buf;
	size_t             aux_buf_size;
	char              *aux_buf;
};

#define ALIGN_VAR(VP, ALIGNMENT)\
	do {\
		if (*(VP) & ((ALIGNMENT) - 1)) {\
			*(VP) |= (ALIGNMENT) - 1;\
			*(VP) += 1;\
		}\
	} while (0)

#define ALIGN(VP, T) ALIGN_VAR(VP, _Alignof(T))

#define MAX(A, B) ((A) > (B) ? (A) : (B))

#if INT_MIN + 1 == -INT_MAX
# define TWOS_COMPLEMENT8(VP)  ((void)0)
# define TWOS_COMPLEMENT16(VP) ((void)0)
# define TWOS_COMPLEMENT32(VP) ((void)0)
#else
# define TWOS_COMPLEMENT8(VP)\
	do {\
		if (*(int8_t *)(VP) < 0)\
			*(uint8_t *)(VP) = (uint16_t)~(uint16_t)(-*(int16_t *)(VP) - 1)\
	} while (0)
# define TWOS_COMPLEMENT16(VP)\
	do {\
		if (*(int16_t *)(VP) < 0)\
			*(uint16_t *)(VP) = (uint16_t)~(uint16_t)(-*(int16_t *)(VP) - 1)\
	} while (0)
# define TWOS_COMPLEMENT32(VP)\
	do {\
		if (*(int32_t *)(VP) < 0)\
			*(uint32_t *)(VP) = (uint32_t)~(uint32_t)(-*(int32_t *)(VP) - 1)\
	} while (0)
#endif

#if INT_MIN + 1 == -INT_MAX
# define UNTWOS_COMPLEMENT8(VP)  ((void)0)
# define UNTWOS_COMPLEMENT16(VP) ((void)0)
# define UNTWOS_COMPLEMENT32(VP) ((void)0)
#else
# define UNTWOS_COMPLEMENT8(VP)\
	do {\
		if (*(uint8_t *)(VP) & ((uint8_t)1 << 7))\
			*(int8_t *)(VP) = -(int8_t)(~*(uint8_t *)(VP) + (uint8_t)1);\
	} while (0)
# define UNTWOS_COMPLEMENT16(VP)\
	do {\
		if (*(uint16_t *)(VP) & ((uint16_t)1 << 15))\
			*(int16_t *)(VP) = -(int16_t)(~*(uint16_t *)(VP) + (uint16_t)1);\
	} while (0)
# define UNTWOS_COMPLEMENT32(VP)\
	do {\
		if (*(uint32_t *)(VP) & ((uint32_t)1 << 31))\
			*(int32_t *)(VP) = -(int32_t)(~*(uint32_t *)(VP) + (uint32_t)1);\
	} while (0)
#endif