[PATCH 2/2] Use enum types for remote fileio flags

Tom Tromey
2026-02-25T21:27:40Z

This changes gdbsupport/fileio.h to use enums with underlying types
for the various constants -- open flags, modes, and lseek flags.
These types replace #defines that were previously used.

Then, this fixes all the users of these flags. This found a few bugs.
Some of these were pedantic (using the constant 0700 where perhaps
FILEIO_S_IRWXU would be more precise), but sparc64-tdep.c confused
host and remote flags.

Also, I believe solib-rocm.c had a couple of arguments in the wrong
order. Once again, the solib-rocm.c changes are best-effort, as I
can't compile this file.

I also found that gdb/remote-fileio.c had essentially duplicated some
code from gdbsupport. This patch removes the duplicates.
---
gdb/inf-child.c | 4 +--
gdb/inf-child.h | 4 +--
gdb/linux-nat.c | 4 +--
gdb/linux-nat.h | 4 +--
gdb/remote-fileio.c | 91 +++++++++-------------------------------------------
gdb/remote.c | 19 ++++++-----
gdb/solib-rocm.c | 2 +-
gdb/sparc64-tdep.c | 5 +--
gdb/target.c | 13 +++++---
gdb/target.h | 10 +++---
gdbserver/hostio.cc | 4 +--
gdbsupport/fileio.cc | 20 ++++++------
gdbsupport/fileio.h | 81 ++++++++++++++++++++++++++--------------------
13 files changed, 111 insertions(+), 150 deletions(-)

diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 934d8c2ba09..22e52686d5e 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -233,8 +233,8 @@ inf_child_target::pid_to_exec_file (int pid)

int
inf_child_target::fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno)
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno)
{
int nat_flags;
mode_t nat_mode;
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
index bb18f08dbcf..7d2d4eab68e 100644
--- a/gdb/inf-child.h
+++ b/gdb/inf-child.h
@@ -74,8 +74,8 @@ class inf_child_target
const char *pid_to_exec_file (int pid) override;

int fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno) override;
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno) override;
int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
ULONGEST offset, fileio_error *target_errno) override;
int fileio_pread (int fd, gdb_byte *read_buf, int len,
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 958b367f4ea..22dbfbc31f9 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -4572,8 +4572,8 @@ linux_nat_fileio_pid_of (struct inferior *inf)

int
linux_nat_target::fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno)
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno)
{
int nat_flags;
mode_t nat_mode;
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index 4641615d531..2d2ccbc2371 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -100,8 +100,8 @@ class linux_nat_target : public inf_ptrace_target
bool filesystem_is_local () override;

int fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno) override;
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno) override;

std::optional<std::string>
fileio_readlink (struct inferior *inf,
diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index 459f249d37b..30afc3737ab 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -120,78 +120,6 @@ remote_fileio_close_target_fd (int target_fd)
remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
}

-static int
-remote_fileio_oflags_to_host (long flags)
-{
- int hflags = 0;
-
- if (flags & FILEIO_O_CREAT)
- hflags |= O_CREAT;
- if (flags & FILEIO_O_EXCL)
- hflags |= O_EXCL;
- if (flags & FILEIO_O_TRUNC)
- hflags |= O_TRUNC;
- if (flags & FILEIO_O_APPEND)
- hflags |= O_APPEND;
- if (flags & FILEIO_O_RDONLY)
- hflags |= O_RDONLY;
- if (flags & FILEIO_O_WRONLY)
- hflags |= O_WRONLY;
- if (flags & FILEIO_O_RDWR)
- hflags |= O_RDWR;
-/* On systems supporting binary and text mode, always open files in
- binary mode. */
-#ifdef O_BINARY
- hflags |= O_BINARY;
-#endif
- return hflags;
-}
-
-static mode_t
-remote_fileio_mode_to_host (long mode, int open_call)
-{
- mode_t hmode = 0;
-
- if (!open_call)
- {
- if (mode & FILEIO_S_IFREG)
- hmode |= S_IFREG;
- if (mode & FILEIO_S_IFDIR)
- hmode |= S_IFDIR;
- if (mode & FILEIO_S_IFCHR)
- hmode |= S_IFCHR;
- }
- if (mode & FILEIO_S_IRUSR)
- hmode |= S_IRUSR;
- if (mode & FILEIO_S_IWUSR)
- hmode |= S_IWUSR;
- if (mode & FILEIO_S_IXUSR)
- hmode |= S_IXUSR;
-#ifdef S_IRGRP
- if (mode & FILEIO_S_IRGRP)
- hmode |= S_IRGRP;
-#endif
-#ifdef S_IWGRP
- if (mode & FILEIO_S_IWGRP)
- hmode |= S_IWGRP;
-#endif
-#ifdef S_IXGRP
- if (mode & FILEIO_S_IXGRP)
- hmode |= S_IXGRP;
-#endif
- if (mode & FILEIO_S_IROTH)
- hmode |= S_IROTH;
-#ifdef S_IWOTH
- if (mode & FILEIO_S_IWOTH)
- hmode |= S_IWOTH;
-#endif
-#ifdef S_IXOTH
- if (mode & FILEIO_S_IXOTH)
- hmode |= S_IXOTH;
-#endif
- return hmode;
-}
-
static int
remote_fileio_seek_flag_to_host (long num, int *flag)
{
@@ -391,14 +319,23 @@ remote_fileio_func_open (remote_target *remote, char *buf)
remote_fileio_ioerror (remote);
return;
}
- flags = remote_fileio_oflags_to_host (num);
+ if (fileio_to_host_openflags ((enum fileio_open_flag) num, &flags))
+ {
+ remote_fileio_ioerror (remote);
+ return;
+ }
+
/* 3. Parameter: open mode */
if (remote_fileio_extract_int (&buf, &num))
{
remote_fileio_ioerror (remote);
return;
}
- mode = remote_fileio_mode_to_host (num, 1);
+ if (fileio_to_host_mode (fileio_mode_flag (num), &mode))
+ {
+ remote_fileio_ioerror (remote);
+ return;
+ }

/* Request pathname. */
pathname = (char *) alloca (length);
@@ -1233,8 +1170,10 @@ remote_fileio_to_host_ulong (fio_ulong_t fnum)
static mode_t
remote_fileio_to_host_mode (fio_mode_t fnum)
{
- return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
- 0);
+ mode_t result;
+ ULONGEST conv = remote_fileio_to_host_uint (fnum);
+ fileio_to_host_mode ((fileio_mode_flag) conv, &result);
+ return result;
}

/* Unpack an fio_time_t. */
diff --git a/gdb/remote.c b/gdb/remote.c
index 22f584f0c57..e5b6942287f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1114,7 +1114,8 @@ class remote_target : public process_stratum_target

int fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow,
fileio_error *target_errno) override;

int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
@@ -1289,8 +1290,8 @@ class remote_target : public process_stratum_target
fileio_error *remote_errno);
/* We should get rid of this and use fileio_open directly. */
int remote_hostio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *remote_errno);
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *remote_errno);
int remote_hostio_close (int fd, fileio_error *remote_errno);

int remote_hostio_unlink (inferior *inf, const char *filename,
@@ -13400,7 +13401,9 @@ remote_target::remote_hostio_set_filesystem (struct inferior *inf,

int
remote_target::remote_hostio_open (inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
+ fileio_open_flags flags,
+ fileio_mode_flags mode,
+ int warn_if_slow,
fileio_error *remote_errno)
{
struct remote_state *rs = get_remote_state ();
@@ -13446,8 +13449,8 @@ remote_target::remote_hostio_open (inferior *inf, const char *filename,

int
remote_target::fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *remote_errno)
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *remote_errno)
{
return remote_hostio_open (inf, filename, flags, mode, warn_if_slow,
remote_errno);
@@ -13828,7 +13831,7 @@ remote_target::filesystem_is_local ()
filename is irrelevant, we only care about whether
the stub recognizes the packet or not. */
fd = remote_hostio_open (NULL, "just probing",
- FILEIO_O_RDONLY, 0700, 0,
+ FILEIO_O_RDONLY, FILEIO_S_IRWXU, 0,
&remote_errno);

if (fd >= 0)
@@ -13960,7 +13963,7 @@ remote_target::remote_file_put (const char *local_file, const char *remote_file,
(this, remote_hostio_open (NULL,
remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
| FILEIO_O_TRUNC),
- 0700, 0, &remote_errno));
+ FILEIO_S_IRWXU, 0, &remote_errno));
if (fd.get () == -1)
remote_hostio_error (remote_errno);

diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c
index 6e05913696a..651a958f162 100644
--- a/gdb/solib-rocm.c
+++ b/gdb/solib-rocm.c
@@ -82,7 +82,7 @@ rocm_solib_fd_cache::open (const std::string &filename,
/* The file is not yet opened on the target. */
remote_fd fd
= target_fileio_open (m_inferior, filename.c_str (), FILEIO_O_RDONLY,
- false, 0, target_errno);
+ 0, false, target_errno);
if (fd != remote_fd::INVALID)
m_cache.emplace (std::piecewise_construct,
std::forward_as_tuple (filename),
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 6919a1c37d3..6733aa7cc48 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -287,8 +287,9 @@ adi_tag_fd ()
char cl_name[MAX_PROC_NAME_SIZE];
snprintf (cl_name, sizeof(cl_name), "/proc/%ld/adi/tags", (long) pid);
fileio_error target_errno;
- proc->stat.tag_fd = target_fileio_open (NULL, cl_name, O_RDWR|O_EXCL,
- false, 0, &target_errno);
+ proc->stat.tag_fd = target_fileio_open (NULL, cl_name,
+ FILEIO_O_RDWR | FILEIO_O_EXCL,
+ FILEIO_S_IRWXU, 0, &target_errno);
return proc->stat.tag_fd;
}

diff --git a/gdb/target.c b/gdb/target.c
index cfdf339b013..012ece5dad5 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3176,8 +3176,8 @@ fileio_fd_to_fh (remote_fd fd)

int
target_ops::fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno)
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno)
{
*target_errno = FILEIO_ENOSYS;
return -1;
@@ -3241,7 +3241,8 @@ target_ops::fileio_readlink (struct inferior *inf, const char *filename,

remote_fd
target_fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, bool warn_if_slow, fileio_error *target_errno)
+ fileio_open_flags flags, fileio_mode_flags mode,
+ bool warn_if_slow, fileio_error *target_errno)
{
for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
{
@@ -3259,7 +3260,8 @@ target_fileio_open (struct inferior *inf, const char *filename,

target_debug_printf_nofunc ("target_fileio_open (%d,%s,0x%x,0%o,%d) = %d (%d)",
inf == NULL ? 0 : inf->num, filename,
- flags, mode, warn_if_slow, int (fd),
+ unsigned (flags), unsigned (mode),
+ warn_if_slow, int (fd),
int (fd) != -1 ? 0 : *target_errno);
return result;
}
@@ -3479,7 +3481,8 @@ target_fileio_read_alloc_1 (struct inferior *inf, const char *filename,
fileio_error target_errno;

scoped_target_fd fd (target_fileio_open (inf, filename, FILEIO_O_RDONLY,
- 0700, false, &target_errno));
+ FILEIO_S_IRWXU, false,
+ &target_errno));
if (fd.get () == remote_fd::INVALID)
return -1;

diff --git a/gdb/target.h b/gdb/target.h
index 87cf8acac28..388acb9cff4 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -991,8 +991,8 @@ struct target_ops
target file descriptor, or -1 if an error occurs (and set
*TARGET_ERRNO). */
virtual int fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int warn_if_slow,
- fileio_error *target_errno);
+ fileio_open_flags flags, fileio_mode_flags mode,
+ int warn_if_slow, fileio_error *target_errno);

/* Write up to LEN bytes from WRITE_BUF to FD on the target.
Return the number of bytes written, or -1 if an error occurs
@@ -2264,8 +2264,10 @@ enum class remote_fd : int
*TARGET_ERRNO). If WARN_IF_SLOW is true, print a warning message
if the file is being accessed over a link that may be slow. */
extern remote_fd target_fileio_open (struct inferior *inf,
- const char *filename, int flags,
- int mode, bool warn_if_slow,
+ const char *filename,
+ fileio_open_flags flags,
+ fileio_mode_flags mode,
+ bool warn_if_slow,
fileio_error *target_errno);

/* Write up to LEN bytes from WRITE_BUF to FD on the target.
diff --git a/gdbserver/hostio.cc b/gdbserver/hostio.cc
index a0a0735deb4..b9ca27c2ff4 100644
--- a/gdbserver/hostio.cc
+++ b/gdbserver/hostio.cc
@@ -318,8 +318,8 @@ handle_open (char *own_buf)
|| require_comma (&p)
|| require_int (&p, &fileio_mode)
|| require_end (p)
- || fileio_to_host_openflags (fileio_flags, &flags)
- || fileio_to_host_mode (fileio_mode, &mode))
+ || fileio_to_host_openflags (fileio_open_flag (fileio_flags), &flags)
+ || fileio_to_host_mode (fileio_mode_flag (fileio_mode), &mode))
{
hostio_packet_error (own_buf);
return;
diff --git a/gdbsupport/fileio.cc b/gdbsupport/fileio.cc
index aedb67335ec..6d2ffb14544 100644
--- a/gdbsupport/fileio.cc
+++ b/gdbsupport/fileio.cc
@@ -130,26 +130,26 @@ fileio_error_to_host (fileio_error errnum)
/* See fileio.h. */

int
-fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p)
+fileio_to_host_openflags (fileio_open_flags fflags, int *open_flags_p)
{
int open_flags = 0;

- if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
+ if (fflags & ~FILEIO_O_SUPPORTED)
return -1;

- if (fileio_open_flags & FILEIO_O_CREAT)
+ if (fflags & FILEIO_O_CREAT)
open_flags |= O_CREAT;
- if (fileio_open_flags & FILEIO_O_EXCL)
+ if (fflags & FILEIO_O_EXCL)
open_flags |= O_EXCL;
- if (fileio_open_flags & FILEIO_O_TRUNC)
+ if (fflags & FILEIO_O_TRUNC)
open_flags |= O_TRUNC;
- if (fileio_open_flags & FILEIO_O_APPEND)
+ if (fflags & FILEIO_O_APPEND)
open_flags |= O_APPEND;
- if (fileio_open_flags & FILEIO_O_RDONLY)
+ if (fflags & FILEIO_O_RDONLY)
open_flags |= O_RDONLY;
- if (fileio_open_flags & FILEIO_O_WRONLY)
+ if (fflags & FILEIO_O_WRONLY)
open_flags |= O_WRONLY;
- if (fileio_open_flags & FILEIO_O_RDWR)
+ if (fflags & FILEIO_O_RDWR)
open_flags |= O_RDWR;
/* On systems supporting binary and text mode, always open files
in binary mode. */
@@ -164,7 +164,7 @@ fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p)
/* See fileio.h. */

int
-fileio_to_host_mode (int fileio_mode, mode_t *mode_p)
+fileio_to_host_mode (fileio_mode_flags fileio_mode, mode_t *mode_p)
{
mode_t mode = 0;

diff --git a/gdbsupport/fileio.h b/gdbsupport/fileio.h
index f7b1bdf6375..04ea99ea22c 100644
--- a/gdbsupport/fileio.h
+++ b/gdbsupport/fileio.h
@@ -21,6 +21,7 @@
#define GDBSUPPORT_FILEIO_H

#include <sys/stat.h>
+#include "enum-flags.h"

/* The following flags are defined to be independent of the host
as well as the target side implementation of these constants.
@@ -29,42 +30,54 @@
corresponding implementation dependent constants in one module. */

/* open(2) flags */
-#define FILEIO_O_RDONLY 0x0
-#define FILEIO_O_WRONLY 0x1
-#define FILEIO_O_RDWR 0x2
-#define FILEIO_O_APPEND 0x8
-#define FILEIO_O_CREAT 0x200
-#define FILEIO_O_TRUNC 0x400
-#define FILEIO_O_EXCL 0x800
-#define FILEIO_O_SUPPORTED (FILEIO_O_RDONLY | FILEIO_O_WRONLY| \
- FILEIO_O_RDWR | FILEIO_O_APPEND| \
- FILEIO_O_CREAT | FILEIO_O_TRUNC| \
- FILEIO_O_EXCL)
+enum fileio_open_flag : unsigned
+{
+ FILEIO_O_RDONLY = 0x0,
+ FILEIO_O_WRONLY = 0x1,
+ FILEIO_O_RDWR = 0x2,
+ FILEIO_O_APPEND = 0x8,
+ FILEIO_O_CREAT = 0x200,
+ FILEIO_O_TRUNC = 0x400,
+ FILEIO_O_EXCL = 0x800,
+ FILEIO_O_SUPPORTED = (FILEIO_O_RDONLY | FILEIO_O_WRONLY
+ | FILEIO_O_RDWR | FILEIO_O_APPEND
+ | FILEIO_O_CREAT | FILEIO_O_TRUNC
+ | FILEIO_O_EXCL),
+};
+DEF_ENUM_FLAGS_TYPE (enum fileio_open_flag, fileio_open_flags);

/* mode_t bits */
-#define FILEIO_S_IFREG 0100000
-#define FILEIO_S_IFDIR 040000
-#define FILEIO_S_IFCHR 020000
-#define FILEIO_S_IRUSR 0400
-#define FILEIO_S_IWUSR 0200
-#define FILEIO_S_IXUSR 0100
-#define FILEIO_S_IRWXU 0700
-#define FILEIO_S_IRGRP 040
-#define FILEIO_S_IWGRP 020
-#define FILEIO_S_IXGRP 010
-#define FILEIO_S_IRWXG 070
-#define FILEIO_S_IROTH 04
-#define FILEIO_S_IWOTH 02
-#define FILEIO_S_IXOTH 01
-#define FILEIO_S_IRWXO 07
-#define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \
- FILEIO_S_IRWXU|FILEIO_S_IRWXG| \
- FILEIO_S_IRWXO)
+enum fileio_mode_flag : unsigned
+{
+ FILEIO_S_IFREG = 0100000,
+ FILEIO_S_IFDIR = 040000,
+ FILEIO_S_IFCHR = 020000,
+ FILEIO_S_IRUSR = 0400,
+ FILEIO_S_IWUSR = 0200,
+ FILEIO_S_IXUSR = 0100,
+ FILEIO_S_IRWXU = 0700,
+ FILEIO_S_IRGRP = 040,
+ FILEIO_S_IWGRP = 020,
+ FILEIO_S_IXGRP = 010,
+ FILEIO_S_IRWXG = 070,
+ FILEIO_S_IROTH = 04,
+ FILEIO_S_IWOTH = 02,
+ FILEIO_S_IXOTH = 01,
+ FILEIO_S_IRWXO = 07,
+ FILEIO_S_SUPPORTED = (FILEIO_S_IFREG | FILEIO_S_IFDIR
+ | FILEIO_S_IRWXU | FILEIO_S_IRWXG
+ | FILEIO_S_IRWXO),
+};
+DEF_ENUM_FLAGS_TYPE (enum fileio_mode_flag, fileio_mode_flags);

/* lseek(2) flags */
-#define FILEIO_SEEK_SET 0
-#define FILEIO_SEEK_CUR 1
-#define FILEIO_SEEK_END 2
+enum fileio_lseek_flag : unsigned
+{
+ FILEIO_SEEK_SET = 0,
+ FILEIO_SEEK_CUR = 1,
+ FILEIO_SEEK_END = 2,
+};
+DEF_ENUM_FLAGS_TYPE (enum fileio_lseek_flag, fileio_lseek_flags);

/* errno values */
enum fileio_error
@@ -146,12 +159,12 @@ extern int fileio_error_to_host (fileio_error errnum);
/* Convert File-I/O open flags FFLAGS to host format, storing
the result in *FLAGS. Return 0 on success, -1 on error. */

-extern int fileio_to_host_openflags (int fflags, int *flags);
+extern int fileio_to_host_openflags (fileio_open_flags fflags, int *flags);

/* Convert File-I/O mode FMODE to host format, storing
the result in *MODE. Return 0 on success, -1 on error. */

-extern int fileio_to_host_mode (int fmode, mode_t *mode);
+extern int fileio_to_host_mode (fileio_mode_flags fmode, mode_t *mode);

/* Pack a host-format integer into a byte buffer in big-endian
format. BYTES specifies the size of the integer to pack in

--
2.53.0