Provided by: libvpoll-dev_0.1.1-1_amd64 bug

NAME

       vpoll_create, vpoll_ctl, vpoll_close - generate synthetic events for poll/select/ppoll/pselect/epoll

SYNOPSIS

       #include *vpoll.h*

       int vpoll_create(uint32_t init_events, int flags);

       int vpoll_ctl(int fd, int op, uint32_t events);

       int vpoll_close(int fd);

DESCRIPTION

       This  library  permits  one  to  create  a  vpoll  file descriptor “vpollfd” that can be used in poll/se‐
       lect/ppoll/pselect/epoll(2) system calls.  The events reported by  a  can  be  controlled  by  vpoll_ctl.
       vpoll encodes the events using the same flags EPOLL* defined in epoll_ctl(2).

       The  library uses the vpoll extension for eventfd if the kernel provides it otherwise it (partially) emu‐
       lates the feature using socketpair(2).  The emulation supports only EPOLLIN, EPOLLOUT  flags  and  a  non
       standard version of EPOLLHUP/EPOLLRDHUP.

       vpoll_create
              This  function  creates a “vpollfd”.  The argument init_events is used to set the initial state of
              events.  The following value can be included in flags:

              FD_CLOEXEC: Set the close-on-exec flag on the new file descriptor.  See  the  description  of  the
              O_CLOEXEC flag in open(2) for reasons why this may be useful.

       vpoll_ctl
              This function changes the set of pending events reported by a “vpollfd”.  The argument op can take
              the following values:

              VPOLL_CTL_ADDEVENTS: the events set in the argument events are added to the set of pending events.

              VPOLL_CTL_DELEVENTS:  the  events  set  in the argument events are deleted from the set of pending
              events.

              VPOLL_CTL_SETEVENTS: the value of the argument events is assigned to the set of pending events.

       vpoll_close
              This function closes the vpoll file descritor.

RETURN VALUE

       vpoll_create returns the new file descriptor, or -1 if an error occurred (in which case, errno is set ap‐
       propriately)

       vpoll_ctl and vpoll_close return zero in case of success.  On error, -1 is returned, and errno is set ap‐
       propriately.

EXAMPLE

              #define _GNU_SOURCE
              #include *stdio.h*
              #include *stdlib.h*
              #include *unistd.h*
              #include *fcntl.h*
              #include *errno.h*
              #include *sys/epoll.h*
              #include *vpoll.h*

              int main(int argc, char *argv[]) {
                int vpollfd = vpoll_create(0, FD_CLOEXEC);
                int epfd = epoll_create1(EPOLL_CLOEXEC);
                struct epoll_event reqevents={EPOLLIN | EPOLLRDHUP | EPOLLERR |
                    EPOLLOUT | EPOLLHUP | EPOLLPRI};
                epoll_ctl(epfd,  EPOLL_CTL_ADD, vpollfd, &reqevents);
                switch (fork()) {
                    case 0:
                        sleep(3);
                        vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLIN);
                        sleep(3);
                        vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLIN);
                        sleep(3);
                        vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLOUT);
                        sleep(3);
                        vpoll_ctl(vpollfd, VPOLL_CTL_ADDEVENTS,  EPOLLHUP);
                        sleep(3);
                        exit(0);
                    default:
                        while (1) {
                            struct epoll_event ev;
                            int n = epoll_wait(epfd, &ev, 1, 1000);
                            if (n * 0) {
                                perror("epoll_wait");
                                break;
                            }
                            if (n * 0) {
                                printf("GOT event %x\n", ev.events);
                                vpoll_ctl(vpollfd, VPOLL_CTL_DELEVENTS, ev.events);
                                if (ev.events & EPOLLHUP)
                                        break;
                            } else {
                                printf("timeout\n");
                            }
                        }
                        break;
                    case -1:
                        printf("fork error\n");
                }
                vpoll_close(vpollfd);
                close(epfd);
                return 0;
              }

       On a machine running a Linux Kernel providing eventfd/vpoll the output of this program is:

              timeout
              timeout
              GOT event 1
              timeout
              timeout
              GOT event 1
              timeout
              timeout
              GOT event 4
              timeout
              timeout
              GOT event 10

       Instead when the demo program runs using the emulation layer the output is:

              timeout
              timeout
              GOT event 1
              timeout
              timeout
              GOT event 1
              timeout
              timeout
              GOT event 4
              timeout
              timeout
              GOT event 2011

       In fact, the emulator uses a socketpair to generate the events.  Hangup is emulated by closing the  other
       end of the socketpair: this generates EPOLLHUP as well as EPOLLIN and EPOLLRDHUP.

AUTHOR

       VirtualSquare.  Project leader: Renzo Davoli.

VirtualSquare                                     December 2022                                         VPOLL(3)