/* File-I/O functions for GDB, the GNU debugger. Copyright (C) 2003-2023 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "common-defs.h" #include "fileio.h" #include #include /* See fileio.h. */ fileio_error host_to_fileio_error (int error) { switch (error) { case EPERM: return FILEIO_EPERM; case ENOENT: return FILEIO_ENOENT; case EINTR: return FILEIO_EINTR; case EIO: return FILEIO_EIO; case EBADF: return FILEIO_EBADF; case EACCES: return FILEIO_EACCES; case EFAULT: return FILEIO_EFAULT; case EBUSY: return FILEIO_EBUSY; case EEXIST: return FILEIO_EEXIST; case ENODEV: return FILEIO_ENODEV; case ENOTDIR: return FILEIO_ENOTDIR; case EISDIR: return FILEIO_EISDIR; case EINVAL: return FILEIO_EINVAL; case ENFILE: return FILEIO_ENFILE; case EMFILE: return FILEIO_EMFILE; case EFBIG: return FILEIO_EFBIG; case ENOSPC: return FILEIO_ENOSPC; case ESPIPE: return FILEIO_ESPIPE; case EROFS: return FILEIO_EROFS; case ENOSYS: return FILEIO_ENOSYS; case ENAMETOOLONG: return FILEIO_ENAMETOOLONG; } return FILEIO_EUNKNOWN; } /* See fileio.h. */ int fileio_error_to_host (fileio_error errnum) { switch (errnum) { case FILEIO_EPERM: return EPERM; case FILEIO_ENOENT: return ENOENT; case FILEIO_EINTR: return EINTR; case FILEIO_EIO: return EIO; case FILEIO_EBADF: return EBADF; case FILEIO_EACCES: return EACCES; case FILEIO_EFAULT: return EFAULT; case FILEIO_EBUSY: return EBUSY; case FILEIO_EEXIST: return EEXIST; case FILEIO_ENODEV: return ENODEV; case FILEIO_ENOTDIR: return ENOTDIR; case FILEIO_EISDIR: return EISDIR; case FILEIO_EINVAL: return EINVAL; case FILEIO_ENFILE: return ENFILE; case FILEIO_EMFILE: return EMFILE; case FILEIO_EFBIG: return EFBIG; case FILEIO_ENOSPC: return ENOSPC; case FILEIO_ESPIPE: return ESPIPE; case FILEIO_EROFS: return EROFS; case FILEIO_ENOSYS: return ENOSYS; case FILEIO_ENAMETOOLONG: return ENAMETOOLONG; } return -1; } /* See fileio.h. */ int fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p) { int open_flags = 0; if (fileio_open_flags & ~FILEIO_O_SUPPORTED) return -1; if (fileio_open_flags & FILEIO_O_CREAT) open_flags |= O_CREAT; if (fileio_open_flags & FILEIO_O_EXCL) open_flags |= O_EXCL; if (fileio_open_flags & FILEIO_O_TRUNC) open_flags |= O_TRUNC; if (fileio_open_flags & FILEIO_O_APPEND) open_flags |= O_APPEND; if (fileio_open_flags & FILEIO_O_RDONLY) open_flags |= O_RDONLY; if (fileio_open_flags & FILEIO_O_WRONLY) open_flags |= O_WRONLY; if (fileio_open_flags & FILEIO_O_RDWR) open_flags |= O_RDWR; /* On systems supporting binary and text mode, always open files in binary mode. */ #ifdef O_BINARY open_flags |= O_BINARY; #endif *open_flags_p = open_flags; return 0; } /* See fileio.h. */ int fileio_to_host_mode (int fileio_mode, mode_t *mode_p) { mode_t mode = 0; if (fileio_mode & ~FILEIO_S_SUPPORTED) return -1; if (fileio_mode & FILEIO_S_IFREG) mode |= S_IFREG; if (fileio_mode & FILEIO_S_IFDIR) mode |= S_IFDIR; if (fileio_mode & FILEIO_S_IFCHR) mode |= S_IFCHR; if (fileio_mode & FILEIO_S_IRUSR) mode |= S_IRUSR; if (fileio_mode & FILEIO_S_IWUSR) mode |= S_IWUSR; if (fileio_mode & FILEIO_S_IXUSR) mode |= S_IXUSR; #ifdef S_IRGRP if (fileio_mode & FILEIO_S_IRGRP) mode |= S_IRGRP; #endif #ifdef S_IWGRP if (fileio_mode & FILEIO_S_IWGRP) mode |= S_IWGRP; #endif #ifdef S_IXGRP if (fileio_mode & FILEIO_S_IXGRP) mode |= S_IXGRP; #endif if (fileio_mode & FILEIO_S_IROTH) mode |= S_IROTH; #ifdef S_IWOTH if (fileio_mode & FILEIO_S_IWOTH) mode |= S_IWOTH; #endif #ifdef S_IXOTH if (fileio_mode & FILEIO_S_IXOTH) mode |= S_IXOTH; #endif *mode_p = mode; return 0; } /* Convert a host-format mode_t into a bitmask of File-I/O flags. */ static LONGEST fileio_mode_pack (mode_t mode) { mode_t tmode = 0; if (S_ISREG (mode)) tmode |= FILEIO_S_IFREG; if (S_ISDIR (mode)) tmode |= FILEIO_S_IFDIR; if (S_ISCHR (mode)) tmode |= FILEIO_S_IFCHR; if (mode & S_IRUSR) tmode |= FILEIO_S_IRUSR; if (mode & S_IWUSR) tmode |= FILEIO_S_IWUSR; if (mode & S_IXUSR) tmode |= FILEIO_S_IXUSR; #ifdef S_IRGRP if (mode & S_IRGRP) tmode |= FILEIO_S_IRGRP; #endif #ifdef S_IWGRP if (mode & S_IWGRP) tmode |= FILEIO_S_IWGRP; #endif #ifdef S_IXGRP if (mode & S_IXGRP) tmode |= FILEIO_S_IXGRP; #endif if (mode & S_IROTH) tmode |= FILEIO_S_IROTH; #ifdef S_IWOTH if (mode & S_IWOTH) tmode |= FILEIO_S_IWOTH; #endif #ifdef S_IXOTH if (mode & S_IXOTH) tmode |= FILEIO_S_IXOTH; #endif return tmode; } /* Pack a host-format mode_t into an fio_mode_t. */ static void host_to_fileio_mode (mode_t num, fio_mode_t fnum) { host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4); } /* Pack a host-format integer into an fio_ulong_t. */ static void host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum) { host_to_bigendian (num, (char *) fnum, 8); } /* See fileio.h. */ void host_to_fileio_stat (struct stat *st, struct fio_stat *fst) { LONGEST blksize; host_to_fileio_uint ((long) st->st_dev, fst->fst_dev); host_to_fileio_uint ((long) st->st_ino, fst->fst_ino); host_to_fileio_mode (st->st_mode, fst->fst_mode); host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink); host_to_fileio_uint ((long) st->st_uid, fst->fst_uid); host_to_fileio_uint ((long) st->st_gid, fst->fst_gid); host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev); host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size); #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE blksize = st->st_blksize; #else blksize = 512; #endif host_to_fileio_ulong (blksize, fst->fst_blksize); #if HAVE_STRUCT_STAT_ST_BLOCKS host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks); #else /* FIXME: This is correct for DJGPP, but other systems that don't have st_blocks, if any, might prefer 512 instead of st_blksize. (eliz, 30-12-2003) */ host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1) / blksize, fst->fst_blocks); #endif host_to_fileio_time (st->st_atime, fst->fst_atime); host_to_fileio_time (st->st_mtime, fst->fst_mtime); host_to_fileio_time (st->st_ctime, fst->fst_ctime); }