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