Page MenuHomeFreeBSD

correct cap_rights_* varargs use
AcceptedPublic

Authored by emaste on Sep 15 2017, 3:02 PM.
Tags
None
Referenced Files
Unknown Object (File)
Jan 4 2024, 6:22 PM
Unknown Object (File)
Dec 20 2023, 8:41 AM
Unknown Object (File)
Dec 14 2023, 10:58 PM
Unknown Object (File)
Oct 17 2023, 10:42 PM
Unknown Object (File)
Sep 25 2023, 4:51 PM
Unknown Object (File)
Aug 24 2023, 4:51 PM
Unknown Object (File)
Aug 22 2023, 9:02 PM
Unknown Object (File)
Aug 5 2023, 1:11 PM
Subscribers
None

Details

Summary

The cap_rights_ macros actually have a non-optional 'cap_rights_t *' first argument followed by a variable number of additional arguments.

Reported by: Ben Laurie
Sponsored by: The FreeBSD Foundation

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Probably the goal of the original version was to avoid the non-standard "foo, ## bar" compiler extension. I am ok with the change, though.

This revision is now accepted and ready to land.Sep 15 2017, 3:26 PM
In D12380#256853, @cem wrote:

Probably the goal of the original version was to avoid the non-standard "foo, ## bar" compiler extension. I am ok with the change, though.

Perhaps, although we already use ##__VA_ARGS__ in many places. The alternative would be `#define cap_rights_init(rights...) but this introduces other awkwardness.

Wait. So the intent of this change is that we should disallow cap_rights_init(), etc. calls with empty arguments, right? If so, that's already prohibited right now:

$ cat foo.c
#include <sys/capsicum.h>

int main() {
  cap_rights_init();
  cap_rights_set();
  cap_rights_clear();
  cap_rights_is_set();
}
$ cc -o bla bla.c
bla.c:4:3: error: expected expression
  cap_rights_init();
  ^
/usr/include/sys/capsicum.h:320:51: note: expanded from macro 'cap_rights_init'
        __cap_rights_init(CAP_RIGHTS_VERSION, __VA_ARGS__, 0ULL)
                                                         ^
bla.c:5:3: error: expected expression
  cap_rights_set();
  ^
/usr/include/sys/capsicum.h:324:30: note: expanded from macro 'cap_rights_set'
        __cap_rights_set(__VA_ARGS__, 0ULL)
                                    ^
bla.c:6:3: error: expected expression
  cap_rights_clear();
  ^
/usr/include/sys/capsicum.h:328:32: note: expanded from macro 'cap_rights_clear'
        __cap_rights_clear(__VA_ARGS__, 0ULL)
                                      ^
bla.c:7:3: error: expected expression
  cap_rights_is_set();
  ^
/usr/include/sys/capsicum.h:332:33: note: expanded from macro 'cap_rights_is_set'
        __cap_rights_is_set(__VA_ARGS__, 0ULL)
                                       ^
4 errors generated.

The reason that empty calls are disallowed is because that would expand to cap_rights_is_set(, 0ULL); notice the bad comma. The advantage of the existing code is that it carefully avoids using ##__VA_ARGS__, which is only permitted in C (not C++) as of C99.

In D12380#256984, @ed wrote:

The reason that empty calls are disallowed is because that would expand to cap_rights_is_set(, 0ULL); notice the bad comma. The advantage of the existing code is that it carefully avoids using ##__VA_ARGS__, which is only permitted in C (not C++) as of C99.

Interesting. We do have a number of examples of ##__VA_ARGS__ in other headers, although it may well be that in practice they'll never be included in C++ source.

This was originally raised as a result of trying to use Capsicum with ffi which did not work with the previous approach.

Interesting. We do have a number of examples of ##__VA_ARGS__ in other headers, although it may well be that in practice they'll never be included in C++ source.

Clang does permit ##__VA_ARGS__ in C++ mode, but it will generate a warning if enough compiler flags are provided.

This was originally raised as a result of trying to use Capsicum with ffi which did not work with the previous approach.

I have to confess I've never used FFI before, so I won't be able to help you there. That said, I can imagine that existing set of functions/macros are quite unfriendly w.r.t. foreign language bindings. There is no way to call these functions with a list of variable size.

I suspect that other languages probably want to have native bindings only with unary calls and build their own wrappers to decompose calls where multiple rights are provided.