[COMMITTED] a68: Fix POSIX fopen flags
Pietro Monteiro
pietro@sociotechnical.xyz
Fri Nov 14 05:20:47 GMT 2025
Caught while testing the lseek patch.
From: Pietro Monteiro <pietro@sociotechnical.xyz>
Subject: [PATCH] a68: Fix POSIX fopen flags
There was no check for the file_o_default flag, so add one.
Use the same values as glibc and musl for read only, read write, write
only and truncate flags.
gcc/ChangeLog:
* algol68/a68-low-prelude.cc (a68_lower_posixfileodefault): Sync
with libga68/ga68-posix.c.
(a68_lower_posixfileordwr): Likewise
(a68_lower_posixfileordonly): Likewise
(a68_lower_posixfileowronly): Likewise
(a68_lower_posixfileotrunc): Likewise
ChangeLog:
* libga68/ga68-posix.c (FILE_O_DEFAULT): Change to 0x99999999.
(FILE_O_RDONLY): Change to 0x0.
(FILE_O_WRONLY): Change to 0x1.
(FILE_O_RDWR): Change to 0x2.
(FILE_O_TRUNC): Change to 0x8.
(_libga68_open): New function.
(_libga68_posixfopen): When the default flag is passed try to
open the file read/write. Failing that, try write only,
failing that read only.
* libga68/ga68.h (_libga68_posixfopen): Adjust prototype.
Signed-off-by: Pietro Monteiro <pietro@sociotechnical.xyz>
---
gcc/algol68/a68-low-prelude.cc | 10 +++----
libga68/ga68-posix.c | 55 ++++++++++++++++++++++++++--------
libga68/ga68.h | 3 +-
3 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/gcc/algol68/a68-low-prelude.cc b/gcc/algol68/a68-low-prelude.cc
index 727dfd4e8ea..9181d1bb720 100644
--- a/gcc/algol68/a68-low-prelude.cc
+++ b/gcc/algol68/a68-low-prelude.cc
@@ -2036,7 +2036,7 @@ a68_lower_posixfileodefault (NODE_T *p ATTRIBUTE_UNUSED,
LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* Please keep in sync with libga68/ga68-posix.c */
- return build_int_cst (a68_bits_type, 0x0);
+ return build_int_cst (a68_bits_type, 0x99999999);
}
tree
@@ -2044,7 +2044,7 @@ a68_lower_posixfileordwr (NODE_T *p ATTRIBUTE_UNUSED,
LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* Please keep in sync with libga68/ga68-posix.c */
- return build_int_cst (a68_bits_type, 0x3);
+ return build_int_cst (a68_bits_type, 0x2);
}
tree
@@ -2052,7 +2052,7 @@ a68_lower_posixfileordonly (NODE_T *p ATTRIBUTE_UNUSED,
LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* Please keep in sync with libga68/ga68-posix.c */
- return build_int_cst (a68_bits_type, 0x1);
+ return build_int_cst (a68_bits_type, 0x0);
}
tree
@@ -2060,7 +2060,7 @@ a68_lower_posixfileowronly (NODE_T *p ATTRIBUTE_UNUSED,
LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* Please keep in sync with libga68/ga68-posix.c */
- return build_int_cst (a68_bits_type, 0x2);
+ return build_int_cst (a68_bits_type, 0x1);
}
tree
@@ -2068,7 +2068,7 @@ a68_lower_posixfileotrunc (NODE_T *p ATTRIBUTE_UNUSED,
LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* Please keep in sync with libga68/ga68-posix.c */
- return build_int_cst (a68_bits_type, 0x4);
+ return build_int_cst (a68_bits_type, 0x8);
}
tree
diff --git a/libga68/ga68-posix.c b/libga68/ga68-posix.c
index 51c92f1cdfe..108bb97f24c 100644
--- a/libga68/ga68-posix.c
+++ b/libga68/ga68-posix.c
@@ -73,19 +73,54 @@ _libga68_posixstrerror (int errnum, size_t *len)
return _libga68_u8_to_u32 ((const uint8_t *)str, strlen (str), NULL, len);
}
-#define FILE_O_DEFAULT 0x0
-#define FILE_O_RDONLY 0x1
-#define FILE_O_WRONLY 0x2
-#define FILE_O_RDWR 0x3
-#define FILE_O_TRUNC 0x4
+/* Helper for _libga68_posixfopen. */
+static int
+_libga68_open (const char *path, unsigned int flags)
+{
+ int fd = open (path, flags);
+ _libga68_errno = errno;
+ return fd;
+}
+
+#define FILE_O_DEFAULT 0x99999999
+#define FILE_O_RDONLY 0x0
+#define FILE_O_WRONLY 0x1
+#define FILE_O_RDWR 0x2
+#define FILE_O_TRUNC 0x8
int
-_libga68_posixfopen (uint32_t *pathname, size_t len, size_t stride,
+_libga68_posixfopen (const uint32_t *pathname, size_t len, size_t stride,
unsigned int flags)
{
+ int fd;
int openflags = 0;
size_t u8len;
- uint8_t *u8pathname = _libga68_u32_to_u8 (pathname, len, stride, NULL, &u8len);
+ const uint8_t *u8pathname = _libga68_u32_to_u8 (pathname, len, stride, NULL,
+ &u8len);
+ char *filepath = (char *) _libga68_malloc_internal (u8len + 1);
+ memcpy (filepath, u8pathname, u8len);
+ filepath[u8len] = '\0';
+
+ /* Default mode: try read-write initially.
+ If that fails, then try read-only.
+ If that fails, then try write-only. */
+ if (flags == FILE_O_DEFAULT)
+ {
+ openflags = O_RDWR;
+ if ((fd = _libga68_open (filepath, openflags)) < 0)
+ {
+ openflags = O_RDONLY;
+ if ((fd = _libga68_open (filepath, openflags)) < 0)
+ {
+ openflags = O_WRONLY;
+ fd = _libga68_open (filepath, openflags);
+ _libga68_free_internal (filepath);
+ return fd;
+ }
+ }
+ _libga68_free_internal (filepath);
+ return fd;
+ }
if (flags & FILE_O_RDONLY)
openflags |= O_RDONLY;
@@ -96,11 +131,7 @@ _libga68_posixfopen (uint32_t *pathname, size_t len, size_t stride,
if (flags & FILE_O_TRUNC)
openflags |= O_TRUNC;
- char *filepath = _libga68_malloc_internal (u8len + 1);
- memcpy (filepath, u8pathname, u8len);
- filepath[u8len] = '\0';
- int fd = open (filepath, openflags);
- _libga68_errno = errno;
+ fd = _libga68_open (filepath, openflags);
_libga68_free_internal (filepath);
return fd;
}
diff --git a/libga68/ga68.h b/libga68/ga68.h
index 4149d81c484..a7e4080c730 100644
--- a/libga68/ga68.h
+++ b/libga68/ga68.h
@@ -78,7 +78,8 @@ int _libga68_posixerrno (void);
void _libga68_posixperror (uint32_t *s, size_t len, size_t stride);
uint32_t *_libga68_posixstrerror (int errnum, size_t *len);
long long int _libga68_posixfsize (int fd);
-int _libga68_posixfopen (uint32_t *pathname, size_t len, size_t stride, unsigned int flags);
+int _libga68_posixfopen (const uint32_t *pathname, size_t len, size_t stride,
+ unsigned int flags);
int _libga68_posixcreat (uint32_t *pathname, size_t len, size_t stride, uint32_t mode);
int _libga68_posixclose (int fd);
int _libga68_posixargc (void);
--
2.43.0
More information about the Algol68
mailing list