Skip site navigation (1)Skip section navigation (2)
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>