scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit a06980e91b715ab72c56024930712c5af8390da5
parent cae1735f86d590f9d71b407e895d81e60fb2bba1
Author: Michael Forney <mforney@mforney.org>
Date:   Sun,  3 Oct 2021 01:27:57 -0700

libc: Fix fopen with mode "r"

On all supported platforms, O_RDONLY is 0, so flags & O_RDONLY is
never true and the FILE does not get marked as _IOREAD, causing all
read operations to fail with EBADF.

To fix this, introduce O_ACCMODE in sys.h, containing a mask of the
bits used for the file access mode. Then, in _fpopen, switch on
access mode.

Diffstat:
Minclude/bits/darwin/sys.h | 1+
Minclude/bits/dragonfly/sys.h | 1+
Minclude/bits/linux/sys.h | 1+
Minclude/bits/netbsd/sys.h | 1+
Minclude/bits/openbsd/sys.h | 1+
Msrc/libc/stdio/_fpopen.c | 11++++++++---
6 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/include/bits/darwin/sys.h b/include/bits/darwin/sys.h @@ -1,6 +1,7 @@ #define O_RDONLY 0x00000000 #define O_WRONLY 0x00000001 #define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 #define O_TRUNC 0x00000400 #define O_APPEND 0x00000008 diff --git a/include/bits/dragonfly/sys.h b/include/bits/dragonfly/sys.h @@ -1,6 +1,7 @@ #define O_RDONLY 0x00000000 #define O_WRONLY 0x00000001 #define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 #define O_TRUNC 0x00000400 #define O_APPEND 0x00000008 diff --git a/include/bits/linux/sys.h b/include/bits/linux/sys.h @@ -1,6 +1,7 @@ #define O_RDONLY 0x00000000 #define O_WRONLY 0x00000001 #define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 #define O_TRUNC 0x00000200 #define O_APPEND 0x00000400 diff --git a/include/bits/netbsd/sys.h b/include/bits/netbsd/sys.h @@ -1,6 +1,7 @@ #define O_RDONLY 0x00000000 #define O_WRONLY 0x00000001 #define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 #define O_TRUNC 0x00000400 #define O_APPEND 0x00000008 diff --git a/include/bits/openbsd/sys.h b/include/bits/openbsd/sys.h @@ -1,6 +1,7 @@ #define O_RDONLY 0x00000000 #define O_WRONLY 0x00000001 #define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 #define O_TRUNC 0x00000400 #define O_APPEND 0x00000008 diff --git a/src/libc/stdio/_fpopen.c b/src/libc/stdio/_fpopen.c @@ -63,12 +63,17 @@ _fpopen(const char *restrict fname, if (!bin) fp->flags |= _IOTXT; - if (flags & O_RDWR) + switch (flags & O_ACCMODE) { + case O_RDWR: fp->flags |= _IORW; - else if (flags & O_RDONLY) + break; + case O_RDONLY: fp->flags |= _IOREAD; - else + break; + case O_WRONLY: fp->flags |= _IOWRITE; + break; + } fp->lp = fp->rp = fp->wp = NULL;