Page MenuHomeFreeBSD

null: support EVFILT_READ/EVFILT_WRITE kevent filters
ClosedPublic

Authored by gahr on Thu, Aug 7, 8:40 PM.
Tags
None
Referenced Files
F126384495: D51807.id160010.diff
Mon, Aug 18, 5:42 PM
Unknown Object (File)
Sun, Aug 17, 3:15 AM
Unknown Object (File)
Sat, Aug 16, 3:10 AM
Unknown Object (File)
Thu, Aug 14, 1:44 AM
Unknown Object (File)
Tue, Aug 12, 12:00 PM
Unknown Object (File)
Tue, Aug 12, 5:38 AM
Unknown Object (File)
Tue, Aug 12, 12:16 AM
Unknown Object (File)
Tue, Aug 12, 12:14 AM
Subscribers

Details

Summary

This enhances the full, null, and zero devices to support read and write kevent filters.

A read event is immediately triggered for full and null, and never for zero.
A write event is immediately triggered for zero and null, and never for full.

Relnotes: yes

Test Plan

The following program has been used:

#include <sys/event.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void test_event(int fd, int kq, const char *what, u_short flag)
{
    char buf = 'a';

    printf("  %s -> ", what);
    struct kevent event[2], tevent;
    EV_SET(&event[0], fd, flag, EV_ADD | EV_CLEAR, 0, 0, NULL);
    EV_SET(&event[1], fd, EVFILT_TIMER, EV_ADD, NOTE_SECONDS, 1, NULL);

    int rc = kevent(kq, event, 2, NULL, 0, NULL);
    if (rc == -1)
    {
        err(EXIT_FAILURE, "kevent (set)");
    }

    rc = kevent(kq, NULL, 0, &tevent, 1, NULL);
    if (rc == -1)
    {
        err(EXIT_FAILURE, "kevent (wait)");
    }
    else if (rc > 0)
    {
        if (tevent.flags & EV_ERROR)
        {
            err(EXIT_FAILURE, "kevent (flags)");
        }
        else
        {
            switch (tevent.filter)
            {
                case EVFILT_READ:
                    printf("read triggered -> ");
                    rc = read(fd, &buf, 1);
                    if (rc == -1)
                    {
                        printf("error: %s\n", strerror(errno));
                    }
                    else if (rc == 0)
                    {
                        printf("ok, EOF\n");
                    }
                    else
                    {
                        printf("ok, %0x\n", buf);
                    }
                    break;
                case EVFILT_WRITE:
                    printf("write triggered -> ");
                    rc = write(fd, &buf, 1);
                    if (rc == -1)
                    {
                        printf("error: %s\n", strerror(errno));
                    }
                    else
                    {
                        printf("ok, written\n");
                    }
                    break;
                case EVFILT_TIMER:
                    printf("timeout\n");
                    break;
                default:
                    printf("unknown event triggered\n");
                    break;
            }
        }
    }
}

void test(const char* path)
{
    printf("%s\n", path);
    int fd = open(path, O_RDWR);
    if (fd == -1)
    {
        err(EXIT_FAILURE, "open failed: %s\n", path);
    }

    int kq = kqueue();
    if (kq == -1)
    {
        err(EXIT_FAILURE, "kqueue failed\n");
    }

    test_event(fd, kq, "read", EVFILT_READ);
    test_event(fd, kq, "write", EVFILT_WRITE);

    close(kq);
    close(fd);
}

int main()
{
    test("/dev/null-o");
    test("/dev/full-o");
    test("/dev/zero-o");

    return 0;
}

The following output is expected:

/dev/null
  read -> timeout
  write -> write triggered -> ok, written
/dev/full
  read -> read triggered -> ok, 0
  write -> timeout
/dev/zero
  read -> read triggered -> ok, 0
  write -> write triggered -> ok, written

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 66087
Build 62970: arc lint + arc unit

Event Timeline

gahr requested review of this revision.Thu, Aug 7, 8:40 PM
This comment was removed by gahr.
This comment was removed by gahr.
This comment was removed by gahr.
This revision is now accepted and ready to land.Thu, Aug 7, 9:56 PM
This revision now requires review to proceed.Thu, Aug 7, 9:57 PM

Fix null and zero: null is write only, zero is read/write

This revision is now accepted and ready to land.Thu, Aug 7, 10:34 PM