svn commit: r352795 - head/lib/libc/sys

Bruce Evans brde at optusnet.com.au
Fri Sep 27 20:24:07 UTC 2019


On Fri, 27 Sep 2019, Konstantin Belousov wrote:

> On Fri, Sep 27, 2019 at 08:32:20PM +0200, Mateusz Guzik wrote:
>> On 9/27/19, Warner Losh <imp at freebsd.org> wrote:
>>> Author: imp
>>> Date: Fri Sep 27 16:11:47 2019
>>> New Revision: 352795
>>> URL: https://svnweb.freebsd.org/changeset/base/352795
>>>
>>> Log:
>>>   Document varadic args as int, since you can't have short varadic args
>>> (they are
>>>   promoted to ints).
>>>
>>>   - `mode_t` is `uint16_t` (`sys/sys/_types.h`)
>>>   - `openat` takes variadic args
>>>   - variadic args cannot be 16-bit, and indeed the code uses int
>>>   - the manpage currently kinda implies the argument is 16-bit by saying
>>> `mode_t`
>>>
>>>   Prompted by Rust things: https://github.com/tailhook/openat/issues/21
>>>   Submitted by: Greg V at unrelenting
>>>   Differential Revision: https://reviews.freebsd.org/D21816
>>>
>>> Modified:
>>>   head/lib/libc/sys/mq_open.2
>>>   head/lib/libc/sys/open.2
>>>
>>> Modified: head/lib/libc/sys/mq_open.2
>>> ==============================================================================
>>> --- head/lib/libc/sys/mq_open.2	Fri Sep 27 15:28:30 2019	(r352794)
>>> +++ head/lib/libc/sys/mq_open.2	Fri Sep 27 16:11:47 2019	(r352795)
>>> @@ -133,7 +133,7 @@ Create a message queue.
>>>  It requires two additional arguments:
>>>  .Fa mode ,
>>>  which is of type
>>> -.Vt mode_t ,
>>> +.Vt int ,
>>>  and
>>>  .Fa attr ,
>>>  which is a pointer to an
>>>
>>> Modified: head/lib/libc/sys/open.2
>>> ==============================================================================
>>> --- head/lib/libc/sys/open.2	Fri Sep 27 15:28:30 2019	(r352794)
>>> +++ head/lib/libc/sys/open.2	Fri Sep 27 16:11:47 2019	(r352795)
>>> @@ -61,7 +61,7 @@ In this case
>>>  and
>>>  .Fn openat
>>>  require an additional argument
>>> -.Fa "mode_t mode" ,
>>> +.Fa "int mode" ,
>>>  and the file is created with mode
>>>  .Fa mode
>>>  as described in
>>
>> But opengroup says it is mode_t. Perhaps it is mode_t which needs
>> to be changed?

POSIX needed to be changed before it became standard in 1988, but it is
too late now.  Types shorter than int shouldn't be used in APIs since
they cause ABI and API problems.  Especially in 1988 when non-prototyped
functions were common.  Non-prototyped functions use the default promotions
much like variadic functions.  open() is variadic, so its mode_t arg is
always promoted, but 'int chmod(const char *path, mode_t mode)' is just
wrong since in 1988 prototypes were not required and the prototype
matching the K&R API was 'int chmod(const char *path,
__default_promotion_of(mode_t) mode)'.

> Yes, users must pass mode_t, and the man page is written for users.
> Implementation needs to be aware of the implicit promotion and handle
> it accordingly.
>
> In theory, mode_t might be wider than int.

Indeed.  mode_t can also be the same size as int, but unsigned.  This
happens naturally if int is 16 bits, which POSIX allowed before 2001.
In V7, mode_t was really a 16-bit u_int, but it was type-punned to int.

When mode_t is u_int or wider than int, then the promotion is null, and
variadic and K&R do it consistently (but the arg type before the call
must be precisely mode_t, not int).

The POSIX list recently discussed a related problem with variadic pid_t
args for fcntl().  For F_SETOWN, the original arg type should be pid_t
as for mode_t for open().  Howver, F_GETOWN only returns int, so pids
larger than INT_MAX cannot work and making pid_t different from int is
just foot shooting.

Bruce


More information about the svn-src-all mailing list