Initial commit

- basic main.c implementation
- event_loop implementation
This commit is contained in:
Nikita Tyukalov, ASUS, Linux
2026-03-24 18:38:56 +03:00
parent b0a38edaad
commit c577779635
7 changed files with 243 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.swp
*.swo
build/

13
build.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/bash
# check if build directory exists
if [ -d build ]; then
echo "[I] build/ directory exists, deleting..."
rm -rf build
fi
# create build/ directory
mkdir build
# build
echo "[I] Building ipoim..."
gcc *.c $(curl-config --cflags) $(curl-config --libs) -I. -o build/ipoim

63
event_loop.c Normal file
View File

@@ -0,0 +1,63 @@
#include "event_loop.h"
#include <stdio.h>
#include <errno.h>
#include <sys/epoll.h>
/*
* Macros
*/
#define MAX_EPOLL_EVENTS (20)
/*
* Data
*/
static int _efd = -1;
static loop_cb_t _cb = NULL;
static struct epoll_event _evs[MAX_EPOLL_EVENTS];
/*
* Public API
*/
bool loop_init(loop_cb_t callback) {
_efd = epoll_create1(0);
if (_efd == -1) {
printf("[!] epoll_create1 failed: %d\n", errno);
return false;
}
_cb = callback;
return true;
}
void loop_deinit() {
close(_efd);
}
bool loop_ctl(int op, int fd, struct epoll_event *event) {
if (epoll_ctl(_efd, op, fd, event) == -1) {
printf("[!] epoll_ctl failed: %d\n", errno);
return false;
}
return true;
}
bool loop_wait() {
int result = epoll_wait(
_efd,
_evs,
MAX_EPOLL_EVENTS,
-1
);
if (result < 0) {
printf("[!] epoll_wait failed: %d\n", errno);
return false;
}
if (!result) {
return true;
}
for (int i = 0; i < result; ++i) {
_cb(_evs[i].data.fd, _evs[i].events);
}
return true;
}

59
event_loop.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef __EVENT_LOOP_H
#define __EVENT_LOOP_H
#include <stdint.h>
#include <stdbool.h>
#include <sys/epoll.h>
#include <unistd.h>
/*
* Type definitions
*/
typedef void (*loop_cb_t)(int fd, uint32_t events);
/*
* Public API
*/
// Initialize the event loop.
// Parameters:
// - callback - callback to use in loop_wait
// Returns:
// - true on success
// - false on failure
// Remarks:
// - must be called before event loop is used
bool loop_init(loop_cb_t callback);
// Finalize the event loop.
// - must be called on app termination
void loop_deinit();
// Set callback for file descriptor event.
// Remarks:
// - this callback gets called in loop_wait
void loop_set_callback(loop_cb_t callback);
// Call epoll_ctl.
// Parameters:
// - op - op
// - fd - fd
// - event - event
// Returns:
// - true on success
// - false on failure
// Remarks:
// - just calls epoll_ctl
bool loop_ctl(int op, int fd, struct epoll_event *event);
// Call epoll_wait and process the events.
// Returns:
// - true on success
// - false on failure
// Remarks:
// - you should terminate the app if this function
// fails
bool loop_wait();
#endif

99
main.c Normal file
View File

@@ -0,0 +1,99 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <sys/epoll.h>
#include <sys/signalfd.h>
#include "event_loop.h"
/*
* Data
*/
static bool _to_work = true;
static int _sig_fd = -1;
/*
* Private API
*/
// Initialize signals.
// Returns:
// - true on success
// Remarks:
// - loop_init() must be called before this one
static bool signals_init() {
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
printf("[!] sigprocmask failed: %d\n", errno);
return false;
}
_sig_fd = signalfd(
-1,
&mask,
SFD_NONBLOCK
);
if (_sig_fd == -1) {
printf("[!] signalfd failed: %d\n", errno);
return false;
}
struct epoll_event ev;
ev.data.fd = _sig_fd;
ev.events = EPOLLIN;
bool loop_res = loop_ctl(
EPOLL_CTL_ADD,
_sig_fd,
&ev
);
if (!loop_res) {
close(_sig_fd);
printf("[!] loop_ctl failed\n");
return false;
}
return true;
}
static void signals_deinit() {
close(_sig_fd);
}
/*
* Callbacks and main
*/
// This callback is called by loop_wait when event happens.
static void on_fd_event(int fd, uint32_t events) {
// Termination
if (fd == _sig_fd) {
_to_work = false;
}
else {
printf("[!] Event has happened on an unknown file descriptor\n");
}
}
int main(int argc, char **argv) {
if (!loop_init(on_fd_event)) {
return 1;
}
if (!signals_init()) {
loop_deinit();
return 1;
}
while (_to_work) {
if (!loop_wait()) {
printf("[!] loop_wait returns false, stopping...\n");
break;
}
printf("--- loop ---\n");
}
signals_deinit();
loop_deinit();
return 0;
}

0
utils.c Normal file
View File

6
utils.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef __UTILS_H
#define __UTILS_H
#endif