examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

timerfd.c (1848B)


      1 #include <sys/epoll.h>
      2 #include <sys/timerfd.h>
      3 #include <unistd.h>
      4 #include <stdio.h>
      5 #include <stdint.h>
      6 #include <stdlib.h>
      7 #include <ctype.h>
      8 
      9 static int timer, event_queue;
     10 
     11 static void succeed_or_die(int n, char const* msg)
     12 {
     13 	if (n >= 0)
     14 		return;
     15 
     16 	perror(msg);
     17 	exit(1);
     18 }
     19 
     20 static void stdin_event(void)
     21 {
     22 	char buf[64];
     23 	int n = read(STDIN_FILENO, buf, sizeof buf - 1);
     24 
     25 	if (n <= 0)
     26 	{
     27 		puts("Stdin closed.");
     28 		exit(0);
     29 	}
     30 	for (int i = 0; i < n; ++i)
     31 		if (iscntrl(buf[i]))
     32 			buf[i] = '.';
     33 	buf[n] = '\0';
     34 
     35 	printf("Stdin: '%s'\n", buf);
     36 }
     37 
     38 static void timerfd_event(void)
     39 {
     40 	static uint64_t ticks;
     41 	uint64_t new_ticks;
     42 	read(timer, &new_ticks, sizeof new_ticks);
     43 	ticks += new_ticks;
     44 	printf("Tick +%lu %lu\n", new_ticks, ticks);
     45 }
     46 
     47 int main()
     48 {
     49 	timer = timerfd_create(CLOCK_MONOTONIC, 0);
     50 	succeed_or_die(timer, "timerfd_create");
     51 
     52 	int res = timerfd_settime(timer, 0, &(struct itimerspec){
     53                .it_interval = {1, 0},  /* Interval for periodic timer */
     54                .it_value = {1, 0},     /* Initial expiration */
     55         }, NULL);
     56 	succeed_or_die(res, "timerfd_settime");
     57 
     58 	event_queue = epoll_create1(0);
     59 	succeed_or_die(event_queue, "epoll_create2");
     60 
     61 	res = epoll_ctl(event_queue, EPOLL_CTL_ADD, STDIN_FILENO, &(struct epoll_event){
     62                .events = EPOLLIN,
     63                .data.ptr = stdin_event,
     64         });
     65 	succeed_or_die(res, "epoll_ctl");
     66 
     67 	res = epoll_ctl(event_queue, EPOLL_CTL_ADD, timer, &(struct epoll_event){
     68                .events = EPOLLIN,
     69                .data.ptr = timerfd_event,
     70         });
     71 	succeed_or_die(res, "epoll_ctl");
     72 
     73 	for (;;)
     74 	{
     75 		struct epoll_event events[8];
     76 		int n_events = epoll_wait(event_queue, events, sizeof events / sizeof *events, -1);
     77 		succeed_or_die(n_events, "epoll_wait");
     78 
     79 		for (int i = 0; i < n_events; ++i)
     80 			((void(*)(void))events[i].data.ptr)();
     81 	}
     82 }