various utils
parent
3851b60310
commit
45284910cc
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct eventloop;
|
||||||
|
|
||||||
|
struct eventloop *eventloop_new(void);
|
||||||
|
void eventloop_free(struct eventloop *el);
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "scoped.h"
|
||||||
|
|
||||||
|
static inline void _close_if_nonnegative(int fd) {
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_SCOPED_TYPE(fd, int, -1, _close_if_nonnegative)
|
||||||
|
|
||||||
|
#define FD_SCOPED(VAL) SCOPED(fd, int, VAL)
|
||||||
|
#define FD_CLOSE(FD) _scoped_fd_cleanup(FD)
|
||||||
|
#define FD_RELEASE(FD) _scoped_fd_release(FD)
|
||||||
|
|
||||||
|
static inline int setsockopt_int(int fd, int level, int option, int val) {
|
||||||
|
return setsockopt(fd, level, option, &val, sizeof(val));
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "scoped.h"
|
||||||
|
|
||||||
|
DEF_SCOPED_TYPE(mem, void *, NULL, free)
|
||||||
|
|
||||||
|
#define MEM_SCOPED(TYPE, VAL) SCOPED(mem, TYPE *, VAL)
|
||||||
|
#define MEM_FREE(TYPE, MEM) ({ CHECK_TYPE(TYPE **, MEM), (TYPE *)_scoped_mem_cleanup((void **)(MEM)); })
|
||||||
|
#define MEM_RELEASE(TYPE, MEM) ({ CHECK_TYPE(TYPE **, MEM), (TYPE *)_scoped_mem_release((void **)(MEM)); })
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CHECK_TYPE(TYPE, VAL) ({ \
|
||||||
|
typedef void (*_check_type_dummy_fn_t)(TYPE); \
|
||||||
|
_check_type_dummy_fn_t _check_type_dummy_fn = (_check_type_dummy_fn_t)NULL; \
|
||||||
|
if (0) \
|
||||||
|
_check_type_dummy_fn(VAL); \
|
||||||
|
1; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define DEF_SCOPED_TYPE(NAME, TYPE, UNOCCUPIED, CLEANUP_FN) \
|
||||||
|
static inline TYPE _scoped_##NAME##_unoccupied(void) { \
|
||||||
|
return (UNOCCUPIED); \
|
||||||
|
} \
|
||||||
|
static inline void _scoped_##NAME##_cleanup(TYPE *_val) { \
|
||||||
|
CLEANUP_FN(*_val); \
|
||||||
|
*_val = (UNOCCUPIED); \
|
||||||
|
} \
|
||||||
|
static inline void _scoped_##NAME##_cleanup_raw(void *_val) { \
|
||||||
|
_scoped_##NAME##_cleanup((TYPE *)_val); \
|
||||||
|
} \
|
||||||
|
static inline TYPE _scoped_##NAME##_release(TYPE *_val) { \
|
||||||
|
TYPE _released = *_val; \
|
||||||
|
*_val = (UNOCCUPIED); \
|
||||||
|
return _released; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCOPED(NAME, TYPE, VAL) \
|
||||||
|
TYPE VAL __attribute__((cleanup(_scoped_##NAME##_cleanup_raw))) = _scoped_##NAME##_unoccupied()
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "eventloop.h"
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
struct eventloop {
|
||||||
|
int kqueue_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eventloop *eventloop_new(void) {
|
||||||
|
MEM_SCOPED(struct eventloop, el);
|
||||||
|
|
||||||
|
if (!(el = malloc(sizeof(struct eventloop)))) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MEM_RELEASE(struct eventloop, &el);
|
||||||
|
}
|
||||||
|
|
||||||
|
void eventloop_free(struct eventloop *el) {
|
||||||
|
if (!el)
|
||||||
|
return;
|
||||||
|
close(el->kqueue_fd);
|
||||||
|
free(el);
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
|
str_buf_t sb_from_sv(str_view_t s) {
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if (sv_is_null(s) || sv_is_empty(s))
|
||||||
|
return SB_NULL;
|
||||||
|
|
||||||
|
if (!(buf = malloc(s.len + 1)))
|
||||||
|
return SB_NULL;
|
||||||
|
|
||||||
|
memcpy(buf, s.ptr, s.len);
|
||||||
|
buf[s.len] = 0;
|
||||||
|
return (str_buf_t) { buf, s.len };
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue