1 /* File-I/O functions for GDB, the GNU debugger. 2 3 Copyright (C) 2003-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "common-defs.h" 21 #include "fileio.h" 22 #include <sys/stat.h> 23 #include <fcntl.h> 24 25 /* See fileio.h. */ 26 27 fileio_error 28 host_to_fileio_error (int error) 29 { 30 switch (error) 31 { 32 case EPERM: 33 return FILEIO_EPERM; 34 case ENOENT: 35 return FILEIO_ENOENT; 36 case EINTR: 37 return FILEIO_EINTR; 38 case EIO: 39 return FILEIO_EIO; 40 case EBADF: 41 return FILEIO_EBADF; 42 case EACCES: 43 return FILEIO_EACCES; 44 case EFAULT: 45 return FILEIO_EFAULT; 46 case EBUSY: 47 return FILEIO_EBUSY; 48 case EEXIST: 49 return FILEIO_EEXIST; 50 case ENODEV: 51 return FILEIO_ENODEV; 52 case ENOTDIR: 53 return FILEIO_ENOTDIR; 54 case EISDIR: 55 return FILEIO_EISDIR; 56 case EINVAL: 57 return FILEIO_EINVAL; 58 case ENFILE: 59 return FILEIO_ENFILE; 60 case EMFILE: 61 return FILEIO_EMFILE; 62 case EFBIG: 63 return FILEIO_EFBIG; 64 case ENOSPC: 65 return FILEIO_ENOSPC; 66 case ESPIPE: 67 return FILEIO_ESPIPE; 68 case EROFS: 69 return FILEIO_EROFS; 70 case ENOSYS: 71 return FILEIO_ENOSYS; 72 case ENAMETOOLONG: 73 return FILEIO_ENAMETOOLONG; 74 } 75 return FILEIO_EUNKNOWN; 76 } 77 78 /* See fileio.h. */ 79 80 int 81 fileio_error_to_host (fileio_error errnum) 82 { 83 switch (errnum) 84 { 85 case FILEIO_EPERM: 86 return EPERM; 87 case FILEIO_ENOENT: 88 return ENOENT; 89 case FILEIO_EINTR: 90 return EINTR; 91 case FILEIO_EIO: 92 return EIO; 93 case FILEIO_EBADF: 94 return EBADF; 95 case FILEIO_EACCES: 96 return EACCES; 97 case FILEIO_EFAULT: 98 return EFAULT; 99 case FILEIO_EBUSY: 100 return EBUSY; 101 case FILEIO_EEXIST: 102 return EEXIST; 103 case FILEIO_ENODEV: 104 return ENODEV; 105 case FILEIO_ENOTDIR: 106 return ENOTDIR; 107 case FILEIO_EISDIR: 108 return EISDIR; 109 case FILEIO_EINVAL: 110 return EINVAL; 111 case FILEIO_ENFILE: 112 return ENFILE; 113 case FILEIO_EMFILE: 114 return EMFILE; 115 case FILEIO_EFBIG: 116 return EFBIG; 117 case FILEIO_ENOSPC: 118 return ENOSPC; 119 case FILEIO_ESPIPE: 120 return ESPIPE; 121 case FILEIO_EROFS: 122 return EROFS; 123 case FILEIO_ENOSYS: 124 return ENOSYS; 125 case FILEIO_ENAMETOOLONG: 126 return ENAMETOOLONG; 127 } 128 return -1; 129 } 130 131 /* See fileio.h. */ 132 133 int 134 fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p) 135 { 136 int open_flags = 0; 137 138 if (fileio_open_flags & ~FILEIO_O_SUPPORTED) 139 return -1; 140 141 if (fileio_open_flags & FILEIO_O_CREAT) 142 open_flags |= O_CREAT; 143 if (fileio_open_flags & FILEIO_O_EXCL) 144 open_flags |= O_EXCL; 145 if (fileio_open_flags & FILEIO_O_TRUNC) 146 open_flags |= O_TRUNC; 147 if (fileio_open_flags & FILEIO_O_APPEND) 148 open_flags |= O_APPEND; 149 if (fileio_open_flags & FILEIO_O_RDONLY) 150 open_flags |= O_RDONLY; 151 if (fileio_open_flags & FILEIO_O_WRONLY) 152 open_flags |= O_WRONLY; 153 if (fileio_open_flags & FILEIO_O_RDWR) 154 open_flags |= O_RDWR; 155 /* On systems supporting binary and text mode, always open files 156 in binary mode. */ 157 #ifdef O_BINARY 158 open_flags |= O_BINARY; 159 #endif 160 161 *open_flags_p = open_flags; 162 return 0; 163 } 164 165 /* See fileio.h. */ 166 167 int 168 fileio_to_host_mode (int fileio_mode, mode_t *mode_p) 169 { 170 mode_t mode = 0; 171 172 if (fileio_mode & ~FILEIO_S_SUPPORTED) 173 return -1; 174 175 if (fileio_mode & FILEIO_S_IFREG) 176 mode |= S_IFREG; 177 if (fileio_mode & FILEIO_S_IFDIR) 178 mode |= S_IFDIR; 179 if (fileio_mode & FILEIO_S_IFCHR) 180 mode |= S_IFCHR; 181 if (fileio_mode & FILEIO_S_IRUSR) 182 mode |= S_IRUSR; 183 if (fileio_mode & FILEIO_S_IWUSR) 184 mode |= S_IWUSR; 185 if (fileio_mode & FILEIO_S_IXUSR) 186 mode |= S_IXUSR; 187 #ifdef S_IRGRP 188 if (fileio_mode & FILEIO_S_IRGRP) 189 mode |= S_IRGRP; 190 #endif 191 #ifdef S_IWGRP 192 if (fileio_mode & FILEIO_S_IWGRP) 193 mode |= S_IWGRP; 194 #endif 195 #ifdef S_IXGRP 196 if (fileio_mode & FILEIO_S_IXGRP) 197 mode |= S_IXGRP; 198 #endif 199 if (fileio_mode & FILEIO_S_IROTH) 200 mode |= S_IROTH; 201 #ifdef S_IWOTH 202 if (fileio_mode & FILEIO_S_IWOTH) 203 mode |= S_IWOTH; 204 #endif 205 #ifdef S_IXOTH 206 if (fileio_mode & FILEIO_S_IXOTH) 207 mode |= S_IXOTH; 208 #endif 209 210 *mode_p = mode; 211 return 0; 212 } 213 214 /* Convert a host-format mode_t into a bitmask of File-I/O flags. */ 215 216 static LONGEST 217 fileio_mode_pack (mode_t mode) 218 { 219 mode_t tmode = 0; 220 221 if (S_ISREG (mode)) 222 tmode |= FILEIO_S_IFREG; 223 if (S_ISDIR (mode)) 224 tmode |= FILEIO_S_IFDIR; 225 if (S_ISCHR (mode)) 226 tmode |= FILEIO_S_IFCHR; 227 if (mode & S_IRUSR) 228 tmode |= FILEIO_S_IRUSR; 229 if (mode & S_IWUSR) 230 tmode |= FILEIO_S_IWUSR; 231 if (mode & S_IXUSR) 232 tmode |= FILEIO_S_IXUSR; 233 #ifdef S_IRGRP 234 if (mode & S_IRGRP) 235 tmode |= FILEIO_S_IRGRP; 236 #endif 237 #ifdef S_IWGRP 238 if (mode & S_IWGRP) 239 tmode |= FILEIO_S_IWGRP; 240 #endif 241 #ifdef S_IXGRP 242 if (mode & S_IXGRP) 243 tmode |= FILEIO_S_IXGRP; 244 #endif 245 if (mode & S_IROTH) 246 tmode |= FILEIO_S_IROTH; 247 #ifdef S_IWOTH 248 if (mode & S_IWOTH) 249 tmode |= FILEIO_S_IWOTH; 250 #endif 251 #ifdef S_IXOTH 252 if (mode & S_IXOTH) 253 tmode |= FILEIO_S_IXOTH; 254 #endif 255 return tmode; 256 } 257 258 /* Pack a host-format mode_t into an fio_mode_t. */ 259 260 static void 261 host_to_fileio_mode (mode_t num, fio_mode_t fnum) 262 { 263 host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4); 264 } 265 266 /* Pack a host-format integer into an fio_ulong_t. */ 267 268 static void 269 host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum) 270 { 271 host_to_bigendian (num, (char *) fnum, 8); 272 } 273 274 /* See fileio.h. */ 275 276 void 277 host_to_fileio_stat (struct stat *st, struct fio_stat *fst) 278 { 279 LONGEST blksize; 280 281 host_to_fileio_uint ((long) st->st_dev, fst->fst_dev); 282 host_to_fileio_uint ((long) st->st_ino, fst->fst_ino); 283 host_to_fileio_mode (st->st_mode, fst->fst_mode); 284 host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink); 285 host_to_fileio_uint ((long) st->st_uid, fst->fst_uid); 286 host_to_fileio_uint ((long) st->st_gid, fst->fst_gid); 287 host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev); 288 host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size); 289 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 290 blksize = st->st_blksize; 291 #else 292 blksize = 512; 293 #endif 294 host_to_fileio_ulong (blksize, fst->fst_blksize); 295 #if HAVE_STRUCT_STAT_ST_BLOCKS 296 host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks); 297 #else 298 /* FIXME: This is correct for DJGPP, but other systems that don't 299 have st_blocks, if any, might prefer 512 instead of st_blksize. 300 (eliz, 30-12-2003) */ 301 host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1) 302 / blksize, 303 fst->fst_blocks); 304 #endif 305 host_to_fileio_time (st->st_atime, fst->fst_atime); 306 host_to_fileio_time (st->st_mtime, fst->fst_mtime); 307 host_to_fileio_time (st->st_ctime, fst->fst_ctime); 308 } 309