aboutsummaryrefslogblamecommitdiffstats
path: root/common.h
blob: 443bcc3352ebf9831adf405dc7b289ac24310aac (plain) (tree)
1
2
3
4
5
6
7
8



                                                         
                        

                       
                   



                   
                
                      
                  

                   
                    








                            


                                                              



                                                 
                                                 





                                                       
                                      


                                      
                                             


                                         
                            


                                                                                


                                                   
       

                                                                                          
                                                                            
                                                                               








                                                                                      





                              
                          

                                                     
                                 
                                                                                                    










                                                                











                                            

                                        

  
                                 
             

                                                  



                                    



                                               










































                                                                                         
/* 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; /* XXX 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