Bug 240015 - kqueue(2) manual example code is a bit wrong.
Summary: kqueue(2) manual example code is a bit wrong.
Status: Closed Overcome By Events
Alias: None
Product: Documentation
Classification: Unclassified
Component: Manual Pages (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Many People
Assignee: Bugmeister
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-08-21 15:14 UTC by Yoshisato Yanagisawa
Modified: 2024-02-24 00:01 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yoshisato Yanagisawa 2019-08-21 15:14:06 UTC
The example code used for kqueue (2) is a bit wrong.  Checking event.flags is
not needed.

What is expected?
Remove event.flags check like this:
@@ -655,8 +655,6 @@
     ret = kevent(kq, &event, 1, NULL, 0, NULL);
     if (ret == -1)
        err(EXIT_FAILURE, "kevent register");
-    if (event.flags & EV_ERROR)
-       errx(EXIT_FAILURE, "Event error: %s", strerror(event.data));

     for (;;) {
        /* Sleep until something happens. */

Why it is expected?
If I understand the manual correctly, if |nevents| argument is 0, -1 would
be returned for error, and it won't modify |changelist| argument.
In the above example, event.
>     The kevent() system call returns the number of events placed in the
>     eventlist, up to the value given by nevents.  If an error occurs while
>     processing an element of the changelist and there is enough room in the
>     eventlist, then the event will be placed in the eventlist with EV_ERROR
>     set in flags and the system error in data.  Otherwise, -1 will be
>     returned, and errno will be set to indicate the error condition.  If the
>     time limit expires, then kevent() returns 0.

However, the above code expect the kernel to update |event|.  Also, a caller
should not usually expect the callee updates const value.

I believe the following code explains my understanding is correct:
https://svnweb.freebsd.org/base/head/sys/kern/kern_event.c?revision=350421&view=markup#l1235
i.e. if |nevents| is 0, registration failure should be notified via return value instead of |changelist| parameter.

Note that this issue was not originally found by myself, but suggested by the person who is not familiar with filing a FreeBSD issue.  I confirmed the suggestion correct by investigating the kernel before filing the issue.
Also, note that NetBSD and OpenBSD use different example code and not affected by this issue.
Comment 1 unitrunker 2024-02-23 13:00:29 UTC
It looks to me as though the sample code was fixed.

         /* Initialize kevent structure. */
         EV_SET(&event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE,
             0, NULL);
         /* Attach event to the kqueue. */
         ret = kevent(kq, &event, 1, NULL, 0, NULL);
         if (ret == -1)
             err(EXIT_FAILURE, "kevent register");

         for (;;) {
             /* Sleep until something happens. */

Those two lines are now gone. @linimon I think this can be closed.
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2024-02-24 00:01:35 UTC
^Triage: apparently OBE.