For what I see in Linux headers
#define O_ACCMODE 00000003
#define O_RDONLY 00000000
#define O_WRONLY 00000001
 #define O_RDWR 00000002

So 3 seems to be a reserved value and because  O_RDONLY in Linux is defined
to 0 the 3 value from Linux is similar to 0 value in NuttX.

Regarding "Yes, for example if I want to set the serial device baud
rate(TCSETS), should I open it with O_WRONLY?" -- I do not have a complete
answer right now due to my competence in Linux is not strong, But what I
can find in the code that _IOC_WRITE and _IOC_READ bits are not checked
against the opened file mode, but specify the direction of data transfer
during ioctl call itself if the pointer is passed as an arg so in
combination of "#define _IOC_TYPECHECK(t) (sizeof(t))" and "_IOC_SIZESHIFT"
the callee know how many bytes need to be copied. Moreover there is a
comment before _IOC_READ and _IOC_WRITE definition:

/* * Direction bits, which any architecture can choose to override *
before including this file. */

So Linux FS layer can't rely on those definitions to do a f_mode checking
and some drivers that I inspected also didn't check the R/W mode of the
file. I most probably will not have time this week to prove it, but maybe
Mr. Xiang Xiao you can find some good Linux experts at Xiaomi and clarify
this question faster than me.

My personal opinion is the following:
1. The POSIX standard clearly defines that one of the five flags should be
passed (also fopen("test.txt", ""); will return NULL) so that should be
fixed and 0 should be invalid value for oflags.
2. "register_driver()" (fs_registerdriver) interface should sanitize and
ensure that at least one of read or write is non-NULL and assert otherwise.
This should be done to ensure that "inode_checkflags()" passes.
3. "register_driver()" (fs_registerdriver) interface should sanitize and
ensure that inode "mode" parameter does not contradict with the presence of
read and write methods otherwise it should assert. In other words if "mode"
contains "r" bits set while read method is NULL or "mode" contains "w" bits
while write is NULL should lead to an assert.
4. The VFS layer should provide the "dummy" read and write handlers that
can be reused by drivers. Dummy read should always return EOF while dummy
write should return that all data have been written.

Best regards,
Petro

сб, 2 квіт. 2022 р. о 17:17 Gregory Nutt <[email protected]> пише:

>
> > Yes, for example if I want to set the serial device baud rate(TCSETS),
> > should I open it with O_WRONLY?
>
> Linux has the concept of read IOCTLs and write IOCTLs as determined by
> the IOCTL macros.  My understanding is that you much provide O_RDONLY or
> O_RDWR to use the read IOCTLs and O_WRONLY or O_RDWR to use the write
> IOCTLs.
>
> But I am not sure of that and there are a lot of things I don't fully
> understand.  I have seen references to some mysterious Bit 3 in the open
> flags that can be used open IOCTL-only drivers.  Like
> https://github.com/NoHomey/open-ioctl:
>
>     "Opens device file in non-blocking ioctl mode. File is opend with
>     flags 3 | O_NONBLOCK.
>
>     "Flag 3 means that only ioctl calls can be made for comunication
>     with the device driver (remember read/write operations are expensive
>     this is why open-ioctl was made in first place to make it easer for
>     performance and command oriented device drivers)."
>
> My gut feeling is that these things are too non-standard and poorly
> thought out to be useful.
>
>

Reply via email to