Skip to content

Instantly share code, notes, and snippets.

@bgaff
Created April 16, 2020 01:13
Show Gist options
  • Save bgaff/607302d86d99ac539efca307ce2dd679 to your computer and use it in GitHub Desktop.
Save bgaff/607302d86d99ac539efca307ce2dd679 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/userfaultfd.h>
struct test_data {
int uffd;
int read_res;
int read_errno;
};
static void *uffd_read_thread(void *arg)
{
struct test_data* data = (struct test_data*)arg;
int res;
struct uffd_msg msg;
res = read(data->uffd, &msg, sizeof(msg));
data->read_res = res;
data->read_errno = errno;
return NULL;
}
static int test_userfaultfd_closing(int close_timeout)
{
struct test_data data;
struct uffdio_api uffdio_api;
pthread_t read_thread;
int uffd = syscall(__NR_userfaultfd, 0);
assert(uffd != -1);
uffdio_api.api = UFFD_API;
uffdio_api.features = 0;
assert(ioctl(uffd, UFFDIO_API, &uffdio_api) != -1);
data.uffd = uffd;
assert(pthread_create(&read_thread, NULL,
uffd_read_thread, (void *)&data) == 0);
/* Wait for the other thread to enter the read */
usleep(1000*close_timeout);
assert(close(uffd) != -1);
assert(fcntl(uffd, F_GETFD) == -1 && errno == EBADF);
pthread_join(read_thread, NULL);
/* We should be woken up about the fd being closed */
fprintf(stderr, "read_res = %d, read_errno=%d\n",
data.read_res, data.read_errno);
assert(data.read_res == -1);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
return 1;
}
return test_userfaultfd_closing(atoi(argv[1]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment