Date: Sat, 12 Jul 2025 11:33:01 -0700 From: Mark Millard <marklmi@yahoo.com> To: John Baldwin <jhb@freebsd.org>, Konstantin Belousov <kib@freebsd.org>, dev-commits-src-main@freebsd.org Subject: Re: git: ba0d9b43e940 - main - kern_descrip.c: provide helpers to translate between fd flags namespace Message-ID: <5BED6279-4414-45B5-8A2A-8DC42A07C4D9@yahoo.com> References: <5BED6279-4414-45B5-8A2A-8DC42A07C4D9.ref@yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
John Baldwin <jhb_at_FreeBSD.org> wrote on Date: Sat, 12 Jul 2025 17:07:28 UTC : > On 7/11/25 15:00, Konstantin Belousov wrote: > > On Fri, Jul 11, 2025 at 11:46:33AM -0400, John Baldwin wrote: > >> On 7/8/25 17:49, Konstantin Belousov wrote: > >>> The branch main has been updated by kib: > >>> > >>> URL: = https://cgit.FreeBSD.org/src/commit/?id=3Dba0d9b43e940077f4025e7e4e85d16c8= d525db79 > >>> > >>> commit ba0d9b43e940077f4025e7e4e85d16c8d525db79 > >>> Author: Konstantin Belousov <kib@FreeBSD.org> > >>> AuthorDate: 2025-07-08 16:30:29 +0000 > >>> Commit: Konstantin Belousov <kib@FreeBSD.org> > >>> CommitDate: 2025-07-08 21:48:59 +0000 > >>> > >>> kern_descrip.c: provide helpers to translate between fd flags = namespace > >>> Reviewed by: markj > >>> Sponsored by: The FreeBSD Foundation > >>> Differential revision: https://reviews.freebsd.org/D51206 > >>> --- > >>> sys/kern/kern_descrip.c | 110 = +++++++++++++++++++++++++++++++++++++++--------- > >>> 1 file changed, 90 insertions(+), 20 deletions(-) > >>> > >>> diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c > >>> index 406236fc2723..2e1da2fdee29 100644 > >>> --- a/sys/kern/kern_descrip.c > >>> +++ b/sys/kern/kern_descrip.c > >>> @@ -480,6 +480,90 @@ kern_fcntl_freebsd(struct thread *td, int fd, = int cmd, intptr_t arg) > >>> return (error); > >>> } > >>> +struct flags_trans_elem { > >>> + u_int f; > >>> + u_int t; > >>> +}; > >>> + > >>> +static u_int > >>> +flags_trans(const struct flags_trans_elem *ftes, int nitems, = u_int from_flags) > >>> +{ > >>> + u_int res; > >>> + int i; > >>> + > >>> + res =3D 0; > >>> + for (i =3D 0; i < nitems; i++) { > >>> + if ((from_flags & ftes[i].f) !=3D 0) > >>> + res |=3D ftes[i].t; > >>> + } > >>> + return (res); > >>> +} > >>> + > >>> +static uint8_t > >>> +fd_to_fde_flags(int fd_flags) > >>> +{ > >>> + static const struct flags_trans_elem fd_to_fde_flags_s[] =3D { > >>> + { .f =3D FD_CLOEXEC, .t =3D UF_EXCLOSE }, > >>> + { .f =3D FD_CLOFORK, .t =3D UF_FOCLOSE }, > >>> + { .f =3D FD_RESOLVE_BENEATH, .t =3D UF_RESOLVE_BENEATH }, > >>> + }; > >>> + > >>> + return (flags_trans(fd_to_fde_flags_s, = nitems(fd_to_fde_flags_s), > >>> + fd_flags)); > >>> +} > >>> + > >>> +static int > >>> +fde_to_fd_flags(uint8_t fde_flags) > >>> +{ > >>> + static const struct flags_trans_elem fde_to_fd_flags_s[] =3D { > >>> + { .f =3D UF_EXCLOSE, .t =3D FD_CLOEXEC }, > >>> + { .f =3D UF_FOCLOSE, .t =3D FD_CLOFORK }, > >>> + { .f =3D UF_RESOLVE_BENEATH, .t =3D FD_RESOLVE_BENEATH }, > >>> + }; > >>> + > >>> + return (flags_trans(fde_to_fd_flags_s, = nitems(fde_to_fd_flags_s), > >>> + fde_flags)); > >>> +} > >>> + > >>> +static uint8_t > >>> +fddup_to_fde_flags(int fddup_flags) > >>> +{ > >>> + static const struct flags_trans_elem fddup_to_fde_flags_s[] =3D = { > >>> + { .f =3D FDDUP_FLAG_CLOEXEC, .t =3D UF_EXCLOSE }, > >>> + { .f =3D FDDUP_FLAG_CLOFORK, .t =3D UF_FOCLOSE }, > >>> + }; > >>> + > >>> + return (flags_trans(fddup_to_fde_flags_s, = nitems(fddup_to_fde_flags_s), > >>> + fddup_flags)); > >>> +} > >>> + > >>> +static uint8_t > >>> +close_range_to_fde_flags(int close_range_flags) > >>> +{ > >>> + static const struct flags_trans_elem = close_range_to_fde_flags_s[] =3D { > >>> + { .f =3D CLOSE_RANGE_CLOEXEC, .t =3D UF_EXCLOSE }, > >>> + { .f =3D CLOSE_RANGE_CLOFORK, .t =3D UF_FOCLOSE }, > >>> + }; > >>> + > >>> + return (flags_trans(close_range_to_fde_flags_s, > >>> + nitems(close_range_to_fde_flags_s), close_range_flags)); > >>> +} > >>> + > >>> +static uint8_t > >>> +open_to_fde_flags(int open_flags, bool sticky_orb) > >>> +{ > >>> + static const struct flags_trans_elem open_to_fde_flags_s[] =3D { > >>> + { .f =3D O_CLOEXEC, .t =3D UF_EXCLOSE }, > >>> + { .f =3D O_CLOFORK, .t =3D UF_FOCLOSE }, > >>> + { .f =3D O_RESOLVE_BENEATH, .t =3D UF_RESOLVE_BENEATH }, > >>> + }; > >>> + _Static_assert(open_to_fde_flags_s[nitems(open_to_fde_flags_s) - = 1].f =3D=3D > >>> + O_RESOLVE_BENEATH, "O_RESOLVE_BENEATH must be last, for = sticky_orb"); > >> > >> This broke the GCC builds it seems. GCC doesn't think that it can = compute this > >> expression at compile time. > >> > >> =46rom = https://ci.freebsd.org/job/FreeBSD-main-amd64-gcc14_build/1022/console: > >> > >> 10:32:02 /workspace/src/sys/kern/kern_descrip.c: In function = 'open_to_fde_flags': > >> 10:32:02 /workspace/src/sys/kern/kern_descrip.c:560:79: error: = expression in static =3D > >> 10:32:02 assertion is not constant > >> 10:32:02 560 | = _Static_assert(open_to_fde_flags_s[nitems(open_to_fde_flags=3D > >> 10:32:02 _s) - 1].f =3D3D=3D3D > >> > >=20 > > I am unable to propose anything better than the patch below. We have = enough > > #ifdef __clang__ in non-contrib sources already, so this should be = not a > > huge crime? > >=20 > > % rg -g '!contrib/*' __clang__ | wc -l > > 171 > >=20 > > commit 96e6b15b0a1407af45ebe1ad38ee53627d09d16b > > Author: Konstantin Belousov <kib@FreeBSD.org> > > Date: Fri Jul 11 21:57:32 2025 +0300 > >=20 > > kern_descrip.c: only allow complex expression in Static_assert() for = clang > >=20 > > gcc cannot compute the assert expression. > >=20 > > Reported by: jhb > >=20 > > diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c > > index 93bdd41d1515..c4f5e586b0ed 100644 > > --- a/sys/kern/kern_descrip.c > > +++ b/sys/kern/kern_descrip.c > > @@ -557,8 +557,10 @@ open_to_fde_flags(int open_flags, bool = sticky_orb) > > { .f =3D O_CLOFORK, .t =3D UF_FOCLOSE }, > > { .f =3D O_RESOLVE_BENEATH, .t =3D UF_RESOLVE_BENEATH }, > > }; > > +#ifdef __clang__ > > _Static_assert(open_to_fde_flags_s[nitems(open_to_fde_flags_s) - = 1].f =3D=3D > > O_RESOLVE_BENEATH, "O_RESOLVE_BENEATH must be last, for = sticky_orb"); > > +#endif >=20 > I think this is fine. Mark Millard followed up with me offline and it = may be that > GCC is technically more correct here with what is allowed to be = computed as a static > constant at compile time FWIW. C++' constexpr allows for a wider range = of > compile-time constant values compared to C and this sort of thing = feels very > constexpr-like. gcc for this seems to stick to what is guaranteed by the C standards in this subject area. But the same N3220 text allows implementation-defined (non-portable) contexts as well: QUOTE An implementation may accept other forms of constant expressions; however, it is implementation defined whether they are an integer constant expression. END QUOTE So clang is not wrong to allow it --but it did not have to. The code is more portable without the array-content access where an integer constant expression is required, avoiding implementation defined aspects of the language definition. So testing for --and then usage of-- a known-to-be-implementation-defined context fits. =3D=3D=3D Mark Millard marklmi at yahoo.com
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5BED6279-4414-45B5-8A2A-8DC42A07C4D9>